static void entityWait() { Entity *e; if (self->mental > 0) { self->thinkTime--; if (self->thinkTime <= 0) { self->thinkTime = 5; e = addExplosion(0, 0); e->x = self->x + self->w / 2 - e->w / 2; e->y = self->y + self->h / 2 - e->h / 2; e->x += prand() % e->w * (prand() % 2 == 0 ? 1 : -1); e->y += prand() % e->h * (prand() % 2 == 0 ? 1 : -1); e->damage = 0; self->mental--; } } checkToMap(self); }
void ld::PlayState::collisionCheck() { if (m_player.getLives() < 1) return; //for (auto &i : m_enemies) for (std::size_t i = 0; i < m_enemies.size(); ++i) { if (ifCollide(m_player, m_enemies[i])) { addExplosion(m_enemies[i].getPosition()); m_enemies.erase(m_enemies.begin() + i); --i; m_player.setLives(m_player.getLives() - 1); if (m_player.getLives() < 1) { addExplosion(m_player.getPosition()); for (auto& i : m_enemies) i.setPlayer(nullptr); break; } } else if (ifCollide(m_player.m_shield, m_enemies[i])) { addExplosion(m_enemies[i].getPosition()); m_enemies.erase(m_enemies.begin() + i); --i; m_score += m_difficulty; ++m_kills; //Aliens explode } } }
static void explode() { int x, y; Entity *e; self->flags |= NO_DRAW|FLY|DO_NOT_PERSIST; self->thinkTime--; if (self->thinkTime <= 0) { x = self->x + self->w / 2; y = self->y + self->h / 2; stopSound(self->endX); x += (prand() % 32) * (prand() % 2 == 0 ? 1 : -1); y += (prand() % 32) * (prand() % 2 == 0 ? 1 : -1); e = addExplosion(x, y); e->x -= e->w / 2; e->y -= e->h / 2; if (self->damage == -1) { e->damage = 1; } self->health--; self->thinkTime = 5; if (self->health == 0) { self->inUse = FALSE; } } self->action = &explode; }
static void miniExplode() { int x, y; Entity *e; self->flags |= NO_DRAW|FLY|DO_NOT_PERSIST; self->thinkTime--; x = self->x + self->w / 2; y = self->y + self->h / 2; stopSound(self->endX); e = addExplosion(x, y); e->x -= e->w / 2; e->y -= e->h / 2; e->damage = 1; self->inUse = FALSE; }
void PlayMode::collisionDetect() { if( (int)player_pos < walls_top[28] && !crashed ) { // crashed into top wall crashExplosion(); crashed = true; } if( (int)player_pos + 10 > walls_bottom[28] && !crashed ) { // crashed into bottom wall crashExplosion(); crashed = true; } if( obstacles[28] && (int)player_pos + 10 > obstacles[28] && (int)player_pos < obstacles[28] + 50 && !crashed ) { // crashed into obstacle crashExplosion(); crashed = true; } // collision of player with stars if( items[28] && (int)player_pos + 10 > items[28] && (int)player_pos < items[28] + 16 && !crashed ) { collected++; score+=1024; items[28] = 0; for(int i = 0; i < 350; i++) { float speed = .5f * (float)rng->rand() / (float)RAND_MAX + .5; float angle = ((float)rng->rand() / (float)RAND_MAX) * 360; particles->add(140, player_pos, (float)cos(angle * (3.14159265 / 180)) * speed - 3, 2 * (float)sin(angle * (3.14159265 / 180)) * speed, rng->rand() % 64, 2, 2, ParticleSystem::PIXEL, hue2rgb(angle + 60)); } floating->add("1024", 130, player_pos, 50); } // detect near-crashes for special power if(!crashed && special < 200) { if((int)player_pos < walls_top[28] + 10) { special++; for(int i = 0; i < 25; i++) { float speed = (float)rng->rand() / (float)RAND_MAX; float angle = ((float)rng->rand() / (float)RAND_MAX) * 360; // TODO radian conversion can be done right here particles->add(145, player_pos + 2, (float)cos(angle * (3.14159265 / 180)) * speed - 3, (float)sin(angle * (3.14159265 / 180)) * speed - .3f, rng->rand() % 100, 6, 4, ParticleSystem::PIXEL, (rng->rand() | 0xFF0000FF) & 0xFFD700FF); } } if((int)player_pos + 10 > walls_bottom[28] - 10) { special++; for(int i = 0; i < 25; i++) { float speed = (float)rng->rand() / (float)RAND_MAX; float angle = ((float)rng->rand() / (float)RAND_MAX) * 360; // TODO radian conversion can be done right here particles->add(145, player_pos + 8, (float)cos(angle * (3.14159265 / 180)) * speed - 3, (float)sin(angle * (3.14159265 / 180)) * speed + .3f, rng->rand() % 100, 6, 4, ParticleSystem::PIXEL, (rng->rand() | 0xFF0000FF) & 0xFFD700FF); } } if(obstacles[28] && (int)player_pos + 10 > obstacles[28] - 10 && (int)player_pos < obstacles[28] + 60) { if(special < 190) special+=10; else special = 200; if(player_pos > obstacles[28]) { for(int i = 0; i < 120; i++) { float speed = 1.5f * (float)rng->rand() / (float)RAND_MAX; float angle = ((float)rng->rand() / (float)RAND_MAX) * 360; // TODO radian conversion can be done right here particles->add(145, player_pos + 2, (float)cos(angle * (3.14159265 / 180)) * speed - 3.5f, (float)sin(angle * (3.14159265 / 180)) * speed - .5f, rng->rand() % 100, 6, 4, ParticleSystem::PIXEL, (rng->rand() | 0xFF0000FF) & 0xFFD700FF); } } else { for(int i = 0; i < 120; i++) { float speed = 1.5f * (float)rng->rand() / (float)RAND_MAX; float angle = ((float)rng->rand() / (float)RAND_MAX) * 360; // TODO radian conversion can be done right here particles->add(145, player_pos + 8, (float)cos(angle * (3.14159265 / 180)) * speed - 3.5f, (float)sin(angle * (3.14159265 / 180)) * speed + .5f, rng->rand() % 100, 6, 4, ParticleSystem::PIXEL, (rng->rand() | 0xFF0000FF) & 0xFFD700FF); } } } } // collision of shots with obstacles for(int i = 0; i < 131; i++) { if(shot[i] && shot[i] + 5 > obstacles[i+28] && shot[i] < obstacles[i+28] + 50) { obstacles[i+28] = 0; if(!justHit) justHit = 3; // If an obstacle was hit by a shot, generate explosion and count score if(justHit == 3) { addExplosion((i+28) * 5, shot[i]); comboTime = 50; score+=512; floating->add("512", (i+28)*5, shot[i], 40); if(hitDuringCombo == 0) { score+=512; floating->add("512", (i+28)*5, shot[i], 40); hitDuringCombo++; } else { score+=512*(pow(2, hitDuringCombo)); std::ostringstream s; s << "512 x" << pow(2, hitDuringCombo); floating->add(s.str().c_str(), (i+28)*5, shot[i], 40); hitDuringCombo++; } } if(justHit) // too warm here to think straight - there must be a more elegant way to do this justHit--; } } if(comboTime) comboTime--; else hitDuringCombo = 0; // ...and with walls for(int i = 1; i < 130; i++) // only from 1..130 because we have to delete 3 elements in the shots array to make sure the shot is erased completely if(shot[i] && (shot[i] + 5 > walls_bottom[i+28] || shot[i] < walls_top[i+28])) { shot[i-1] = shot[i] = shot[i+1] = 0; } }
void GameplayState::resolveCollisions() { servLoc.getProfiler()->start("collisions"); servLoc.getProfiler()->start("pbullet, enemy"); //player bullet, enemy -> hit enemy, destroy bullet for(auto playerBullet : player->gun->bullets) for(Enemy* enemy : enemies) if(Collision::PixelPerfectTest(playerBullet->representation.getSFMLSprite(), enemy->representation.getSFMLSprite())) { enemy->hit(playerBullet->attack); playerBullet->destroy(); addExplosion(300, enemy->representation.getPosition(), 3.f); explosionSound.play(); if(!enemy->exist) player->score++; } servLoc.getProfiler()->stop(); servLoc.getProfiler()->start("ebullet, player"); //enemies bullets, player -> hit player for(auto enemy : enemies) for(auto enemyBullet : enemy->gun->bullets) if(Collision::PixelPerfectTest(enemyBullet->representation.getSFMLSprite(), player->representation.getSFMLSprite())) { player->hit(enemyBullet->attack); addExplosion(100, player->representation.getPosition(), 3.f); explosionSound.play(); enemyBullet->destroy(); } servLoc.getProfiler()->stop(); servLoc.getProfiler()->start("enemy, player"); //enemy, player -> bounce for(Enemy* enemy : enemies) if(Collision::PixelPerfectTest(player->representation.getSFMLSprite(), enemy->representation.getSFMLSprite())) { enemy->representation.setPosition(enemy->oldPosition); //todo: implement better solution(using good equation(this including mass)) sf::Vector2f tempVel = enemy->velocity; enemy->velocity = player->velocity; //bounce from colliding object player->representation.setPosition(player->oldPosition); //todo: implement better solution(using good equation(this including mass)) player->velocity = tempVel; //bounce from colliding object break; } servLoc.getProfiler()->stop(); servLoc.getProfiler()->start("enemy, enemy"); //enemy, enemy -> bounce for(Enemy* enemy1 : enemies) for(Enemy* enemy2 : enemies) if(enemy1 != enemy2 && Collision::PixelPerfectTest(enemy1->representation.getSFMLSprite(), enemy2->representation.getSFMLSprite())) { enemy1->representation.setPosition(enemy1->oldPosition); //todo: implement better solution(using good equation(this including mass)) sf::Vector2f tempVel = enemy1->velocity; enemy1->velocity = enemy2->velocity; //bounce from colliding object enemy2->representation.setPosition(enemy2->oldPosition); //todo: implement better solution(using good equation(this including mass)) enemy2->velocity = tempVel; //bounce from colliding object } servLoc.getProfiler()->stop(); servLoc.getProfiler()->stop(); }
void ActionManager::createExplosion(const vector3df& position, int size){ plane3df plane(vector3df(0,0,0), vector3df(0,0,-1)); addExplosion(position,vector3df(0,0,0), size, device->getSceneManager(), plane, 0); //create cool particle explosion explosionSound->setVolume(SETTINGS->soundVolume); // 0.0 to 1.0 explosionSound->play(); }
void gameUpdate(void) { point vertex, port, starboard, exhaust, playerPos; point playerShip[5]; int i, j; //Level defaults to finished, changed when rocks or enemies are alive. HWREGBITW(&gFlags, LEVEL_COMPLETE) = True; //Update player gPlayer.x += gPlayer.dx; gPlayer.y += gPlayer.dy; gPlayer.x = floatMod(gPlayer.x, 128); gPlayer.y = floatMod(gPlayer.y, 96); gPlayer.dx = (gPlayer.dx*SPEED_DECAY); gPlayer.dy = (gPlayer.dy*SPEED_DECAY); gPlayer.exhaustOn = False; playerPos = makePoint((int)gPlayer.x, (int)gPlayer.y); vertex = rotPoint(playerPos, gPlayer.angle, makePoint(playerPos.x+6, playerPos.y)); port = rotPoint(playerPos, gPlayer.angle, makePoint(playerPos.x-5, playerPos.y-5)); starboard = rotPoint(playerPos, gPlayer.angle, makePoint(playerPos.x-5, playerPos.y+5)); exhaust = rotPoint(playerPos, gPlayer.angle, makePoint(playerPos.x-3, playerPos.y)); playerShip[0] = vertex; playerShip[1] = port; playerShip[2] = exhaust; playerShip[3] = starboard; playerShip[4] = makePoint((int)gPlayer.x, (int)gPlayer.y); switch(gPlayer.status) { case ALIVE: ////Button movement input //Forward (up) if ((GPIO_PORTG_DATA_R&0x08) == 0 || HWREGBITW(&gFlags, ANALOG_UP)) { if((gPlayer.dx*gPlayer.dx + gPlayer.dy*gPlayer.dy) < MAX_PLAYER_SPEED*MAX_PLAYER_SPEED) { gPlayer.dx += cosDeg(gPlayer.angle)*PLAYER_ACCEL; gPlayer.dy -= sinDeg(gPlayer.angle)*PLAYER_ACCEL; } gPlayer.exhaustOn = True; } //Left if((GPIO_PORTG_DATA_R&0x20) == 0) {//|| HWREGBITW(&gFlags, ANALOG_LEFT)) { gPlayer.angle += PLAYER_TURN_RATE; } //Right if((GPIO_PORTG_DATA_R&0x40) == 0) {// || HWREGBITW(&gFlags, ANALOG_RIGHT)) { gPlayer.angle -= PLAYER_TURN_RATE; } //Select (positive edge) if((GPIO_PORTG_DATA_R & 0x80) != 0) { selectNotPressed = True; } if(HWREGBITW(&gFlags, SELECT_DOWN) == 1 || (selectNotPressed == True && (GPIO_PORTG_DATA_R & 0x80) == 0)) { selectNotPressed = False; if(HWREGBITW(&gFlags, TITLE_SCREEN) == True) { HWREGBITW(&gFlags, TITLE_SCREEN) = False; setXYAvg(); } HWREGBITW(&gFlags, SELECT_DOWN) = 0; //reset flag addBullet(makePoint((int)gPlayer.x, (int)gPlayer.y), (cosDeg(gPlayer.angle)*MAX_BULLET_SPEED), -1*(sinDeg(gPlayer.angle)*MAX_BULLET_SPEED), True); } break; case HIT: gPlayer.status = DEAD; addExplosion(makePoint(gPlayer.x, gPlayer.y), 12); gPlayer.dx = 0; gPlayer.dy = 0; killBullets(); killRocks(); break; case DEAD: //Wait for explosions to stop, then stop updating the game. for(i = 0; i < MAX_EXPLOSIONS; i++) { if(gExplosions[i].status == ALIVE) { break; } } HWREGBITW(&gFlags, LEVEL_COMPLETE) = False; HWREGBITW(&gFlags, GAME_OVER) = True; killRocks(); killBullets(); killEnemies(); return; } if(HWREGBITW(&gFlags, TITLE_SCREEN) == True) { return; } //Update bullets for(i = 0; i < MAX_PLAYER_BULLETS; i++) { switch(gPlayerBullets[i].status) { //Only update visible bullets. case ALIVE: if(gPlayerBullets[i].life++ > BULLET_LIFETICKS) { gPlayerBullets[i].status = DEAD; break; } gPlayerBullets[i].x = gPlayerBullets[i].x+gPlayerBullets[i].dx; gPlayerBullets[i].y = gPlayerBullets[i].y+gPlayerBullets[i].dy; break; case HIT: break; case DEAD: break; } } for(i = 0; i < MAX_ENEMY_BULLETS; i++) { switch(gEnemyBullets[i].status) { //Only update visible bullets. case ALIVE: if(gEnemyBullets[i].life++ > BULLET_LIFETICKS) { gEnemyBullets[i].status = DEAD; break; } HWREGBITW(&gFlags, LEVEL_COMPLETE) = False; gEnemyBullets[i].x = gEnemyBullets[i].x+gEnemyBullets[i].dx; gEnemyBullets[i].y = gEnemyBullets[i].y+gEnemyBullets[i].dy; break; case HIT: break; case DEAD: break; } } //Update rocks for(i = 0; i < MAX_ROCKS; i++) { switch(gRocks[i].status) { case ALIVE: //Only update visible rocks. HWREGBITW(&gFlags, LEVEL_COMPLETE) = False; //Update rock position if(gRocks[i].dx < 0.1 && gRocks[i].dy < 0.1) { gRocks[i].dx = (randRange(32,64)*-1+randRange(32,64)*1)/64.; gRocks[i].dy = randRange(0,256)/256; } gRocks[i].x = floatMod(gRocks[i].x+gRocks[i].dx, 128); gRocks[i].y = floatMod(gRocks[i].y+gRocks[i].dy, 96); //Check collisions with enemies, players and bullets. //Player collision for(j = 0; j < 5; j++) { if(pointInRock(makePoint(((int)gRocks[i].x), ((int)gRocks[i].y)), gRocks[i].rockType, gRocks[i].rockSize, playerShip[j])) { gPlayer.status = HIT; return; } } //Bullet collision for(j = 0; j < MAX_PLAYER_BULLETS; j++) { if(gPlayerBullets[j].status == ALIVE) { if(pointInRock(makePoint(((int)gRocks[i].x), ((int)gRocks[i].y)), gRocks[i].rockType, gRocks[i].rockSize, makePoint(((int)gPlayerBullets[j].x), ((int)gPlayerBullets[j].y)))) { score += 1; addExplosion(makePoint(gPlayerBullets[j].x, gPlayerBullets[j].y), 2); gRocks[i].status = HIT; gPlayerBullets[j].status = DEAD; } } }/* for(j = 0; j < MAX_ENEMY_BULLETS; j++) { if(gEnemyBullets[i].status == ALIVE) { if(pointInRock(makePoint(((int)gRocks[i].x), ((int)gRocks[i].y)), gRocks[i].rockType, gRocks[i].rockSize, makePoint(((int)gEnemyBullets[j].x)%128, ((int)gEnemyBullets[j].y)%96))) { gRocks[i].status = HIT; addExplosion(makePoint(gEnemyBullets[j].x, gEnemyBullets[j].y), 2); gEnemyBullets[j].status = DEAD; } } }*/ if(gRocks[i].status == ALIVE) { break; } case HIT: if(gRocks[i].rockSize > 1) { addRock(makePoint((int)gRocks[i].x+1, (int)gRocks[i].y+1), randRange(24, 64)/-64., randRange(24, 64)/-64., gRocks[i].rockSize-1); addRock(makePoint((int)gRocks[i].x-1, (int)gRocks[i].y-1), randRange(64, 24)/64., randRange(64, 24)/64., gRocks[i].rockSize-1); } gRocks[i].status = DEAD; break; case DEAD: break; } } //Update UFOs for(i = 0; i < MAX_UFOS; i++) { switch(gUFOs[i].status) { case ALIVE: //Only update visible rocks. HWREGBITW(&gFlags, LEVEL_COMPLETE) = False; //Update rock position if(gUFOs[i].dx < 0.1 && gUFOs[i].dy < 0.1) { gUFOs[i].dx = (randRange(32,64)*-1+randRange(32,64)*1)/64.; gUFOs[i].dy = randRange(0,256)/256; } gUFOs[i].pos.x = floatMod(gUFOs[i].pos.x+gUFOs[i].dx, 128); gUFOs[i].pos.y = floatMod(gUFOs[i].pos.y+gUFOs[i].dy, 96); if(gUFOs[i].status == ALIVE) { break; } case HIT: gUFOs[i].status = DEAD; break; case DEAD: break; } } //Update explosions for(i = 0; i < MAX_EXPLOSIONS; i++) { if(gExplosions[i].status == ALIVE) { HWREGBITW(&gFlags, LEVEL_COMPLETE) = False; if(gExplosions[i].current++ > gExplosions[i].lifetime) { gExplosions[i].status = DEAD; continue; } } } }