//// // Creation Routine //// CPlayGameVorticon::CPlayGameVorticon( CExeFile &ExeFile, char level, char numplayers, CSaveGameController &SavedGame) : CPlayGame(ExeFile, level, numplayers) { mMap.reset(new CMap()); m_level_command = (level==WORLD_MAP_LEVEL_VORTICON) ? GOTO_WORLD_MAP : START_LEVEL; if(!m_Player.empty()) m_Player.clear(); m_Player.assign(m_NumPlayers, CPlayer(m_Episode, m_Level, mp_level_completed, *mMap.get() ) ); for(int i=0 ; i<m_NumPlayers ; i++) { // Put some important Player properties CPlayer &thisPlayer = m_Player[i]; thisPlayer.m_index = i; thisPlayer.setDatatoZero(); thisPlayer.setupCameraObject(); thisPlayer.mpCamera->attachObject(&thisPlayer); } // Set the whole completed level list to false memset( mp_level_completed, false, MAX_LEVELS_VORTICON*sizeof(bool)); m_showPauseDialog = false; if(g_pBehaviorEngine->mDifficulty==EASY) g_pGfxEngine->Palette.setdarkness(FADE_DARKNESS_EASY); else if(g_pBehaviorEngine->mDifficulty==NORMAL) g_pGfxEngine->Palette.setdarkness(FADE_DARKNESS); else g_pGfxEngine->Palette.setdarkness(FADE_DARKNESS_HARD); }
/** * Initializes variables in CGlobalSyncedStuff */ CGlobalSyncedStuff::CGlobalSyncedStuff() { hmapx=256; hmapy=256; Uint64 li; li = SDL_GetTicks(); randSeed=18655;//li.LowPart; frameNum=0; speedFactor=1; userSpeedFactor=1; paused=false; cheatEnabled=false; noHelperAIs=false; editDefsEnabled=false; tempNum=2; gameMode=0; useLuaGaia=true; gaiaTeamID=-1; gaiaAllyTeamID=-1; useLuaRules=true; sunVector=float3(0,0,1); sunVector4[0]=0; sunVector4[1]=0; sunVector4[2]=1; sunVector4[3]=0; for(int a=0;a<MAX_TEAMS;a++){ teams[a]=SAFE_NEW CTeam(); teams[a]->teamNum=a; team2allyteam[a]=a; } for(int a=0;a<MAX_PLAYERS;a++){ players[a]=SAFE_NEW CPlayer(); players[a]->team=(a%2); } for(int a=0;a<MAX_TEAMS;++a){ for(int b=0;b<MAX_TEAMS;++b){ allies[a][b]=false; } allies[a][a]=true; } activeTeams=2; activeAllyTeams=2; activePlayers=MAX_PLAYERS; teams[0]->active=true; teams[1]->active=true; sunVector=float3(0,1,2).Normalize(); gravity = -0.1f; }
//// // Creation Routine //// CPlayGameVorticon::CPlayGameVorticon( CExeFile &ExeFile, char level, char numplayers, Uint8& difficulty, const bool finale, CSavedGame &SavedGame) : CPlayGame(ExeFile, level, numplayers, difficulty), mp_ObjectAI(NULL), m_SavedGame(SavedGame), mp_HighScores(NULL), mp_HUD(NULL), mp_KeenLeftSfc(NULL) { m_level_command = (level==WORLD_MAP_LEVEL_VORTICON) ? GOTO_WORLD_MAP : START_LEVEL; mp_Menu = NULL; mp_Finale = NULL; mp_gameoverbmp = NULL; if(!m_Player.empty()) m_Player.clear(); m_Player.assign(m_NumPlayers, CPlayer(m_Episode, m_Level, mp_level_completed, m_Object, m_Map)); for(int i=0 ; i<m_NumPlayers ; i++) { // Put some important Player properties CPlayer &thisPlayer = m_Player.at(i); thisPlayer.m_index = i; thisPlayer.setDatatoZero(); thisPlayer.mp_camera->attachObject(&thisPlayer); } // Create completed level list memset(mp_level_completed,false,MAX_LEVELS_VORTICON*sizeof(bool)); m_showPauseDialog = false; if(m_Difficulty==0) g_pGfxEngine->Palette.setdarkness(FADE_DARKNESS_EASY); else if(m_Difficulty==1) g_pGfxEngine->Palette.setdarkness(FADE_DARKNESS); else g_pGfxEngine->Palette.setdarkness(FADE_DARKNESS_HARD); if(finale) m_level_command = GOTO_FINALE; }
/** * Initializes variables in CGlobalSyncedStuff */ CGlobalSyncedStuff::CGlobalSyncedStuff() { hmapx = 256; hmapy = 256; randSeed = 18655; initRandSeed = randSeed; frameNum = 0; speedFactor = 1; userSpeedFactor = 1; paused = false; godMode = false; globalLOS = false; cheatEnabled = false; noHelperAIs = false; editDefsEnabled = false; tempNum = 2; gameMode = 0; useLuaGaia = true; gaiaTeamID = -1; gaiaAllyTeamID = -1; useLuaRules = true; for(int a = 0; a < MAX_TEAMS; ++a) { teams[a] = SAFE_NEW CTeam(); teams[a]->teamNum = a; team2allyteam[a] = a; } for(int a = 0; a < MAX_PLAYERS; ++a) { players[a] = SAFE_NEW CPlayer(); players[a]->playerNum = a; } for (int a = 0; a < MAX_TEAMS; ++a) { for (int b = 0; b < MAX_TEAMS; ++b) { allies[a][b] = false; } allies[a][a] = true; } activeTeams = 2; activeAllyTeams = 2; activePlayers = MAX_PLAYERS; }
//// // Creation Routine //// /// \brief CPlayGameVorticon::CPlayGameVorticon /// \param ExeFile /// \param level /// \param SavedGame /// /// CPlayGameVorticon::CPlayGameVorticon(const int startlevel) : CPlayGame(g_pBehaviorEngine->m_ExeFile, startlevel) { // If no level has been set or is out of bound, set it to map. if(m_Level > 100 || m_Level <= 0 ) m_Level = WORLD_MAP_LEVEL_VORTICON; mMap.reset(new CMap()); m_level_command = (m_Level==WORLD_MAP_LEVEL_VORTICON) ? GOTO_WORLD_MAP : START_LEVEL; if(!m_Player.empty()) m_Player.clear(); const int numPlayers = g_pBehaviorEngine->mPlayers; m_Player.assign( numPlayers, CPlayer(mpLevelCompleted, *mMap.get(), 0) ); for(int i=0 ; i<numPlayers ; i++ ) { // Put some important Player properties auto &player = m_Player[i]; player.m_index = i; player.setDatatoZero(); player.setupCameraObject(); player.setSpriteVariantId(i); player.mpCamera->attachObject(&player); } // Set the whole completed level list to false memset( mpLevelCompleted, false, MAX_LEVELS_VORTICON*sizeof(bool)); m_showPauseDialog = false; if(g_pBehaviorEngine->mDifficulty==EASY) gGraphics.Palette.setdarkness(FADE_DARKNESS_EASY); else if(g_pBehaviorEngine->mDifficulty==NORMAL) gGraphics.Palette.setdarkness(FADE_DARKNESS); else gGraphics.Palette.setdarkness(FADE_DARKNESS_HARD); }
/////////////////////////// // Game State Management // /////////////////////////// bool CPlayGameVorticon::loadGameState() { CSaveGameController &savedGame = *(gpSaveGameController); // This fills the datablock from CSavedGame object if(savedGame.load()) { // Create the special merge effect (Fadeout) CColorMerge *pColorMergeFX = new CColorMerge(8); // Prepare for loading the new level map and the players. cleanup(); // get the episode, level and difficulty char newLevel; savedGame.decodeData(m_Episode); savedGame.decodeData(newLevel); bool loadmusic = ( m_Level != newLevel || m_Level == 80 ); m_Level = newLevel; savedGame.decodeData(g_pBehaviorEngine->mDifficulty); bool dark, checkpointset; int checkx, checky; savedGame.decodeData(checkpointset); savedGame.decodeData(checkx); savedGame.decodeData(checky); savedGame.decodeData(dark); // Load number of Players savedGame.decodeData(m_NumPlayers); if(!m_Player.empty()) m_Player.clear(); m_Player.assign(m_NumPlayers, CPlayer(m_Episode, m_Level, mp_level_completed, *mMap.get() ) ); for( size_t i=0 ; i < m_Player.size() ; i++ ) { m_Player.at(i).m_index = i; m_Player.at(i).setDatatoZero(); } CVorticonMapLoaderWithPlayer Maploader(mMap, m_Player, mSpriteObjectContainer); m_checkpointset = checkpointset; Maploader.m_checkpointset = m_checkpointset; if(!Maploader.load(m_Episode, m_Level, m_Gamepath, loadmusic, false)) return false; m_checkpoint_x = checkx; m_checkpoint_y = checky; m_level_command = START_LEVEL; std::vector<CPlayer> :: iterator player; for( player=m_Player.begin() ; player != m_Player.end() ; player++ ) { int x, y; player->setupforLevelPlay(); savedGame.decodeData(x); savedGame.decodeData(y); player->moveToForce(VectorD2<int>(x,y)); savedGame.decodeData(player->blockedd); savedGame.decodeData(player->blockedu); savedGame.decodeData(player->blockedl); savedGame.decodeData(player->blockedr); savedGame.decodeData(player->inventory); player->pdie = 0; } // load the number of objects on screen Uint32 size; savedGame.decodeData(size); for( Uint32 i=0 ; i<size ; i++ ) { unsigned int x,y; if(i >= mSpriteObjectContainer.size()) { std::unique_ptr<CVorticonSpriteObject> object( new CVorticonSpriteObject( mMap.get(), 0, 0, OBJ_NONE) ); object->exists = false; mSpriteObjectContainer.push_back(move(object)); } CVorticonSpriteObject &object = *(mSpriteObjectContainer.at(i)); savedGame.decodeData(object.m_type); savedGame.decodeData(x); savedGame.decodeData(y); object.moveToForce(VectorD2<int>(x,y)); savedGame.decodeData(object.dead); savedGame.decodeData(object.onscreen); savedGame.decodeData(object.hasbeenonscreen); savedGame.decodeData(object.exists); savedGame.decodeData(object.blockedd); savedGame.decodeData(object.blockedu); savedGame.decodeData(object.blockedl); savedGame.decodeData(object.blockedr); savedGame.decodeData(object.mHealthPoints); savedGame.decodeData(object.canbezapped); savedGame.decodeData(object.cansupportplayer); savedGame.decodeData(object.inhibitfall); savedGame.decodeData(object.honorPriority); savedGame.decodeData(object.sprite); object.performCollisions(); if(object.m_type == OBJ_DOOR or object.m_type == OBJ_RAY or object.m_type == OBJ_SNDWAVE or object.m_type == OBJ_FIREBALL or object.m_type == OBJ_ICECHUNK or object.m_type == OBJ_ICEBIT or object.m_type == OBJ_GOTPOINTS or object.m_type == OBJ_ANKHSHIELD) // Some objects are really not needed. So don't load them object.exists = false; } // TODO: An algorithm for comparing the number of players saved and we actually have need to be in sync // Load the map_data as it was left last savedGame.decodeData(mMap->m_width); savedGame.decodeData(mMap->m_height); savedGame.readDataBlock( reinterpret_cast<byte*>(mMap->getForegroundData()) ); // Load completed levels savedGame.readDataBlock( (byte*)(mp_level_completed) ); m_Player[0].setMapData(mMap.get()); m_Player[0].setupCameraObject(); m_Player[0].mpCamera->attachObject(&m_Player[0]); while(m_Player[0].mpCamera->m_moving) { m_Player[0].mpCamera->process(); m_Player[0].mpCamera->processEvents(); } mMap->drawAll(); // Create the special merge effect (Fadeout) g_pGfxEngine->setupEffect(pColorMergeFX); mpObjectAI.reset( new CVorticonSpriteObjectAI(mMap.get(), mSpriteObjectContainer, m_Player, m_NumPlayers, m_Episode, m_Level, mMap->m_Dark) ); setupPlayers(); mMap->m_Dark = dark; g_pGfxEngine->Palette.setdark(mMap->m_Dark); return true; } return false; }
int main(int argc, char** argv) { int defw = 640; int defh = 480; if (argc == 3) { /*the program was run using 3 arguments argv[0] = name of the executable file argv[1] = screen width (as a string) argv[2] = screen height (as a string) */ defw = atoi(argv[1]); defh = atoi(argv[2]); } if (!al_init()) return 1; //exit if can't initialize allegro //initialize most stuff al_install_keyboard(); al_init_primitives_addon(); //run in a window al_set_new_display_flags(ALLEGRO_WINDOWED); //initialize our display and event queue ALLEGRO_DISPLAY* display = al_create_display(defw, defh); ALLEGRO_EVENT_QUEUE* eventq = al_create_event_queue(); //this timer will tick once per frame ALLEGRO_TIMER* framet = al_create_timer(1.0 / 30.0); //30 frames per second al_start_timer(framet); //register the event sources so they send events to our queue al_register_event_source(eventq, al_get_display_event_source(display)); //display/window al_register_event_source(eventq, al_get_keyboard_event_source()); //keyboard al_register_event_source(eventq, al_get_timer_event_source(framet)); //fps timer //this box is our play field (covers the whole screen) CBox fieldbox(0, 0, defw, defh); //we setup the ball at the center of the screen with white color CBall ball(CBox(defw / 2 - 10, defh / 2 - 10, 20, 20), al_map_rgb(255, 255, 255)); //we tell it to move to the left ball.setXYMovement(-5.0, 0.0); //we initialize our both players in an array CPlayer players[2] = { //red player on the left CPlayer(CBox(10, defh / 2 - 80 / 2, 20, 80), al_map_rgb(255, 0, 0)), //blue player on the right CPlayer(CBox(defw - 10 - 20, defh / 2 - 80 / 2, 20, 80), al_map_rgb(0, 0, 255)), }; /*when this variable is set to true the program will quit the main loop and free the allocated resources before quitting */ bool exit = false; while (!exit) { al_wait_for_event(eventq, NULL); ALLEGRO_EVENT ev; while (al_get_next_event(eventq, &ev)) { if (ev.type == ALLEGRO_EVENT_TIMER) { if (ev.timer.source == framet) { //fill the screen with black al_clear_to_color(al_map_rgb(0, 0, 0)); //move and draw our two players for (int i = 0; i<2; i++) { players[i].move(fieldbox); players[i].draw(); } //move, collide and draw the ball switch (ball.move(fieldbox, players)) { case 0: break; case 1: players[0].setScore(players[0].getScore() + 1); ball.setXYMovement(5.0, 0.0); break; case 2: players[1].setScore(players[1].getScore() + 1); ball.setXYMovement(-5.0, 0.0); break; } ball.draw(); //show what we've drawn al_flip_display(); } } else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { //quit if the user tries to close the window if (ev.display.source == display) exit = true; } else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { //handle key presses switch (ev.keyboard.keycode) { case ALLEGRO_KEY_W: players[0].setYMovement(-3.0); break; case ALLEGRO_KEY_S: players[0].setYMovement(3.0); break; case ALLEGRO_KEY_UP: players[1].setYMovement(-3.0); break; case ALLEGRO_KEY_DOWN: players[1].setYMovement(3.0); break; case ALLEGRO_KEY_ESCAPE: exit = true; break; case ALLEGRO_EVENT_DISPLAY_CLOSE: exit = true; break; } } else if (ev.type == ALLEGRO_EVENT_KEY_UP) { int code = ev.keyboard.keycode; /*avoid clumsy movement making sure the released key corresponds with the moving direction*/ if (code == ALLEGRO_KEY_W && players[0].getYMovement() < 0) players[0].setYMovement(0.0); else if (code == ALLEGRO_KEY_S && players[0].getYMovement() > 0) players[0].setYMovement(0.0); else if (code == ALLEGRO_KEY_UP && players[1].getYMovement() < 0) players[1].setYMovement(0.0); else if (code == ALLEGRO_KEY_DOWN && players[1].getYMovement() > 0) players[1].setYMovement(0.0); } } } al_destroy_event_queue(eventq); al_destroy_timer(framet); al_destroy_display(display); }