Hoang Tran
@maxxxd
Viet Nam, Hanoi
Institution: VNU
#include "Init.h" #include "CommonFunction.h" #include "Map.h" //#include "BaseObject.h" #include "MainObject.h" #include "Enemy.h" #include "ScoreManager.h" #include "PowerUps.h" // Initialize ScoreManager with the renderer and desired position and font size ScoreManager scoreManager(gRenderer, 790, 100, 38); string EnemyTankTypes[] = {"images/enemyTank1R.png", "images/enemyTank1R_1.png", "images/enemyTank2R.png", "images/enemyTank2R_1.png", "images/enemyTank3R.png", "images/enemyTank4R_3.png", "images/enemyTank4R.png"}; string Maps_array[] = {"maps/map1.txt", "maps/map2.txt"}; int currentLevel = 1; int enemiesDestroyed = 0; const int enemiesToAdvance = 20; // Number of enemies needed to advance to the next level void CheckCollisionWithEnemyBullets(MainObject& MyTank, vector<Enemy>& Enemy_array, SDL_Renderer* renderer) { SDL_Rect MyTankRect = {MyTank.GetX(), MyTank.GetY(), MyTank.GetObjectWidth(), MyTank.GetObjectHeight()}; for (auto& enemy : Enemy_array) { for (auto* bullet : enemy.bullets) { SDL_Rect BulletRect = {bullet->getX(), bullet->getY(), bullet->GetObjectWidth(), bullet->GetObjectHeight()}; if (Check_Collision(MyTankRect, BulletRect)) { MyTank.GetHit(renderer); bullet->setDirection(-1); // Mark bullet for deletion return; // Exit after first hit to prevent multiple hits in one frame } } } } void CheckCollisionWithEnemy(MainObject& MyTank, vector<Enemy>& enemyTanks, SDL_Renderer* renderer, ScoreManager& scoreManager, int &tmp) { SDL_Texture* explosionTexture = IMG_LoadTexture(renderer, "images/explosion.png"); const int explosionFrameWid = 50; const int explosionFrameHei = 50; const int totalExplosionFrames = 8; for (auto it = MyTank.bullets.begin(); it != MyTank.bullets.end(); ) { bool hit = false; for (auto et = enemyTanks.begin(); et != enemyTanks.end(); ) { SDL_Rect EnemyRect = {et->GetX(), et->GetY(), et->GetObjectWidth(), et->GetObjectHeight()}; SDL_Rect BulletRect = {(*it)->GetX(), (*it)->getY(), (*it)->GetObjectWidth(), (*it)->GetObjectHeight()}; if(MyTank.CheckCollision(EnemyRect, BulletRect) && et->GetHealth() > 0){ et->SetHealth(et->GetHealth() - 1); (*it)->SetDir(-1); } else if (MyTank.CheckCollision(EnemyRect, BulletRect)) { //khoi tao powerups showPowerUps(renderer, "images/star.png"); if (et->Object_Texture) { SDL_DestroyTexture(et->Object_Texture); et->Object_Texture = nullptr; tmp--; } // Explosion animation for (int frame = 0; frame < totalExplosionFrames; frame++) { renderTexture(explosionTexture, renderer, et->GetX(), et->GetY(), et->GetObjectWidth(), et->GetObjectHeight()); SDL_RenderPresent(renderer); SDL_Delay(15); } // Add score when enemy is destroyed scoreManager.AddScore(et->getScoreEnemy(), renderer); // Increment the count of destroyed enemies enemiesDestroyed++; if (enemiesDestroyed >= enemiesToAdvance) { currentLevel++; enemiesDestroyed = 0; // Reset the count for the next level // Optionally, increase difficulty here (e.g., spawn more enemies, reduce spawn interval) } et = enemyTanks.erase(et); hit = true; break; } else { ++et; } } if (hit) { delete *it; it = MyTank.bullets.erase(it); } else { ++it; } } SDL_DestroyTexture(explosionTexture); } void SpawnEnemy(vector<Enemy>& Enemy_array, SDL_Renderer* gRenderer, Uint32& lastSpawnTime, const Uint32 spawnCooldown, int& cnt, const int EnemyNum) { Uint32 currentTime = SDL_GetTicks(); int index = rand() % 7; if (cnt < EnemyNum && currentTime - lastSpawnTime >= spawnCooldown) { Enemy enemy; int startX = rand() % (SCREEN_WIDTH - 40 - 150); // Random vị trí x trong khoảng chiều rộng màn hình int startY = 0; // Hàng đầu tiên if(EnemyTankTypes[index] == "images/enemyTank1R.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 1); enemy.setScoreEnemy(200); enemy.SetHealth(1); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank1R_1.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 1); enemy.setScoreEnemy(200); enemy.SetHealth(1); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank2R.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 4); enemy.setScoreEnemy(300); enemy.SetHealth(2); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank2R_1.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 4); enemy.setScoreEnemy(300); enemy.SetHealth(2); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank3R.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 3); enemy.setScoreEnemy(300); enemy.SetHealth(3); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank4R.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 2); enemy.setScoreEnemy(400); enemy.SetHealth(4); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank4R_3.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 2); enemy.setScoreEnemy(400); enemy.SetHealth(4); enemy.Init(gRenderer, EnemyTankTypes[index]); } Enemy_array.push_back(enemy); lastSpawnTime = currentTime; cnt++; } else if(cnt == 0){ Enemy enemy; int startX = rand() % (SCREEN_WIDTH - 40 - 150); // Random vị trí x trong khoảng chiều rộng màn hình int startY = 0; // Hàng đầu tiên //int Enemy_Index = rand() % 6; if(EnemyTankTypes[index] == "images/enemyTank1R.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 1); enemy.setScoreEnemy(200); enemy.SetHealth(1); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank1R_1.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 1); enemy.setScoreEnemy(200); enemy.SetHealth(1); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank2R.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 4); enemy.setScoreEnemy(300); enemy.SetHealth(2); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank2R_1.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 4); enemy.setScoreEnemy(300); enemy.SetHealth(2); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank3R.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 3); enemy.setScoreEnemy(300); enemy.SetHealth(3); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank4R.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 2); enemy.setScoreEnemy(400); enemy.SetHealth(4); enemy.Init(gRenderer, EnemyTankTypes[index]); } else if(EnemyTankTypes[index] == "images/enemyTank4R_3.png"){ enemy.Get_Parameters(startX, startY, 40, 40, 2); enemy.setScoreEnemy(400); enemy.SetHealth(4); enemy.Init(gRenderer, EnemyTankTypes[index]); } Enemy_array.push_back(enemy); cnt++; } } bool CheckTankCollision(MainObject& MyTank, vector<Enemy>& Enemy_array) { SDL_Rect MyTankRect = {MyTank.GetX(), MyTank.GetY(), MyTank.GetObjectWidth(), MyTank.GetObjectHeight()}; for (auto& enemy : Enemy_array) { SDL_Rect EnemyRect = {enemy.GetX(), enemy.GetY(), enemy.GetObjectWidth(), enemy.GetObjectHeight()}; if (MyTank.CheckCollision(MyTankRect, EnemyRect)) { MyTank.RevertMove(); // Khôi phục lại vị trí cũ của MyTank enemy.RevertMove(); // Khôi phục lại vị trí cũ của enemy (nếu cần) int tmp = rand() % 4; if(tmp == 0) enemy.SetDir(0); else if(tmp == 90) enemy.SetDir(90); else if(tmp == 180) enemy.SetDir(180); else enemy.SetDir(270); return true; } } return false; } bool CheckCollision(SDL_Rect a, SDL_Rect b) { // Kiểm tra nếu không có sự chồng chéo if (a.x + a.w <= b.x || a.x >= b.x + b.w || a.y + a.h <= b.y || a.y >= b.y + b.h) { return false; } return true; } void CheckEnemyCollisions(vector<Enemy>& enemies) { for (size_t i = 0; i < enemies.size(); ++i) { SDL_Rect rect1 = {enemies[i].GetX(), enemies[i].GetY(), enemies[i].GetObjectWidth(), enemies[i].GetObjectHeight()}; for (size_t j = i + 1; j < enemies.size(); ++j) { SDL_Rect rect2 = {enemies[j].GetX(), enemies[j].GetY(), enemies[j].GetObjectWidth(), enemies[j].GetObjectHeight()}; if (CheckCollision(rect1, rect2)) { // Nếu có va chạm, khôi phục lại vị trí cũ của cả hai xe enemies[i].RevertMove(); enemies[j].RevertMove(); int tmp = rand() % 4; if(tmp == 0) enemies[i].SetDir(0); else if(tmp == 90) enemies[i].SetDir(90); else if(tmp == 180) enemies[i].SetDir(180); else enemies[i].SetDir(270); int temp = rand() % 4; if(temp == 0) enemies[j].SetDir(0); else if(temp == 90) enemies[j].SetDir(90); else if(temp == 180) enemies[j].SetDir(180); else enemies[j].SetDir(270); } } } } #undef main int main(int argc, char* argv[]) { srand(time(0)); bool quit = false; bool startGame = false; if (!Init(gWindow, gRenderer)) { std::cerr << "Failed to initialize!" << std::endl; return -1; } //khoi tao background if(!loadImage(gRenderer, "images/cover.png", gTexture)){ cout << "Faild to load background" << IMG_GetError() << endl; close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); } //create menu and buttons //menu SDL_Surface* MenuSurface = IMG_Load("images/cover.png"); SDL_Texture* MenuBackground = SDL_CreateTextureFromSurface(gRenderer, MenuSurface); SDL_FreeSurface(MenuSurface); //newgame button if(!loadImage(gRenderer, "images/NewGameButton.png", gTexture)){ cout << "Faild to load newgame button" << IMG_GetError() << endl; close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); } SDL_Surface* NewGameButtonSurface = IMG_Load("images/NewGameButton.png"); SDL_Texture* NewGameButtonTexture = SDL_CreateTextureFromSurface(gRenderer, NewGameButtonSurface); SDL_FreeSurface(NewGameButtonSurface); //instruction button if(!loadImage(gRenderer, "images/Instruction_Button.png", gTexture)){ cout << "Faild to load instruction button" << IMG_GetError() << endl; close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); } SDL_Surface* InstructionButtonSurface = IMG_Load("images/Instruction_Button.png"); SDL_Texture* InstructionButtonTexture = SDL_CreateTextureFromSurface(gRenderer, InstructionButtonSurface); SDL_FreeSurface(InstructionButtonSurface); //exit button if(!loadImage(gRenderer, "images/ExitGameButton.png", gTexture)){ cout << "Faild to load exit button" << IMG_GetError() << endl; close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); } SDL_Surface* ExitGameButtonSurface = IMG_Load("images/ExitGameButton.png"); SDL_Texture* ExitGameButtonTexture = SDL_CreateTextureFromSurface(gRenderer, ExitGameButtonSurface); SDL_FreeSurface(ExitGameButtonSurface); //instruction menu if(!loadImage(gRenderer, "images/Instruction_Menu.png", gTexture)){ cout << "Faild to load Instruction_Menu" << IMG_GetError() << endl; //close(gWindow, renderer, gMusic, gSoundEffect, gFont); } SDL_Surface* InstructionMenuSurface = IMG_Load("images/Instruction_Menu.png"); SDL_Texture* InstructionMenuTexture = SDL_CreateTextureFromSurface(gRenderer, InstructionMenuSurface); //SDL_FreeSurface(InstructionButtonSurface); //khoi tao music background if(!loadMusic("sounds/We_The_People.mp3", gMusic)){ cout << "Failed to load music background" << endl; close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); } //chay music background Mix_Music* MenuMusic = gMusic; //Mix_PlayMusic(MenuMusic, -1); //game loop gameLoop: //hien ra menu va cac nut bam va dong thi xoa het ca texture showMenu(gRenderer, MenuBackground, NewGameButtonTexture, ExitGameButtonTexture, InstructionButtonTexture, InstructionMenuTexture, quit, startGame); //tat nhac //Mix_HaltMusic(); //background chinh cua game if(!loadImage(gRenderer, "images/GameBackground.png", gTexture)){ cout << "Faild to load background" << IMG_GetError() << endl; close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); } SDL_Surface* MainBackgroundSurface = IMG_Load("images/GameBackground.png"); SDL_Texture* MainBackgroundTexture = SDL_CreateTextureFromSurface(gRenderer, MainBackgroundSurface); SDL_FreeSurface(MainBackgroundSurface); //thanh ben phai cua game if(!loadImage(gRenderer, "images/Right_bar.png", gTexture)){ cout << "Fail to load Right bar image" << endl; close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); } SDL_Surface* RightBarSurface = IMG_Load("images/Right_bar.png"); SDL_Texture* RightBarTexture = SDL_CreateTextureFromSurface(gRenderer, RightBarSurface); SDL_FreeSurface(RightBarSurface); //la co level cua game if(!loadImage(gRenderer, "images/Level_Flag.png", gTexture)){ cout << "Fail to load Level_Flag image" << endl; close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); } SDL_Surface* LevelFlagSurface = IMG_Load("images/Level_Flag.png"); SDL_Texture* LevelFlagTexture = SDL_CreateTextureFromSurface(gRenderer, LevelFlagSurface); SDL_FreeSurface(LevelFlagSurface); //doc vao map readFileToMatrix(Maps_array[currentLevel - 1]); InitMap(gRenderer); //khoi tao nhac nen game if(!loadMusic("sounds/BgMusic.mp3", gMusic)){ cout << "Failed to load Moving_Sound" << endl; close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); } Mix_Music* GameMusicBackround = gMusic; //Mix_PlayMusic(GameMusicBackround, -1); //Khoi tao main Object - My tank MainObject My_Tank; if(My_Tank.loadImage("images/tank1D.png", gRenderer) == true){ My_Tank.Get_Parameters(200, SCREEN_HEIGHT - 40, 40, 40, 1); } My_Tank.SetHealth(3); //khoi tao gameover image if(!loadImage(gRenderer, "images/gameover.png", gTexture)){ cout << "Fail to load gameover image" << endl; close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); } SDL_Surface* GameOverSurface = IMG_Load("images/gameover.png"); SDL_Texture* GameOverTexture = SDL_CreateTextureFromSurface(gRenderer, GameOverSurface); SDL_FreeSurface(GameOverSurface); scoreManager.AddScore(-scoreManager.getScore(), gRenderer); scoreManager.Render(gRenderer); //khoi tao enemies int EnemyNum = 20; int tmp = 20; vector<Enemy> Enemy_array; int cnt = 0; Uint32 lastSpawnTime = 0; // Thời gian lần cuối cùng sinh ra enemy tank const Uint32 spawnCooldown = 3000; // Thời gian giữa mỗi lần sinh ra enemy tank (5 giây) while(!quit){ while(SDL_PollEvent(&e) != 0){ if (e.type == SDL_QUIT) { quit = true; //nhan ban phim di chuyen } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) { // Handle ESC key press to return to the main menu ReturnToMainMenu(gRenderer, MenuBackground, NewGameButtonTexture, ExitGameButtonTexture, InstructionButtonTexture, InstructionMenuTexture, quit, startGame); // scoreManager.AddScore(-scoreManager.getScore(), gRenderer); goto gameLoop; } else { My_Tank.HandleInputAction(e, gRenderer); } } SDL_RenderClear(gRenderer); CheckCollisionWithEnemyBullets(My_Tank, Enemy_array, gRenderer); if (My_Tank.GetHealth() <= 0) { SDL_RenderClear(gRenderer); renderTexture(GameOverTexture, gRenderer, 0 ,0, SCREEN_WIDTH, SCREEN_HEIGHT); SDL_RenderPresent(gRenderer); SDL_Delay(5000); ReturnToMainMenu(gRenderer, MenuBackground, NewGameButtonTexture, ExitGameButtonTexture, InstructionButtonTexture, InstructionMenuTexture, quit, startGame); goto gameLoop; } else if(enemiesDestroyed == 20) goto gameLoop; //in ra main background, rigth bar, level flag, renderTexture(MainBackgroundTexture, gRenderer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); renderTexture(RightBarTexture, gRenderer, 750, 0, 150, SCREEN_HEIGHT); renderTexture(LevelFlagTexture, gRenderer, 790, 550, 75, 75); //renderTexture(BulletTexture, gRenderer, 0, 0, 50, 50); //show my tank My_Tank.Move(gRenderer); if (CheckTankCollision(My_Tank, Enemy_array)) { // If collision detected, revert the tank position My_Tank.RevertMove(); } My_Tank.ShowBullets(gRenderer); My_Tank.ShowObject(gRenderer); //check game over if(!CheckGameOver()){ SDL_RenderClear(gRenderer); renderTexture(GameOverTexture, gRenderer, 0 ,0, SCREEN_WIDTH, SCREEN_HEIGHT); SDL_RenderPresent(gRenderer); SDL_Delay(5000); //reset ReturnToMainMenu(gRenderer, MenuBackground, NewGameButtonTexture, ExitGameButtonTexture, InstructionButtonTexture, InstructionMenuTexture, quit, startGame); goto gameLoop; } SpawnEnemy(Enemy_array, gRenderer, lastSpawnTime, spawnCooldown, cnt, EnemyNum); // Enemy Tanks/kiem tra va cham dan va dic for (auto& enemy : Enemy_array) { enemy.Move(); enemy.Shoot(gRenderer); enemy.ShowBullets(gRenderer); enemy.ShowObject(gRenderer); } showMap(gRenderer); CheckEnemyCollisions(Enemy_array); CheckCollisionWithEnemy(My_Tank, Enemy_array, gRenderer, scoreManager, tmp); // Render the score scoreManager.Render(gRenderer); SDL_RenderPresent(gRenderer); SDL_Delay(1); } //system("pause"); SDL_DestroyTexture(MenuBackground); SDL_DestroyTexture(NewGameButtonTexture); SDL_DestroyTexture(InstructionButtonTexture); SDL_DestroyTexture(ExitGameButtonTexture); SDL_DestroyTexture(InstructionMenuTexture); SDL_DestroyTexture(MainBackgroundTexture); SDL_DestroyTexture(RightBarTexture); close(gWindow, gRenderer, gMusic, gSoundEffect, gFont); return 0; } #include "PowerUps.h" void showPowerUps(SDL_Renderer* renderer, string file_path){ Uint32 startTime = SDL_GetTicks(); SDL_Texture* PowerUpsTexture = IMG_LoadTexture(renderer, file_path.c_str()); int random_i, random_j; do { random_i = rand() % MAP_SIZE; // Random row index random_j = rand() % MAP_SIZE; // Random column index } while (!(Maps[random_i][random_j] != 0 && Maps[random_i][random_j] != 3 && Maps[random_i][random_j] < 5)); Uint32 currentTime = SDL_GetTicks(); Uint32 elapsedTime = currentTime - startTime; if (elapsedTime < 10000){ renderTexture(PowerUpsTexture, renderer, random_j * TILE_SIZE, random_i * TILE_SIZE, TILE_SIZE + 25, TILE_SIZE + 25); //lastTime = currentTime; } }
History of submissions(plaintext version)