// Attempt to fire at enemy; return true if destroyed bool Tower::Fire(Enemy &enemy, vector <Bullet> &Shots) { if (reloadTime <= 0) { double dx, dy, towerX, towerY, enemyX, enemyY; towerX = (gridX + .5)*TILESIZE; towerY = (gridY + .5)*TILESIZE; enemyX = enemy.x + .5*TILESIZE; enemyY = enemy.y + .5*TILESIZE; dx = enemyX - towerX; dy = enemyY - towerY; if (dx*dx + dy*dy <= range*range) { double angle = atan2(dy, dx)/M_PI + 1; direction = (int)((4*(angle))+6.5)%8; reloadTime+=1./rate; angle = (direction+2)*M_PI/4; int bulletX = towerX - TILESIZE*cos(angle)/2; int bulletY = towerY - TILESIZE*sin(angle)/2; Shots.push_back(Bullet(bulletX, bulletY, enemyX, enemyY)); if (enemy.damage(power)) { return true; } } } return false; };
string MusicManager::checkSkillTrackName(Skill* skill, SkillPerformType& performeType) { performeType = SkillPerformTypeNone; if (skill) { _characterManager->setWaitTurn(_characterManager->getWaitTurn() + 1); if (_characterManager->getWaitTurn() == skill->getTurn()) { if (_characterManager->getLastSkill() && string(_characterManager->getLastSkill()->getIdentifier()) != string(skill->getIdentifier())) { _characterManager->setRepeatCount(0); _characterManager->setRepeatCountRaw(0); } if (_characterManager->getLastSkill() == NULL || _characterManager->getLastSkill()->getIdentifier() != skill->getIdentifier()) { // 前のターンがwaitだった場合、カウンターをリセット _characterManager->setRepeatCount(0); _characterManager->setRepeatCountRaw(0); } else { // そうじゃなかったら+1 _characterManager->setRepeatCount(_characterManager->getRepeatCount() + 1); _characterManager->setRepeatCountRaw(_characterManager->getRepeatCountRaw() + 1); } if (skill->isLoop()) { _characterManager->setRepeatCount((_characterManager->getRepeatCount()) % skill->getMaxRepeat()); } else { _characterManager->setRepeatCount(min(_characterManager->getRepeatCount(), skill->getMaxRepeat() - 1)); } Skill* lastSkill = _characterManager->getLastSkill(); _characterManager->setLastSkill(skill); _characterManager->setCurrentSkill(NULL); _characterManager->setWaitTurn(0); performeType = SkillPerformTypeSuccess; // 攻撃ミスってたら失敗扱いに CCArray* targets = _enemyManager->getTargets(skill); bool isMiss = targets->count() > 0; if (targets->count() > 0) { int power = skill->getPower(_characterManager); for (int i = 0; i < targets->count(); ++i) { Enemy* enemy = (Enemy*)targets->objectAtIndex(i); DamageType damageType = DamageTypeNone; enemy->damage(power, skill, _characterManager, damageType, true); // ダメージは与えずに結果だけ取り出す if (damageType != DamageTypePhysicalInvalid && damageType != DamageTypeMagicalInvalid && damageType != DamageTypeDisable) { isMiss = false; } } } if (skill->getMP() > _characterManager->getMP()) { // MP足りてないとき、失敗に performeType = SkillPerformTypeFailure; isMiss = true; } else if (lastSkill && !skill->canRepeat() && lastSkill->getIdentifier() == skill->getIdentifier()) { performeType = SkillPerformTypeFailure; isMiss = true; } if (performeType == SkillPerformTypeFailure || isMiss) { // 失敗したとき、もしくはピロったとき、miss音を返す return this->buildTrackName("miss", NULL, -1); } else { return this->buildTrackName(skill->getIdentifier().c_str(), skill, _characterManager->getRepeatCount()); } } else { _characterManager->setCurrentSkill(skill); performeType = SkillPerformTypeCharge; std::stringstream ss; ss << _characterManager->getCurrentCharacter()->getIdentifier() << skill->getIdentifier() << "_charge" << (_characterManager->getWaitTurn() - 1); // チャージ中の時、チャージ音返す return ss.str().c_str(); } } else { if (_characterManager->getLastSkill() == NULL) { int newWaitCount = ((_characterManager->getRepeatCount() + 1) % _musicSet->getWaitCount()); if (_isAfterIntro) { newWaitCount = 0; } _characterManager->setRepeatCount(newWaitCount); return this->buildTrackName("wait", NULL, newWaitCount); } else { _characterManager->setRepeatCount(0); _characterManager->setRepeatCountRaw(0); } _characterManager->setLastSkill(skill); } return this->buildTrackName("wait", NULL, _characterManager->getRepeatCount()); }
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; } } } }
/** * Handles a numerous amount of collisions that happen in this game. * Will detect if the player is colliding with an enemy or a , * or if an enemy is colliding with an enemy or bullet and then respond * appropriately */ void checkEntityCollision() { for(std::vector<Enemy*>::iterator iter = enemies.begin(); iter != enemies.end(); ++iter) { Enemy * eni = *iter; // Check if bullets are colliding with enemies for(std::vector<Bullet*>::iterator checkAgainst = bullets.begin(); checkAgainst != bullets.end(); ++checkAgainst) { Bullet * b = *checkAgainst; if(eni->isColliding(*b)) { eni->damage(*b); b->damage(*eni); score += 50; } } // Check if player is colliding with enemies if(p.isColliding(*eni)) { Direction moveTo = eni->getDirection(); p.move(moveTo); eni->move(eni->flipDirection(moveTo)); p.damage(*eni); eni->damage(p); p.setBlinking(true); sf::SoundBuffer buffer; buffer.loadFromFile("hit.wav"); sf::Sound sound; sound.setBuffer(buffer); sound.play(); } // Check if sword is colliding with enemies Sword * s = p.getSword(); if(s->swordColliding(*eni) && s->isSwung()) { Direction moveTo = eni->getDirection(); eni->move(eni->flipDirection(moveTo), 200); s->damage(*eni); eni->damage(*s); } // Check if enemies are colliding with each other for(std::vector<Enemy*>::iterator checkAgainst = enemies.begin(); checkAgainst != enemies.end(); ++checkAgainst) { Enemy * next = *checkAgainst; Enemy nexter = *next; Direction moveTo = eni->flipDirection(eni->getDirection()); if(eni->isColliding(nexter) && (eni != next)) { bool checkOverlap = true; while(checkOverlap) { eni->move(moveTo); if(eni->isColliding(nexter) && (eni != next)) { checkOverlap = true; } else { checkOverlap = false; } } } } } }