|
|
|
@ -14,14 +14,8 @@ enum GAMESTATE{ |
|
|
|
|
WAITING_FOR_CUTSCENE_3, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum TILES{ |
|
|
|
|
DIRT, |
|
|
|
|
GRASS, |
|
|
|
|
WATER, |
|
|
|
|
PLANTS |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum CUTSCENE{ |
|
|
|
|
NONE, |
|
|
|
|
PAN_DOME, |
|
|
|
|
PAUSE_TO_CUTSCENE_3, |
|
|
|
|
CUTSCENE_4, |
|
|
|
@ -39,6 +33,7 @@ class Object{ |
|
|
|
|
public: |
|
|
|
|
float x,y; |
|
|
|
|
olc::Decal*spr; |
|
|
|
|
std::string name; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class SeasonsOfLoneliness : public olc::PixelGameEngine |
|
|
|
@ -50,7 +45,7 @@ public: |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
GAMESTATE GAME_STATE=CUTSCENE_1; |
|
|
|
|
GAMESTATE GAME_STATE=GAMEWORLD; |
|
|
|
|
int textInd=0; |
|
|
|
|
int cursorX=0; |
|
|
|
|
int transitionTime=0; |
|
|
|
@ -67,7 +62,7 @@ public: |
|
|
|
|
float PLAYER_COORDS[2] = {}; |
|
|
|
|
std::vector<Object> OBJECTS; |
|
|
|
|
bool CUTSCENE_ACTIVE=false; |
|
|
|
|
CUTSCENE CURRENT_CUTSCENE=PAN_DOME; |
|
|
|
|
CUTSCENE CURRENT_CUTSCENE=NONE; |
|
|
|
|
int CUTSCENE_TIMER=0; |
|
|
|
|
bool CUTSCENE_FLAGS[8]; |
|
|
|
|
bool messageBoxVisible=false; |
|
|
|
@ -81,79 +76,27 @@ public: |
|
|
|
|
int foodCount=3; |
|
|
|
|
bool oxygenMeterVisible=false; |
|
|
|
|
int oxygenQualityLevel=34; |
|
|
|
|
int plantState=0b10010110101000101010100110101010; |
|
|
|
|
olc::SplashScreen splash; |
|
|
|
|
|
|
|
|
|
olc::Decal*DOME_DECAL,*FOOD_METER_DECAL,*OXYGEN_METER_DECAL; |
|
|
|
|
olc::Decal*DOME_DECAL,*FOOD_METER_DECAL,*OXYGEN_METER_DECAL,*PLANT_DECAL; |
|
|
|
|
std::map<std::string,olc::Decal*> BASE_OBJECTS; |
|
|
|
|
|
|
|
|
|
void LoadMap(char*mapName) { |
|
|
|
|
std::ifstream f(mapName); |
|
|
|
|
std::string data; |
|
|
|
|
MAP_WIDTH=MAP_HEIGHT=-1; |
|
|
|
|
if (MAP!=NULL) { |
|
|
|
|
for (int y=0;y<MAP_HEIGHT;y++) { |
|
|
|
|
free(MAP[y]); |
|
|
|
|
} |
|
|
|
|
free(MAP); |
|
|
|
|
MAP=NULL; |
|
|
|
|
} |
|
|
|
|
OBJECTS.clear(); |
|
|
|
|
|
|
|
|
|
int y=0; |
|
|
|
|
if (f.is_open()) { |
|
|
|
|
while (f.good()) { |
|
|
|
|
f>>data; |
|
|
|
|
if (MAP_WIDTH==-1) { |
|
|
|
|
std::stringstream stream(data); |
|
|
|
|
stream>>MAP_WIDTH; |
|
|
|
|
} else |
|
|
|
|
if (MAP_HEIGHT==-1) { |
|
|
|
|
std::stringstream stream(data); |
|
|
|
|
stream>>MAP_HEIGHT; |
|
|
|
|
} else
|
|
|
|
|
if (y<MAP_HEIGHT) { |
|
|
|
|
if (MAP==NULL) { |
|
|
|
|
MAP=(int**)malloc(sizeof(int**)*MAP_HEIGHT); |
|
|
|
|
} |
|
|
|
|
MAP[y]=(int*)malloc(sizeof(int*)*MAP_WIDTH); |
|
|
|
|
for (int i=0;i<data.length();i++) { |
|
|
|
|
MAP[y][i]=data[i]-'0'; |
|
|
|
|
} |
|
|
|
|
y++; |
|
|
|
|
} else { |
|
|
|
|
Object obj; |
|
|
|
|
std::stringstream split1(data.substr(0,data.find(';'))); |
|
|
|
|
split1>>obj.x; |
|
|
|
|
std::stringstream split2(data.substr(data.find(';')+1,data.find(';',data.find(";")+1)-(data.find(';')+1))); |
|
|
|
|
split2>>obj.y; |
|
|
|
|
std::string split3 = data.substr(data.find(';',data.find(";")+1)+1,data.length()-(data.find(';',data.find(";")+1)+1)); |
|
|
|
|
obj.spr=BASE_OBJECTS[split3]; |
|
|
|
|
printf("Loaded object %s: (%f,%f)\n",split3.c_str(),obj.x,obj.y); |
|
|
|
|
OBJECTS.push_back(obj); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
printf("Loaded %dx%d map:\n",MAP_WIDTH,MAP_HEIGHT); |
|
|
|
|
for (int y=0;y<MAP_HEIGHT;y++) { |
|
|
|
|
for (int x=0;x<MAP_WIDTH;x++) { |
|
|
|
|
printf("%d",MAP[y][x]); |
|
|
|
|
} |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool OnUserCreate() override |
|
|
|
|
{ |
|
|
|
|
SetPixelMode(olc::Pixel::ALPHA); |
|
|
|
|
//ConsoleCaptureStdOut(true);
|
|
|
|
|
ConsoleCaptureStdOut(true); |
|
|
|
|
//ConsoleShow(olc::F1,false);
|
|
|
|
|
// Called once at the start, so create things here
|
|
|
|
|
TILES=new olc::Decal(new olc::Sprite("assets/tiles.png")); |
|
|
|
|
DOME_DECAL=new olc::Decal(new olc::Sprite("assets/dome.png")); |
|
|
|
|
FOOD_METER_DECAL=new olc::Decal(new olc::Sprite("assets/corn.png")); |
|
|
|
|
OXYGEN_METER_DECAL=new olc::Decal(new olc::Sprite("assets/co2.png")); |
|
|
|
|
PLANT_DECAL=new olc::Decal(new olc::Sprite("assets/plant.png")); |
|
|
|
|
BASE_OBJECTS["DOME"]=DOME_DECAL; |
|
|
|
|
LoadMap("assets/maps/map1"); |
|
|
|
|
BASE_OBJECTS["PLANT"]=PLANT_DECAL; |
|
|
|
|
BASE_OBJECTS["EXIT"]=NULL; |
|
|
|
|
LoadMap("assets/maps/map2"); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -183,6 +126,9 @@ public: |
|
|
|
|
elapsedTime-=TARGET_RATE; |
|
|
|
|
updateGame(); |
|
|
|
|
} |
|
|
|
|
if (GetKey(olc::F1).bPressed) { |
|
|
|
|
ConsoleShow(olc::F1,false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
drawGame(); |
|
|
|
|
// called once per frame
|
|
|
|
@ -228,13 +174,12 @@ public: |
|
|
|
|
for (int i=0;i<8;i++) { |
|
|
|
|
CUTSCENE_FLAGS[i]=false; |
|
|
|
|
} |
|
|
|
|
CUTSCENE_ACTIVE=true; |
|
|
|
|
CUTSCENE_TIMER=0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void updateGame(){ |
|
|
|
|
frameCount++; |
|
|
|
|
if (CUTSCENE_ACTIVE) { |
|
|
|
|
if (CURRENT_CUTSCENE!=NONE) { |
|
|
|
|
CUTSCENE_TIMER++; |
|
|
|
|
} |
|
|
|
|
if (fade&&transparency<255) { |
|
|
|
@ -256,21 +201,27 @@ public: |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (GetKey(olc::F1).bPressed) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!CUTSCENE_ACTIVE&&!messageBoxVisible) { |
|
|
|
|
if (CURRENT_CUTSCENE==NONE&&!messageBoxVisible) { |
|
|
|
|
if (GetKey(olc::D).bHeld||GetKey(olc::RIGHT).bHeld) { |
|
|
|
|
PLAYER_COORDS[0]=clamp(PLAYER_COORDS[0]+MOVE_SPD,0.1,(double)MAP_WIDTH); |
|
|
|
|
ConsoleClear(); |
|
|
|
|
cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")"; |
|
|
|
|
} |
|
|
|
|
if (GetKey(olc::A).bHeld||GetKey(olc::LEFT).bHeld) { |
|
|
|
|
PLAYER_COORDS[0]=clamp(PLAYER_COORDS[0]-MOVE_SPD,0.1,(double)MAP_WIDTH); |
|
|
|
|
ConsoleClear(); |
|
|
|
|
cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")"; |
|
|
|
|
} |
|
|
|
|
if (GetKey(olc::W).bHeld||GetKey(olc::UP).bHeld) { |
|
|
|
|
PLAYER_COORDS[1]=clamp(PLAYER_COORDS[1]-MOVE_SPD,0.1,(double)MAP_HEIGHT); |
|
|
|
|
ConsoleClear(); |
|
|
|
|
cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")"; |
|
|
|
|
} |
|
|
|
|
if (GetKey(olc::S).bHeld||GetKey(olc::DOWN).bHeld) { |
|
|
|
|
PLAYER_COORDS[1]=clamp(PLAYER_COORDS[1]+MOVE_SPD,0.1,(double)MAP_HEIGHT); |
|
|
|
|
ConsoleClear(); |
|
|
|
|
cout<<"("<<PLAYER_COORDS[0]<<","<<PLAYER_COORDS[1]<<+")"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -443,6 +394,7 @@ public: |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
FillRectDecal({0,0},{WIDTH,HEIGHT},olc::Pixel(0,0,0,transparency)); |
|
|
|
|
FillRectDecal({WIDTH/2-2,HEIGHT/2-2},{4,4},olc::WHITE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void DrawGameWorld() { |
|
|
|
@ -460,13 +412,30 @@ public: |
|
|
|
|
tileRot++; |
|
|
|
|
} |
|
|
|
|
if ((int)(xOffset+x)>=0&&(int)(xOffset+x)<MAP_WIDTH&&(int)(yOffset+y)>=0&&(int)(yOffset+y)<MAP_HEIGHT) { |
|
|
|
|
DrawPartialRotatedDecal({(x-(PLAYER_COORDS[0]-(int)PLAYER_COORDS[0]))*32,(y-(PLAYER_COORDS[1]-(int)PLAYER_COORDS[1]))*32},TILES,tileRot*M_PI_2,{16,16},{tileX*32,0},{32,32},{1,1},TILE_COLORS[MAP[(int)(yOffset+y)][(int)(xOffset+x)]]); |
|
|
|
|
DrawPartialRotatedDecal({(x-(PLAYER_COORDS[0]-(int)PLAYER_COORDS[0])+1)*32-16,(y-(PLAYER_COORDS[1]-(int)PLAYER_COORDS[1])+1)*32},TILES,tileRot*M_PI_2,{16,16},{tileX*32,0},{32,32},{1,1},TILE_COLORS[MAP[(int)(yOffset+y)][(int)(xOffset+x)]]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for (auto&obj:OBJECTS) { |
|
|
|
|
if (obj.spr!=NULL) { |
|
|
|
|
if (obj.name.compare("PLANT")==0) { |
|
|
|
|
DrawPartialDecal({(obj.x-PLAYER_COORDS[0])*32+WIDTH/2,(obj.y-PLAYER_COORDS[1])*32+HEIGHT/2},{32,32},obj.spr,{getPlantStatus(obj)*32,0},{32,32}); |
|
|
|
|
} else { |
|
|
|
|
DrawDecal({(obj.x-PLAYER_COORDS[0])*32+WIDTH/2,(obj.y-PLAYER_COORDS[1])*32+HEIGHT/2},obj.spr); |
|
|
|
|
} |
|
|
|
|
} else
|
|
|
|
|
if (obj.name.compare("EXIT")==0) { |
|
|
|
|
GradientFillRectDecal({(obj.x-PLAYER_COORDS[0])*32+WIDTH/2,(obj.y-PLAYER_COORDS[1])*32+HEIGHT/2},{32,32},olc::Pixel(0,0,0,0),olc::WHITE,olc::WHITE,olc::Pixel(0,0,0,0)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int getPlantId(Object obj) { |
|
|
|
|
return ((int)obj.x-8)%4+((int)obj.y-2)*4; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int getPlantStatus(Object obj) { |
|
|
|
|
return plantState>>getPlantId(obj)*2&0b11; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void DrawDialogBox(const olc::vi2d &pos, const olc::vi2d &size, olc::Pixel p = olc::WHITE, olc::Pixel p2 = olc::DARK_GREY, olc::Pixel p3 = olc::VERY_DARK_GREY) { |
|
|
|
@ -486,6 +455,11 @@ public: |
|
|
|
|
void fadeIn() { |
|
|
|
|
fade=false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void EndCutscene() { |
|
|
|
|
CURRENT_CUTSCENE=NONE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void DisplayMessageBox(int dialogNumber) { |
|
|
|
|
messageBoxVisible=true; |
|
|
|
|
messageBoxCursor=0; |
|
|
|
@ -496,6 +470,67 @@ public: |
|
|
|
|
messageBoxText=""; |
|
|
|
|
messageBoxRefText=split3; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void LoadMap(char*mapName) { |
|
|
|
|
std::ifstream f(mapName); |
|
|
|
|
std::string data; |
|
|
|
|
MAP_WIDTH=MAP_HEIGHT=-1; |
|
|
|
|
if (MAP!=NULL) { |
|
|
|
|
for (int y=0;y<MAP_HEIGHT;y++) { |
|
|
|
|
free(MAP[y]); |
|
|
|
|
} |
|
|
|
|
free(MAP); |
|
|
|
|
MAP=NULL; |
|
|
|
|
} |
|
|
|
|
OBJECTS.clear(); |
|
|
|
|
|
|
|
|
|
int y=0; |
|
|
|
|
if (f.is_open()) { |
|
|
|
|
while (f.good()) { |
|
|
|
|
f>>data; |
|
|
|
|
if (MAP_WIDTH==-1) { |
|
|
|
|
std::stringstream stream(data); |
|
|
|
|
stream>>MAP_WIDTH; |
|
|
|
|
} else |
|
|
|
|
if (MAP_HEIGHT==-1) { |
|
|
|
|
std::stringstream stream(data); |
|
|
|
|
stream>>MAP_HEIGHT; |
|
|
|
|
} else
|
|
|
|
|
if (y<MAP_HEIGHT) { |
|
|
|
|
if (MAP==NULL) { |
|
|
|
|
MAP=(int**)malloc(sizeof(int**)*MAP_HEIGHT); |
|
|
|
|
} |
|
|
|
|
MAP[y]=(int*)malloc(sizeof(int*)*MAP_WIDTH); |
|
|
|
|
for (int i=0;i<data.length();i++) { |
|
|
|
|
MAP[y][i]=data[i]-'0'; |
|
|
|
|
} |
|
|
|
|
y++; |
|
|
|
|
} else { |
|
|
|
|
Object obj; |
|
|
|
|
std::stringstream split1(data.substr(0,data.find(';'))); |
|
|
|
|
split1>>obj.x; |
|
|
|
|
std::stringstream split2(data.substr(data.find(';')+1,data.find(';',data.find(";")+1)-(data.find(';')+1))); |
|
|
|
|
split2>>obj.y; |
|
|
|
|
std::string split3 = data.substr(data.find(';',data.find(";")+1)+1,data.length()-(data.find(';',data.find(";")+1)+1)); |
|
|
|
|
if (split3.compare("NULL")!=0) { |
|
|
|
|
obj.spr=BASE_OBJECTS[split3]; |
|
|
|
|
} else { |
|
|
|
|
obj.spr=NULL; |
|
|
|
|
} |
|
|
|
|
obj.name=split3; |
|
|
|
|
printf("Loaded object %s: (%f,%f)\n",split3.c_str(),obj.x,obj.y); |
|
|
|
|
OBJECTS.push_back(obj); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
printf("Loaded %dx%d map:\n",MAP_WIDTH,MAP_HEIGHT); |
|
|
|
|
for (int y=0;y<MAP_HEIGHT;y++) { |
|
|
|
|
for (int x=0;x<MAP_WIDTH;x++) { |
|
|
|
|
printf("%d",MAP[y][x]); |
|
|
|
|
} |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|