void PlayState::advanceStage() { EnemyIterator itr = enemies.begin(); if(itr.next() == 0) { switch (stageCount) { case 1: { currentStage->increaseDifficulty(); currentStage = g_stage2; currentStage->reset(); stageCount = 2; break; } case 2: { currentStage->increaseDifficulty(); currentStage = g_stage3; currentStage->reset(); stageCount = 3; break; } case 3: { currentStage->increaseDifficulty(); currentStage = g_stage1; currentStage->reset(); stageCount = 1; break; } } gameStateMan->pushState(g_stageEndState); } }
void PlayState::updateEnemies() { EnemyIterator itr = enemies.begin(); Enemy* curEnemy; while ((curEnemy = itr.next()) != 0) { curEnemy->update(); if (curEnemy->X() < (-1*curEnemy->width()) || curEnemy->X() > MAX_ENEMY_X || curEnemy->Y() < MIN_ENEMY_Y || curEnemy->Y() > MAX_ENEMY_Y) { curEnemy->setVisible(false); itr.dealloc(); } else { if(player.hitBox.checkCollision(curEnemy->hitBox)) { //assert2(false, "The player crashed into an enemy. If found, comment this out on line 854 in PlayState.cpp"); if (!player.isInvincible()) { if(!player.getIsShielded()) { player.setPos(PLAYER_ORIGIN); player.setInvincibility(90); } player.killPlayer(); int lifeCount = player.getLifeCount(); lives[lifeCount-1].setVisible(false); // If you're out of lives, the game is over. if(lifeCount == 0) { gameStateMan->changeState(g_gameOverState); return; } } g_playerScore += 200; curEnemy->setVisible(false); g_audioMan->playOneShot(enemyDiedNoise, enemyDiedNoiseSize, 32); itr.dealloc(); } } } }
void PlayState::checkInput() { // Start = pause game if (key_hit(KEY_START)) { gameStateMan->pushState(g_pauseState); } // R-Button = swap weapon modes if (key_hit(KEY_R)) { R_triggered = !R_triggered; R_triggered_indicator.setTileIndex(R_triggered ? g_bullet_selection2TilesPos : g_bullet_selection1TilesPos); } // Check for A button press // First block checks for an immediate button press. // Second block allows constant fire by holding a button. This is forced to a specific frequency. if (key_is_down(KEY_A)) { if (R_triggered) { player.shootLightWide(); } else { player.shootLightFocus(); } } else { player.idleLight(); } // secondary fire if (key_is_down(KEY_B)) { player.shootHeavy(); } else { player.idleHeavy(); } // L-Button = bomb the screen, destroying all enemies and bullets if (key_hit(KEY_L) && player.hasBomb()) { player.subtractBomb(); // play the bomb sound g_audioMan->playOneShot(bombNoise, bombNoiseSize); // Destroy enemies EnemyIterator itr = enemies.begin(); Enemy* curEnemy; while ((curEnemy = itr.next()) != 0) { curEnemy->setVisible(false); itr.dealloc(); g_playerScore = g_playerScore + 200; } bombAnimation = true; // Destroy enemy bullets EnemyBulletIterator enemyBulletItr = enemyBullets.begin(); Bullet* toUpdate; while ((toUpdate = enemyBulletItr.next()) != 0) { toUpdate->setVisible(false); enemyBulletItr.dealloc(); } // Destroy player bullets PlayerBulletIterator bulletItr = playerBullets.begin(); Bullet* playerToUpdate; while ((playerToUpdate = bulletItr.next()) != 0) { playerToUpdate->setVisible(false); bulletItr.dealloc(); } powerUp.setVisible(false); powerUpExists = false; } }
void PlayState::updateBullets() { PlayerBulletIterator playerBulletItr = playerBullets.begin(); // Update each player bullet Bullet* toUpdate; bool bulletDestroyed; while ((toUpdate = playerBulletItr.next()) != 0) { bulletDestroyed = false; toUpdate->update(); // Check if the bullet has gone off-screen. If it is, we hide it and dealloc. // Otherwise, we check for enemy collisions if(toUpdate->X() > (SCREEN_WIDTH + toUpdate->width()) || toUpdate->X() < (-1*toUpdate->width()) || toUpdate->Y() < (-1*toUpdate->height()) || toUpdate->Y() > SCREEN_HEIGHT) { toUpdate->setVisible(false); playerBulletItr.dealloc(); } else { // Check if a bullet has collided with an enemy. EnemyIterator enemyItr = enemies.begin(); Enemy* curEnemy; while ((curEnemy = enemyItr.next()) != 0) { if(toUpdate->hitBox.checkCollision(curEnemy->hitBox)) { if(!bulletDestroyed) { g_playerStageBulletsHit++; toUpdate->setVisible(false); playerBulletItr.dealloc(); bulletDestroyed = true; } if (curEnemy->damage(toUpdate->getDamage())) { curEnemy->setVisible(false); g_audioMan->playOneShot(enemyDiedNoise, enemyDiedNoiseSize, 32); enemyItr.dealloc(); g_playerScore += 200; } } } } } EnemyBulletIterator enemyBulletItr = enemyBullets.begin(); // Update each enemy bullet while ((toUpdate = enemyBulletItr.next()) != 0) { bulletDestroyed = false; toUpdate->update(); // Check if a bullet has collided with the player. if(player.hitBox.checkCollision(toUpdate->hitBox)) { if (!player.isInvincible()) { // Decrement life count if(!player.getIsShielded()) { player.setPos(PLAYER_ORIGIN); // Give temporary immunity to damage player.setInvincibility(90); } player.killPlayer(); int lifeCount = player.getLifeCount(); lives[lifeCount - 1].setVisible(false); // If you're out of lives, the game is over if(lifeCount == 0) { gameStateMan->changeState(g_gameOverState); return; } } toUpdate->setVisible(false); if (!bulletDestroyed) { enemyBulletItr.dealloc(); bulletDestroyed = true; } } // Check if the bullet has gone off-screen. If it is, we hide it and dealloc, // which effectively steps to the next iterator value. Otherwise, we'll step // forward ourselves.. if (toUpdate->X() > (SCREEN_WIDTH + toUpdate->width()) || toUpdate->X() < (-1*toUpdate->width()) || toUpdate->Y() < (-1*toUpdate->height()) || toUpdate->Y() > SCREEN_HEIGHT) { toUpdate->setVisible(false); if (!bulletDestroyed) { enemyBulletItr.dealloc(); bulletDestroyed = true; } } } }
void PlayState::destroy() { // deinit display sprites at bottom lifeIndic.setVisible(false); lifeIndic.unuseImg(); bombIndic.setVisible(false); bombIndic.unuseImg(); starsBG_Pos = Vec2(0, 0); REG_BG0VOFS = starsBG_Pos.y; REG_BG0HOFS = starsBG_Pos.x; player.setVisible(false); player.unuseImg(); PlayerBulletIterator playerBulletItr = playerBullets.begin(); Bullet* curBullet; while((curBullet = playerBulletItr.next()) != 0) { curBullet->setVisible(false); playerBulletItr.dealloc(); } EnemyBulletIterator enemyBulletItr = enemyBullets.begin(); while((curBullet = enemyBulletItr.next()) != 0) { curBullet->setVisible(false); enemyBulletItr.dealloc(); } EnemyIterator enemyItr = enemies.begin(); Enemy* curEnemy; while((curEnemy = enemyItr.next()) != 0) { curEnemy->setVisible(false); enemyItr.dealloc(); } playerBullets.spriteDestroy(); enemyBullets.spriteDestroy(); enemies.spriteDestroy(); R_triggered_indicator.setVisible(false); R_triggered_indicator.unuseImg(); int lifeCount = player.getLifeCount(); for(int i = 0; i < lifeCount - 1; ++i) { lives[i].setVisible(false); lives[i].unuseImg(); } powerUp.setVisible(false); powerUp.unuseImg(); if (poweredUp) { powerUp.powerDown(&player); } clearText(); g_oamMan->deallocSprites(sprites, NUM_SPRITES); }
void PlayState::spawnEnemy(int count, StageEvent::EnemyType * enemyTypes, int * xSpawn, int * ySpawn, int yOffset, int difficulty) { EnemyIterator itr = enemies.alloc(count); Enemy * curEnemy; int i = 0; while ((curEnemy = itr.next()) != 0) { assert2(i < count, "The allocator gave more enemies than were suppose to be created."); switch(enemyTypes[i]) { case StageEvent::jellyfish: { curEnemy->setPos(xSpawn[i], ySpawn[i] + yOffset); curEnemy->setPath(JELLYFISH_PATH); curEnemy->setBulletPath(JELLYFISH_BULLET_PATH); curEnemy->setMaxHealth(JELLYFISH_HEALTH + difficulty); curEnemy->setBulletFrequency(JELLYFISH_BULLET_FREQUENCY); curEnemy->setDamage(1); curEnemy->setParent(this); curEnemy->setSize(Sprite::size_16x32); curEnemy->setTileIndex(g_jellyfishTilesPos); curEnemy->hitBox.left = xSpawn[i] + JELLYFISH_LEFT_OFFSET; curEnemy->hitBox.right = xSpawn[i] + JELLYFISH_RIGHT_OFFSET; curEnemy->hitBox.top = ySpawn[i] + yOffset + JELLYFISH_TOP_OFFSET; curEnemy->hitBox.bottom = ySpawn[i] + yOffset + JELLYFISH_BOTTOM_OFFSET; break; } case StageEvent::mine: { curEnemy->setPos(xSpawn[i], ySpawn[i] + yOffset); curEnemy->setPath(MINE_PATH); curEnemy->setBulletPath(MINE_BULLET_PATH); curEnemy->setMaxHealth(MINE_HEALTH + difficulty); curEnemy->setBulletFrequency(MINE_BULLET_FREQUENCY); curEnemy->setDamage(1); curEnemy->setParent(this); curEnemy->setSize(Sprite::size_8x8); curEnemy->setTileIndex(g_mineTilesPos); curEnemy->hitBox.left = xSpawn[i] + MINE_LEFT_OFFSET; curEnemy->hitBox.right = xSpawn[i] + MINE_RIGHT_OFFSET; curEnemy->hitBox.top = ySpawn[i] + yOffset + MINE_TOP_OFFSET; curEnemy->hitBox.bottom = ySpawn[i] + yOffset + MINE_BOTTOM_OFFSET; break; } case StageEvent::squid: { curEnemy->setPos(xSpawn[i], ySpawn[i] + yOffset); curEnemy->setPath(SQUID_PATH); curEnemy->setBulletPath(SQUID_BULLET_PATH); curEnemy->setMaxHealth(SQUID_HEALTH); curEnemy->setBulletFrequency(SQUID_BULLET_FREQUENCY); curEnemy->setDamage(1); curEnemy->setParent(this); curEnemy->setSize(Sprite::size_16x16); curEnemy->setTileIndex(g_squidTilesPos); curEnemy->hitBox.left = xSpawn[i] + SQUID_LEFT_OFFSET; curEnemy->hitBox.right = xSpawn[i] + SQUID_RIGHT_OFFSET; curEnemy->hitBox.top = ySpawn[i] + yOffset + SQUID_TOP_OFFSET; curEnemy->hitBox.bottom = ySpawn[i] + yOffset + SQUID_BOTTOM_OFFSET; break; } case StageEvent::crab: { curEnemy->setPos(xSpawn[i], ySpawn[i] + yOffset); curEnemy->setPath(CRAB_PATH); curEnemy->setBulletPath(CRAB_BULLET_PATH); curEnemy->setMaxHealth(CRAB_HEALTH); curEnemy->setBulletFrequency(CRAB_BULLET_FREQUENCY); curEnemy->setDamage(1); curEnemy->setParent(this); curEnemy->setSize(Sprite::size_32x32); curEnemy->setTileIndex(g_crabTilesPos); curEnemy->hitBox.left = xSpawn[i] + CRAB_LEFT_OFFSET; curEnemy->hitBox.right = xSpawn[i] + CRAB_RIGHT_OFFSET; curEnemy->hitBox.top = ySpawn[i] + yOffset + CRAB_TOP_OFFSET; curEnemy->hitBox.bottom = ySpawn[i] + yOffset + CRAB_BOTTOM_OFFSET; break; } case StageEvent::shark: { curEnemy->setPos(xSpawn[i], ySpawn[i] + yOffset); curEnemy->setPath(SHARK_PATH); curEnemy->setBulletPath(SHARK_BULLET_PATH); curEnemy->setMaxHealth(SHARK_HEALTH); curEnemy->setBulletFrequency(SHARK_BULLET_FREQUENCY); curEnemy->setDamage(1); curEnemy->setParent(this); curEnemy->setSize(Sprite::size_16x8); curEnemy->setTileIndex(g_sharkTilesPos); curEnemy->hitBox.left = xSpawn[i] + SHARK_LEFT_OFFSET; curEnemy->hitBox.right = xSpawn[i] + SHARK_RIGHT_OFFSET; curEnemy->hitBox.top = ySpawn[i] + yOffset + SHARK_TOP_OFFSET; curEnemy->hitBox.bottom = ySpawn[i] + yOffset + SHARK_BOTTOM_OFFSET; break; } default: { assert2(false, "Invalid enemy type"); break; } } curEnemy->setVisible(true); curEnemy->resetTimer(); ++i; } }
void TyranoForce::Hero::computeNextMove(float dt) { // determine target position (default bottom-center) vec2 target = vec(0.5f, 0.75f) *gWorld.view.size(); // if powerup // TODO powerups // determine closest enemy EnemyUnit *closest = 0; for(EnemyIterator i; i.next();) { if (i->pos.y < pos.y - 4 && (!closest || i->pos.y > closest->pos.y)) { closest = i; } } if (closest) { target.x = closest->pos.x; } // spring physics vec2 accel = float(kHeroTargetAccel) * (target - pos); if (flickeringTimer < 0.8f) { // bullet avoidance for(auto& p : gWorld.enemyBullets) { vec2 delta = pos - p.pos; float distSq = delta.norm(); if (distSq < kHeroAvoidRadius * kHeroAvoidRadius) { float dist = sqrtf(distSq); accel += (kHeroAvoidAccel * (kHeroAvoidRadius - dist) / dist) * delta; } } // TODO missiles } // dumb euler integration speed += dt * accel; float speedMagnitude = speed.magnitude(); if (speedMagnitude > kHeroMaxSpeed) { speed *= (kHeroMaxSpeed / speedMagnitude); } pos += dt * speed; // limits float pad = 8; if (pos.x < pad) { pos.x = pad; speed.x = 0; } else if (pos.x > gWorld.view.width()-pad) { pos.x = gWorld.view.width()-pad; speed.x = 0; } if (pos.y < 0) { pos.y = 0; speed.y = 0; } else if (pos.y > gWorld.view.height()) { pos.y = gWorld.view.height(); speed.y = 0; } // drag speed -= kHeroDrag * speed * dt; }