diff --git a/checklist.md b/checklist.md index f5465a7..7c32e4a 100644 --- a/checklist.md +++ b/checklist.md @@ -2,14 +2,14 @@ - [x] Xử lý truyền dòng: 1 điểm - [x] Cài đặt cơ chế vào/ra socket trên server: 2 điểm -- [x] Đăng ký và quản lý tài khoản: 2 điểm -- [x] Đăng nhập và quản lý phiên: 2 điểm -- [x] Tạo phòng chơi: 1 điểm -- [x] Hiển thị phòng chơi và tham gia chơi: 2 điểm -- [x] Quản lý gameplay online có tương tác: 5-8 điểm -- [x] Xây dựng các màn chơi/chế độ chơi khác nhau: 2 -8 điểm -- [x] Người dùng dừng trò chơi: 2 điểm -- [x] Lưu điểm số và thứ hạng: 2 điểm -- [x] Xây dựng hệ thống xếp hạng: 1-3 điểm -- [x] Giao diện đồ họa: 3 điểm +- [ ] Đăng ký và quản lý tài khoản: 2 điểm +- [ ] Đăng nhập và quản lý phiên: 2 điểm +- [ ] Tạo phòng chơi: 1 điểm +- [ ] Hiển thị phòng chơi và tham gia chơi: 2 điểm +- [ ] Quản lý gameplay online có tương tác: 5-8 điểm +- [ ] Xây dựng các màn chơi/chế độ chơi khác nhau: 2 -8 điểm +- [ ] Người dùng dừng trò chơi: 2 điểm +- [ ] Lưu điểm số và thứ hạng: 2 điểm +- [ ] Xây dựng hệ thống xếp hạng: 1-3 điểm +- [ ] Giao diện đồ họa: 3 điểm - [ ] Các tính năng khác: 1 - 5 điểm diff --git a/include/QuickSDL/Graphics.h b/include/QuickSDL/Graphics.h index f60a00f..153b4e7 100644 --- a/include/QuickSDL/Graphics.h +++ b/include/QuickSDL/Graphics.h @@ -27,15 +27,15 @@ namespace QuickSDL { class Graphics { public: // The Width of the game's window - const int SCREEN_WIDTH = 1920; + const int SCREEN_WIDTH = 960; // The Height of the game's window - const int SCREEN_HEIGHT = 1024; + const int SCREEN_HEIGHT = 512; // The title of the game's window const char* WINDOW_TITLE = "QuickSDL"; // Cell size used for image const int CELL_SIZE = 128; // Cell size used for the map - const int MAP_CELL_SIZE = 64; + const int MAP_CELL_SIZE = 32; private: // Needed to make GameManager a singleton class diff --git a/include/headers/LeaderBoardScreen.h b/include/headers/LeaderBoardScreen.h index b3c1d03..4158867 100644 --- a/include/headers/LeaderBoardScreen.h +++ b/include/headers/LeaderBoardScreen.h @@ -39,7 +39,8 @@ class LeaderBoardScreen : public GameEntity { class LeaderBoardPlayer : public PlayerRanking { public: - LeaderBoardPlayer(std::string name, int score, int rank); + LeaderBoardPlayer(std::string name, int score, int rank, + bool isThisPlayer = false); }; #endif diff --git a/include/headers/LobbyScreen.h b/include/headers/LobbyScreen.h index 9377228..5b9cbcb 100644 --- a/include/headers/LobbyScreen.h +++ b/include/headers/LobbyScreen.h @@ -32,11 +32,15 @@ class PlayerInfo : public GameEntity { int index, bool isReady = false, bool isLeader = false) : name(_name), color(_color), isThisPlayer(isThisPlayer) { Pos(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, - 500.0f + index * 80.0f)); + 250.0f + index * 40.0f)); - mPlayerName = new Texture(name, "Font/ARCADE.TTF", 40, {230, 230, 230}); + if (isThisPlayer) { + mPlayerName = new Texture(name, "Font/ARCADE.TTF", 20, {150, 0, 0}); + } else { + mPlayerName = new Texture(name, "Font/ARCADE.TTF", 20, {230, 230, 230}); + } mPlayerName->Parent(this); - mPlayerName->Pos(Vector2(-150.0f, 0.0f)); + mPlayerName->Pos(Vector2(-75.0f, 0.0f)); mIsReady = isReady; mIsLeader = isLeader; @@ -46,8 +50,8 @@ class PlayerInfo : public GameEntity { Graphics::Instance()->CELL_SIZE, Graphics::Instance()->CELL_SIZE, 2, 0.2f, AnimatedTexture::horizontal); mBase->Parent(this); - mBase->Pos(Vector2(150.0f, 0.0f)); - mBase->Scale(Vector2(0.7f, 0.7f)); + mBase->Pos(Vector2(75.0f, 0.0f)); + mBase->Scale(Vector2(0.35f, 0.35f)); mWeapon = new AnimatedTexture( "Tank/" + colorMap.at(color) + "/Weapons/turret_01_mk1.png", 0, 0, @@ -55,18 +59,18 @@ class PlayerInfo : public GameEntity { 0.7f, AnimatedTexture::horizontal); mWeapon->WrapMode(AnimatedTexture::once); mWeapon->Parent(this); - mWeapon->Pos(Vector2(150.0f, 0.0f)); - mWeapon->Scale(Vector2(0.7f, 0.7f)); + mWeapon->Pos(Vector2(75.0f, 0.0f)); + mWeapon->Scale(Vector2(0.35f, 0.35f)); mReady = new Texture("Check/check.jpg"); mReady->Parent(this); - mReady->Pos(Vector2(300.0f, 0.0f)); - mReady->Scale(Vector2(0.1f, 0.1f)); + mReady->Pos(Vector2(150.0f, 0.0f)); + mReady->Scale(Vector2(0.04f, 0.04f)); mCrown = new Texture("Menu/queen-crown.png"); mCrown->Parent(this); - mCrown->Pos(Vector2(-300.0f, 0.0f)); - mCrown->Scale(Vector2(0.75f, 0.75f)); + mCrown->Pos(Vector2(-150.0f, 0.0f)); + mCrown->Scale(Vector2(0.35f, 0.35f)); } ~PlayerInfo() { diff --git a/include/headers/ResultScreen.h b/include/headers/ResultScreen.h index 51c4c6b..c2d4e46 100644 --- a/include/headers/ResultScreen.h +++ b/include/headers/ResultScreen.h @@ -15,7 +15,8 @@ class PlayerRanking : public GameEntity { AnimatedTexture *mBase, *mWeapon; public: - PlayerRanking(std::string name, int score, COLOR color); + PlayerRanking(std::string name, int score, COLOR color, + bool isThisPlayer = false); ~PlayerRanking(); void Update(); diff --git a/src/entities/Base.cpp b/src/entities/Base.cpp index 6188b4a..6313db3 100644 --- a/src/entities/Base.cpp +++ b/src/entities/Base.cpp @@ -28,6 +28,7 @@ Base::Base(BASE_POSITION basePos, bool isThisPlayer, COLOR color, bool isBot) { mTexture = new Texture("Base/eagle.png", 0, 0, 60, 60); mTexture->Parent(this); + mTexture->Scale(Vector2(0.5f, 0.5f)); AddCollider(new BoxCollider(mTexture->ScaledDimensions())); mDeathAnimation = @@ -143,6 +144,7 @@ void Base::Dead() { mAnimating = true; Active(false); mTank->Dead(); + if (mIsBot) mClient->player_dead(); if (mIsThisPlayer) mClient->player_dead(); for (int i = 0; i < 3; i++) { diff --git a/src/entities/Brick.cpp b/src/entities/Brick.cpp index 5782535..23c1714 100644 --- a/src/entities/Brick.cpp +++ b/src/entities/Brick.cpp @@ -14,13 +14,15 @@ Brick::Brick() : PhysicEntity() { mTexture = new AnimatedTexture("Base/brick.png", 0, 0, 16, 16, 3, 1.0f, AnimatedTexture::horizontal); mTexture->Parent(this); - mTexture->Scale(Vector2(4.0f, 4.0f)); + mTexture->Scale(Vector2(Graphics::Instance()->MAP_CELL_SIZE / 16, + Graphics::Instance()->MAP_CELL_SIZE / 16)); mDeathAnimation = new AnimatedTexture("Explosion/explosion.png", 0, 0, 256, 256, 8, 0.68f, AnimatedTexture::horizontal); mDeathAnimation->Parent(this); - mDeathAnimation->Scale(Vector2(0.25f, 0.25f)); + mDeathAnimation->Scale(Vector2(Graphics::Instance()->MAP_CELL_SIZE / 256, + Graphics::Instance()->MAP_CELL_SIZE / 256)); mDeathAnimation->WrapMode(AnimatedTexture::once); AddCollider(new BoxCollider(mTexture->ScaledDimensions())); diff --git a/src/entities/Bullet.cpp b/src/entities/Bullet.cpp index d6fa19c..aeaae4c 100644 --- a/src/entities/Bullet.cpp +++ b/src/entities/Bullet.cpp @@ -8,10 +8,11 @@ Bullet::Bullet(bool isFriendly) : PhysicEntity() { mTexture = new AnimatedTexture("Bullet/bullet.png", 11 * 32, 0, 32, 32, 4, 0.2f, AnimatedTexture::horizontal); mTexture->Parent(this); + mTexture->Scale(Vector2(0.25f, 0.25f)); mTexture->Pos(VEC2_ZERO); mTexture->WrapMode(AnimatedTexture::loop); - mSpeed = 500.0f; + mSpeed = 250.0f; mDirection = up; diff --git a/src/entities/Tank.cpp b/src/entities/Tank.cpp index 0a66009..02768de 100644 --- a/src/entities/Tank.cpp +++ b/src/entities/Tank.cpp @@ -30,17 +30,22 @@ Tank::Tank(bool isThisPlayer, BASE_POSITION basePos, COLOR color) switch (basePos) { case topLeft: - Pos(Vector2(192.0f, mGraphics->MAP_CELL_SIZE)); + Pos(Vector2(mGraphics->MAP_CELL_SIZE + mGraphics->CELL_SIZE * 0.5f, + mGraphics->MAP_CELL_SIZE)); break; case bottomLeft: - Pos(Vector2(192.0f, mGraphics->SCREEN_HEIGHT - mGraphics->MAP_CELL_SIZE)); + Pos(Vector2(mGraphics->MAP_CELL_SIZE + mGraphics->CELL_SIZE * 0.5f, + mGraphics->SCREEN_HEIGHT - mGraphics->MAP_CELL_SIZE)); break; case bottomRight: - Pos(Vector2(mGraphics->SCREEN_WIDTH - 192.0f, + Pos(Vector2(mGraphics->SCREEN_WIDTH - + (mGraphics->MAP_CELL_SIZE + mGraphics->CELL_SIZE * 0.5f), mGraphics->SCREEN_HEIGHT - mGraphics->MAP_CELL_SIZE)); break; case topRight: - Pos(Vector2(mGraphics->SCREEN_WIDTH - 192.0f, mGraphics->MAP_CELL_SIZE)); + Pos(Vector2(mGraphics->SCREEN_WIDTH - + (mGraphics->MAP_CELL_SIZE + mGraphics->CELL_SIZE * 0.5f), + mGraphics->MAP_CELL_SIZE)); break; } @@ -49,6 +54,7 @@ Tank::Tank(bool isThisPlayer, BASE_POSITION basePos, COLOR color) Graphics::Instance()->CELL_SIZE, Graphics::Instance()->CELL_SIZE, 2, 0.2f, AnimatedTexture::horizontal); mBase->Parent(this); + mBase->Scale(Vector2(0.5f, 0.5f)); mBase->Pos(VEC2_ZERO); mWeapon = new AnimatedTexture( @@ -57,19 +63,21 @@ Tank::Tank(bool isThisPlayer, BASE_POSITION basePos, COLOR color) AnimatedTexture::horizontal); mWeapon->WrapMode(AnimatedTexture::once); mWeapon->Parent(this); + mWeapon->Scale(Vector2(0.5f, 0.5f)); mWeapon->Pos(VEC2_ZERO); mDeathAnimation = new AnimatedTexture("Explosion/explosion.png", 0, 0, 256, 256, 8, 0.68f, AnimatedTexture::horizontal); - mDeathAnimation->Scale(Vector2(0.5f, 0.5f)); + mDeathAnimation->Scale(Vector2(mGraphics->MAP_CELL_SIZE / 256.0f, + mGraphics->MAP_CELL_SIZE / 256.0f)); mDeathAnimation->Parent(this); mDeathAnimation->Pos(VEC2_ZERO); mDeathAnimation->WrapMode(AnimatedTexture::once); - mMoveSpeed = 100.0f; - mMoveBoundsX = Vector2(50, Graphics::Instance()->SCREEN_WIDTH - 50); - mMoveBoundsY = Vector2(50, Graphics::Instance()->SCREEN_HEIGHT - 50); + mMoveSpeed = 50.0f; + mMoveBoundsX = Vector2(10, Graphics::Instance()->SCREEN_WIDTH - 10); + mMoveBoundsY = Vector2(10, Graphics::Instance()->SCREEN_HEIGHT - 10); mDirection = DIRECTION::up; mFireDirection = DIRECTION::up; @@ -82,7 +90,7 @@ Tank::Tank(bool isThisPlayer, BASE_POSITION basePos, COLOR color) } } - AddCollider(new BoxCollider(Vector2(64.0f, 90.0f)), Vector2(0.0f, -5.0f)); + AddCollider(new BoxCollider(Vector2(32.0f, 40.0f))); } Tank::~Tank() { @@ -168,20 +176,34 @@ void Tank::Shoot() { mAnimating = true; switch (mFireDirection) { case up: - mBullets[i]->Fire(Pos() - Vector2(0.0f, 64.0f), mFireDirection); - mClient->shot_bullet(Pos().x, Pos().y - 64.0f, mFireDirection); + mBullets[i]->Fire( + Pos() - Vector2(0.0f, Graphics::Instance()->MAP_CELL_SIZE), + mFireDirection); + mClient->shot_bullet(Pos().x, + Pos().y - Graphics::Instance()->MAP_CELL_SIZE, + mFireDirection); break; case down: - mBullets[i]->Fire(Pos() + Vector2(0.0f, 64.0f), mFireDirection); - mClient->shot_bullet(Pos().x, Pos().y + 64.0f, mFireDirection); + mBullets[i]->Fire( + Pos() + Vector2(0.0f, Graphics::Instance()->MAP_CELL_SIZE), + mFireDirection); + mClient->shot_bullet(Pos().x, + Pos().y + Graphics::Instance()->MAP_CELL_SIZE, + mFireDirection); break; case left: - mBullets[i]->Fire(Pos() - Vector2(64.0f, 0.0f), mFireDirection); - mClient->shot_bullet(Pos().x - 64.0f, Pos().y, mFireDirection); + mBullets[i]->Fire( + Pos() - Vector2(Graphics::Instance()->MAP_CELL_SIZE, 0.0f), + mFireDirection); + mClient->shot_bullet(Pos().x - Graphics::Instance()->MAP_CELL_SIZE, + Pos().y, mFireDirection); break; case right: - mBullets[i]->Fire(Pos() + Vector2(64.0f, 0.0f), mFireDirection); - mClient->shot_bullet(Pos().x + 64.0f, Pos().y, mFireDirection); + mBullets[i]->Fire( + Pos() + Vector2(Graphics::Instance()->MAP_CELL_SIZE, 0.0f), + mFireDirection); + mClient->shot_bullet(Pos().x + Graphics::Instance()->MAP_CELL_SIZE, + Pos().y, mFireDirection); break; } break; diff --git a/src/main.cpp b/src/main.cpp index 13ced3e..d3abaa1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -108,7 +108,7 @@ void *auto_recv_message() { int alive_count = 0; for (int i = 0; i < room->players.size(); i++) - if (room->players[i].status == 1) alive_count++; + if (room->players[i].status != 3) alive_count++; client->alive_players = alive_count; diff --git a/src/screen/JoinScreen.cpp b/src/screen/JoinScreen.cpp index 56cefd4..9559a4f 100644 --- a/src/screen/JoinScreen.cpp +++ b/src/screen/JoinScreen.cpp @@ -28,9 +28,9 @@ JoinScreen::JoinScreen() { mTitleBar = new GameEntity(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, Graphics::Instance()->SCREEN_HEIGHT * 0.1f)); - mTitle = new Texture("ENTER ROOM CODE", "Font/ARCADE.TTF", 48, {150, 0, 0}); + mTitle = new Texture("ENTER ROOM CODE", "Font/ARCADE.TTF", 24, {150, 0, 0}); mTitle->Parent(mTitleBar); - mTitle->Pos(Vector2(0.0f, 0.0f)); + mTitle->Pos(VEC2_ZERO); // input box mInputBox = @@ -40,15 +40,15 @@ JoinScreen::JoinScreen() { mInputText = " "; mInputBoxLabel = - new Texture("ROOM CODE: ", "Font/ARCADE.TTF", 32, {255, 255, 255}); + new Texture("ROOM CODE: ", "Font/ARCADE.TTF", 16, {255, 255, 255}); mInputBoxLabel->Parent(mInputBox); - mInputBoxLabel->Pos(Vector2(-200.0f, 0.0f)); + mInputBoxLabel->Pos(Vector2(-100.0f, 0.0f)); // input text mInputBoxTexture = - new Texture(mInputText, "Font/ARCADE.TTF", 32, {255, 255, 255}); + new Texture(mInputText, "Font/ARCADE.TTF", 16, {255, 255, 255}); mInputBoxTexture->Parent(mInputBox); - mInputBoxTexture->Pos(Vector2(100.0f, 0.0f)); + mInputBoxTexture->Pos(Vector2(50.0f, 0.0f)); for (int i = 0; i < 5; i++) { mRoomList[i] = NULL; @@ -56,6 +56,7 @@ JoinScreen::JoinScreen() { mCursor = new Texture("Cursor/cursor.png"); mCursor->Parent(this); + mCursor->Scale(Vector2(0.5f, 0.5f)); mSelectedRoom = -1; @@ -126,7 +127,7 @@ void JoinScreen::Update() { if (mSelectedRoom != -1) mCursor->Parent(mRoomList[mSelectedRoom]); - mCursor->Pos(Vector2(-400.0f, 0.0f)); + mCursor->Pos(Vector2(-200.0f, 0.0f)); } void JoinScreen::UpdateRoomList() { @@ -167,7 +168,7 @@ void JoinScreen::UpdateRoomList() { mRoomList[count]->Parent(this); mRoomList[count]->Pos(Vector2( Graphics::Instance()->SCREEN_WIDTH * 0.5f, - Graphics::Instance()->SCREEN_HEIGHT * 0.5f + (count * 100.0f))); + Graphics::Instance()->SCREEN_HEIGHT * 0.5f + (count * 50.0f))); count++; } @@ -222,9 +223,9 @@ void JoinScreen::UpdateInputText(char c) { } mInputBoxTexture = - new Texture(mInputText, "Font/ARCADE.TTF", 32, {255, 255, 255}); + new Texture(mInputText, "Font/ARCADE.TTF", 16, {255, 255, 255}); mInputBoxTexture->Parent(mInputBox); - mInputBoxTexture->Pos(Vector2(100.0f, 0.0f)); + mInputBoxTexture->Pos(Vector2(50.0f, 0.0f)); } void JoinScreen::Render() { @@ -253,26 +254,26 @@ RoomInfo::RoomInfo(std::string code, int playerCount, Status status) mCount = playerCount; mStatus = status; - mCode = new Texture(mRoomCode, "Font/ARCADE.TTF", 32, {255, 255, 255}); + mCode = new Texture(mRoomCode, "Font/ARCADE.TTF", 16, {255, 255, 255}); mPlayerCount = new Texture(std::to_string(playerCount) + "/4", - "Font/ARCADE.TTF", 32, {255, 255, 255}); + "Font/ARCADE.TTF", 16, {255, 255, 255}); switch (status) { case RoomInfo::Status::WAITING: mStatusText = new Texture("Menu/waiting.png"); mStatusTexture = - new Texture("waiting", "Font/ARCADE.TTF", 32, {255, 255, 255}); + new Texture("waiting", "Font/ARCADE.TTF", 16, {255, 255, 255}); break; case RoomInfo::Status::FULL: mStatusText = new Texture("Menu/full.png"); mStatusTexture = - new Texture("full", "Font/ARCADE.TTF", 32, {255, 255, 255}); + new Texture("full", "Font/ARCADE.TTF", 16, {255, 255, 255}); break; case RoomInfo::Status::STARTED: mStatusText = new Texture("Menu/playing.png"); mStatusTexture = - new Texture("playing", "Font/ARCADE.TTF", 32, {255, 255, 255}); + new Texture("playing", "Font/ARCADE.TTF", 16, {255, 255, 255}); break; } @@ -281,29 +282,29 @@ RoomInfo::RoomInfo(std::string code, int playerCount, Status status) Graphics::Instance()->CELL_SIZE, 2, 0.2f, AnimatedTexture::horizontal); mBase->Parent(this); - mBase->Pos(Vector2(50.0f, 0.0f)); - mBase->Scale(Vector2(0.7f, 0.7f)); + mBase->Pos(Vector2(25.0f, 0.0f)); + mBase->Scale(Vector2(0.35f, 0.35f)); mWeapon = new AnimatedTexture("Tank/Red/Weapons/turret_01_mk1.png", 0, 0, Graphics::Instance()->CELL_SIZE, Graphics::Instance()->CELL_SIZE, 8, 0.7f, AnimatedTexture::horizontal); mWeapon->Parent(this); - mWeapon->Pos(Vector2(50.0f, 0.0f)); - mWeapon->Scale(Vector2(0.7f, 0.7f)); + mWeapon->Pos(Vector2(25.0f, 0.0f)); + mWeapon->Scale(Vector2(0.35f, 0.35f)); mCode->Parent(this); - mCode->Pos(Vector2(-250.0f, 0.0f)); + mCode->Pos(Vector2(-125.0f, 0.0f)); mPlayerCount->Parent(this); - mPlayerCount->Pos(Vector2(-50.0f, 0.0f)); + mPlayerCount->Pos(Vector2(-25.0f, 0.0f)); mStatusText->Parent(this); - mStatusText->Scale(Vector2(0.25f, 0.25f)); - mStatusText->Pos(Vector2(100.0f, 0.0f)); + mStatusText->Scale(Vector2(0.125f, 0.125f)); + mStatusText->Pos(Vector2(50.0f, 0.0f)); mStatusTexture->Parent(this); - mStatusTexture->Pos(Vector2(250.0f, 0.0f)); + mStatusTexture->Pos(Vector2(125.0f, 0.0f)); } RoomInfo::~RoomInfo() { diff --git a/src/screen/LeaderBoardScreen.cpp b/src/screen/LeaderBoardScreen.cpp index 779fb88..24dddcf 100644 --- a/src/screen/LeaderBoardScreen.cpp +++ b/src/screen/LeaderBoardScreen.cpp @@ -19,7 +19,7 @@ LeaderBoardScreen::LeaderBoardScreen() : GameEntity() { mIsPlayerTop5 = false; - mTitle = new Texture("LEADERBOARD", "Font/ARCADE.TTF", 80, {150, 0, 0}); + mTitle = new Texture("LEADERBOARD", "Font/ARCADE.TTF", 40, {150, 0, 0}); mTitle->Parent(this); mTitle->Pos(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, Graphics::Instance()->SCREEN_HEIGHT * 0.2f)); @@ -29,9 +29,9 @@ LeaderBoardScreen::LeaderBoardScreen() : GameEntity() { mRankingsContainer->Pos(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, Graphics::Instance()->SCREEN_HEIGHT * 0.4f)); - mThreeDot = new Texture("...", "Font/ARCADE.TTF", 32, {150, 0, 0}); + mThreeDot = new Texture("...", "Font/ARCADE.TTF", 16, {150, 0, 0}); mThreeDot->Parent(mRankingsContainer); - mThreeDot->Pos(Vector2(0.0f, 4 * 100.0f)); + mThreeDot->Pos(Vector2(0.0f, 4 * 50.0f)); for (int i = 0; i < 5; i++) { mRankings[i] = NULL; @@ -81,15 +81,16 @@ void LeaderBoardScreen::UpdateRankings() { continue; mRankings[count] = - new LeaderBoardPlayer(player->username, player->points, i); + new LeaderBoardPlayer(player->username, player->points, i, + player->username == mClient->get_username()); mRankings[count]->Parent(mRankingsContainer); - mRankings[count]->Pos(Vector2(0.0f, count * 100.0f)); + mRankings[count]->Pos(Vector2(0.0f, count * 50.0f)); count++; } if (!mIsPlayerTop5) { - mRankings[4]->Pos(Vector2(0.0f, 5 * 100.0f)); + mRankings[4]->Pos(Vector2(0.0f, 5 * 50.0f)); } } } @@ -112,18 +113,19 @@ void LeaderBoardScreen::Render() { } // =============LEADERBOARDPLAYER================ -LeaderBoardPlayer::LeaderBoardPlayer(std::string name, int score, int rank) - : PlayerRanking(name, score, COLOR::red) { +LeaderBoardPlayer::LeaderBoardPlayer(std::string name, int score, int rank, + bool isThisPlayer) + : PlayerRanking(name, score, COLOR::red, isThisPlayer) { std::string rank_str = rank == 0 ? "1ST" : rank == 1 ? "2ND" : rank == 2 ? "3RD" : std::to_string(rank + 1) + "TH"; - mRankText = new Texture(rank_str, "Font/ARCADE.TTF", 32, {150, 0, 0}); + mRankText = new Texture(rank_str, "Font/ARCADE.TTF", 16, {150, 0, 0}); mRankText->Parent(this); - mRankText->Pos(Vector2(300.0f, 0.0f)); + mRankText->Pos(Vector2(150.0f, 0.0f)); - mScoreText->Pos(Vector2(150.0f, 0.0f)); + mScoreText->Pos(Vector2(75.0f, 0.0f)); - mTank->Pos(Vector2(-300.0f, 0.0f)); + mTank->Pos(Vector2(-150.0f, 0.0f)); } diff --git a/src/screen/LobbyScreen.cpp b/src/screen/LobbyScreen.cpp index 90484f5..d8ee09f 100644 --- a/src/screen/LobbyScreen.cpp +++ b/src/screen/LobbyScreen.cpp @@ -20,14 +20,14 @@ LobbyScreen::LobbyScreen() { mClient = TSS::Client::Instance(); - mTitle = new Texture("LOBBY", "Font/ARCADE.TTF", 80, {150, 0, 0}); + mTitle = new Texture("LOBBY", "Font/ARCADE.TTF", 40, {150, 0, 0}); mTitle->Parent(this); - mTitle->Pos(Vector2(0.0f, 70.0f)); + mTitle->Pos(Vector2(0.0f, 35.0f)); mInstruction = new Texture("Press SPACE to toggle ready", "Font/ARCADE.TTF", - 50, {150, 0, 0}); + 25, {150, 0, 0}); mInstruction->Parent(mTitle); - mInstruction->Pos(Vector2(0.0f, 100.0f)); + mInstruction->Pos(Vector2(0.0f, 50.0f)); mRoomCode = NULL; @@ -101,7 +101,7 @@ void LobbyScreen::SetRoomCode(std::string code) { } mRoomCode = - new Texture("Room code: " + code, "Font/ARCADE.TTF", 40, {230, 230, 230}); + new Texture("Room code: " + code, "Font/ARCADE.TTF", 20, {230, 230, 230}); mRoomCode->Parent(this); - mRoomCode->Pos(Vector2(0.0f, 300.0f)); + mRoomCode->Pos(Vector2(0.0f, 150.0f)); } diff --git a/src/screen/MapChooseScreen.cpp b/src/screen/MapChooseScreen.cpp index 8674849..8543d84 100644 --- a/src/screen/MapChooseScreen.cpp +++ b/src/screen/MapChooseScreen.cpp @@ -17,7 +17,7 @@ void MapChooseScreen::Release() { MapChooseScreen::MapChooseScreen() { mInput = InputManager::Instance(); - mTitle = new Texture("Choose Map", "Font/ARCADE.TTF", 60, {150, 0, 0}); + mTitle = new Texture("Choose Map", "Font/ARCADE.TTF", 30, {150, 0, 0}); mTitle->Parent(this); mTitle->Pos(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, Graphics::Instance()->SCREEN_HEIGHT * 0.1f)); @@ -27,44 +27,45 @@ MapChooseScreen::MapChooseScreen() { Graphics::Instance()->SCREEN_HEIGHT * 0.6f)); mChooseBox->Parent(this); - mMap1Title = new Texture("Map 1", "Font/ARCADE.TTF", 32, {150, 0, 0}); + mMap1Title = new Texture("Map 1", "Font/ARCADE.TTF", 16, {150, 0, 0}); mMap1Title->Parent(mChooseBox); - mMap1Title->Pos(Vector2(-512.0f, 0.0f)); + mMap1Title->Pos(Vector2(-256.0f, 0.0f)); mMap1 = new Texture("Map/map1.jpg"); mMap1->Parent(mMap1Title); - mMap1->Scale(Vector2(0.2f, 0.2f)); - mMap1->Pos(Vector2(0.0f, -128.0f)); + mMap1->Scale(Vector2(0.1f, 0.1f)); + mMap1->Pos(Vector2(0.0f, -64.0f)); - mMap2Title = new Texture("Map 2", "Font/ARCADE.TTF", 32, {150, 0, 0}); + mMap2Title = new Texture("Map 2", "Font/ARCADE.TTF", 16, {150, 0, 0}); mMap2Title->Parent(mChooseBox); mMap2Title->Pos(Vector2(0.0f, 0.0f)); mMap2 = new Texture("Map/map2.jpg"); mMap2->Parent(mMap2Title); - mMap2->Scale(Vector2(0.2f, 0.2f)); - mMap2->Pos(Vector2(0.0f, -128.0f)); + mMap2->Scale(Vector2(0.1f, 0.1f)); + mMap2->Pos(Vector2(0.0f, -64.0f)); - mMap3Title = new Texture("Map 3", "Font/ARCADE.TTF", 32, {150, 0, 0}); + mMap3Title = new Texture("Map 3", "Font/ARCADE.TTF", 16, {150, 0, 0}); mMap3Title->Parent(mChooseBox); - mMap3Title->Pos(Vector2(512.0f, 0.0f)); + mMap3Title->Pos(Vector2(256.0f, 0.0f)); mMap3 = new Texture("Map/map3.jpg"); mMap3->Parent(mMap3Title); - mMap3->Scale(Vector2(0.2f, 0.2f)); - mMap3->Pos(Vector2(0.0f, -128.0f)); + mMap3->Scale(Vector2(0.1f, 0.1f)); + mMap3->Pos(Vector2(0.0f, -64.0f)); mSelectedMap = 1; mCursor = new Texture("Cursor/cursor.png"); mCursor->Parent(mChooseBox); - mCursor->Pos(Vector2(-512.0f, -300.0f)); + mCursor->Pos(Vector2(-256.0f, -150.0f)); + mCursor->Scale(Vector2(0.5f, 0.5f)); mCursor->Rotate(90.0f); - mCursorStartPos = Vector2(-512.0f, -300.0f); - mCursorOffset = 512; + mCursorStartPos = Vector2(-256.0f, -150.0f); + mCursorOffset = 256; mInstructions = new Texture("Press Enter to select map", "Font/ARCADE.TTF", - 32, {150, 0, 0}); + 16, {150, 0, 0}); mInstructions->Parent(this); mInstructions->Pos(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, Graphics::Instance()->SCREEN_HEIGHT * 0.8f)); diff --git a/src/screen/PlayScreen.cpp b/src/screen/PlayScreen.cpp index 7bcabb0..ff6026d 100644 --- a/src/screen/PlayScreen.cpp +++ b/src/screen/PlayScreen.cpp @@ -24,29 +24,29 @@ PlayScreen::PlayScreen() { mGameOverSent = false; mIsTraining = false; - mPauseText = new Texture("PAUSED", "Font/ARCADE.TTF", 80, {150, 0, 0}); + mPauseText = new Texture("PAUSED", "Font/ARCADE.TTF", 40, {150, 0, 0}); mPauseText->Parent(this); mPauseText->Pos(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, Graphics::Instance()->SCREEN_HEIGHT * 0.4f)); mPauseDetailText = - new Texture("PRESS ESC TO CONTINUE", "Font/ARCADE.TTF", 32, {150, 0, 0}); + new Texture("PRESS ESC TO CONTINUE", "Font/ARCADE.TTF", 16, {150, 0, 0}); mPauseDetailText->Parent(mPauseText); - mPauseDetailText->Pos(Vector2(0.0f, 80.0f)); + mPauseDetailText->Pos(Vector2(0.0f, 40.0f)); - mGameOverText1 = new Texture("GAME OVER", "Font/ARCADE.TTF", 50, {255, 0, 0}); + mGameOverText1 = new Texture("GAME OVER", "Font/ARCADE.TTF", 25, {255, 0, 0}); // set position of mGameOverText1 to bottom center of the screen mGameOverText1->Pos(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, Graphics::Instance()->SCREEN_HEIGHT * 1.2f)); - mYouWinText = new Texture("YOU WIN", "Font/ARCADE.TTF", 50, {255, 0, 0}); + mYouWinText = new Texture("YOU WIN", "Font/ARCADE.TTF", 25, {255, 0, 0}); mYouWinText->Pos(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, Graphics::Instance()->SCREEN_HEIGHT * 1.2f)); - mGameOverText2 = new Texture("PRESS ENTER TO CONTINUE", "Font/ARCADE.TTF", 32, + mGameOverText2 = new Texture("PRESS ENTER TO CONTINUE", "Font/ARCADE.TTF", 16, {150, 0, 0}); mGameOverText2->Parent(mGameOverText1); - mGameOverText2->Pos(Vector2(0.0f, 40.0f)); + mGameOverText2->Pos(Vector2(0.0f, 20.0f)); for (int i = 0; i < 4; i++) { mPlayer[i] = NULL; diff --git a/src/screen/ResultScreen.cpp b/src/screen/ResultScreen.cpp index 02a88a0..992db9f 100644 --- a/src/screen/ResultScreen.cpp +++ b/src/screen/ResultScreen.cpp @@ -16,7 +16,7 @@ void ResultScreen::Release() { ResultScreen::ResultScreen() : GameEntity() { mClient = TSS::Client::Instance(); - mTitle = new Texture("RESULT", "Font/ARCADE.TTF", 50, {255, 0, 0}); + mTitle = new Texture("RESULT", "Font/ARCADE.TTF", 25, {255, 0, 0}); mTitle->Pos(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, Graphics::Instance()->SCREEN_HEIGHT * 0.2f)); mTitle->Parent(this); @@ -64,12 +64,13 @@ void ResultScreen::UpdatePlayerRanking() { new PlayerRanking(room->players[i].username, room->players[i].points, static_cast(room->players[i].tank)); mPlayerRanking[i]->Parent(mPlayerRankingContainer); - mPlayerRanking[i]->Pos(Vector2(0.0f, i * 100)); + mPlayerRanking[i]->Pos(Vector2(0.0f, i * 50)); } } // ============PlayerRanking================ -PlayerRanking::PlayerRanking(std::string name, int score, COLOR color) +PlayerRanking::PlayerRanking(std::string name, int score, COLOR color, + bool isThisPlayer) : GameEntity() { mTank = new GameEntity(Vector2(-250.0f, 0.0f)); mTank->Parent(this); @@ -80,7 +81,7 @@ PlayerRanking::PlayerRanking(std::string name, int score, COLOR color) AnimatedTexture::horizontal); mBase->Parent(mTank); mBase->Pos(VEC2_ZERO); - mBase->Scale(Vector2(0.7f, 0.7f)); + mBase->Scale(Vector2(0.35f, 0.35f)); mWeapon = new AnimatedTexture( "Tank/" + colorMap.at(color) + "/Weapons/turret_01_mk1.png", 0, 0, @@ -89,25 +90,30 @@ PlayerRanking::PlayerRanking(std::string name, int score, COLOR color) mWeapon->WrapMode(AnimatedTexture::once); mWeapon->Parent(mTank); mWeapon->Pos(VEC2_ZERO); - mWeapon->Scale(Vector2(0.7f, 0.7f)); + mWeapon->Scale(Vector2(0.35f, 0.35f)); + + if (isThisPlayer) { + mNameText = new Texture(name, "Font/ARCADE.TTF", 16, {150, 0, 0}); + } else { + mNameText = new Texture(name, "Font/ARCADE.TTF", 16, {255, 255, 255}); + } - mNameText = new Texture(name, "Font/ARCADE.TTF", 32, {255, 255, 255}); mNameText->Parent(this); - mNameText->Pos(Vector2(-50.0f, 0.0f)); + mNameText->Pos(Vector2(-25.0f, 0.0f)); - mScoreText = new Texture(std::to_string(score), "Font/ARCADE.TTF", 32, + mScoreText = new Texture(std::to_string(score), "Font/ARCADE.TTF", 16, {255, 255, 255}); mScoreText->Parent(this); - mScoreText->Pos(Vector2(100.0f, 0.0f)); + mScoreText->Pos(Vector2(50.0f, 0.0f)); std::string rankText = score == 8 ? "1st" : score == 4 ? "2nd" : score == 2 ? "3rd" : "4th"; - mRankText = new Texture(rankText, "Font/ARCADE.TTF", 32, {255, 255, 255}); + mRankText = new Texture(rankText, "Font/ARCADE.TTF", 16, {255, 255, 255}); mRankText->Parent(this); - mRankText->Pos(Vector2(250.0f, 0.0f)); + mRankText->Pos(Vector2(125.0f, 0.0f)); } PlayerRanking::~PlayerRanking() { diff --git a/src/screen/ScreenManager.cpp b/src/screen/ScreenManager.cpp index 0dc27a7..1ba5c72 100644 --- a/src/screen/ScreenManager.cpp +++ b/src/screen/ScreenManager.cpp @@ -69,6 +69,7 @@ void ScreenManager::Update() { mCurrentScreen = join; } else if (mStartScreen->SelectedMode() == training) { mClient->is_training = true; + mClient->alive_players = 4; mPlayScreen->StartNewGame(true); mCurrentScreen = play; } else if (mStartScreen->SelectedMode() == leaderBoard) { @@ -145,6 +146,12 @@ void ScreenManager::Update() { mClient->leave_room(); } } + } else if (mInput->KeyPressed(SDL_SCANCODE_Q)) { + if (mClient->is_training && mClient->is_game_paused) { + mCurrentScreen = start; + mClient->leave_room(); + mClient->is_game_paused = false; + } } break; @@ -203,6 +210,7 @@ void ScreenManager::Render() { case result: mResultScreen->Render(); + break; case leaderBoard: mLeaderBoardScreen->Render(); diff --git a/src/screen/StartScreen.cpp b/src/screen/StartScreen.cpp index 6a51901..fc1903d 100644 --- a/src/screen/StartScreen.cpp +++ b/src/screen/StartScreen.cpp @@ -21,16 +21,16 @@ StartScreen::StartScreen() { // Top bar entities mTopBar = new GameEntity(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, 80.0f)); - mPlayerOne = new Texture("1UP", "Font/ARCADE.TTF", 32, {150, 0, 0}); - mHighScore = new Texture("HIGH SCORE", "Font/ARCADE.TTF", 32, {150, 0, 0}); - mPlayerTwo = new Texture("2UP", "Font/ARCADE.TTF", 32, {150, 0, 0}); + mPlayerOne = new Texture("1UP", "Font/ARCADE.TTF", 16, {150, 0, 0}); + mHighScore = new Texture("HIGH SCORE", "Font/ARCADE.TTF", 16, {150, 0, 0}); + mPlayerTwo = new Texture("2UP", "Font/ARCADE.TTF", 16, {150, 0, 0}); mPlayerOne->Parent(mTopBar); mHighScore->Parent(mTopBar); mPlayerTwo->Parent(mTopBar); mPlayerOne->Pos(Vector2(-Graphics::Instance()->SCREEN_WIDTH * 0.35f, 0.0f)); - mHighScore->Pos(Vector2(-32.0f, 0.0f)); + mHighScore->Pos(Vector2(-16.0f, 0.0f)); mPlayerTwo->Pos(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.2f, 0.0f)); mTopBar->Parent(this); @@ -41,14 +41,15 @@ StartScreen::StartScreen() { Graphics::Instance()->SCREEN_HEIGHT * 0.6f)); mLeaderBoardMode = - new Texture("LEADER BOARD", "Font/ARCADE.TTF", 32, {230, 230, 230}); + new Texture("LEADER BOARD", "Font/ARCADE.TTF", 16, {230, 230, 230}); mTrainingMode = - new Texture("TRAINING", "Font/ARCADE.TTF", 32, {230, 230, 230}); + new Texture("TRAINING", "Font/ARCADE.TTF", 16, {230, 230, 230}); mNewGameMode = - new Texture("NEW ROOM", "Font/ARCADE.TTF", 32, {230, 230, 230}); + new Texture("NEW ROOM", "Font/ARCADE.TTF", 16, {230, 230, 230}); mConnectGameMode = - new Texture("JOIN ROOM", "Font/ARCADE.TTF", 32, {230, 230, 230}); + new Texture("JOIN ROOM", "Font/ARCADE.TTF", 16, {230, 230, 230}); mCursor = new Texture("Cursor/cursor.png"); + mCursor->Scale(Vector2(0.5f, 0.5f)); mLeaderBoardMode->Parent(mPlayMode); mTrainingMode->Parent(mPlayMode); @@ -56,16 +57,16 @@ StartScreen::StartScreen() { mConnectGameMode->Parent(mPlayMode); mCursor->Parent(mPlayMode); - mTrainingMode->Pos(Vector2(0.0f, 32.0f)); - mNewGameMode->Pos(Vector2(0.0f, -96.0f)); - mConnectGameMode->Pos(Vector2(0.0f, -32.0f)); - mLeaderBoardMode->Pos(Vector2(0.0f, 96.0f)); - mCursor->Pos(Vector2(-250.0f, -96.0f)); + mTrainingMode->Pos(Vector2(0.0f, 16.0f)); + mNewGameMode->Pos(Vector2(0.0f, -48.0f)); + mConnectGameMode->Pos(Vector2(0.0f, -16.0f)); + mLeaderBoardMode->Pos(Vector2(0.0f, 48.0f)); + mCursor->Pos(Vector2(-125.0f, -48.0f)); mPlayMode->Parent(this); mCursorStartPos = mCursor->Pos(local); - mCursorOffset = Vector2(0.0f, 64.0f); + mCursorOffset = Vector2(0.0f, 32.0f); mSelectedMode = 0; // game title @@ -73,7 +74,7 @@ StartScreen::StartScreen() { new GameEntity(Vector2(Graphics::Instance()->SCREEN_WIDTH * 0.5f, Graphics::Instance()->SCREEN_HEIGHT * 0.3f)); - mTitle = new Texture("TANK SHOOTER", "Font/ARCADE.TTF", 64, {150, 0, 0}); + mTitle = new Texture("TANK SHOOTER", "Font/ARCADE.TTF", 32, {150, 0, 0}); mTitle->Parent(mGameTitle); mTitle->Pos(VEC2_ZERO); diff --git a/src/socket/Networking/Client.cpp b/src/socket/Networking/Client.cpp index d2f6a7d..32c4c17 100644 --- a/src/socket/Networking/Client.cpp +++ b/src/socket/Networking/Client.cpp @@ -195,7 +195,10 @@ void TSS::Client::resume_game() { } void TSS::Client::player_dead() { - if (is_training) return; + if (is_training) { + alive_players--; + return; + }; std::string send_message = "game:player_dead:" + currentRoom->room_id + ":" + username; diff --git a/src/socket/Networking/Handler/RoomHandler.cpp b/src/socket/Networking/Handler/RoomHandler.cpp index 517b8fa..f33dc22 100644 --- a/src/socket/Networking/Handler/RoomHandler.cpp +++ b/src/socket/Networking/Handler/RoomHandler.cpp @@ -38,6 +38,10 @@ std::string TSS::RoomHandler::join_room(std::string username, return ""; } + if (room->status != 1) { + return ""; + } + Player *player = new Player(); player->username = username; player->tank = room->players.size() + 1; @@ -63,15 +67,8 @@ std::string TSS::RoomHandler::leave_room(std::string username, return ""; } - for (int i = 0; i < room->players.size(); i++) { - if (room->players[i].username == username) { - room->players.erase(room->players.begin() + i); - break; - } - } - - // remove room if no player in room - if (room->players.size() == 0) { + // remove room if no player left in room + if (room->players.size() <= 1) { for (int i = 0; i < rooms->length; i++) { Room *r = static_cast(rooms->retrieve(i)); if (r->room_id == room_id) { @@ -83,6 +80,25 @@ std::string TSS::RoomHandler::leave_room(std::string username, return "room_empty"; } + // remove player from room + for (int i = 0; i < room->players.size(); i++) { + if (room->players[i].username == username) { + // if leader leave room, assign new leader + if (room->players[i].is_leader) { + room->players[i + 1].is_leader = true; + } + + room->players.erase(room->players.begin() + i); + + break; + } + } + + // reassign tank color + for (int i = 0; i < room->players.size(); i++) { + room->players[i].tank = i + 1; + } + return json_to_string(*room_to_json(room)); } @@ -99,7 +115,7 @@ std::string TSS::RoomHandler::get_rooms_list() { for (int i = 0; i < rooms->length; i++) { Room *room = static_cast(rooms->retrieve(i)); - room_list_json.push_back(*room_to_json(room)); + if (room->status == 1) room_list_json.push_back(*room_to_json(room)); } return json_to_string(room_list_json); diff --git a/src/socket/Networking/Server.cpp b/src/socket/Networking/Server.cpp index 7fbd639..248f7ee 100644 --- a/src/socket/Networking/Server.cpp +++ b/src/socket/Networking/Server.cpp @@ -203,6 +203,9 @@ void TSS::Server::handle_room(int client_socket) { auth_handler->update_online_user(std::string(username), true); + // Broadcast to all clients that room has new player joined + broadcast("room:get_rooms:success\n" + room_handler->get_rooms_list()); + broadcast_to_room(client_socket, result, std::string(room_id)); } @@ -238,6 +241,9 @@ void TSS::Server::handle_room(int client_socket) { std::string response_msg = make_response("room:leave_room", result); + // Broadcast to all clients that room has a player leave + broadcast("room:get_rooms:success\n" + room_handler->get_rooms_list()); + broadcast_to_room(client_socket, response_msg, std::string(room_id), false); } } @@ -271,6 +277,9 @@ void TSS::Server::handle_game(int client_socket) { std::string result = make_response("game:start", game_handler->start_game(room_id)); + // Broadcast to all clients that room has started + broadcast("room:get_rooms:success\n" + room_handler->get_rooms_list()); + broadcast_to_room(client_socket, result, std::string(room_id)); }