#include "gamecode.h" #include "main_code.h" using namespace SE; //const std::string fendl = "\x0D\x0A"; //Windows-style, for files const int CONST_LEVELSTATE_STANDBY = 0; const int CONST_LEVELSTATE_PLAYING = 1; const int CONST_LEVELSTATE_GO_TO_PAUSE = 2; const int CONST_LEVELSTATE_PAUSE = 3; const int CONST_LEVELSTATE_LOADING = 4; const int CONST_LEVELSTATE_NODRAW = 5; const int CONST_LEVELSTATE_FINISH_FREEZE = 6; const int CONST_LEVELSTATE_FINISHED = 7; const float CONST_TIMER_LOADING = 150.f; const float CONST_PAUSE_APPEAR_TIME = 150.f; const float CONST_FINISH_FREEZE_TIME = 1000.f; const float CONST_FINISHING_TIME = 250.f; const float CONST_BALL_VELOCITY = 200.f; const Vector2f CONST_SLIDE_UP_POS(240.f, 64.f); const Vector2f CONST_TAP_TO_CONTINUE_POS(240.f, 200.f); bool operator<(const PairColorTexture& p1, const PairColorTexture& p2) { if (p1.second == p2.second) { if (p1.first(0) == p2.first(0)) { if (p1.first(1) == p2.first(1)) { if (p1.first(2) == p2.first(2)) { return p1.first(3) < p2.first(3); } else { return p1.first(2) < p2.first(2); } } else { return p1.first(1) < p2.first(1); } } else { return p1.first(0) < p2.first(0); } } return (p1.second < p2.second); } TBrick::TBrick() : State(CONST_BRICKSTATE_VISIBLE) , StateTimer(0.f) , Color(Vector4f(0.f, 0.f, 0.f, 1.f)) , Locked(0) , InitialLocked(0) { } void TBrick::SetVisible(Vector4f color, int locked) { State = CONST_BRICKSTATE_VISIBLE; Color = color; InitialLocked = locked; Locked = InitialLocked; } void TBrick::SetInvisible() { State = CONST_BRICKSTATE_INVISIBLE; } void TBrick::TryDrawAppear(int ipos, int jpos) { *SE::Console << "TBrick::TryDrawAppear"; Vector2f centerPos = GetPosFrom(ipos, jpos); Vector2f blockHalfSize = Vector2f(0.5f*CONST_BRICK_WIDTH * (Renderer->GetScreenWidth()/480.f), 0.5f*CONST_BRICK_HEIGHT * (Renderer->GetScreenHeight()/320.f)); std::string texName; if (Locked == 2) { texName = CONST_BLOCK_TEXTURE3; } else if (Locked == 1) { texName = CONST_BLOCK_TEXTURE2; } else { texName = CONST_BLOCK_TEXTURE1; } if (State == CONST_BRICKSTATE_DISAPPEAR) { RenderUniform1f("Transparency", StateTimer/CONST_BRICK_DISAPPEAR_TIME); RenderUniform4fv("BrickColor", (Color.data())); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[texName]); Renderer->DrawRect(centerPos - blockHalfSize, centerPos + blockHalfSize); } else if (State == CONST_BRICKSTATE_APPEAR) { RenderUniform1f("Transparency", 1.f - StateTimer/CONST_BRICK_APPEAR_TIME); RenderUniform4fv("BrickColor", Color.data()); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[texName]); Renderer->DrawRect(centerPos - blockHalfSize, centerPos + blockHalfSize); } } void TBrick::Update(size_t dt) { if (State == CONST_BRICKSTATE_DISAPPEAR) { *SE::Console << "TBrick::Update - CONST_BRICKSTATE_DISAPPEAR"; StateTimer -= dt; if (StateTimer < 0.f) { StateTimer = 0.f; State = CONST_BRICKSTATE_INVISIBLE; } } if (State == CONST_BRICKSTATE_APPEAR) { *SE::Console << "TBrick::Update - CONST_BRICKSTATE_APPEAR"; StateTimer -= dt; if (StateTimer < 0.f) { StateTimer = 0.f; State = CONST_BRICKSTATE_VISIBLE; } } } Vector4f TBrick::GetColor() { *SE::Console << "TBrick::GetColor"; return Color; } Vector2f TBrick::GetPosFrom(int ipos, int jpos) { *SE::Console << "TBrick::GetPosFrom"; const Vector2f BorderShift(CONST_BRICK_SHIFT_X * (Renderer->GetScreenWidth()/480.f), CONST_BRICK_SHIFT_Y * (Renderer->GetScreenHeight()/320.f)); return BorderShift+Vector2f(CONST_BRICK_WIDTH*(Renderer->GetScreenWidth()/480.f)*ipos + 0.5f*CONST_BRICK_WIDTH*(Renderer->GetScreenWidth()/480.f), Renderer->GetScreenHeight() - CONST_BRICK_HEIGHT*(Renderer->GetScreenHeight()/320.f)*(jpos)-0.5f*CONST_BRICK_HEIGHT*(Renderer->GetScreenHeight()/320.f)); } void TBrick::Disappear() { *SE::Console << "TBrick::Disappear"; StateTimer = CONST_BRICK_DISAPPEAR_TIME; State = CONST_BRICKSTATE_DISAPPEAR; } void TBrick::Hit() { if (Locked == 0) { *SE::Console << "TBrick::Hit == 0"; Disappear(); } else { *SE::Console << "TBrick::Hit else"; Locked--; } } void TBrick::Appear(Vector4f color, int locked) { *SE::Console << "TBrick::Appear"; StateTimer = CONST_BRICK_APPEAR_TIME; State = CONST_BRICKSTATE_APPEAR; Color = color; InitialLocked = locked; Locked = InitialLocked; } void TBrick::Appear() { *SE::Console << "TBrick::Appear"; Appear(Color, InitialLocked); } int TBrick::GetLocked() { *SE::Console << "TBrick::GetLocked"; return Locked; } bool TBrick::CanReact() { *SE::Console << "TBrick::CanReact"; return (State == CONST_BRICKSTATE_VISIBLE) || (State == CONST_BRICKSTATE_APPEAR); } //=========================================== //=========================================== //=========================================== TBonusFalling::TBonusFalling(Vector2f pos) : BonusType(rand() % 3) , Pos(pos) , Lifetime(0.f) { if (BonusType == 0) { TexName = CONST_BONUS_MULTIPLIER_TEXTURE; } if (BonusType == 1) { TexName = CONST_BONUS_GOTHROUGH_TEXTURE; } if (BonusType == 2) { TexName = CONST_BONUS_FLOOR_TEXTURE; } } Vector2f TBonusFalling::GetPos() { *SE::Console << "TBrick::GetPos"; return Pos; } int TBonusFalling::GetType() { *SE::Console << "TBonusFalling::GetType"; return BonusType; } void TBonusFalling::Draw() { *SE::Console << "TBonusFalling::Draw"; Vector2f BonusHalfSize = Vector2f(16.f, 16.f); float transparency = min_t(Lifetime/CONST_BONUS_APPEAR_TIME , 1.f); RenderUniform4fv("BrickColor", Vector4f(1.0f, 1.0f, 1.0f, 1.0f).data()); RenderUniform1f("Transparency", transparency); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[TexName]); Renderer->DrawRect(Pos - BonusHalfSize, Pos + BonusHalfSize); } void TBonusFalling::Update(size_t dt) { *SE::Console << "TBonusFalling::Update"; Lifetime += dt; Pos(1) -= dt * CONST_BONUS_FALL_SPEED / 1000.f; } //=========================================== //=========================================== //=========================================== TBall::TBall(Vector2f pos, Vector2f velocity, Vector4f color) : Pos(pos) , Velocity(velocity) , Color(color) { //must be 5 TalePos.push_back(Pos); TalePos.push_back(Pos); TalePos.push_back(Pos); TalePos.push_back(Pos); TalePos.push_back(Pos); } Vector2f TBall::GetPos() { *SE::Console << "TBall::GetPos"; return Pos; } Vector2f TBall::GetVelocityVector() { *SE::Console << "TBall::GetVelocityVector"; return Velocity; } void TBall::Go() { *SE::Console << "TBall::Go"; // Velocity = Normalize(Vector2f(2.f, 1.f)); Velocity = Vector2f(2.f, 1.f).normalized(); } void TBall::ReflectToLeft() { *SE::Console << "TBall::ReflectToLeft"; if (Velocity(0) > 0.f) { Velocity(0) = - Velocity(0); } } void TBall::ReflectToRight() { *SE::Console << "TBall::ReflectToRight"; if (Velocity(0) < 0.f) { Velocity(0) = - Velocity(0); } } void TBall::ReflectToUp() { *SE::Console << "TBall::ReflectToUp"; if (Velocity(1) < 0.f) { Velocity(1) = - Velocity(1); } } void TBall::ReflectToDown() { *SE::Console << "TBall::ReflectToDown"; if (Velocity(1) > 0.f) { Velocity(1) = - Velocity(1); } } //function for reflector surface. float ReflectorPlaneFunction(float shift) { *SE::Console << "ReflectorPlaneFunction(float shift)"; /* _______ / \ | | Something like this */ if (shift>=-70.f && shift < -40.f) { float t = (shift+70.f)/30.f; //0 to 1 return 9.f + 21.f * t; } if (shift>=-40.f && shift < 40.f) { return 30.f; } if (shift >= 40.f && shift <= 70.f) { float t = (70.f - shift)/30.f; //1 to 0 return 9.f + 21.f * t; } return 0.f; } void TBall::TryReflectOnReflector(Vector2f refPos) { *SE::Console << "TBall::TryReflectOnReflector(Vector2f refPos)"; const float reflectionShiftY = 13.f; const float reflectionMaxHeight = 30.f; if ((Pos(1) < reflectionMaxHeight + reflectionShiftY) && Pos(1) > 0.0f && Velocity(1) < 0) { float dy = ReflectorPlaneFunction(Pos(0) - refPos(0)); if (dy > 0 && (dy + reflectionShiftY > Pos(1))) { float shift = (Pos(0) - refPos(0)) / 128.f; shift = min_t(shift, 0.5f); shift = max_t(shift, -0.5f); //Vector2f n = Normalize(Vector2f(shift, 1.0f)); Vector2f n = Vector2f(shift, 1.0f).normalized(); Velocity = Velocity - n * 2.f * (Velocity(0)*n(0) + Velocity(1)*n(1)); if ((Velocity(1) <= 0) || (fabs(Velocity(0)/Velocity(1)) > 4.f)) { Velocity(0) = 4.f*sign(Velocity(0)); Velocity(1) = 1.f; //Velocity = Normalize(Velocity); Velocity = Velocity.normalized(); } } } } void TBall::Update(size_t dt) { *SE::Console << "TBall::Update(size_t dt)"; Pos += Velocity * (CONST_BALL_VELOCITY * dt / 1000.f); TalePos.push_back(Pos); if (TalePos.size() > 4) { TalePos.erase(TalePos.begin()); } } //=========================================== //=========================================== //=========================================== TGameLevel::TGameLevel() { *SE::Console << "TGameLevel::TGameLevel"; BkgTexture = "bkg"; RenderBufferReady = false; PrevLevelStateIsStandby = false; OutScale = 1.f; OutScaleVelocity = 0.f; StateTimer = 0.f; LevelState = CONST_LEVELSTATE_NODRAW; BallColor = Vector4f(0.2f, 0.8f, 1.0f, 1.0f); BonusFloorPosY = 0.f; } TGameLevel::~TGameLevel() { } void TGameLevel::ReloadBlockInstansingList() { *SE::Console << "TGameLevel::ReloadBlockInstansingList"; std::map ConstTextureBlockMap = boost::assign::map_list_of (0,CONST_BLOCK_TEXTURE1) (1,CONST_BLOCK_TEXTURE2) (2,CONST_BLOCK_TEXTURE3); std::pair tempPair; BlockInstansingList.ColorBlockList.clear(); for (int i=0; i>::iterator itr = BlockInstansingList.ColorBlockList.end(); for (auto b = BlockInstansingList.ColorBlockList.begin(); b != BlockInstansingList.ColorBlockList.end(); ++b) { if (b->first == tempPair) { itr = b; } } if (itr == BlockInstansingList.ColorBlockList.end()) { BlockInstansingList.ColorBlockList.push_back(std::pair(tempPair, TTriangleList())); itr = BlockInstansingList.ColorBlockList.end(); itr--; } Vector2f posFrom = BlockMatrix[i][j].GetPosFrom(i,j) + Vector2f(-0.5f*CONST_BRICK_WIDTH*(Renderer->GetScreenWidth()/480.f), -0.5f*CONST_BRICK_HEIGHT*(Renderer->GetScreenHeight()/320.f)); Vector2f posTo = BlockMatrix[i][j].GetPosFrom(i,j) + Vector2f(+0.5f*CONST_BRICK_WIDTH*(Renderer->GetScreenWidth()/480.f), +0.5f*CONST_BRICK_HEIGHT*(Renderer->GetScreenHeight()/320.f)); itr->second.Data += MakeDataTriangleList(posFrom, posTo); } } } for (auto it = BlockInstansingList.ColorBlockList.begin(); it != BlockInstansingList.ColorBlockList.end(); ++it) { it->second.RefreshBuffer(); } } Vector2f TGameLevel::GetBlock(const Vector2f& pos) { *SE::Console << "TGameLevel::GetBlock"; int x = static_cast((pos(0) - CONST_BRICK_SHIFT_X*(Renderer->GetScreenWidth()/480.f)) / (CONST_BRICK_WIDTH*(Renderer->GetScreenWidth()/480.f))); int y = static_cast((Renderer->GetScreenHeight() + CONST_BRICK_SHIFT_Y*(Renderer->GetScreenHeight()/320.f) - pos(1)) / (CONST_BRICK_HEIGHT*(Renderer->GetScreenHeight()/320.f))); if (x < 0) x = 0; if (x > CONST_BRICKMATRIX_WIDTH-1) x = CONST_BRICKMATRIX_WIDTH-1; if (y < 0) y = 0; if (y > CONST_BRICKMATRIX_HEIGHT-1) y = CONST_BRICKMATRIX_HEIGHT-1; return Vector2f(x, y); } bool TGameLevel::TapInBackBtnArea(const Vector2f& pos) { *SE::Console << "TGameLevel::TapInBackBtnArea"; return (pos(1) > 320.f - 64.f) && (pos(0)>=240.f-75.f) && (pos(0)<=240.f+75.f); } void TGameLevel::SetFinishFreeze() { *SE::Console << "TGameLevel::SetFinishFreeze"; StateTimer = CONST_FINISH_FREEZE_TIME; LevelState = CONST_LEVELSTATE_FINISH_FREEZE; } void TGameLevel::SetFinished() { *SE::Console << "TGameLevel::SetFinished"; StateTimer = CONST_FINISHING_TIME; LevelState = CONST_LEVELSTATE_FINISHED; OutScale = 1.f; } Vector4f TGameLevel::ParseColor(const std::string& s) { *SE::Console << "TGameLevel::ParseColor"; Vector4f r; std::string ss(s); int i = ss.find(", "); int c = toint(ss.substr(0, i)); ss.erase(0, i+2); r(0) = c / 255.f; i = ss.find(", "); c = toint(ss.substr(0, i)); ss.erase(0, i+2); r(1) = c / 255.f; i = ss.find(", "); c = toint(ss.substr(0, i)); ss.erase(0, i+2); r(2) = c / 255.f; //c = toint(ss); //r(3) = c / 255.f; i = ss.find("\r"); c = toint(ss.substr(0, i)); ss.erase(0, i + 2); r(3) = c / 255.f; return r; } void TGameLevel::ReloadLevel() { *SE::Console << "TGameLevel::ReloadLevel"; size_t byteCount; boost::shared_array file = CreateMemFromFile(LevelFileName, byteCount); std::string fileString(&file[0]); char c; //int n = 0; std::vector rows; int rowLen; while (fileString.size() > 0) { rowLen = fileString.find(SE::fendl); rows.push_back(fileString.substr(0, rowLen)); fileString.erase(0, rowLen+2); } std::vector::iterator rowIterator = rows.begin(); BallColor = ParseColor(*rowIterator); ++rowIterator; std::vector colors; Vector4f tc; while (*rowIterator != "Colormap") { tc = ParseColor(*rowIterator); colors.push_back(tc); ++rowIterator; } std::vector::iterator rowColorIterator; std::vector::iterator rowLockIterator; rowColorIterator = rowIterator + 1; rowLockIterator = rowColorIterator + 14; for (int j=0; jBallInBlock = GetBlock(ballPos); BallList.begin()->PrevBallInBlock = BallList.begin()->BallInBlock; BonusGothroughTimer = 0.f; BonusFloorTimer = 0.f; BonusFallingList.clear(); RenderBufferReady = false; ReloadBallInstancingList(); BonusFloorPosY = 0.f; } bool TGameLevel::IsLoaded() { *SE::Console << "TGameLevel::IsLoaded" ; return (LevelState == CONST_LEVELSTATE_STANDBY); } void TGameLevel::Draw() { *SE::Console << "TGameLevel::Draw"; if (LevelState == CONST_LEVELSTATE_NODRAW) { CheckGlError(); return; } if (LevelState == CONST_LEVELSTATE_LOADING) { Renderer->PushMatrix(); float scale = 1.f - 0.5f*StateTimer/CONST_TIMER_LOADING; if (scale < 0.5f) scale = 0.5f; if (scale > 1.f) scale = 1.f; Renderer->TranslateMatrix(Vector3f(Renderer->GetMatrixWidth() * 0.5f, Renderer->GetMatrixHeight() * 0.5f, 0)); Renderer->ScaleMatrix(scale); Renderer->TranslateMatrix(-Vector3f(Renderer->GetMatrixWidth() * 0.5f, Renderer->GetMatrixHeight() * 0.5f, 0)); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[LevelScreenTexture]); Renderer->DrawRect(Vector2f(0, 0), Vector2f(Renderer->GetScreenWidth(), Renderer->GetScreenHeight())); // Game Screen Scale Renderer->PopMatrix(); CheckGlError(); return; } bool mustShowButtons = ((LevelState == CONST_LEVELSTATE_PAUSE) || (LevelState == CONST_LEVELSTATE_GO_TO_PAUSE)); bool pause = (mustShowButtons || (LevelState == CONST_LEVELSTATE_FINISHED)); bool renderBufferReady = RenderBufferReady; if (pause && renderBufferReady) { //See also below (same method) Renderer->PushMatrix(); Renderer->TranslateMatrix(Vector3f(Renderer->GetMatrixWidth() * 0.5f, Renderer->GetMatrixHeight() * 0.5f, 0)); Renderer->ScaleMatrix(OutScale); Renderer->TranslateMatrix(-Vector3f(Renderer->GetMatrixWidth() * 0.5f, Renderer->GetMatrixHeight() * 0.5f, 0)); DrawBuffer(); if (mustShowButtons) { DrawPauseButtons(); } Renderer->PopMatrix(); CheckGlError(); return; } if (pause && !renderBufferReady) { Renderer->SwitchToFrameBuffer("LevelBuffer"); Renderer->SetProjectionMatrix(Renderer->GetScreenWidth(), Renderer->GetScreenHeight()); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); CheckGlError(); } glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[BkgTexture]); Renderer->DrawRect(Vector2f(0, 0), Vector2f(Renderer->GetScreenWidth(), Renderer->GetScreenHeight())); std::list::iterator iBall; Renderer->PushShader("BrickShader"); for (int i=0; i>::iterator colorBlockIterator; for (colorBlockIterator = BlockInstansingList.ColorBlockList.begin(); colorBlockIterator != BlockInstansingList.ColorBlockList.end(); ++colorBlockIterator) { RenderUniform4fv("BrickColor", colorBlockIterator->first.first.data()); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[colorBlockIterator->first.second]); Renderer->DrawTriangleList(colorBlockIterator->second); } std::list::iterator iBonus; for (iBonus = BonusFallingList.begin(); iBonus != BonusFallingList.end(); ++iBonus) { iBonus->Draw(); } DrawBallInstancingList(); Renderer->PopShader(); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[CONST_REFLECTOR_TEXTURE]); Renderer->DrawRect(Vector2f(-128.f, -16.f)+ReflectorPos, Vector2f(128.f, 16.f)+ReflectorPos); float tSW = Renderer->GetScreenWidth(); // Screen Width float tSH = Renderer->GetScreenHeight(); // Screen Height float lrFBO = 4 * tSH/320.f; // Left/Right Wall Textures offset from bottom float uWTW = tSW * (static_cast(ResourceManager->TexList.GetTextureHeight(CONST_WALL_UP_TEXTURE)) / static_cast(ResourceManager->TexList.GetTextureWidth(CONST_WALL_UP_TEXTURE))); // up Wall Texture Width float lWTW = (static_cast(ResourceManager->TexList.GetTextureWidth(CONST_WALL_LEFT_TEXTURE))/static_cast(ResourceManager->TexList.GetTextureHeight(CONST_WALL_LEFT_TEXTURE))) * (tSH-uWTW-lrFBO); // left Wall Texture Width float rWTW = lWTW; // right Wall Texture Width float bWTO = (lWTW+rWTW) * 0.5f; // bonus Wall x-Offset float bWTW = (tSW - bWTO) * (static_cast(ResourceManager->TexList.GetTextureHeight(CONST_WALL_BONUS_TEXTURE))/static_cast(ResourceManager->TexList.GetTextureWidth(CONST_WALL_BONUS_TEXTURE))); // bonus Wall Texture Width //const Vector2f wallUpPos1(240.f-256.f, 320.f-64.f); //const Vector2f wallUpPos2(240.f+256.f, 320.f); const Vector2f wallUpPos1(0.f, tSH-uWTW); const Vector2f wallUpPos2(tSW, tSH); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[CONST_WALL_UP_TEXTURE]); Renderer->DrawRect(wallUpPos1, wallUpPos2); //const Vector2f wallLeftPos1(0.f, 320.f - 512.f); //const Vector2f wallLeftPos2(32.f, 320.f); const Vector2f wallLeftPos1(0.f, lrFBO); const Vector2f wallLeftPos2(lWTW, tSH - uWTW); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[CONST_WALL_LEFT_TEXTURE]); Renderer->DrawRect(wallLeftPos1, wallLeftPos2); //const Vector2f wallRightPos1(480.f-32.f, 320.f - 512.f); //const Vector2f wallRightPos2(480.f, 320.f); const Vector2f wallRightPos1(tSW-rWTW, lrFBO); const Vector2f wallRightPos2(tSW, tSH-uWTW); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[CONST_WALL_RIGHT_TEXTURE]); Renderer->DrawRect(wallRightPos1, wallRightPos2); if (BonusFloorTimer>0.f) { const Vector2f wallDownPos(240.f, BonusFloorPosY); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[CONST_WALL_BONUS_TEXTURE]); //Renderer->DrawRect(Vector2f(-256.f, -16.f)+wallDownPos, Vector2f(256.f, 16.f)+wallDownPos); const Vector2f wallBonusPos1(bWTO, wallDownPos[1] - bWTW*0.5f); const Vector2f wallBonusPos2(tSW - bWTO, wallDownPos[1] + bWTW*0.5f); Renderer->DrawRect(wallBonusPos1, wallBonusPos2); } if (!pause) { RenderUniform1f("Transparency", 1.f); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[CONST_BACK_BTN_TEXTURE]); const Vector2f BackBtnPos(240.f, 320.f - 32.f - 20.f); Renderer->DrawRect(Vector2f(-128.f, -32.f)+BackBtnPos, Vector2f(128.f, 32.f)+BackBtnPos); } if (pause && !renderBufferReady) { //ololo //See also above (same method) Renderer->SwitchToScreen(); Renderer->SetFullScreenViewport(); Renderer->PushMatrix(); //Renderer->LoadIdentity(); Renderer->TranslateMatrix(Vector3f(Renderer->GetMatrixWidth() * 0.5f, Renderer->GetMatrixHeight() * 0.5f, 0)); Renderer->ScaleMatrix(OutScale); Renderer->TranslateMatrix(-Vector3f(Renderer->GetMatrixWidth() * 0.5f, Renderer->GetMatrixHeight() * 0.5f, 0)); DrawBuffer(); if (mustShowButtons) { DrawPauseButtons(); } Renderer->PopMatrix(); RenderBufferReady = true; CheckGlError(); } CheckGlError(); } void TGameLevel::DrawPauseButtons() { *SE::Console << "TGameLevel::DrawPauseButtons"; glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[CONST_SLIDE_UP_BTN_TEXTURE]); Renderer->DrawRect(Vector2f(-128.f, -64.f)+CONST_SLIDE_UP_POS, Vector2f(128.f, 64.f)+CONST_SLIDE_UP_POS); glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[CONST_TAP_TO_CONTINUE_BTN_TEXTURE]); Renderer->DrawRect(Vector2f(-128.f, -128.f)+CONST_TAP_TO_CONTINUE_POS, Vector2f(128.f, 128.f)+CONST_TAP_TO_CONTINUE_POS); } void TGameLevel::DrawBallInstancingList() { *SE::Console << "TGameLevel::DrawBallInstancingList"; RenderUniform1f("Transparency", 1.f); RenderUniform4fv("BrickColor", BallColor.data()); if (BonusGothroughTimer > 0.f) { glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[CONST_BALLGLOW_TEXTURE]); Renderer->DrawTriangleList(BallInstancingList.BallAndGlowList[1]); } glBindTexture(GL_TEXTURE_2D,ResourceManager->TexList[CONST_BALL_TEXTURE]); Renderer->DrawTriangleList(BallInstancingList.BallAndGlowList[0]); } void TGameLevel::DrawBuffer() { *SE::Console << "TGameLevel::DrawBuffer"; Renderer->PushShader("FrameShader"); float brightness; if (CONST_LEVELSTATE_GO_TO_PAUSE) { brightness = 0.3f + 0.7f * StateTimer / CONST_PAUSE_APPEAR_TIME; } else { brightness = 0.3f; } RenderUniform1f("Brightness", brightness); glBindTexture(GL_TEXTURE_2D,ResourceManager->FrameManager.GetFrameTexture("LevelBuffer")); //Matrix switched to identity //Vector2f RectPos = Vector2f(-1, -1); //Vector2f RectSize = Vector2f(2, 2); Vector2f RectPos = Vector2f(240.f, 160.f); Vector2f RectSize = Vector2f(240.f, 160.f); Renderer->DrawRect(RectPos-RectSize, RectPos+RectSize); Renderer->PopShader(); CheckGlError(); } void TGameLevel::SetPause() { *SE::Console << "TGameLevel::SetPause"; OutScaleVelocity = 0.f; OutScale = 1.f; RenderBufferReady = false; LevelState = CONST_LEVELSTATE_GO_TO_PAUSE; StateTimer = CONST_PAUSE_APPEAR_TIME; Application->MarkSetGameLevelPause(); } void TGameLevel::ReleasePause() { *SE::Console << "TGameLevel::ReleasePause"; RenderBufferReady = false; if (PrevLevelStateIsStandby) { LevelState = CONST_LEVELSTATE_STANDBY; PrevLevelStateIsStandby = false; } else { LevelState = CONST_LEVELSTATE_PLAYING; } Application->MarkReleaseGameLevelPause(); } bool TGameLevel::IsPaused() { *SE::Console << "TGameLevel::IsPaused"; return ((LevelState == CONST_LEVELSTATE_PAUSE) || (LevelState == CONST_LEVELSTATE_GO_TO_PAUSE) || (LevelState == CONST_LEVELSTATE_FINISHED)); } void TGameLevel::Update(size_t dt) { *SE::Console << "TGameLevel::Update"; *SE::Console << "before_upd LEVEL_STATE::== " << tostr(LevelState); if (LevelState == CONST_LEVELSTATE_NODRAW) { return; } if (LevelState == CONST_LEVELSTATE_GO_TO_PAUSE) { StateTimer -= dt; if (StateTimer <= 0.f) { StateTimer = 0.f; LevelState = CONST_LEVELSTATE_PAUSE; } return; } if (LevelState == CONST_LEVELSTATE_PAUSE) { OutScale += OutScaleVelocity * dt; TryGoToMenu(); CheckGlError(); return; } if (LevelState == CONST_LEVELSTATE_FINISHED) { StateTimer -= dt; OutScale = StateTimer/CONST_FINISHING_TIME; if (StateTimer <= 0.f) { TryGoToMenu(); } CheckGlError(); return; } if (LevelState == CONST_LEVELSTATE_LOADING) { StateTimer -= dt; if (StateTimer <= 0.f) { StateTimer = 0.f; RenderBufferReady = false; LevelState = CONST_LEVELSTATE_STANDBY; } } if (LevelState == CONST_LEVELSTATE_FINISH_FREEZE) { StateTimer -= dt; if (StateTimer <= 0.f) { SetFinished(); CheckGlError(); return; } //To make the whole scene like freeze dt = static_cast(dt / max_t((CONST_FINISH_FREEZE_TIME-StateTimer)/100.f, 1.f)); } if (BonusGothroughTimer > 0.f) { BonusGothroughTimer -= dt; BonusGothroughTimer = max_t(BonusGothroughTimer, 0.f); } if (BonusFloorTimer > 0.f) { BonusFloorTimer -= dt; BonusFloorTimer = max_t(BonusFloorTimer, 0.f); } UpdateBallList(dt); for (int i=0; i::iterator iBonus = BonusFallingList.begin(); while (iBonus != BonusFallingList.end()) { iBonus->Update(dt); if ((fabs(ReflectorPos(0) - iBonus->GetPos()(0))GetPos()(1))GetType(); iBonus = BonusFallingList.erase(iBonus); if (bonusType == CONST_BONUS_TYPE_GOTHROUGH) { BonusGothroughTimer = CONST_BONUS_GOTHROUGH_TIME; } else if (bonusType == CONST_BONUS_TYPE_MULTIPLIER) { Vector2f pos = BallList.begin()->GetPos(); Vector2f velocity = BallList.begin()->GetVelocityVector(); MultiplyBalls(pos, velocity); } else if (bonusType == CONST_BONUS_TYPE_FLOOR) { BonusFloorTimer = CONST_BONUS_FLOOR_TIME; } } else if (iBonus->GetPos()(1) < -15.f) { iBonus = BonusFallingList.erase(iBonus); } if (iBonus != BonusFallingList.end()) { ++iBonus; } } //Bonus floor pos if (BonusFloorTimer/CONST_BONUS_GOTHROUGH_TIME < 0.2f) { //Bonus must go down until 0.f if (BonusFloorPosY > 0.f) { BonusFloorPosY -= CONST_BONUS_FLOOR_APPEAR_SPEED * dt / 1000.f; BonusFloorPosY = max_t(BonusFloorPosY, 0.f); } } else { //Bonus must go up until 16.f if (BonusFloorPosY < 16.f) { BonusFloorPosY += CONST_BONUS_FLOOR_APPEAR_SPEED * dt / 1000.f; BonusFloorPosY = min_t(BonusFloorPosY, 16.f); } } bool noMoreBlocks = true; for (int i=0; iOpenNextLevel(); Application->MarkSetGameLevelPause(); SetFinishFreeze(); CheckGlError(); } if (BallList.size() == 0 && LevelState != CONST_LEVELSTATE_FINISH_FREEZE) { SetStandBy(); } *SE::Console << "after_upd LEVEL_STATE::== " << tostr(LevelState); } void TGameLevel::ReloadBallInstancingList() { *SE::Console << "TGameLevel::ReloadBallInstancingList"; //Changing this function? Don't forget to change next one! BallInstancingList.BallAndGlowList.clear(); std::list::iterator i; /* Vector3f p1; Vector3f p2; Vector3f p3; Vector3f p4; Vector2f t1 = Vector2f(0.0f, 0.0f); Vector2f t2 = Vector2f(0.0f, 1.0f); Vector2f t3 = Vector2f(1.0f, 1.0f); Vector2f t4 = Vector2f(1.0f, 0.0f); */ for (i = BallList.begin(); i != BallList.end(); ++i) { /* p1 = Vector3f(i->Pos, 0.f) + Vector3f(-8.f, -8.f, 0.f); p2 = Vector3f(i->Pos, 0.f) + Vector3f(-8.f, +8.f, 0.f); p3 = Vector3f(i->Pos, 0.f) + Vector3f(+8.f, +8.f, 0.f); p4 = Vector3f(i->Pos, 0.f) + Vector3f(+8.f, -8.f, 0.f); BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p1); BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p2); BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p3); BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p3); BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p4); BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p1); BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t1); BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t2); BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t3); BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t3); BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t4); BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t1); */ BallInstancingList.BallAndGlowList[0].Data += MakeDataTriangleList(i->Pos + Vector2f(-8.f, -8.f), i->Pos + Vector2f(8.f, 8.f)); //Replace6PointsInTriangleList(BallInstancingList.BallAndGlowList[0].Data, n, i->Pos + Vector2f(-8.f, -8.f), i->Pos + Vector2f(8.f, 8.f)); //n += 6; } std::list::iterator j; for (i = BallList.begin(); i != BallList.end(); ++i) { for (j = i->TalePos.begin(); j != i->TalePos.end(); ++j) { /* p1 = Vector3f(*j, 0.f) + Vector3f(-16.f, -16.f, 0.f); p2 = Vector3f(*j, 0.f) + Vector3f(-16.f, +16.f, 0.f); p3 = Vector3f(*j, 0.f) + Vector3f(+16.f, +16.f, 0.f); p4 = Vector3f(*j, 0.f) + Vector3f(+16.f, -16.f, 0.f); BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p1); BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p2); BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p3); BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p3); BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p4); BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].push_back(p1); BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t1); BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t2); BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t3); BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t3); BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t4); BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].push_back(t1); */ BallInstancingList.BallAndGlowList[1].Data += MakeDataTriangleList(*j + Vector2f(-16.f, -16.f), *j + Vector2f(16.f, 16.f)); //Replace6PointsInTriangleList(BallInstancingList.BallAndGlowList[1].Data, n, *j + Vector2f(-16.f, -16.f), *j + Vector2f(16.f, 16.f)); //n += 6; } } //std::map::iterator it; auto it = BallInstancingList.BallAndGlowList.begin(); for (; it != BallInstancingList.BallAndGlowList.end(); ++it) //for (auto it = BallInstancingList.BallAndGlowList.begin(); it != BallInstancingList.BallAndGlowList.end(); ++it) { it->second.RefreshBuffer(); } } void TGameLevel::RefreshBallInstancingList() { *SE::Console << "TGameLevel::RefreshBallInstancingList"; //Changing this function? Don't forget to change previous one! /* Vector3f p1; Vector3f p2; Vector3f p3; Vector3f p4; Vector2f t1 = Vector2f(0.0f, 0.0f); Vector2f t2 = Vector2f(0.0f, 1.0f); Vector2f t3 = Vector2f(1.0f, 1.0f); Vector2f t4 = Vector2f(1.0f, 0.0f); */ int n = 0; int m = 0; std::list::iterator i; for (i = BallList.begin(); i != BallList.end(); ++i) { /* p1 = Vector3f(i->Pos, 0.f) + Vector3f(-8.f, -8.f, 0.f); p2 = Vector3f(i->Pos, 0.f) + Vector3f(-8.f, +8.f, 0.f); p3 = Vector3f(i->Pos, 0.f) + Vector3f(+8.f, +8.f, 0.f); p4 = Vector3f(i->Pos, 0.f) + Vector3f(+8.f, -8.f, 0.f); BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p1; BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p2; BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p3; BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p3; BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p4; BallInstancingList.BallAndGlowList[0].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p1; BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t1; BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t2; BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t3; BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t3; BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t4; BallInstancingList.BallAndGlowList[0].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t1; */ Replace6PointsInTriangleList(BallInstancingList.BallAndGlowList[0].Data, n, i->Pos + Vector2f(-8.f, -8.f), i->Pos + Vector2f(8.f, 8.f)); n += 6; } std::list::iterator j; n = 0; m = 0; for (i = BallList.begin(); i != BallList.end(); ++i) { for (j = i->TalePos.begin(); j != i->TalePos.end(); ++j) { /* p1 = Vector3f(*j, 0.f) + Vector3f(-16.f, -16.f, 0.f); p2 = Vector3f(*j, 0.f) + Vector3f(-16.f, +16.f, 0.f); p3 = Vector3f(*j, 0.f) + Vector3f(+16.f, +16.f, 0.f); p4 = Vector3f(*j, 0.f) + Vector3f(+16.f, -16.f, 0.f); BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p1; BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p2; BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p3; BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p3; BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p4; BallInstancingList.BallAndGlowList[1].Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][n++] = p1; BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t1; BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t2; BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t3; BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t3; BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t4; BallInstancingList.BallAndGlowList[1].Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][m++] = t1;*/ //BallInstancingList.BallAndGlowList[1].Data += MakeDataTriangleList(); Replace6PointsInTriangleList(BallInstancingList.BallAndGlowList[1].Data, n, *j + Vector2f(-16.f, -16.f), *j + Vector2f(16.f, 16.f)); n += 6; } } std::map::iterator it; for (it = BallInstancingList.BallAndGlowList.begin(); it != BallInstancingList.BallAndGlowList.end(); ++it) { it->second.RefreshBuffer(); } } void TGameLevel::UpdateBallList(size_t dt) { *SE::Console << "TGameLevel::UpdateBallList"; std::list::iterator iBall; bool mustReloadBalls = false; //If not loaded - force load if (BallInstancingList.BallAndGlowList.size() == 0) { mustReloadBalls = true; } if (BonusFloorTimer == 0.f) { Vector2f ballPos; iBall = BallList.begin(); while (iBall != BallList.end()) { ballPos = iBall->GetPos(); if (ballPos(1)<0.f) { iBall = BallList.erase(iBall); mustReloadBalls = true; } if (iBall != BallList.end()) { ++iBall; } } } bool blockListChanged = false; for (iBall = BallList.begin(); iBall != BallList.end(); ++iBall) { iBall->Update(dt); Vector2f ballPos = iBall->GetPos(); if (ballPos(0) > Renderer->GetScreenWidth()-15.f*(Renderer->GetScreenWidth()/480.f)) { iBall->ReflectToLeft(); } if (ballPos(0) < 15.f) { iBall->ReflectToRight(); } if (ballPos(1) > Renderer->GetScreenHeight()-16.f * (Renderer->GetScreenHeight()/320.f)) { iBall->ReflectToDown(); } if (BonusFloorTimer > 0.f) { if (ballPos(1) < 13.0f* (Renderer->GetScreenHeight()/320.f)) { iBall->ReflectToUp(); } } iBall->TryReflectOnReflector(ReflectorPos); Vector2f ipos = GetBlock(ballPos); if (!(ipos == iBall->BallInBlock)) { iBall->PrevBallInBlock = iBall->BallInBlock; iBall->BallInBlock = ipos; int i = static_cast(iBall->BallInBlock(0)); int j = static_cast(iBall->BallInBlock(1)); int iprev = static_cast(iBall->PrevBallInBlock(0)); int jprev = static_cast(iBall->PrevBallInBlock(1)); if (BlockMatrix[i][j].CanReact()) { bool canThrowBonus; blockListChanged = true; if (BonusGothroughTimer > 0.f) { BlockMatrix[i][j].Disappear(); canThrowBonus = true; } else { canThrowBonus = (BlockMatrix[i][j].GetLocked() == 0); BlockMatrix[i][j].Hit(); } Vector2f blockPos = BlockMatrix[i][j].GetPosFrom(i, j); if (canThrowBonus && rand() % 20 == 0) { BonusFallingList.push_back(TBonusFalling(blockPos)); } if (BonusGothroughTimer == 0.f) { if (j < jprev) { iBall->ReflectToDown(); } else if (j > jprev) { iBall->ReflectToUp(); } else if (i < iprev) { iBall->ReflectToRight(); } else if (i > iprev) { iBall->ReflectToLeft(); } } } } } if (blockListChanged) { ReloadBlockInstansingList(); } if (mustReloadBalls) { ReloadBallInstancingList(); } else { RefreshBallInstancingList(); } } void TGameLevel::MultiplyBalls(Vector2f pos, Vector2f velocity) { *SE::Console << "TGameLevel::MultiplyBalls"; //mat2 r; Matrix2f r; Vector2f v; for (int i = -2; i<=2; i++) { float alpha = i*pi / 4.f; r(0, 0) = cosf(alpha); r(1, 0) = sinf(alpha); r(0, 1) = -sinf(alpha); r(1, 1) = cosf(alpha); v = r*velocity; v(1) = max_t(static_cast(fabs(v(1))), 0.2f) * sign(v(1)); //Prevent velocityY from being ~= 0 BallList.push_back(TBall(pos, v, BallColor)); } ReloadBallInstancingList(); } void TGameLevel::OnTapDown(Vector2f pos) { *SE::Console << "TGameLevel::OnTapDown"; if (LevelState == CONST_LEVELSTATE_STANDBY) { if (TapInBackBtnArea(pos)) { SetPause(); PrevLevelStateIsStandby = true; } else { LevelState = CONST_LEVELSTATE_PLAYING; BallList.begin()->Go(); } } else if (LevelState == CONST_LEVELSTATE_PLAYING) { if (TapInBackBtnArea(pos)) { SetPause(); } else if (fabs(ReflectorPos(0) - pos(0))>64.f) { ReflectorPos(0) = pos(0); } } else if (LevelState == CONST_LEVELSTATE_PAUSE) { if (pos(1) > 128.f) { ReleasePause(); } } } void TGameLevel::OnTapUp(Vector2f pos) { *SE::Console << "TGameLevel::OnTapUp"; } void TGameLevel::OnFling(Vector2f slideSpeed) { *SE::Console << "TBrick::TryDrawAppear"; if (LevelState == CONST_LEVELSTATE_PAUSE) { OutScaleVelocity = slideSpeed(1)/320.f; } } void TGameLevel::OnScroll(Vector2f shift) { *SE::Console << "TGameLevel::OnScroll"; const float CONST_SCROLL_SCALE = 1.1f; if (LevelState == CONST_LEVELSTATE_PLAYING || LevelState == CONST_LEVELSTATE_STANDBY) { ReflectorPos(0) -= CONST_SCROLL_SCALE*shift(0); } else if (LevelState == CONST_LEVELSTATE_PAUSE) { OutScale += shift(1)/320.f; TryGoToMenu(); } } void TGameLevel::TryGoToMenu() { *SE::Console << "TGameLevel::TryGoToMenu"; if (OutScale < 0.5f) { OutScale = 0.5f; LevelState = CONST_LEVELSTATE_NODRAW; Application->GoFromGameToMenu(); } if (OutScale > 1.f) { OutScale = 1.f; } }