void GameAudio::processPunchSound() { if (soundEffectRegistrationMap[ENUM_SOUND_EFFECT_PUNCH] == true) { Game *game = Game::getSingleton(); GameStateManager *gsm = game->getGSM(); SpriteManager *spriteMgr = gsm->getSpriteManager(); PlayerSprite *player = spriteMgr->getPlayer(); wstring playerState = player->getCurrentState(); if (playerState.compare(L"PUNCH_LEFT") == 0 || playerState.compare(L"PUNCH_RIGHT") == 0 || playerState.compare(L"PUNCH_BACK") == 0 || playerState.compare(L"PUNCH_FRONT") == 0) { IXAudio2SourceVoice *punchSound = soundEffectMap[ENUM_SOUND_EFFECT_PUNCH]; XAUDIO2_VOICE_STATE voiceState; punchSound->GetState(&voiceState); //// [voiceState.BuffersQueued <= 0] means there are nothing in the buffer //// so let's make a new buffer to queue the sound if (voiceState.BuffersQueued <= 0) { XAUDIO2_BUFFER *proto = audioBufferPrototypeMap[ENUM_SOUND_EFFECT_PUNCH]; bool ssbSuccess = SUCCEEDED(punchSound->SubmitSourceBuffer(proto)); punchSound->Start(); } //// if there is something in the buffer else { /// do nothing } } } }
/**\brief Update function on every frame. */ void Ship::Update( lua_State *L ) { Sprite::Update( L ); // update momentum and other generic sprite attributes if( status.isAccelerating == false && status.isRotatingLeft == false && status.isRotatingRight == false) { flareAnimation->Reset(); } flareAnimation->Update(); Coordinate momentum = GetMomentum(); momentum.EnforceMagnitude( shipStats.GetMaxSpeed()*engineBooster ); // Show the hits taken as part of the radar color if(IsDisabled()) SetRadarColor( GREY ); else SetRadarColor( RED * GetHullIntegrityPct() ); // Ship has taken as much damage as possible... // It Explodes! if( status.hullDamage >= (float)shipStats.GetHullStrength() ) { SpriteManager *sprites = Simulation_Lua::GetSimulation(L)->GetSpriteManager(); Camera* camera = Simulation_Lua::GetSimulation(L)->GetCamera(); // Play explode sound if(OPTION(int, "options/sound/explosions")) { Sound *explodesnd = Sound::Get("Resources/Audio/Effects/18384__inferno__largex.wav.ogg"); explodesnd->Play( GetWorldPosition() - camera->GetFocusCoordinate()); } // Create Explosion sprites->Add( new Effect( GetWorldPosition(), "Resources/Animations/explosion1.ani", 0) ); // Remove this Sprite from the SpriteManager sprites->Delete( (Sprite*)this ); }
void SmartEnemySprite::move() { //offscreen if (offset.x == 0) { state = DEAD; GameWorld::Instance()->activateSmartEnemies(); } offset.x -= xVel; if (state == ALIVE) { //Consult strategy if(currentStrategy->shoot()) { SpriteManager* spriteManager = SpriteManager::Instance(); spriteManager->newEnemyBullet(&offset); } } //If we have finished imploding if (animation->getCurrentFrame()==5) { state = DEAD; delete animation; //This will ensure the strategy memory is deallocated changeStrategy((Strategy*)0); GameWorld::Instance()->activateSmartEnemies(); GameWorld::Instance()->increaseScore(2500); } }
void GameAudio::processHealSound() { if (soundEffectRegistrationMap[ENUM_SOUND_EFFECT_HEAL] == true) { Game *game = Game::getSingleton(); GameStateManager *gsm = game->getGSM(); SpriteManager *spriteMgr = gsm->getSpriteManager(); PlayerSprite *player = spriteMgr->getPlayer(); bool isHealing = player->getIshealing(); if (isHealing == true) { IXAudio2SourceVoice *healSound = soundEffectMap[ENUM_SOUND_EFFECT_HEAL]; XAUDIO2_VOICE_STATE voiceState; healSound->GetState(&voiceState); //// [voiceState.BuffersQueued <= 0] means there are nothing in the buffer //// so let's make a new buffer to queue the sound if (voiceState.BuffersQueued <= 0) { XAUDIO2_BUFFER *proto = audioBufferPrototypeMap[ENUM_SOUND_EFFECT_HEAL]; bool ssbSuccess = SUCCEEDED(healSound->SubmitSourceBuffer(proto)); healSound->Start(); //// After all, there will be only one buffer node in the queue always ... } //// if there is something in the buffer else { /// do nothing } } } }
void WalkaboutMouseEventHandler::handleMousePressEvent(Game *game, int mouseX, int mouseY) { if (game->getGSM()->isGameInProgress()) { Viewport *viewport = game->getGUI()->getViewport(); // DETERMINE WHERE ON THE MAP WE HAVE CLICKED int worldCoordinateX = mouseX + viewport->getViewportX(); int worldCoordinateY = mouseY + viewport->getViewportY(); SpriteManager *spriteManager = game->getGSM()->getSpriteManager(); Player* player = static_cast<Player*>(spriteManager->getPlayer()); PhysicalProperties* playerPP = spriteManager->getPlayer()->getPhysicalProperties(); if(!player->getIsDead() && !player->getIsDying() && player->getAmmo() != 0) { float dx = worldCoordinateX - playerPP->getX(); float dy = worldCoordinateY - playerPP->getY(); float distanceToMouse = sqrtf(dx*dx + dy*dy); dx /= distanceToMouse; dy /= distanceToMouse; float bulletOffset = 60; float bulletSpeed = 50; //Fire projectile spriteManager->createProjectile(playerPP->getX() + bulletOffset*dx, playerPP->getY() + bulletOffset*dy, bulletSpeed*dx,bulletSpeed*dy); player->decrementAmmo(); } } }
Sprite::Sprite(const Sprite& _other) { mRect.x = _other.mRect.x; mRect.y = _other.mRect.y; mElevation = _other.mElevation; mFile = _other.mFile; loadTexture(*mFile); SpriteManager* manager = SpriteManager::getInstance(); manager->addSprite(*this); }
Sprite::Sprite(const char* _file) { mRect.x = 0; mRect.y = 0; mElevation = 0; mFile = _file; loadTexture(*mFile); SpriteManager* manager = SpriteManager::getInstance(); manager->addSprite(*this); }
void RenderScene(void) { static clock_t lastTime = 0; clock_t now; now = clock(); SpriteManager* sprites = SpriteManager::instance(); if (!isPaused && now -lastTime > CLOCKS_PER_SEC/60) { sprites->update(); } lastTime = now; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); Matrix4f ViewProjectionMatrix; if (!cameraLock) { ViewProjectionMatrix = projectionMatrix * camera; }else{ ViewProjectionMatrix = projectionMatrix * player->getCamera(); } /* GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f }; glUseProgram( shader.program ); glUniform4f( shader.uniforms.colour, vRed[0], vRed[1], vRed[2], vRed[3] ); Matrix4f modelView; //modelView.rotate( [0], rotation[1], rotation[2]); modelView.translate( 0, 0, 5 ); Matrix4f modelViewProjectionMatrix =ViewProjectionMatrix * modelView; modelViewProjectionMatrix.loadUniform( shader.uniforms.modelViewProjectionMatrix); test->draw( shader.attributes.pos ); */ sprites->draw( ViewProjectionMatrix, shader); // Perform the buffer swap to display back buffer glutSwapBuffers(); glutPostRedisplay(); }
/**\brief The last function call to the ship before it get's deleted * * At this point, the ship still exists. It has not been removed from the Universe * * \note We don't want to make this a destructor call because we want the rest * of the system to still treat the ship normally. */ void AI::Killed( lua_State *L ) { LogMsg( WARN, "AI %s has been killed\n", GetName().c_str() ); SpriteManager *sprites = Simulation_Lua::GetSimulation(L)->GetSpriteManager(); Sprite* killer = sprites->GetSpriteByID( target ); if(killer != NULL) { if( killer->GetDrawOrder() == DRAW_ORDER_PLAYER ) { ((Player*)killer)->UpdateFavor( this->GetAlliance()->GetName(), -1 ); } } }
Sprite::Sprite(int _width, int _height) { mRect.x = 0; mRect.y = 0; mRect.w = _width; mRect.h = _height; mOriginalRect = mRect; mElevation = 0; mTexture = NULL; SpriteManager* manager = SpriteManager::getInstance(); manager->addSprite(*this); }
void ScienceMouseEventHandler::handleMousePressEvent(Game *game, int mouseX, int mouseY) { if (game->getGSM()->isGameInProgress()) { Viewport *viewport = game->getGUI()->getViewport(); // DETERMINE WHERE ON THE MAP WE HAVE CLICKED int worldCoordinateX = mouseX + viewport->getViewportX(); int worldCoordinateY = mouseY + viewport->getViewportY(); // NOW LET'S SEE IF THERE IS A SPRITE THERE GameStateManager *gsm = game->getGSM(); SpriteManager *spriteManager = gsm->getSpriteManager(); // IF THERE IS NO SELECTED SPRITE LOOK FOR ONE if (!(spriteManager->getIsSpriteSelected())) { // IF THIS DOES NOT RETURN NULL THEN YOU FOUND A SPRITE AT THAT LOCATION if((spriteManager->getSpriteAt(worldCoordinateX, worldCoordinateY) != NULL)) { AnimatedSprite *selected = spriteManager->getSpriteAt(worldCoordinateX, worldCoordinateY); spriteManager->setIsSpriteSelected(true); } } else if (spriteManager->getSelectedSprite() != NULL) { // MOVE A SPRITE IN A DESIRED DIRECTION AnimatedSprite *selected = spriteManager->getSelectedSprite(); PhysicalProperties *pp = selected->getPhysicalProperties(); float spriteX = pp->getX(); float spriteY = pp->getY(); //IF A SPRITE IS WHERE YOU WANT IT THEN STOP IT if (((spriteX > worldCoordinateX - 64) && (spriteX < worldCoordinateX + 64)) && (spriteY > worldCoordinateY - 64) && (spriteY < worldCoordinateY + 64)) { pp->setVelocity(0, 0); } else { float deltaX = worldCoordinateX - spriteX; float deltaY = worldCoordinateY - spriteY; float hyp = sqrtf((deltaX * deltaX) + (deltaY * deltaY)); pp->setVelocity((deltaX / hyp) * 3, (deltaY / hyp) * 3); } spriteManager->setIsSpriteSelected(false); // GridPathfinder *pathfinder = spriteManager->getPathfinder(); // pathfinder->mapPath(selected, (float)worldCoordinateX, (float)worldCoordinateY); // gsm->setSpriteSelected(false, selected); } else { spriteManager->setIsSpriteSelected(false); } } }
Sprite::Sprite() { mRect.x = 0; mRect.y = 0; mRect.w = 0; mRect.h = 0; mOriginalRect = mRect; mElevation = 0; mTexture = NULL; SpriteManager* manager = SpriteManager::getInstance(); manager->addSprite(*this); }
int main(int argc, char** argv){ StringHelper::init(); Log >> new ConsoleLogger(); //Set filter to include all. Log.setLevelFilter(LogManager::ll_Verbose); for(int i = 1; i < argc; i+=2){ Log << argv[i] << " to " << argv[i+1]; SpriteManager manager; manager.loadRaw(argv[i]); manager.save(argv[i+1]); } Log.close(); return 0; }
void Radar::Draw( SpriteManager &sprites ) { short int radar_mid_x = RADAR_MIDDLE_X + Video::GetWidth() - 129; short int radar_mid_y = RADAR_MIDDLE_Y + 5; int radarSize; const list<Sprite*>& spriteList = sprites.GetSprites(); for( list<Sprite*>::const_iterator iter = spriteList.begin(); iter != spriteList.end(); iter++) { Coordinate blip( -(RADAR_HEIGHT / 2.0), (RADAR_WIDTH / 2.0), (RADAR_HEIGHT / 2.0), -(RADAR_WIDTH / 2.0) ); Sprite *sprite = *iter; if( sprite->GetDrawOrder() == DRAW_ORDER_PLAYER ) continue; // Calculate the blip coordinate for this sprite Coordinate wpos = sprite->GetWorldPosition(); WorldToBlip( wpos, blip ); if( blip.ViolatesBoundary() == false ) { /* blip is on the radar */ /* Convert to screen coords */ blip.SetX( blip.GetX() + radar_mid_x ); blip.SetY( blip.GetY() + radar_mid_y ); radarSize = int((sprite->GetRadarSize() / float(visibility)) * (RADAR_HEIGHT/4.0)); Video::DrawCircle( blip, (radarSize>=1) ?radarSize: 1, 1, sprite->GetRadarColor() ); } } }
int main() { GameManager gm; RenderSystem rs(gm); SpriteManager sm; Sprite* s = sm.loadSprite("data/sprites/HorrifyingSmiley.png"); Sprite* s2 = sm.loadSprite("data/sprites/Circle.png"); //PrintTransformSystem pts(gm); //gm.addSystem(pts); gm.addSystem(rs); Entity& player = gm.createEntity("player"); TransformComponent* tc = gm.addComponentToEntity<TransformComponent>(player); tc->position.x = 100; tc->position.y = 100; SpriteComponent* sc = gm.addComponentToEntity<SpriteComponent>(player); sc->sprite = s; Entity& test2 = gm.createEntity("test2"); //Might as well reuse these tc = gm.addComponentToEntity<TransformComponent>(test2); tc->position.x = 500; tc->position.y = 150; sc = gm.addComponentToEntity<SpriteComponent>(test2); sc->sprite = s2; Input::initInput(); Input::addMapping("Up", 'W'); Input::addMapping("Up", Input::Keys::UP); Input::addMapping("Down", 'S'); Input::addMapping("Down", Input::Keys::DOWN); Input::addMapping("Exit", 'Q'); Input::addMapping("Exit", 'P'); Input::addMapping("Exit", Input::Keys::ESC); for(int i =0; i < 10; i++){ Entity& e = gm.createEntity("whatevs"); TransformComponent* tComp = gm.addComponentToEntity<TransformComponent>(e); tComp->position.x = (i * 100);// % 800; tComp->position.y = (i * 100);// % 600; SpriteComponent* spr = gm.addComponentToEntity<SpriteComponent>(e); if(i % 2 == 0) spr->sprite = s2; else spr->sprite = s; spr->layer = i; } gm.run(); }
void Gate::Update() { // The Bottom Gate doesn't do anything if(!top) return; SpriteManager *sprites = SpriteManager::Instance(); Sprite* ship = sprites->GetNearestSprite( (Sprite*)this, 50,DRAW_ORDER_SHIP|DRAW_ORDER_PLAYER ); if(ship!=NULL) { if(exitID != 0) { SendToExit(ship); } else if(rand()&1) { SendToRandomLocation(ship); } else { SendRandomDistance(ship); } } }
Image * Sprite::GetSpriteSheetImageNoCache() { SpriteManager *pSpriteManager = NULL; switch (managerSource) { case ManagerSourceCaseFile: pSpriteManager = Case::GetInstance()->GetSpriteManager(); break; case ManagerSourceCommonResources: pSpriteManager = CommonCaseResources::GetInstance()->GetSpriteManager(); break; } return pSpriteManager->GetImageFromId(spriteSheetImageId); }
ActionMenu::ActionMenu(Window &win, bool isSelected, MenuEnum::eMenu typeAction, SpriteManager sprite) { this->_window = win; this->_selected = isSelected; this->_typeAction = typeAction; this->_sprite = sprite.getCurrentFrame(); if (this->_selected == true) this->_sprite.setColor(sf::Color(0, 128, 0, 255)); else this->_sprite.setColor(sf::Color(255, 255, 255, 255)); }
/**\brief Update the Projectile * * Projectiles do all the normal Sprite things like moving. * Projectiles check for collisions with nearby Ships, and if they collide, * they deal damage to that ship. Note that since each projectile knows which ship fired it and will never collide with them. * * Projectiles have a life time limit (in milli-seconds). Each tick they need * to check if they've lived to long and need to disappear. * * Projectiles have the ability to track down a specific target. This only * means that they will turn slightly to head towards their target. */ void Projectile::Update( void ) { Sprite::Update(); // update momentum and other generic sprite attributes SpriteManager *sprites = SpriteManager::Instance(); // Check for projectile collisions Sprite* impact = sprites->GetNearestSprite( (Sprite*)this, 100,DRAW_ORDER_SHIP|DRAW_ORDER_PLAYER ); if( (impact != NULL) && (impact->GetID() != ownerID) && ((this->GetWorldPosition() - impact->GetWorldPosition()).GetMagnitude() < impact->GetRadarSize() )) { ((Ship*)impact)->Damage( (weapon->GetPayload())*damageBoost ); sprites->Delete( (Sprite*)this ); // Create a fire burst where this projectile hit the ship's shields. // TODO: This shows how much we need to improve our collision detection. Effect* hit = new Effect(this->GetWorldPosition(), "Resources/Animations/shield.ani", 0); hit->SetAngle( -this->GetAngle() ); hit->SetMomentum( impact->GetMomentum() ); sprites->Add( hit ); } // Expire the projectile after a time period if (( Timer::GetTicks() > secondsOfLife + start )) { sprites->Delete( (Sprite*)this ); } // Track the target Sprite* target = sprites->GetSpriteByID( targetID ); float tracking = weapon->GetTracking(); if( target != NULL && tracking > 0.00000001f ) { float angleTowards = normalizeAngle( ( target->GetWorldPosition() - this->GetWorldPosition() ).GetAngle() - GetAngle() ); SetMomentum( GetMomentum().RotateBy( angleTowards*tracking ) ); SetAngle( GetMomentum().GetAngle() ); } }
Sprite * Animation::Frame::GetSprite() { if (pSprite == NULL) { SpriteManager *pSpriteManager = NULL; switch (managerSource) { case ManagerSourceCaseFile: pSpriteManager = Case::GetInstance()->GetSpriteManager(); break; case ManagerSourceCommonResources: pSpriteManager = CommonCaseResources::GetInstance()->GetSpriteManager(); break; } pSprite = pSpriteManager->GetSpriteFromId(spriteId); } return pSprite; }
void BotSpawningPool::update() { countdownCounter--; if (countdownCounter <= 0) { // SPAWN A BOT Game *game = Game::getSingleton(); GameStateManager *gsm = game->getGSM(); SpriteManager *spriteManager = gsm->getSpriteManager(); BotRecycler *botRecycler = spriteManager->getBotRecycler(); Bot *spawnedBot = botRecycler->retrieveBot(botType); spriteManager->addBot(spawnedBot); initCountdownCounter(); // DO IT'S SPAWNING BEHAVIOR BotBehavior *spawningBehavior = spawnedBot->getBehavior(BotState::SPAWNING); spawningBehavior->behave(spawnedBot); // AND START IT LOCATED AT THE SPAWNING POOL PhysicalProperties *pp = spawnedBot->getPhysicalProperties(); pp->setX(x); pp->setY(y); } }
void BalloonEscapeCollisionListener::respondToCollision(Game *game, Collision *collision) { // NOTE FROM THE COLLIDABLE OBJECTS, WHICH ARE IN THE COLLISION, // WE CAN CHECK AND SEE ON WHICH SIDE THE COLLISION HAPPENED AND // CHANGE SOME APPROPRIATE STATE ACCORDINGLY GameStateManager *gsm = game->getGSM(); AnimatedSprite *player = gsm->getSpriteManager()->getPlayer(); PhysicalProperties *pp = player->getPhysicalProperties(); //AnimatedSprite *bot = collision CollidableObject *sprite2 = collision->getCO2(); PhysicalProperties *pp2 = sprite2->getPhysicalProperties(); AnimatedSprite *bot = (AnimatedSprite*)sprite2; if (!collision->isCollisionWithTile() && player->getCurrentState() != L"DYING") { CollidableObject *sprite = collision->getCO1(); if (sprite2->getPhysicalProperties()->getZ() == 1.0f) { bot = (AnimatedSprite*)sprite; pp = sprite2->getPhysicalProperties(); pp2 = sprite->getPhysicalProperties(); sprite = collision->getCO2(); sprite2 = collision->getCO1(); if (sprite->getCollisionEdge() == BOTTOM_EDGE) { bot->setCurrentState(L"DYING"); pp2->setVelocity(0.0f, 0.0f); pp2->setAccelerationX(0); pp2->setAccelerationY(0); // ENEMY IS DEAD - WE SHOULD PLAY A DEATH ANIMATION // AND MARK IT FOR REMOVAL } else if (bot->getCurrentState() != L"DYING") { if (pp->getDelay() == 0) { if (pp->getHP() == 10 ) { //lives->setCurrentState(L"TWO"); if(deadonce == true) //lives->setCurrentState(L"ONE"); player->setCurrentState(L"DYING"); pp->setDelay(90); pp->setVelocity(0.0f, 0.0f); pp->setAccelerationX(0); pp->setAccelerationY(0); deadonce=true; } else { pp->setDelay(90); pp->setHP(pp->getHP()-10); SpriteManager *spriteManager = gsm->getSpriteManager(); AnimatedSpriteType *yellowman = spriteManager->getSpriteType(3); player->setSpriteType(yellowman); } } // PLAYER IS DEAD - WE SHOULD PLAY A DEATH ANIMATION // AND MARK IT FOR REMOVAL/RESPAWN/RESTART GAME, WHATEVER // THE DEMANDS OF THE GAME ARE } } else if(sprite->getPhysicalProperties()->getZ() == 1.0f) { PhysicalProperties *pp = sprite->getPhysicalProperties(); if (sprite->getCollisionEdge() == BOTTOM_EDGE) { bot->setCurrentState(L"DYING"); pp2->setVelocity(0.0f, 0.0f); pp2->setAccelerationX(0); pp2->setAccelerationY(0); // ENEMY IS DEAD - WE SHOULD PLAY A DEATH ANIMATION // AND MARK IT FOR REMOVAL } else if (bot->getCurrentState() != L"DYING") { if (pp->getDelay() == 0) { if (pp->getHP() == 10 ) { //lives->setCurrentState(L"TWO"); if(deadonce == true) //lives->setCurrentState(L"ONE"); player->setCurrentState(L"DYING"); pp->setDelay(90); pp->setVelocity(0.0f, 0.0f); pp->setAccelerationX(0); pp->setAccelerationY(0); deadonce=true; } else { pp->setDelay(90); pp->setHP(pp->getHP()-10); SpriteManager *spriteManager = gsm->getSpriteManager(); AnimatedSpriteType *yellowman = spriteManager->getSpriteType(3); player->setSpriteType(yellowman); } } // PLAYER IS DEAD - WE SHOULD PLAY A DEATH ANIMATION // AND MARK IT FOR REMOVAL/RESPAWN/RESTART GAME, WHATEVER // THE DEMANDS OF THE GAME ARE } } } if (pp->getDelay() == 0) { SpriteManager *spriteManager = gsm->getSpriteManager(); AnimatedSpriteType *redman = spriteManager->getSpriteType(2); player->setSpriteType(redman); } }
/* This is where all game physics starts each frame. It is called each frame by the game statem manager after player input and AI have been processed. It updates the physical state of all dynamic objects in the game and moves all objects to their end of frame positions, updates all necessary object velocities, and calls all collision event handlers. */ void Physics::update(Game *game) { // WE'LL USE A CONTINUOUS COLLISION SYSTEM TO ENSURE TEMPORAL // COHERENCE, WHICH MEANS WE'LL MAKE SURE COLLISIONS ARE RESOLVED // IN THE ORDER WITH WHICH THEY HAPPEN. WE DON'T WANT GAME EVENTS // TO APPEAR TO HAPPEN IN THE WRONG ORDER. WE'LL TRY TO MAKE IT // A LITTLE MORE EFFICIENT BY EMPLOYING A VARIATION ON THE // SWEEP AND PRUNE ALGORITHM FOR DYNAMIC-DYNAMIC OBJECT COLLISIONS // IN CASE WE'RE DOING THE ONE UPDATE STEP AT A TIME // THIS MAKES SURE THE UPDATE DOESN'T GET CALLED AGAIN // NEXT FRAME WITHOUT THE USER EXPLICITY REQUESTING IT // BY PRESSING THE 'T' KEY (for Time sTep) activatedForSingleUpdate = false; // WE'LL NEED THE WORLD TO ACCESS THE SPRITES AND WORLD LAYERS GameStateManager *gsm = game->getGSM(); World *world = gsm->getWorld(); // NOTE THAT WE MAKE SURE THE activeCollisions VECTOR IS // EMPTIED BEFORE THIS METHOD EXITS, SO WE CAN ASSUME // IT'S EMPTY NOW. activeCollisions CONTAINS ALL THE COLLISIONS // EMPTIED BEFORE THIS METHOD EXITS, SO WE CAN ASSUME // IT'S EMPTY NOW. activeCollisions CONTAINS ALL THE COLLISIONS // DETECTED SO FAR THIS FRAME. THESE ARE THE THINGS WE MUST // RESOLVE. // START THE CLOCK AT 0, THAT MEANS 0% OF THE WAY THROUGH THE FRAME. // NOTE THAT TIME 0 IS THE MOST DANGEROUS TIME FOR DETECTING COLLISIONS // BECAUSE THEY CAN BE EASILY OVERLOOKED. THE SAME FOR SIMULTANEOUS // COLLISIONS. TO MINIMIZE RIGID BODY PENETRATION, SUCH CIRCUMSTANCES // ARE TYPICALLY HANDLED AS SPECIAL CASES currentCollisionTime = 0.0f; // FIRST WE NEED TO DO COLLISION TESTING PREP WORK FOR SPRITES // APPLY ACCELERATION AND GRAVITY TO VELOCITY // INIT TILE COLLISION INFO // SET ON TILE LAST FRAME USING ON TILE THIS FRAME // SET ON TILE THIS FRAME TO FALSE // GET COLLISIONS WITH ALL TILES TO HAPPEN DURING THIS FRAME // PUT THESE COLLISIONS INTO A SORTABLE DATA STRUCTURE // INIT SPRITE'S SWEPT SHAPE INFO // FOR ALL SPRITES, INCLUDING THE BOTS AND PLAYER vector<CollidableObject*>::iterator spritesIt = sortedSweptShapes[LEFT_EDGE]->begin(); while (spritesIt != sortedSweptShapes[LEFT_EDGE]->end()) { CollidableObject *sprite = (*spritesIt); prepSpriteForCollisionTesting(world, sprite); getAllTileCollisionsForAGivenSprite(world, sprite, 1.0f); spritesIt++; } // PREPARE FOR SPRITE-SPRITE COLLISION TESTING // SWEEP AND PRUNE DATA STRUCTURES PREP WORK // SORT S_AND_P VECTOR SORTED BY START X OF SWEPT SHAPE // SORT S_AND_P VECTOR SORTED BY END X OF SWEPT SHAPE // WE DON'T NEED THE Y-AXIS SORTED, BUT WOULD IF THIS // WERE A 3D SYSTEM TO SAVE ON COMPARISONS. // WE'RE USING C++'s STL sort METHOD AND ARE PROVIDING // A CUSTOM MEANS FOR COMPARISON sort(sortedSweptShapes[LEFT_EDGE]->begin(), sortedSweptShapes[LEFT_EDGE]->end(), SweptShapesComparitorByLeft()); sort(sortedSweptShapes[RIGHT_EDGE]->begin(), sortedSweptShapes[RIGHT_EDGE]->end(), SweptShapesComparitorByRight()); // RECORD SORTED POSITIONS WITH EACH SPRITE. THEY NEED TO KNOW WHERE // THEY ARE IN THOSE DATA STRUCTURES SUCH THAT WE CAN JUMP INTO // THOSE DATA STRUCTURES TO TEST COLLISIONS WITH NEIGHBORS updateSweptShapeIndices(); // YOU'LL NEED TO TEST FOR SPRITE-TO-SPRITE COLLISIONS HERE // *** LOOP STARTS HERE. WE'LL DO THIS UNTIL THERE ARE NO // MORE COLLISIONS TO RESOLVE FOR THIS FRAME while (activeCollisions.size() > 0) { // SORT COLLISION OBJECTS BY TIME OF COLLISION // NOTE THAT I'M JUST EMPLOYING THE STL'S List // CLASS' SORT METHOD BY PROVIDING MY OWN // MEANS FOR COMPARING Collision OBJECTS activeCollisions.sort(CollisionComparitor()); // GET FIRST COLLISION - NOTE THAT WE HAVE THE COLLISIONS SORTED // IN DESCENDING ORDER, SO TO TAKE THE EARLIEST ONE, WE REMOVE IT // FOM THE BACK OF THE SORTED LIST Collision *earliestCollision = activeCollisions.back(); activeCollisions.pop_back(); float collisionTime = earliestCollision->getTimeOfCollision(); // MOVE ALL SPRITES UP TO TIME OF FIRST COLLISION USING // APPROPRIATELY SCALED VELOCITIES moveAllSpritesUpToBufferedTimeOfCollision(earliestCollision); // AND ADVANCE COLLISION TIME currentCollisionTime = collisionTime; // AND UPDATE THE VELOCITIES OF THE SPRITE(S) INVOLVED IN THE COLLISION performCollisionResponse(earliestCollision); // EXECUTE COLLISION EVENT CODE // TEST TO SEE TYPES OF OBJECTS AND APPROPRIATE RESPONSE // ACCORDING TO CUSTOMIZED COLLISION EVENT HANDLER collisionListener->respondToCollision(game, earliestCollision); // FOR THE TWO OBJECTS INVOLVED IN THE COLLISION // REMOVE ALL OTHER COLLISIONS INVOLVING THEM // SINCE THEY ARE NOW OBSOLETE. THE REASON BEING // THE OBJECT COLLISION NOW LIKELY HAS A // DIFFERENT VECTOR // UPDATE THEIR SWEPT SHAPES // TEST THEM AGAINST TILES AGAIN CollidableObject *co1 = earliestCollision->getCO1(); CollidableObject *co2 = earliestCollision->getCO2(); removeActiveCOCollisions(co1); co1->updateSweptShape(1.0f - currentCollisionTime); getAllTileCollisionsForAGivenSprite(world, co1, 1.0f - currentCollisionTime); // ONLY DO IT FOR THE SECOND ONE IF IT'S NOT A TILE if (!earliestCollision->isCollisionWithTile()) { removeActiveCOCollisions(co2); co2->updateSweptShape(1.0f - currentCollisionTime); getAllTileCollisionsForAGivenSprite(world, co2, 1.0f - currentCollisionTime); } else { spriteToTileCollisionsThisFrame[co1].insert(earliestCollision->getTile()); recycledCollidableObjectsList.push_back(co2); } // NOW WE NEED TO SEE IF THE SPRITES INVOLVED IN THE JUST // RESOLVED COLLISION ARE GOING TO BE INVOLVED IN ANY MORE // WITH OTHER SPRITES BUT WE DON'T WANT TO CHECK ALL OF THEM, // WE ONLY WANT TO CHECK NEIGHBORS, BUT FIRST WE HAVE TO // MAKE SURE THE SPRITE(S) THAT WE JUST RESOLVED ARE IN THEIR // PROPER SWEPT SHAPE LOCATIONS WITHOUT HAVING TO RESORT EVERTYHING // IF IT WAS ONLY ONE SPRITE WITH A TILE THIS IS EASY TO DO if (earliestCollision->isCollisionWithTile()) { reorderCollidableObject(co1); } // YOU'LL HAVE TO WORRY ABOUT REORDERING STUFF FOR COLLISIONS // BETWEEN TWO SPRITES // NOW TEST NEIGHBORS OF SPRITES INVOLVED IN RESOLVED COLLISION // AGAINST NEIGHBORS IN SWEPT SHAPE DATA STRUCTURES. YOU'LL HAVE // TO FIGURE OUT HOW TO DO THIS AND HOW TO RESOLVE SUCH COLLISIONS // RECYCLE THE COLLISION SINCE WE'RE NOW DONE WITH IT recycledCollisions.push_back(earliestCollision); } // APPLY THE REMAINING TIME TO MOVE THE SPRITES. NOTE THAT // THIS IS ACTUALLY A VERY RISKY, TRICKY STEP BECAUSE IT COULD // MOVE OBJECTS ALMOST TO THE POINT OF COLLISION, WHICH MAY THEN // BE DETECTED ALMOST AT TIME 0 NEXT FRAME. THERE ARE OTHER TRICKY // ISSUES RELATED TO OUR BUFFER AS WELL, SO WE CHEAT A LITTLE HERE // AND SCALE THE TIME REMAINING DOWN A LITTE if (currentCollisionTime < 1.0f) moveAllSpritesToEndOfFrame(); // INIT TILE COLLISION INFO // SET ON TILE LAST FRAME USING ON TILE THIS FRAME // SET ON TILE THIS FRAME TO FALSE spritesIt = sortedSweptShapes[LEFT_EDGE]->begin(); while (spritesIt != sortedSweptShapes[LEFT_EDGE]->end()) { CollidableObject *sprite = (*spritesIt); sprite->advanceOnTileStatus(); spritesIt++; } // while(!colliding){ for (b2Contact* contact = game->getbworld()->GetContactList(); contact; contact = contact->GetNext()) { b2Body* a = contact->GetFixtureA()->GetBody(); b2Body* b = contact->GetFixtureB()->GetBody(); AnimatedSprite* c = (AnimatedSprite*) a->GetUserData(); AnimatedSprite* d = (AnimatedSprite*) b->GetUserData(); unsigned int x = c->getSpriteType()->getSpriteTypeID(); unsigned int y = d->getSpriteType()->getSpriteTypeID(); switch(x){ case 0: // player break; case 1: // break; case 2: GarbageMon *e; e= (GarbageMon*)c; //co.remove(e); //game->getbworld()->DestroyBody(e->getBody()); //e->collisionResponse(game); break; case 4: //Trash *f = (Trash*)c; //f->collisionResponse(game); break; } switch(y){ // if (x == 0) { case 0: // player break; case 1: // break; case 2: // colliding = true; GarbageMon *g; g= (GarbageMon*)d; co.push_back(g); co.remove(g); //g->setCurrentState(L"DYING"); g->getPhysicalProperties()->setPosition(9999.9f, 9999.9f); game->playExplosion(); //wstring s = c->getCurrentState(); g->getBody()->ApplyLinearImpulse(b2Vec2(99999.9f, 0.0f), g->getBody()->GetPosition(), true); //game->getbworld()->DestroyBody(g->getBody()); //g->getBody()->DestroyFixture(g->getBody()->GetFixtureList()); //g->getBody()->GetWorld()->DestroyBody(g->getBody()); g->collisionResponse(game); //colliding = false; break; case 5: Trash *h = (Trash*)d; co.remove(h); //h->collisionResponse(game); break; } } //} //} //update sprites according to box2d thingies list<CollidableObject*>::iterator i = co.begin(); while (i != co.end()) { CollidableObject* c = *i; PhysicalProperties* p = c->getPhysicalProperties(); p->setX(c->getBody()->GetPosition().x * pikachu); p->setY(c->getBody()->GetPosition().y * pikachu); i++; } float32 time = 1.0f/1.25f; int32 vel = 8; int32 pos = 3; game->getbworld()->Step (time, vel, pos); for (b2Contact* contact = game->getbworld()->GetContactList(); contact; contact = contact->GetNext()) { b2Fixture* a = contact->GetFixtureA(); b2Fixture* b = contact->GetFixtureB(); AnimatedSprite* a2 = (AnimatedSprite*) a->GetBody()->GetUserData(); AnimatedSprite* b2 = (AnimatedSprite*) b->GetBody()->GetUserData(); if(a2->getSpriteType()->getSpriteTypeID() == 0 && b2->getSpriteType()->getSpriteTypeID() == 2){ b->GetBody()->ApplyLinearImpulse(a->GetBody()->GetWorldVector(b2Vec2(0,-2)), b->GetBody()->GetPosition(), true); b->GetBody()->SetLinearVelocity(b2Vec2 (0,0)); SpriteManager *sm = game->getGSM()->getSpriteManager(); int health = (int) _wtoi(sm->getHealthBar()->getCurrentState().c_str()); if (health <= 10){ // WHEN PLAYER RUNS OUT OF HEALTH, SKIP TO NEXT DAY // PENALTY LIES IN THE PLAYER NOT ACHIEVING THE DAY'S GOALS // AND HAVE TO SUFFER INCREASE IN POLLUTION BAR sm->getHealthBar()->setCurrentState(to_wstring(100)); } else{ //OutputDebugStringW(L"HI"); sm->getHealthBar()->setCurrentState(to_wstring(health - 10)); } } //contact->GetFixtureB()->GetBody()->DestroyFixture(a); } // WE'RE NOT GOING TO ALLOW MULTIPLE COLLISIONS TO HAPPEN IN A FRAME // BETWEEN THE SAME TWO OBJECTS spriteToTileCollisionsThisFrame.clear(); }
void Physics::update(Game *game) { // REMEMBER, AT THIS POINT, ALL PLAYER INPUT AND AI // HAVE ALREADY BEEN PROCESSED AND BOT AND PLAYER // STATES, VELOCITIES, AND ACCELERATIONS HAVE ALREADY // BEEN UPDATED. NOW WE HAVE TO PROCESS THE PHYSICS // OF ALL THESE OBJECTS INTERACTING WITH EACH OTHER // AND THE STATIC GAME WORLD. THIS MEANS WE NEED TO // DETECT AND RESOLVE COLLISIONS IN THE ORDER THAT // THEY WILL HAPPEN, AND WITH EACH COLLISION, EXECUTE // ANY GAMEPLAY RESPONSE CODE, UPDATE VELOCITIES, AND // IN THE END, UPDATE POSITIONS // FIRST, YOU SHOULD START BY ADDING ACCELERATION TO ALL // VELOCITIES, WHICH INCLUDES GRAVITY, NOTE THE EXAMPLE // BELOW DOES NOT DO THAT // FOR NOW, WE'LL JUST ADD THE VELOCITIES TO THE // POSITIONS, WHICH MEANS WE'RE NOT APPLYING GRAVITY OR // ACCELERATION AND WE ARE NOT DOING ANY COLLISION // DETECTION OR RESPONSE float timer = 0; GameStateManager *gsm = game->getGSM(); SpriteManager *sm = gsm->getSpriteManager(); World *w = gsm->getWorld(); GameRules* gR = game->getGameRules(); vector<WorldLayer*> *layers = w->getLayers(); AnimatedSprite *player; PhysicalProperties *pp; TiledLayer *tL; list<Collision*> collisions; //finding TileLayer for(unsigned int i = 0; i < layers->size(); i++) { WorldLayer *currentLayer = (*layers)[i]; if(currentLayer->hasCollidableTiles() == true) { tL = dynamic_cast<TiledLayer*>(currentLayer); if(tL != 0) { i = layers->size(); }//end if }//end if } player = sm->getPlayer(); pp = player->getPhysicalProperties(); //UPDATING ALL VELOCITIES AND DOING TILE COLLISION pp->incVelocity(this,pp->getAccelerationX(), pp->getAccelerationY() + gravity); collideTestWithTiles(player, tL, &collisions); list<Bot*>::iterator botIterator = sm->getBotsIterator(); while (botIterator != sm->getEndOfBotsIterator()) { Bot *bot = (*botIterator); pp = bot->getPhysicalProperties(); pp->incVelocity(this, pp->getAccelerationX(), pp->getAccelerationY()); if(pp->isGravAffected() == true) pp->incVelocity(this, 0, gravity); collideTestWithTiles(bot, tL, &collisions); botIterator++; } //HERE, COLLIDE SPRITES WITH OTHER SPRITES collideTestWithSprites(game, player, &collisions); botIterator = sm->getBotsIterator(); while (botIterator != sm->getEndOfBotsIterator()) { Bot *bot = (*botIterator); if(bot->isCurrentlyCollidable() == true); collideTestWithSprites(game, bot, &collisions); botIterator++; } //SORT COLLISIONS collisions.sort(compare_collisionTime); //RESOLVING ALL THE COLLISIONS while(collisions.empty() == false) { Collision* currentCollision = collisions.front(); collisions.pop_front(); float colTime = currentCollision->getTOC(); CollidableObject* co1 = currentCollision->getCO1(); CollidableObject* co2 = currentCollision->getCO2(); if(colTime >= 0 && colTime <= 1) { pp = co1->getPhysicalProperties(); //pp->setVelocity(pp->getVelocityX()*9.99f,pp->getVelocityY()*9.99f); pp = co2->getPhysicalProperties(); //pp->setVelocity(pp->getVelocityX()*9.99f,pp->getVelocityY()*9.99f); pp = player->getPhysicalProperties(); pp->setPosition(pp->getX() + (pp->getVelocityX()*(colTime-timer)),pp->getY() + (pp->getVelocityY()*(colTime-timer))); botIterator = sm->getBotsIterator(); while (botIterator != sm->getEndOfBotsIterator()) { Bot *bot = (*botIterator); pp = bot->getPhysicalProperties(); pp->setPosition(pp->getX() + (pp->getVelocityX()*(colTime-timer)), pp->getY() + (pp->getVelocityY()*(colTime-timer))); botIterator++; } gsm->updateViewport(game, colTime-timer); resolveCollision(game, currentCollision); gR->gameSpecificResolve(game, currentCollision); boolean deleteLast = false; list<Collision*>::iterator cIterator = collisions.begin(); list<Collision*>::iterator lastIterator; while(cIterator != collisions.end()) { if(deleteLast == true) { collisions.erase(lastIterator); } deleteLast = false; Collision* check = (*cIterator); if(check->contains(co1) || check->contains(co2)) { CollidableObject* checkStatic = check->getCO2(); if(checkStatic->isStaticObject()) { coStackCounter ++; coStack[coStackCounter] = checkStatic; } collisionStackCounter ++; collisionStack[collisionStackCounter] = check; lastIterator = cIterator; deleteLast = true; } else { //check->calculateTimes(); } cIterator++; } if(deleteLast == true) { collisions.erase(lastIterator); } collideTestWithTiles(co1, tL, &collisions); collideTestWithSprites(game, co1, &collisions); if(co2->isStaticObject() == false) { collideTestWithTiles(co2, tL, &collisions); collideTestWithSprites(game, co2, &collisions); } collisions.sort(compare_collisionTime); timer += (colTime-timer); }//end if if(co2->isStaticObject() == true) { coStackCounter ++; coStack[coStackCounter] = co2; } collisionStackCounter ++; collisionStack[collisionStackCounter] = currentCollision; } if(timer < 1) { gsm->updateViewport(game, 1-timer); pp = player->getPhysicalProperties(); pp->setPosition(pp->getX() + (pp->getVelocityX()*(1-timer)),pp->getY() + (pp->getVelocityY()*(1-timer))); //pp->setVelocity(0.0f, pp->getVelocityY()); botIterator = sm->getBotsIterator(); while (botIterator != sm->getEndOfBotsIterator()) { Bot *bot = (*botIterator); pp = bot->getPhysicalProperties(); pp->setPosition(pp->getX() + (pp->getVelocityX()*(1-timer)), pp->getY() + (pp->getVelocityY()*(1-timer))); botIterator++; } gsm->updateViewport(game, 1-timer); } pp = player->getPhysicalProperties(); if(pp->getX() < 0) { pp->setX(0); } if(pp->getY() < 0) { pp->setY(0); } //pp->setVelocity(0.0f, pp->getVelocityY()); /*pp->setPosition(pp->getX() + pp->getVelocityX(), pp->getY() + pp->getVelocityY()); // FOR NOW THE PLAYER IS DIRECTLY CONTROLLED BY THE KEYBOARD, // SO WE'LL NEED TO TURN OFF ANY VELOCITY APPLIED BY INPUT // SO THE NEXT FRAME IT DOESN'T GET ADDED pp->setVelocity(0.0f, pp->getVelocityY()); // AND NOW MOVE ALL THE BOTS list<Bot*>::iterator botIterator = sm->getBotsIterator(); while (botIterator != sm->getEndOfBotsIterator()) { Bot *bot = (*botIterator); pp = bot->getPhysicalProperties(); pp->setPosition(pp->getX() + pp->getVelocityX(), pp->getY() + pp->getVelocityY()); botIterator++; }*/ }
//FOR NOW, TESTS SPRITES AGAINST ALL OTHER SPRITES. IF I HAVE TIME, I WILL IMPLEMENT SWEEP AND PRUNE void Physics::collideTestWithSprites(Game* game, CollidableObject* c, list<Collision*> *collisions) { SpriteManager *sm = game->getGSM()->getSpriteManager(); AnimatedSprite* player = sm->getPlayer(); if(c != player) { if(player->isCurrentlyCollidable() == true) { if(willObjectsCollide(player, c) == true) { Collision* currentCollision = collisionStack[collisionStackCounter]; collisionStackCounter --; currentCollision->setCO1(player); currentCollision->setCO2(c); currentCollision->calculateTimes(); if(currentCollision->getTOC() > 0 && currentCollision->getTOC() <= 1) { collisions->push_back(currentCollision); } else { collisionStackCounter ++; collisionStack[collisionStackCounter] = currentCollision; } }//end if }//end if }//end if else { list<Bot*>::iterator botIterator = sm->getBotsIterator(); while (botIterator != sm->getEndOfBotsIterator()) { Bot *bot = (*botIterator); if(c != bot && bot->isCurrentlyCollidable() == true) { if(willObjectsCollide(c, bot) == true) { Collision* currentCollision = collisionStack[collisionStackCounter]; collisionStackCounter --; currentCollision->setCO1(c); currentCollision->setCO2(bot); currentCollision->calculateTimes(); if(currentCollision->getTOC() > 0 && currentCollision->getTOC() <= 1) { collisions->push_back(currentCollision); } else { collisionStackCounter ++; collisionStack[collisionStackCounter] = currentCollision; } }//end if }//end if botIterator++; }//end while } /*Collision* currentCollision = collisionStack[collisionStackCounter]; collisionStackCounter --; currentCollision->setCO1(c); currentCollision->setCO2(tileCO); currentCollision->calculateTimes(); collisions->push_back(currentCollision);*/ }
void SetupRC() { SpriteManager *sprites = SpriteManager::instance(); Vector p(0.0f,0.0f,-1.0f); player = new Player("resources/Models/cube.ogl", p); sprites->AddSprite( player); std::string filename="resources/Models/cube.ogl"; test = new Model(filename); /* Vector v((GLfloat)(0), (GLfloat)(0), (GLfloat) (5) ); sprites->AddSprite( new Sprite("resources/Models/cube.ogl", v) ); */ for (int i=0; i<30; i++) { Vector v((GLfloat)(0), (GLfloat)(i *3 ), (GLfloat) (10) ); sprites->AddSprite( new Sprite("resources/Models/cube.ogl", v, i*8, i*2, i*5) ); } glEnable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); shader.vertexShader = makeShader( GL_VERTEX_SHADER, "resources/Shaders/identity.vs"); if(shader.vertexShader == 0){ printf("failed to make vertex shader"); exit(0); } shader.fragmentShader = makeShader(GL_FRAGMENT_SHADER, "resources/Shaders/identity.fs"); if(shader.fragmentShader == 0){ printf("failed to make fragment shader"); exit(0); } shader.program = makeProgram(shader.vertexShader, shader.fragmentShader); if(shader.program == 0){ printf("failed to make program"); exit(0); } shader.uniforms.colour = glGetUniformLocation( shader.program, "colour"); if( shader.uniforms.colour == -1){ printf( "failed to locate uniform colour location"); exit(0); } shader.uniforms.modelViewProjectionMatrix = glGetUniformLocation(shader.program, "modelViewProjectionMatrix"); if( shader.uniforms.modelViewProjectionMatrix == -1){ printf("failed to locate uniform modelViewProjectionMatrix"); exit(0); } shader.attributes.pos = glGetAttribLocation( shader.program, "position"); }
//Main loop that the game goes though void GameEngine::gameLoop() { //Load title screen sf::Texture title; title.loadFromFile("assets/art/titlescreen.png"); sf::Sprite sprite1; sprite1.setTexture(title); sf::View titlescreen; titlescreen.setSize(rendEng->window.getSize().x, rendEng->window.getSize().y); titlescreen.setCenter(500,238); //Display title screen rendEng->window.setView(titlescreen); rendEng->centerViews(sf::Vector2f(-titlescreen.getSize().x/2,0)); rendEng->window.draw(sprite1); rendEng->window.display(); //Wait for user to press space while(!inputEng->getJump()){ inputEng->update(this); } sf::Clock frameClock; SpriteManager spriteMan; spriteMan.loadFile("assets/SamusSprites.xml"); spriteMan.loadFile("assets/explosionSprite.xml"); GuiLoader testGui; testGui.load("main.gui", this); Level testLevel; testLevel.loadLevel("scifi.tmx", rendEng); //play background music sf::Music music; //Declare music object music.openFromFile("assets/sound/stormeaglegenesis.wav"); //open this sound for music music.setVolume(30); //Set volume of music music.setLoop(true); //loop the music throughout //music.play(); //sound should now play throughout the game! //Load dying sound sf::Sound dyingsound; sf::SoundBuffer dyingbuffer; dyingbuffer.loadFromFile("assets/sound/death.wav"); dyingsound.setBuffer(dyingbuffer); dyingsound.setLoop(false); while (rendEng->window.isOpen() && !died) { sf::Time frameTime = frameClock.restart(); ComponentManager::getInst().processAll(frameTime); rendEng->render(frameTime, physEng); physEng->step(frameTime); inputEng->update(this); //Play dying sound if(playerDying){ if(dyingsound.getStatus()!=sf::SoundSource::Status::Playing) dyingsound.play(); music.stop(); } } //Game over screen music.stop(); sf::Texture gameover; gameover.loadFromFile("assets/art/gameover.png"); sf::Sprite sprite; sprite.setTexture(gameover); //Display game over screen sf::View endView; endView.setSize(rendEng->window.getSize().x, rendEng->window.getSize().y); endView.setCenter(500,238); rendEng->window.setView(endView); //sprite.setPosition(gameover.getSize().x/2, gameover.getSize().y/2); rendEng->centerViews(sf::Vector2f(-gameover.getSize().x/2,0)); rendEng->window.draw(sprite); rendEng->window.display(); Options::instance().save(); //Exit after 3 seconds sf::Clock clk; while(clk.getElapsedTime() <= sf::seconds(3) && rendEng->window.isOpen()){ } }
/* This is where all game physics starts each frame. It is called each frame by the game statem manager after player input and AI have been processed. It updates the physical state of all dynamic objects in the game and moves all objects to their end of frame positions, updates all necessary object velocities, and calls all collision event handlers. */ void Physics::update(Game *game) { GameStateManager *gsm = game->getGSM(); SpriteManager *spm = gsm->getSpriteManager(); AnimatedSprite *player = spm->getPlayer(); if (once == 0) { /* b2PolygonShape groundBox; groundBox.SetAsBox(50.0f, 10.0f); groundBody->CreateFixture(&groundBox, 0.0f); */ b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(600, 9280); body = world->CreateBody(&bodyDef); b2PolygonShape dynamicBox; dynamicBox.SetAsBox(32.0f, 32.0f); b2FixtureDef fixtureDef; fixtureDef.shape = &dynamicBox; // Set the box density to be non-zero, so it will be dynamic. fixtureDef.density = 1.0f; // Override the default friction. fixtureDef.friction = 0.3f; // Add the shape to the body. body->CreateFixture(&fixtureDef); //body->SetLinearVelocity(b2Vec2(0,-1000)); //body->SetUserData(player); player->setBody(body); // This is our little game loop. once += 1; } body->ApplyForce( world->GetGravity(), body->GetWorldCenter(), true ); float32 timeStep = 1.0f / 60.0f; int32 velocityIterations = 6; int32 positionIterations = 2; world->Step(timeStep, velocityIterations, positionIterations); // Now print the position and angle of the body. b2Vec2 position = body->GetPosition(); //b2Vec2 position2 = body2->GetPosition(); float32 angle = body->GetAngle(); printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle); if (f == 0) { World *woorld = gsm->getWorld(); vector<WorldLayer*> *layers = woorld->getLayers(); CollidableObject *sprite = NULL; for (int i = 0; i < woorld->getNumLayers(); i++) { WorldLayer *layer = layers->at(i); if (layer->hasCollidableTiles()) { layer->findTileCollisionsForSprite(this,sprite); } } f++; } if (player->getinvincible() == true) { if (invincibletimer == 0) { invincibletimer = 100; } invincibletimer -= 1; if (invincibletimer == 0) { player->setinvincible(false); } } if (z!=0)z--; if (z==0) if (player->getinvincible() == false) for (b2ContactEdge* edge = body->GetContactList(); edge; edge = edge->next) if (edge->contact->IsTouching()) { z=50; if(game->getPlayerLife() > 0) {game->decreasePlayerLife(); PlaySound(L"data/sounds/explosion.wav", NULL, SND_FILENAME|SND_SYNC);} else { if(game->getLives() > 1) { game->decreaseLives(); } else if(game->getLives() == 1 && game->getPlayerLife() == 0) { GameStateManager *gsm = game->getGSM(); once = 0; //body->SetTransform(b2Vec2((600-position.x),(9280-position.y)),body->GetAngle()); Viewport *viewport = game->getGUI()->getViewport(); viewport->setViewportX(0); viewport->setViewportY(8880); gsm->gameOver(); PlaySound(L"data/sounds/end.wav", NULL, SND_FILENAME|SND_SYNC); } game->setPlayerLife(); } } /*if (f > 0) { if(game->getPlayerLife() > 0) game->decreasePlayerLife(); else { if(game->getLives() > 1) game->decreaseLives(); else if(game->getLives() == 1 && game->getPlayerLife() == 0) { GameStateManager *gsm = game->getGSM(); gsm->setCurrentGameState(GS_GAME_OVER); } game->setPlayerLife(); } }*/ //OutputDebug(L"My output string."); // activatedForSingleUpdate = false; //// WE'LL NEED THE WORLD TO ACCESS THE SPRITES AND WORLD LAYERS //World *woorld = gsm->getWorld(); //currentCollisionTime = 0.0f; //// FOR ALL SPRITES, INCLUDING THE BOTS AND PLAYER //vector<CollidableObject*>::iterator spritesIt = sortedSweptShapes[LEFT_EDGE]->begin(); //while (spritesIt != sortedSweptShapes[LEFT_EDGE]->end()) //{ // CollidableObject *sprite = (*spritesIt); // prepSpriteForCollisionTesting(woorld, sprite); // getAllTileCollisionsForAGivenSprite(woorld, sprite, 1.0f); // spritesIt++; //} //// PREPARE FOR SPRITE-SPRITE COLLISION TESTING // // SWEEP AND PRUNE DATA STRUCTURES PREP WORK // // SORT S_AND_P VECTOR SORTED BY START X OF SWEPT SHAPE // // SORT S_AND_P VECTOR SORTED BY END X OF SWEPT SHAPE // // WE DON'T NEED THE Y-AXIS SORTED, BUT WOULD IF THIS // // WERE A 3D SYSTEM TO SAVE ON COMPARISONS. //// WE'RE USING C++'s STL sort METHOD AND ARE PROVIDING //// A CUSTOM MEANS FOR COMPARISON //sort(sortedSweptShapes[LEFT_EDGE]->begin(), sortedSweptShapes[LEFT_EDGE]->end(), SweptShapesComparitorByLeft()); //sort(sortedSweptShapes[RIGHT_EDGE]->begin(), sortedSweptShapes[RIGHT_EDGE]->end(), SweptShapesComparitorByRight()); // //// RECORD SORTED POSITIONS WITH EACH SPRITE. THEY NEED TO KNOW WHERE //// THEY ARE IN THOSE DATA STRUCTURES SUCH THAT WE CAN JUMP INTO //// THOSE DATA STRUCTURES TO TEST COLLISIONS WITH NEIGHBORS //updateSweptShapeIndices(); //// YOU'LL NEED TO TEST FOR SPRITE-TO-SPRITE COLLISIONS HERE //// *** LOOP STARTS HERE. WE'LL DO THIS UNTIL THERE ARE NO //// MORE COLLISIONS TO RESOLVE FOR THIS FRAME //while (activeCollisions.size() > 0) //{ // // SORT COLLISION OBJECTS BY TIME OF COLLISION // // NOTE THAT I'M JUST EMPLOYING THE STL'S List // // CLASS' SORT METHOD BY PROVIDING MY OWN // // MEANS FOR COMPARING Collision OBJECTS // activeCollisions.sort(CollisionComparitor()); // // GET FIRST COLLISION - NOTE THAT WE HAVE THE COLLISIONS SORTED // // IN DESCENDING ORDER, SO TO TAKE THE EARLIEST ONE, WE REMOVE IT // // FOM THE BACK OF THE SORTED LIST // Collision *earliestCollision = activeCollisions.back(); // activeCollisions.pop_back(); // float collisionTime = earliestCollision->getTimeOfCollision(); // // MOVE ALL SPRITES UP TO TIME OF FIRST COLLISION USING // // APPROPRIATELY SCALED VELOCITIES // moveAllSpritesUpToBufferedTimeOfCollision(earliestCollision); // // AND ADVANCE COLLISION TIME // currentCollisionTime = collisionTime; // // AND UPDATE THE VELOCITIES OF THE SPRITE(S) INVOLVED IN THE COLLISION // performCollisionResponse(earliestCollision); // // EXECUTE COLLISION EVENT CODE // // TEST TO SEE TYPES OF OBJECTS AND APPROPRIATE RESPONSE // // ACCORDING TO CUSTOMIZED COLLISION EVENT HANDLER // collisionListener->respondToCollision(game, earliestCollision); // CollidableObject *co1 = earliestCollision->getCO1(); // CollidableObject *co2 = earliestCollision->getCO2(); // removeActiveCOCollisions(co1); // co1->updateSweptShape(1.0f - currentCollisionTime); // getAllTileCollisionsForAGivenSprite(woorld, co1, 1.0f - currentCollisionTime); // // ONLY DO IT FOR THE SECOND ONE IF IT'S NOT A TILE // if (!earliestCollision->isCollisionWithTile()) // { // removeActiveCOCollisions(co2); // co2->updateSweptShape(1.0f - currentCollisionTime); // getAllTileCollisionsForAGivenSprite(woorld, co2, 1.0f - currentCollisionTime); // } // else // { // spriteToTileCollisionsThisFrame[co1].insert(earliestCollision->getTile()); // recycledCollidableObjectsList.push_back(co2); // } // // // IF IT WAS ONLY ONE SPRITE WITH A TILE THIS IS EASY TO DO // if (earliestCollision->isCollisionWithTile()) // { // reorderCollidableObject(co1); // } // // YOU'LL HAVE TO WORRY ABOUT REORDERING STUFF FOR COLLISIONS // // BETWEEN TWO SPRITES // // // NOW TEST NEIGHBORS OF SPRITES INVOLVED IN RESOLVED COLLISION // // AGAINST NEIGHBORS IN SWEPT SHAPE DATA STRUCTURES. YOU'LL HAVE // // TO FIGURE OUT HOW TO DO THIS AND HOW TO RESOLVE SUCH COLLISIONS // // // RECYCLE THE COLLISION SINCE WE'RE NOW DONE WITH IT // recycledCollisions.push_back(earliestCollision); //} //// APPLY THE REMAINING TIME TO MOVE THE SPRITES. NOTE THAT //// THIS IS ACTUALLY A VERY RISKY, TRICKY STEP BECAUSE IT COULD //// MOVE OBJECTS ALMOST TO THE POINT OF COLLISION, WHICH MAY THEN //// BE DETECTED ALMOST AT TIME 0 NEXT FRAME. THERE ARE OTHER TRICKY //// ISSUES RELATED TO OUR BUFFER AS WELL, SO WE CHEAT A LITTLE HERE //// AND SCALE THE TIME REMAINING DOWN A LITTE //if (currentCollisionTime < 1.0f) // moveAllSpritesToEndOfFrame(); //// INIT TILE COLLISION INFO //// SET ON TILE LAST FRAME USING ON TILE THIS FRAME //// SET ON TILE THIS FRAME TO FALSE //spritesIt = sortedSweptShapes[LEFT_EDGE]->begin(); //while (spritesIt != sortedSweptShapes[LEFT_EDGE]->end()) //{ // CollidableObject *sprite = (*spritesIt); // sprite->advanceOnTileStatus(); // spritesIt++; //} //// WE'RE NOT GOING TO ALLOW MULTIPLE COLLISIONS TO HAPPEN IN A FRAME //// BETWEEN THE SAME TWO OBJECTS //spriteToTileCollisionsThisFrame.clear(); // }
/**\brief chooses who the AI should target given the list of the AI's enemies * */ int AI::ChooseTarget( lua_State *L ){ //printf("choosing target\n"); SpriteManager *sprites = Simulation_Lua::GetSimulation(L)->GetSpriteManager(); list<Sprite*> *nearbySprites = sprites->GetSpritesNear(this->GetWorldPosition(), COMBAT_RANGE, DRAW_ORDER_SHIP); nearbySprites->sort(CompareAI); list<Sprite*>::iterator it; list<enemy>::iterator enemyIt=enemies.begin(); //printf("printing list of enemies\n"); //printf("the size of enemies = %d\n", enemies.size() ); for(enemyIt=enemies.begin(); enemyIt!=enemies.end();){ if(sprites->GetSpriteByID( enemyIt->id)==NULL){ enemyIt=enemies.erase(enemyIt); } else { enemyIt++; } } //printf("printing list of nearby it->GetTarget()\n"); //int nearbySpritesSize=(*nearbySprites).size(); //printf("the size of nearbySprites = %d\n",nearbySpritesSize); /*for(it=nearbySprites->begin(); it!=nearbySprites->end(); it++){ if( (*it)->GetDrawOrder() ==DRAW_ORDER_SHIP ) printf("it->GetTarget() = %d\n",((AI*)(*it))->GetTarget() ); printf("it->GetID() = %d\n",(*it)->GetID() ); }*/ it=nearbySprites->begin(); enemyIt=enemies.begin(); int max=0,currTarget=-1; int threat=0; //printf("starting sprite iteration\n"); for(it= nearbySprites->begin(); it!=nearbySprites->end() && enemyIt!=enemies.end() ; it++){ if( (*it)->GetID()== this->GetID() ) continue; if( (*it)->GetDrawOrder() ==DRAW_ORDER_SHIP){ if( enemyIt->id < ((AI*) (*it))->GetTarget() ){ //printf("starting enemyIt iteration\n"); while ( enemyIt!=enemies.end() && enemyIt->id < ( (AI*) (*it) )->GetTarget() ) { // printf("enemyIt = %d\n",enemyIt->id); // printf("it->GetTarget() = %d\n", ((AI*) (*it))->GetTarget() ); if ( !InRange( sprites->GetSpriteByID(enemyIt->id)->GetWorldPosition() , this->GetWorldPosition() ) ) { enemyIt=enemies.erase(enemyIt); threat=0; continue; } int cost= CalcCost( threat + ( (Ship*)sprites->GetSpriteByID(enemyIt->id))->GetTotalCost() , enemyIt->damage); //damage might need to be scaled so that the damage can be adquately compared to the treat level if(currTarget==-1 || max<cost){ currTarget=enemyIt->id; max=cost; } threat=0; enemyIt++; } //printf("successfully completed enemyIt iteration\n"); it--; continue; } if( enemyIt->id == ((AI*) (*it))->GetTarget() ) threat-= ( (Ship*)(*it) )->GetTotalCost(); } else{ LogMsg( ERR, "Error Sprite %d is not an AI\n", (*it)->GetID() ); } } // printf("finished sprite iteration\n"); // cout<<"enemies.size()="<<enemies.size()<<'\n'; while (enemyIt!=enemies.end()) { //printf("starting enemyIt iteration mark2\n"); if ( !InRange( sprites->GetSpriteByID(enemyIt->id)->GetWorldPosition() , this->GetWorldPosition() ) ) { enemyIt=enemies.erase(enemyIt); threat=0; continue; } //printf("finished In range check\n"); //printf("calculate cost\n"); int cost= CalcCost( threat + ( (Ship*)sprites->GetSpriteByID(enemyIt->id))->GetTotalCost() , enemyIt->damage); //damage might need to be scaled so that the damage can be adquately compared to the treat level threat=0; //printf("finished calculating cost\n"); if( currTarget==-1 || max < cost){ max=cost; currTarget=enemyIt->id; } //printf("successfully completed enemyIt iteration mark 2\n"); enemyIt++; } //printf("finished choosing target. %d is the target\n",currTarget); return currTarget; }
void RebelleUpgradeScreenGUI::loadPlayerStats() { Game* game = Game::getSingleton(); GameStateManager* gsm = game->getGSM(); SpriteManager* spriteMgr = gsm->getSpriteManager(); GameGraphics *graphics = game->getGraphics(); TextureManager *guiTextureManager = graphics->getGUITextureManager(); PlayerSprite *player = spriteMgr->getPlayer(); int speed = player->getSpeed(); int attack = player->getAttack(); int defense = player->getDefense(); unsigned int speedIconTID = guiTextureManager->loadTexture(SPEED_ICON_PATH); unsigned int attackIconTID = guiTextureManager->loadTexture(ATTACK_ICON_PATH); unsigned int defenseIconTID = guiTextureManager->loadTexture(DEFENSE_ICON_PATH); //// - first speed icon will be rendered at 20px right to upgrade button int speedIconY = statListY + statLineHeight + ydistBetweenStats; int nextSpeedIconX = statListX + statTitleWidth + statTitleWidth + upgradeButtonWidth + 20; for (int i = 0; i < speed; i++) { OverlayImage *speedIcon = new OverlayImage(); speedIcon->alpha = 255; speedIcon->width = STAT_ICON_WIDTH; speedIcon->height = STAT_ICON_HEIGHT; speedIcon->x = nextSpeedIconX; speedIcon->y = speedIconY; speedIcon->z = 0; speedIcon->imageID = speedIconTID; this->addOverlayImage(speedIcon); nextSpeedIconX += STAT_ICON_WIDTH + 3; } //// attack icons should be next to Attack stat title and the button. int attackIconY = speedIconY + statLineHeight + ydistBetweenStats; int nextAttackIconX = statListX + statTitleWidth + statTitleWidth + upgradeButtonWidth + 20; for (int i = 0; i < attack; i++) { OverlayImage *attackIcon = new OverlayImage(); attackIcon->alpha = 255; attackIcon->width = STAT_ICON_WIDTH; attackIcon->height = STAT_ICON_HEIGHT; attackIcon->x = nextAttackIconX; attackIcon->y = attackIconY; attackIcon->z = 0; attackIcon->imageID = attackIconTID; this->addOverlayImage(attackIcon); nextAttackIconX += STAT_ICON_WIDTH + 3; } //// defense icons int defenseIconY = attackIconY + statLineHeight + ydistBetweenStats; int nextDefenseIconX = statListX + statTitleWidth + statTitleWidth + upgradeButtonWidth + 20; for (int i = 0; i < attack; i++) { OverlayImage *defenseIcon = new OverlayImage(); defenseIcon->alpha = 255; defenseIcon->width = STAT_ICON_WIDTH; defenseIcon->height = STAT_ICON_HEIGHT; defenseIcon->x = nextDefenseIconX; defenseIcon->y = defenseIconY; defenseIcon->z = 0; defenseIcon->imageID = defenseIconTID; this->addOverlayImage(defenseIcon); nextDefenseIconX += STAT_ICON_WIDTH + 3; } }