/*! * * @file display.cpp * @author RUBINI Thomas * @author SIMAILA Djalim * @date January 2022 * @version 1.0 * @brief game display * */ #include "game.h" /** Displays the screen once, and returns * The more important stuff must be drawn last */ void Game::displayAll() const { pm->drawSprite(pm->gameBackground); for (unsigned i = 0; i < this->grid.size(); ++i){ for (unsigned j = 0; j < this->grid[i].size(); ++j){ Position vec( basePos.getX() + i * confData.invadersSize + i * confData.invadersDistance, basePos.getY() + j * confData.invadersSize + j * confData.invadersDistance ); displayInvader(vec, grid[i][j]); } } for(const missile& miss : missiles){ pm->drawMissile(miss, confData.missilesWidth, confData.missilesColor); } for(const Torpedo& tor : torpedos){ pm->drawTorpedo(tor, confData.torpedosWidth, confData.torpedosColor); } displayGod(); DEBUG_INSTR( pm->drawText(Position(pm->getScreenWidth()-200, 20), "FPS : "+to_string(fps), nsGraphics::KWhite, Font::BITMAP_8_BY_13); ) for(unsigned i=0;idrawPlayer(players[i].x, confData.playersWidth, confData.playerDefs[i].color); } } // out of the condition, because we still need to display the falling heart displayHearts(i); } } void Game::displayHearts(playerID pID) const { // As said before, the player loop is an illusion, 2 players max unsigned x; if(pID==PLAYER1)x = 0; else x = pm->getScreenWidth()-HEART_LENGTH; unsigned y = GOD_BENCH_SIZE+5; for(unsigned i=0;idrawHeart(Position(x, y)); y+=HEART_LENGTH+5; } if(players[pID].hasDeathAnimation()){ pm->drawHeart(Position(x, y+players[pID].deathAnimCounter*5)); } } void Game::displayInvader(const Position& pos, InvaderType type) const { if(type==InvaderType::NONE)return; const InvaderTypeDef& invDef = confData.invadersDef.at(type); switch(type){ case InvaderType::TYPEA:{ pm->drawInvaderA(pos, confData.invadersSize, invDef.color); return; } case InvaderType::TYPEB:{ pm->drawInvaderB(pos, confData.invadersSize, invDef.color); return; } case InvaderType::TYPEC:{ pm->drawInvaderC(pos, confData.invadersSize, invDef.color); return; } } } void applyBezier(Position& pos, const Position& point, const double percent) { pos += (point-pos)*percent; } void Game::displayGod() const { switch (god.state) { case GodState::NONE: return; case GodState::AWAKE: { pm->drawGodBench(god.counter - GOD_BENCH_SIZE); Position leftHand(GOD_HAND_DISTANCE, god.counter-GOD_BENCH_SIZE); Position rightHand(pm->getScreenWidth()-GOD_HAND_DISTANCE-GOD_HAND_SIZE, god.counter-GOD_BENCH_SIZE); pm->drawGodLeftHand(leftHand); pm->drawGodRightHand(rightHand); pm->drawGodFace(god.counter - GOD_BENCH_SIZE); break; } case GodState::WAIT:{ pm->drawGodBench(0); Position leftHand(GOD_HAND_DISTANCE, 0); Position rightHand(god.getRightHandPos(pm->getScreenWidth())); pm->drawGodLeftHand(leftHand); pm->drawGodRightHand(rightHand); pm->drawGodFace(0); break; } case GodState::RETRIEVE1: case GodState::RETRIEVE2:{ // Bezier curve // counter goes [0-100] pm->drawGodBench(0); pm->drawGodLeftHand(Position(GOD_HAND_DISTANCE, 0)); pm->drawGodFace(0); Position pos(god.getRightHandPos(pm->getScreenWidth())); Position endPos = invIndexToPos(god.thrownInvPosX, god.thrownInvPosY); applyBezier(pos, god.thrownTransition, god.counter / 100.0); applyBezier(pos, endPos, god.counter / 100.0); // pos is now the position we need to draw our hand to pm->drawGodRightHand(pos); if(god.thrownInvType!=InvaderType::NONE){ pos+=Position(GOD_HAND_SIZE/2, GOD_HAND_SIZE/2); pos-=Position(confData.invadersSize/2, confData.invadersSize/2); displayInvader(pos, god.thrownInvType); } break; } case GodState::THROW:{ pm->drawGodBench(0); pm->drawGodLeftHand(Position(GOD_HAND_DISTANCE, 0)); pm->drawGodFace(0); // compute start position (not sure if we should store it or compute it each time ?) Position handPos = god.getRightHandPos(pm->getScreenWidth()); Position invaderPos = handPos; applyTransformation(invaderPos, GOD_HAND_SIZE, confData.invadersSize); Position a = god.thrownVector * (god.counter / 100.0); invaderPos = invaderPos + a; displayInvader(invaderPos, god.thrownInvType); if(god.counter<30){ // handling hand retraction unsigned handCounter; if(god.counter<15)handCounter = god.counter; else handCounter = 30-god.counter; handPos = handPos + god.thrownVector * (handCounter / 100.0); } pm->drawGodRightHand(handPos); break; } } }