diff --git a/.github/workflows/release-snapshot.yml b/.github/workflows/release-snapshot.yml index 3626132..c73c082 100644 --- a/.github/workflows/release-snapshot.yml +++ b/.github/workflows/release-snapshot.yml @@ -51,7 +51,7 @@ jobs: overwrite: true prerelease: true release_name: "Zoned Developer Build" - body: "Latest bleeding edge version of Zoned. Might be buggy" + body: "Latest bleeding edge version of Zoned" - name: Upload apk release uses: kittaakos/upload-release-action@GH-26 diff --git a/README.md b/README.md index 6a241e3..a737fc9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Zoned   [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Version: 0.0.2-beta](https://img.shields.io/badge/version-0.0.2--beta-orange)](https://github.com/Spikatrix/Zoned/releases/tag/v0.0.2-beta) +# Zoned   [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Version: 0.0.3-dev](https://img.shields.io/badge/version-0.0.3--dev-orange)](https://github.com/Spikatrix/Zoned/releases/tag/v0.0.3-dev) Zoned Icon diff --git a/android/assets/fonts/austere.otf b/android/assets/fonts/austere.otf deleted file mode 100644 index 534cb92..0000000 Binary files a/android/assets/fonts/austere.otf and /dev/null differ diff --git a/android/assets/fonts/recharge.otf b/android/assets/fonts/recharge.otf new file mode 100644 index 0000000..dbcda16 Binary files /dev/null and b/android/assets/fonts/recharge.otf differ diff --git a/android/assets/icons/ic_libgdx.png b/android/assets/icons/ic_libgdx.png index b9ba137..bc456e4 100644 Binary files a/android/assets/icons/ic_libgdx.png and b/android/assets/icons/ic_libgdx.png differ diff --git a/android/assets/icons/ic_loading.png b/android/assets/icons/ic_loading.png index e43626e..58c59e7 100644 Binary files a/android/assets/icons/ic_loading.png and b/android/assets/icons/ic_loading.png differ diff --git a/android/assets/neon-skin/neon-ui.atlas b/android/assets/neon-skin/neon-ui.atlas index ebcfe4b..1827be1 100644 --- a/android/assets/neon-skin/neon-ui.atlas +++ b/android/assets/neon-skin/neon-ui.atlas @@ -230,6 +230,15 @@ select-box-pressed orig: 52, 42 offset: 0, 0 index: -1 +select-box-disabled + rotate: false + xy: 263, 164 + size: 52, 42 + split: 18, 22, 14, 22 + pad: 15, 23, 14, 14 + orig: 52, 42 + offset: 0, 0 + index: -1 slider rotate: false xy: 228, 341 diff --git a/android/assets/neon-skin/neon-ui.json b/android/assets/neon-skin/neon-ui.json index 0999a5b..64d10cf 100644 --- a/android/assets/neon-skin/neon-ui.json +++ b/android/assets/neon-skin/neon-ui.json @@ -136,6 +136,10 @@ "name": "select-box-pressed", "color": "color" }, + "select-box-disabled-c": { + "name": "select-box-disabled", + "color": "color" + }, "slider-before-c": { "name": "slider-before", "color": "color" @@ -247,7 +251,7 @@ "checkboxOn": "checkbox-pressed-c", "checkboxOff": "checkbox-c", "checkboxOver": "checkbox-over-c", - "font": "regular-font", + "font": "regular", "fontColor": "text-themed", "downFontColor": "text-selected", "checkedFontColor": "text-selected" @@ -256,7 +260,7 @@ "checkboxOn": "radio-pressed-c", "checkboxOff": "radio-c", "checkboxOver": "radio-over-c", - "font": "regular-font", + "font": "regular", "fontColor": "custom-color", "downFontColor": "selected", "checkedFontColor": "text-themed" @@ -271,7 +275,7 @@ }, "com.badlogic.gdx.scenes.scene2d.ui.ImageTextButton$ImageTextButtonStyle": { "default": { - "font": "regular-font", + "font": "regular", "fontColor": "text-themed", "downFontColor": "text-selected", "up": "button-c", @@ -284,7 +288,7 @@ "imageOver": "checkbox-over-c", "imageChecked": "checkbox-pressed-c", "imageCheckedOver": "checkbox-pressed-over-c", - "font": "regular-font", + "font": "regular", "fontColor": "text-themed", "downFontColor": "text-selected", "checkedFontColor": "text-selected" @@ -295,7 +299,7 @@ "imageOver": "radio-over-c", "imageChecked": "radio-pressed-c", "imageCheckedOver": "radio-over-c", - "font": "regular-font", + "font": "regular", "fontColor": "text-themed", "downFontColor": "text-selected", "checkedFontColor": "text-selected" @@ -303,17 +307,17 @@ }, "com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle": { "default": { - "font": "regular-font", + "font": "regular", "fontColor": "text" }, "themed": { - "font": "regular-font", + "font": "regular", "fontColor": "text-themed" } }, "com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle": { "default": { - "font": "regular-font", + "font": "regular", "fontColorSelected": "selected", "fontColorUnselected": "text-themed", "selection": "color", @@ -342,12 +346,13 @@ }, "com.badlogic.gdx.scenes.scene2d.ui.SelectBox$SelectBoxStyle": { "default": { - "font": "regular-font", + "font": "regular", "background": "select-box-c", "scrollStyle": "default", "listStyle": "default", "backgroundOver": "select-box-over-c", - "backgroundOpen": "select-box-pressed-c" + "backgroundOpen": "select-box-pressed-c", + "backgroundDisabled": "select-box-disabled-c" } }, "com.badlogic.gdx.scenes.scene2d.ui.Slider$SliderStyle": { @@ -376,7 +381,7 @@ }, "com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle": { "default": { - "font": "regular-font", + "font": "regular", "fontColor": "text-themed", "downFontColor": "text-selected", "up": "button-c", @@ -386,7 +391,7 @@ }, "com.badlogic.gdx.scenes.scene2d.ui.TextField$TextFieldStyle": { "default": { - "font": "regular-font", + "font": "regular", "fontColor": "text-themed", "background": "textfield-c", "focusedBackground": "textfield-selected-c", @@ -394,7 +399,7 @@ "selection": "selected" }, "login": { - "font": "regular-font", + "font": "regular", "fontColor": "text-themed", "background": "textfield-login-c", "focusedBackground": "textfield-login-selected-c", @@ -402,7 +407,7 @@ "selection": "selected" }, "password": { - "font": "regular-font", + "font": "regular", "fontColor": "text-themed", "background": "textfield-password-c", "focusedBackground": "textfield-password-selected-c", @@ -432,7 +437,7 @@ "com.badlogic.gdx.scenes.scene2d.ui.Window$WindowStyle": { "default": { "background": "window-c", - "titleFont": "regular-font", + "titleFont": "regular", "titleFontColor": "text-themed" } } diff --git a/android/assets/neon-skin/neon-ui.png b/android/assets/neon-skin/neon-ui.png index b32f029..50e079f 100644 Binary files a/android/assets/neon-skin/neon-ui.png and b/android/assets/neon-skin/neon-ui.png differ diff --git a/android/build.gradle b/android/build.gradle index c92737e..630c476 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -21,11 +21,13 @@ android { minSdkVersion 14 targetSdkVersion 29 versionCode 2 - versionName "0.0.2-beta" + versionName "0.0.3-dev" // Remember to update the GAME_VERSION in Constants.java // And project.setVersion in Desktop's build.gradle // And the version in the badge in the README file // Or for Linux users, use the versionUpdate.sh script + + setProperty("archivesBaseName", "${appName}-${versionName}") } buildTypes { release { diff --git a/android/src/com/cg/zoned/AndroidLauncher.java b/android/src/com/cg/zoned/AndroidLauncher.java index 14fdf77..9d754af 100644 --- a/android/src/com/cg/zoned/AndroidLauncher.java +++ b/android/src/com/cg/zoned/AndroidLauncher.java @@ -37,6 +37,6 @@ private void startGame() { config.useCompass = false; config.hideStatusBar = true; config.useImmersiveMode = true; - initialize(new Zoned(), config); + initialize(new Zoned(null), config); // Discord RPC is not available on Android, hence null } } diff --git a/build.gradle b/build.gradle index 3eadf0a..094edd9 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ buildscript { } dependencies { classpath 'org.wisepersist:gwt-gradle-plugin:1.0.9' - classpath 'com.android.tools.build:gradle:3.6.3' + classpath 'com.android.tools.build:gradle:3.6.3' // Updating this might break shit so meh } } @@ -20,11 +20,7 @@ allprojects { version = '1.0' ext { appName = "Zoned" - gdxVersion = '1.9.10' - roboVMVersion = '2.3.6' - box2DLightsVersion = '1.4' - ashleyVersion = '1.7.0' - aiVersion = '1.8.0' + gdxVersion = '1.9.10' // Should I update? Hmm pieMenuVersion = '4.2.0' } @@ -75,7 +71,7 @@ project(":android") { } } -// No HTML support since the game uses Kryonet which isn't supported there +// No HTML support since the game uses Kryonet and generated FreeTypeFonts which isn't supported there /*project(":html") { apply plugin: "gwt" apply plugin: "war" @@ -98,9 +94,7 @@ project(":core") { api "com.esotericsoftware:kryonet:2.22.0-RC1" api "com.github.payne911:PieMenu:$pieMenuVersion" - // Pie menu depends on ShapeDrawer, so that'll get imported as well - - implementation files("libs/discord-rpc.jar") + // Piemenu depends on ShapeDrawer, so that'll get imported as well } } diff --git a/core/src/com/cg/zoned/Assets.java b/core/src/com/cg/zoned/Assets.java index 9df302b..e36715e 100644 --- a/core/src/com/cg/zoned/Assets.java +++ b/core/src/com/cg/zoned/Assets.java @@ -41,4 +41,35 @@ public void setAssetManager(AssetManager assetManager) { public void dispose() { assetManager.dispose(); } + + // TODO: The default font size is way too big (really noticeable on mobile screens) + public enum FontManager { + STYLED_LARGE ("recharge.otf", 65), + STYLED_SMALL ("recharge.otf", 24), + REGULAR ("glametrix.otf", 32), // Default font, required to be named as 'REGULAR' + SMALL ("bebasneue.otf", 18), + PLAYER_LABEL_NOSCALE("bebasneue.otf", + (int) (Map.playerLabelRegionScale * (Constants.CELL_SIZE - (2 * Constants.MAP_GRID_LINE_WIDTH)))); + // Player label font height is based on cell size minus a bit of line width as calculated above + + private String fontFileName; + private int fontSize; + + FontManager(String fontFileName, int fontSize) { + this.fontFileName = fontFileName; + this.fontSize = fontSize; + } + + public int getFontSize() { + return fontSize; + } + + public String getFontName() { + return this.toString().toLowerCase(); + } + + public String getFontFileName() { + return fontFileName; + } + } } diff --git a/core/src/com/cg/zoned/Constants.java b/core/src/com/cg/zoned/Constants.java index 1e3bd19..1c31a30 100644 --- a/core/src/com/cg/zoned/Constants.java +++ b/core/src/com/cg/zoned/Constants.java @@ -7,7 +7,7 @@ import java.util.Map; public final class Constants { - public static final String GAME_VERSION = "0.0.2-beta"; + public static final String GAME_VERSION = "0.0.3-dev"; // Remember to update the versionName in Android's build.gradle // And project.setVersion in Desktop's build.gradle // And the version in the badge in the README file @@ -57,7 +57,7 @@ public final class Constants { */ public static final Map PLAYER_COLORS = new LinkedHashMap() { { - put("GREEN", new Color(0, 0.8f, 0, 1.0f)); + put("GREEN", new Color(0, 0.8f, 0, 1.0f)); // Alpha won't matter put("RED", new Color(0.8f, 0, 0, 1.0f)); put("BLUE", new Color(0, 0, 0.8f, 1.0f)); put("YELLOW", new Color(0.8f, 0.8f, 0, 1.0f)); @@ -86,49 +86,17 @@ public final class Constants { public static final float DESKTOP_FONT_SCALE_FACTOR = 1.0f; // Values from https://developer.android.com/training/multiscreen/screendensities - public static final float ANDROID_LDPI_FONT_SCALE_FACTOR = 0.75f; - public static final float ANDROID_MDPI_FONT_SCALE_FACTOR = 1.0f; - public static final float ANDROID_HDPI_FONT_SCALE_FACTOR = 1.5f; - public static final float ANDROID_XHDPI_FONT_SCALE_FACTOR = 2.0f; - public static final float ANDROID_XXHDPI_FONT_SCALE_FACTOR = 3.0f; + public static final float ANDROID_LDPI_FONT_SCALE_FACTOR = 0.75f; + public static final float ANDROID_MDPI_FONT_SCALE_FACTOR = 1.0f; + public static final float ANDROID_HDPI_FONT_SCALE_FACTOR = 1.5f; + public static final float ANDROID_XHDPI_FONT_SCALE_FACTOR = 2.0f; + public static final float ANDROID_XXHDPI_FONT_SCALE_FACTOR = 3.0f; public static final float ANDROID_XXXHDPI_FONT_SCALE_FACTOR = 4.0f; public static final String LOG_TAG = "ZONED"; - public static final String ZONED_PREFERENCES = "Zoned_Preferences"; - public static final String FPS_PREFERENCE = "FPS_Preference"; - public static final String CONTROL_PREFERENCE = "Control_Preference"; - public static final String NAME_PREFERENCE = "Name_Preference"; // The last used name - public static final String SHOW_TUTORIAL_PREFERENCE = "Show_Tutorial_Preference"; // Shows the tutorial dialog prompt the first time - public static final String SPLITSCREEN_PLAYER_COUNT_PREFERENCE = "Splitscreen_Player_Count_Preference"; - public static final String MAP_START_POS_SPLITSCREEN_COUNT_PREFERENCE = "Map_Start_Pos_Splitscreen_Count_Preference"; - public static final String DEV_MODE_PREFERENCE = "Dev_Mode_Preference"; - - public static final int PIE_MENU_CONTROL = 0; - public static final int FLING_CONTROL = 1; - - public enum Direction {UP, LEFT, DOWN, RIGHT} - - public enum FONT_MANAGER { - LARGE("large-font", 80), - REGULAR("regular-font", 32), - SMALL("small-font", 18), - PLAYER_LABEL("player-label-font-noscale", 20); - - private String name; - private int size; - - FONT_MANAGER(String name, int size) { - this.name = name; - this.size = size; - } - - public int getSize() { - return size; - } - - public String getName() { - return name; - } - } + // Preferences moved to Preferences.java + // Directions moved to Player.java + // Controls moved to managers/ControlManager.java + // Fonts moved to Assets.java } \ No newline at end of file diff --git a/core/src/com/cg/zoned/GameMode.java b/core/src/com/cg/zoned/GameMode.java new file mode 100644 index 0000000..b72d6ac --- /dev/null +++ b/core/src/com/cg/zoned/GameMode.java @@ -0,0 +1,13 @@ +package com.cg.zoned; + +public class GameMode { + public String previewLocation; + public String name; + public Class targetClass; + + public GameMode(String name, String previewLocation, Class targetClass) { + this.name = name; + this.previewLocation = previewLocation; + this.targetClass = targetClass; + } +} diff --git a/core/src/com/cg/zoned/KryoHelper.java b/core/src/com/cg/zoned/KryoHelper.java index c10972f..a3ff16e 100644 --- a/core/src/com/cg/zoned/KryoHelper.java +++ b/core/src/com/cg/zoned/KryoHelper.java @@ -1,9 +1,10 @@ package com.cg.zoned; -import com.cg.zoned.Constants.Direction; +import com.cg.zoned.Player.Direction; import com.cg.zoned.buffers.BufferClientConnect; import com.cg.zoned.buffers.BufferDirections; import com.cg.zoned.buffers.BufferGameStart; +import com.cg.zoned.buffers.BufferMapData; import com.cg.zoned.buffers.BufferNewMap; import com.cg.zoned.buffers.BufferPlayerData; import com.cg.zoned.buffers.BufferPlayerDisconnected; @@ -11,7 +12,6 @@ import com.esotericsoftware.kryo.Kryo; public class KryoHelper { - public static void registerClasses(Kryo kryo) { kryo.register(BufferServerRejectedConnection.class); kryo.register(BufferPlayerDisconnected.class); @@ -19,10 +19,12 @@ public static void registerClasses(Kryo kryo) { kryo.register(BufferPlayerData.class); kryo.register(BufferDirections.class); kryo.register(BufferGameStart.class); + kryo.register(BufferMapData.class); kryo.register(BufferNewMap.class); kryo.register(Direction[].class); kryo.register(Direction.class); kryo.register(String[].class); + kryo.register(byte[].class); kryo.register(int[].class); } } \ No newline at end of file diff --git a/core/src/com/cg/zoned/Map.java b/core/src/com/cg/zoned/Map.java index f96e938..de74d9f 100644 --- a/core/src/com/cg/zoned/Map.java +++ b/core/src/com/cg/zoned/Map.java @@ -15,7 +15,6 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; -import com.cg.zoned.Constants.Direction; import com.cg.zoned.managers.PlayerManager; import space.earlygrey.shapedrawer.JoinType; @@ -33,9 +32,11 @@ public class Map { private Rectangle userViewRect = null; private FrameBuffer playerLabelFbo = null; + public static float playerLabelRegionScale = 2f; // Rendered at higher (2x rn) res, downscaled to required size private TextureRegion[] playerLabels = null; private FrameBuffer playerFbo = null; + public static float playerTextureRegionScale = 2f; // Rendered at higher (2x rn) res, downscaled to required size private TextureRegion playerTextureRegion = null; private FrameBuffer mapFbo = null; @@ -62,7 +63,7 @@ public Map(Cell[][] mapGrid, int wallCount, ShapeDrawer shapeDrawer) { } private void createPlayerTexture(ShapeDrawer shapeDrawer) { - int size = (int) Constants.CELL_SIZE; + int size = (int) (((int) Constants.CELL_SIZE) * playerTextureRegionScale); Batch batch = shapeDrawer.getBatch(); batch.setProjectionMatrix(new Matrix4().setToOrtho2D(0, 0, size, size)); @@ -71,15 +72,16 @@ private void createPlayerTexture(ShapeDrawer shapeDrawer) { playerFbo.dispose(); } - playerFbo = new FrameBuffer(Pixmap.Format.RGB565, size, size, false); + playerFbo = new FrameBuffer(Pixmap.Format.RGBA4444, size, size, false); playerFbo.begin(); batch.begin(); - Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClearColor(0, 0, 0, 0); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); shapeDrawer.setColor(Constants.PLAYER_CIRCLE_COLOR); - shapeDrawer.circle(size / 2f, size / 2f, size / 3f, Constants.PLAYER_CIRCLE_WIDTH, JoinType.SMOOTH); + shapeDrawer.circle(size / 2f, size / 2f, size / 3f, + Constants.PLAYER_CIRCLE_WIDTH * playerTextureRegionScale, JoinType.SMOOTH); batch.end(); playerFbo.end(); @@ -88,7 +90,7 @@ private void createPlayerTexture(ShapeDrawer shapeDrawer) { playerTextureRegion.flip(false, true); } - private void createMapTexture(ShapeDrawer shapeDrawer) { + public void createMapTexture(ShapeDrawer shapeDrawer) { int width = (int) ((cols * Constants.CELL_SIZE) + Constants.MAP_GRID_LINE_WIDTH); int height = (int) ((rows * Constants.CELL_SIZE) + Constants.MAP_GRID_LINE_WIDTH); @@ -100,11 +102,11 @@ private void createMapTexture(ShapeDrawer shapeDrawer) { mapFbo.dispose(); } - mapFbo = new FrameBuffer(Pixmap.Format.RGB565, width, height, false); + mapFbo = new FrameBuffer(Pixmap.Format.RGBA4444, width, height, false); mapFbo.begin(); batch.begin(); - Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClearColor(0, 0, 0, 0); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); drawGrid(shapeDrawer); @@ -119,9 +121,9 @@ private void createMapTexture(ShapeDrawer shapeDrawer) { public void createPlayerLabelTextures(Player[] players, ShapeDrawer shapeDrawer, BitmapFont playerLabelFont) { playerLabels = new TextureRegion[players.length]; - int totalHeight = ((int) playerLabelFont.getLineHeight()) * players.length; + int totalHeight = (((int) (playerLabelFont.getLineHeight() - (Constants.MAP_GRID_LINE_WIDTH / 2))) * players.length); int height = totalHeight / players.length; - int width = (int) (Constants.CELL_SIZE * 3f); + int width = (int) (((int) (Constants.CELL_SIZE * 3f)) * playerLabelRegionScale); float radius = height / 2f; Batch batch = shapeDrawer.getBatch(); @@ -131,11 +133,11 @@ public void createPlayerLabelTextures(Player[] players, ShapeDrawer shapeDrawer, playerLabelFbo.dispose(); } - playerLabelFbo = new FrameBuffer(Pixmap.Format.RGB565, width, totalHeight, false); + playerLabelFbo = new FrameBuffer(Pixmap.Format.RGBA4444, width, totalHeight, false); playerLabelFbo.begin(); batch.begin(); - Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClearColor(0, 0, 0, 0); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); for (int i = 0; i < playerLabels.length; i++) { @@ -217,25 +219,25 @@ public void update(PlayerManager playerManager, Player[] players, float delta) { continue; } - mapColorUpdated = false; // Might need a bit more testing + mapColorUpdated = false; - Direction direction = player.direction; - if (direction == Direction.UP && player.position.y < rows - 1 && + Player.Direction direction = player.direction; + if (direction == Player.Direction.UP && player.position.y < rows - 1 && mapGrid[Math.round(player.position.y) + 1][Math.round(player.position.x)].isMovable) { player.moveTo(new Vector2(player.position.x, player.position.y + 1), delta); - } else if (direction == Direction.RIGHT && player.position.x < cols - 1 && + } else if (direction == Player.Direction.RIGHT && player.position.x < cols - 1 && mapGrid[Math.round(player.position.y)][Math.round(player.position.x) + 1].isMovable) { player.moveTo(new Vector2(player.position.x + 1, player.position.y), delta); - } else if (direction == Direction.DOWN && player.position.y > 0 && + } else if (direction == Player.Direction.DOWN && player.position.y > 0 && mapGrid[Math.round(player.position.y) - 1][Math.round(player.position.x)].isMovable) { player.moveTo(new Vector2(player.position.x, player.position.y - 1), delta); - } else if (direction == Direction.LEFT && player.position.x > 0 && + } else if (direction == Player.Direction.LEFT && player.position.x > 0 && mapGrid[Math.round(player.position.y)][Math.round(player.position.x) - 1].isMovable) { player.moveTo(new Vector2(player.position.x - 1, player.position.y), delta); @@ -252,6 +254,7 @@ public void update(PlayerManager playerManager, Player[] players, float delta) { setMapWeights(players); setMapColors(playerManager, players); + updateCapturePercentage(playerManager); } } } @@ -279,6 +282,7 @@ private void setMapColors(PlayerManager playerManager, Player[] players) { int posX = Math.round(player.position.x); int posY = Math.round(player.position.y); if (mapGrid[posY][posX].cellColor == null && mapGrid[posY][posX].playerCount == 1) { + // TODO: Should we allow multiple players of the same team in the same location capture the cell? mapGrid[posY][posX].cellColor = new Color(player.color.r, player.color.g, player.color.b, 0.1f); if (playerManager != null) { playerManager.incrementScore(player); @@ -290,6 +294,17 @@ private void setMapColors(PlayerManager playerManager, Player[] players) { fillSurroundedCells(playerManager, players); } + private void updateCapturePercentage(PlayerManager playerManager) { + if (playerManager == null) { + return; + } + + Array teamData = playerManager.getTeamData(); + for (TeamData td : teamData) { + td.setCapturePercentage((this.rows * this.cols) - this.wallCount); + } + } + private void fillSurroundedCells(PlayerManager playerManager, Player[] players) { FloodFillGridState[][] gridState = new FloodFillGridState[rows][cols]; for (int i = 0; i < rows; i++) { @@ -364,64 +379,71 @@ private Rectangle calcUserViewRect(OrthographicCamera camera) { } public void render(Player[] players, ShapeDrawer shapeDrawer, OrthographicCamera camera, float delta) { - Rectangle userViewRect = calcUserViewRect(camera); + render(players, 0, shapeDrawer, camera, delta); + } - drawColors(shapeDrawer, userViewRect, delta); + public void render(Player[] players, int playerIndex, ShapeDrawer shapeDrawer, OrthographicCamera camera, float delta) { + Rectangle userViewRect = calcUserViewRect(camera); Batch batch = shapeDrawer.getBatch(); - batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE); - drawGrid(userViewRect, batch); + drawColors(shapeDrawer, playerIndex, userViewRect, delta); + drawGrid(batch); drawPlayers(players, userViewRect, batch); - renderPlayerLabels(players, userViewRect, batch); - - batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); + drawPlayerLabels(players, playerIndex, userViewRect, batch); } private void drawPlayers(Player[] players, Rectangle userViewRect, Batch batch) { for (Player player : players) { - player.render(userViewRect, batch, playerTextureRegion); + player.render(userViewRect, batch, playerTextureRegion, playerTextureRegionScale); } } - private void drawColors(ShapeDrawer shapeDrawer, Rectangle userViewRect, float delta) { + private void drawColors(ShapeDrawer shapeDrawer, int playerIndex, Rectangle userViewRect, float delta) { for (int i = 0; i < this.rows; i++) { for (int j = 0; j < this.cols; j++) { float startX = j * Constants.CELL_SIZE; float startY = i * Constants.CELL_SIZE; - if (mapGrid[i][j].cellColor != null && userViewRect.contains(startX, startY)) { - shapeDrawer.setColor(mapGrid[i][j].cellColor); - shapeDrawer.filledRectangle(startX, startY, - Constants.CELL_SIZE, Constants.CELL_SIZE); - - mapGrid[i][j].cellColor.add(0, 0, 0, 2f * delta); + if (mapGrid[i][j].cellColor != null) { + if (playerIndex == 0 && mapGrid[i][j].cellColor.a != 1f) { + mapGrid[i][j].cellColor.add(0, 0, 0, 2f * delta); + } - // Use the constant color object to avoid too many redundant color objects - Color constColor = PlayerColorHelper.getConstantColor(mapGrid[i][j].cellColor); - if (constColor != null) { - mapGrid[i][j].cellColor = constColor; + if (userViewRect.contains(startX, startY)) { + shapeDrawer.setColor(mapGrid[i][j].cellColor); + shapeDrawer.filledRectangle(startX, startY, Constants.CELL_SIZE, Constants.CELL_SIZE); } } } } } - private void drawGrid(Rectangle userViewRect, Batch batch) { - // TODO: Optimization: Draw only the region that is in view + private void drawGrid(Batch batch) { batch.draw(mapTextureRegion, -Constants.MAP_GRID_LINE_WIDTH / 2, -Constants.MAP_GRID_LINE_WIDTH / 2); } - public void renderPlayerLabels(Player[] players, Rectangle userViewRect, Batch batch) { + public void drawPlayerLabels(Player[] players, int playerIndex, Rectangle userViewRect, Batch batch) { if (playerLabels != null) { for (int i = 0; i < players.length; i++) { - float posX = (players[i].position.x * Constants.CELL_SIZE) - (playerLabels[i].getRegionWidth() / 2f) + (Constants.CELL_SIZE / 2); - float posY = (players[i].position.y * Constants.CELL_SIZE) + Constants.CELL_SIZE + (Constants.MAP_GRID_LINE_WIDTH / 2); - if (userViewRect.contains(posX + playerLabels[i].getRegionWidth(), posY - (Constants.CELL_SIZE / 2)) || - userViewRect.contains(posX, posY - (Constants.CELL_SIZE / 2))) { - batch.draw(playerLabels[i], posX, posY); + if (i == playerIndex) { + continue; } + renderPlayerLabel(players[i], playerLabels[i], userViewRect, batch); } + + // Render the current player's label on top of other labels + renderPlayerLabel(players[playerIndex], playerLabels[playerIndex], userViewRect, batch); + } + } + + private void renderPlayerLabel(Player player, TextureRegion playerLabel, Rectangle userViewRect, Batch batch) { + float posX = (player.position.x * Constants.CELL_SIZE) - (playerLabel.getRegionWidth() / (playerLabelRegionScale * 2f)) + (Constants.CELL_SIZE / 2); + float posY = (player.position.y * Constants.CELL_SIZE) + Constants.CELL_SIZE + (Constants.MAP_GRID_LINE_WIDTH / 2); + if (userViewRect.contains(posX + playerLabel.getRegionWidth(), posY - (Constants.CELL_SIZE / 2)) || + userViewRect.contains(posX, posY - (Constants.CELL_SIZE / 2))) { + batch.draw(playerLabel, posX, posY, + playerLabel.getRegionWidth() / playerLabelRegionScale, playerLabel.getRegionHeight() / playerLabelRegionScale); } } @@ -506,7 +528,7 @@ public boolean gameComplete(Array teamData) { if (teamData.size == 2) { for (TeamData td : teamData) { // For two team games, end the game when a team has captured more than 50% of the cells - if (100 * (td.score / (((double) this.rows * this.cols) - this.wallCount)) > 50.0) { + if (td.getCapturePercentage() > 50.0) { return true; } } diff --git a/core/src/com/cg/zoned/MapSelector.java b/core/src/com/cg/zoned/MapSelector.java index 8a9e4c6..d885375 100644 --- a/core/src/com/cg/zoned/MapSelector.java +++ b/core/src/com/cg/zoned/MapSelector.java @@ -2,6 +2,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.badlogic.gdx.scenes.scene2d.ui.Label; @@ -124,6 +125,7 @@ private void showExtraParamDialog(final MapExtraParams prompts, final MapEntity Table contentTable = new Table(); contentTable.center(); + Array focusableDialogButtons = new Array<>(); for (int i = 0; i < prompts.spinnerVars.size + 1; i++) { Label label; if (i == 0) { @@ -140,12 +142,16 @@ private void showExtraParamDialog(final MapExtraParams prompts, final MapEntity int snapValue = prompts.spinnerVars.get(i - 1).snapValue; label = new Label(prompts.spinnerVars.get(i - 1).prompt, skin); - spinners[i - 1] = new Spinner(skin, skin.getFont(Constants.FONT_MANAGER.REGULAR.getName()).getLineHeight(), + spinners[i - 1] = new Spinner(skin, skin.getFont(Assets.FontManager.REGULAR.getFontName()).getLineHeight(), 64f * scaleFactor, true); spinners[i - 1].generateValueRange(lowValue, highValue, skin); spinners[i - 1].snapToStep(snapValue - lowValue); contentTable.add(label).left(); contentTable.add(spinners[i - 1]); + + focusableDialogButtons.add(spinners[i - 1].getLeftButton()); + focusableDialogButtons.add(spinners[i - 1].getRightButton()); + focusableDialogButtons.add(null); } contentTable.row(); } @@ -154,7 +160,7 @@ private void showExtraParamDialog(final MapExtraParams prompts, final MapEntity buttonTexts.add("Cancel"); buttonTexts.add("Set"); - stage.showDialog(contentTable, buttonTexts, false, scaleFactor, + stage.showDialog(contentTable, focusableDialogButtons, buttonTexts, false, scaleFactor, new FocusableStage.DialogResultListener() { @Override public void dialogResult(String buttonText) { diff --git a/core/src/com/cg/zoned/Player.java b/core/src/com/cg/zoned/Player.java index 0590176..c258eff 100644 --- a/core/src/com/cg/zoned/Player.java +++ b/core/src/com/cg/zoned/Player.java @@ -7,30 +7,27 @@ import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; -import com.cg.zoned.Constants.Direction; public class Player extends InputAdapter { public Color color; public String name; - public int score; - public Vector2 position; public int[] controls; public Direction direction; public Direction updatedDirection; + public Vector2 position; public Vector2 prevPosition; + public Vector2 targetPosition; public boolean dummyMoving; private Vector2 dummyPosition; - public Vector2 targetPosition; private float timeElapsed; public Player(Color color, String name) { this.color = color; this.name = name; - this.score = 0; this.position = new Vector2(); this.prevPosition = null; @@ -69,7 +66,7 @@ public void moveTo(Vector2 targetPosition, float delta) { } } - public void dummyMoveTo(Vector2 targetPosition, float delta) { // Simulate a fake movement for proper timing for server-client synchronization + public void dummyMoveTo(Vector2 targetPosition, float delta) { // Simulate a fake movement for timed movement from all players if (this.targetPosition == null) { this.targetPosition = targetPosition; this.dummyMoving = true; @@ -87,12 +84,14 @@ public void dummyMoveTo(Vector2 targetPosition, float delta) { // Simulate a fak } } - public void render(Rectangle userViewRect, Batch batch, TextureRegion playerTexture) { + public void render(Rectangle userViewRect, Batch batch, TextureRegion playerTexture, float playerTextureRegionScale) { float startX = (this.position.x * Constants.CELL_SIZE); float startY = (this.position.y * Constants.CELL_SIZE); if (userViewRect.contains(startX, startY)) { - batch.draw(playerTexture, startX, startY); + batch.draw(playerTexture, startX, startY, + playerTexture.getRegionWidth() / playerTextureRegionScale, + playerTexture.getRegionHeight() / playerTextureRegionScale); } } @@ -110,4 +109,6 @@ public boolean keyDown(int keycode) { return false; } + + public enum Direction {UP, LEFT, DOWN, RIGHT} } diff --git a/core/src/com/cg/zoned/PlayerColorHelper.java b/core/src/com/cg/zoned/PlayerColorHelper.java index b146ab4..5514cd8 100644 --- a/core/src/com/cg/zoned/PlayerColorHelper.java +++ b/core/src/com/cg/zoned/PlayerColorHelper.java @@ -1,11 +1,16 @@ package com.cg.zoned; import com.badlogic.gdx.graphics.Color; -import com.cg.zoned.Constants; import java.util.Map; public final class PlayerColorHelper { + public static void resetPlayerColorAlpha() { + for (Map.Entry entry : Constants.PLAYER_COLORS.entrySet()) { + entry.getValue().a = 1f; + } + } + public static Color getColorFromString(String color) { return Constants.PLAYER_COLORS.get(color.toUpperCase()); } diff --git a/core/src/com/cg/zoned/Preferences.java b/core/src/com/cg/zoned/Preferences.java new file mode 100644 index 0000000..701035e --- /dev/null +++ b/core/src/com/cg/zoned/Preferences.java @@ -0,0 +1,23 @@ +package com.cg.zoned; + +public class Preferences { + // Preferences file name + public static final String ZONED_PREFERENCES = "Zoned_Preferences"; + + // Show FPS or not + public static final String FPS_PREFERENCE = "FPS_Preference"; + // 0 = Piemenu control, 1 = Fling control + public static final String CONTROL_PREFERENCE = "Control_Preference"; + // The last used name to be autofilled in the Player name field in the Host join screen + public static final String NAME_PREFERENCE = "Name_Preference"; + // Shows the tutorial prompt the first time the user visits the splitscreen multiplayer screen + public static final String SHOW_TUTORIAL_PREFERENCE = "Show_Tutorial_Preference"; + // Player count in splitscreen multiplayer mode (Developer options) + public static final String SPLITSCREEN_PLAYER_COUNT_PREFERENCE = "Splitscreen_Player_Count_Preference"; + // Splitscreen count in the Map start pos screen (Developer option) + public static final String MAP_START_POS_SPLITSCREEN_COUNT_PREFERENCE = "Map_Start_Pos_Splitscreen_Count_Preference"; + // Developer mode unlocked or not + public static final String DEV_MODE_PREFERENCE = "Dev_Mode_Preference"; + // Enable Discord RPC or not + public static final String DISCORD_RPC_PREFERENCE = "Discord_RPC_Preference"; +} diff --git a/core/src/com/cg/zoned/ScoreBar.java b/core/src/com/cg/zoned/ScoreBar.java index 8c8ae71..abf0f9e 100644 --- a/core/src/com/cg/zoned/ScoreBar.java +++ b/core/src/com/cg/zoned/ScoreBar.java @@ -8,40 +8,56 @@ import com.badlogic.gdx.utils.viewport.Viewport; public class ScoreBar { + private static final float SCOREBAR_LERP_VALUE = 3.0f; + public float scoreBarHeight; private float totalWidth; private float totalHeight; - private float[] currentPos; - private float[] scoreBarStartX; - private float[] scoreBarWidths; + private float[] scoreBarCurrentWidth; + private float[] scoreBarTargetWidth; + private float[] scoreBarDrawStartPos; public ScoreBar(Viewport viewport, int size, float scaleFactor) { - currentPos = new float[size]; - scoreBarStartX = new float[size]; - scoreBarWidths = new float[size]; + scoreBarCurrentWidth = new float[size]; + scoreBarTargetWidth = new float[size]; + scoreBarDrawStartPos = new float[size]; totalWidth = viewport.getWorldWidth(); totalHeight = viewport.getWorldHeight(); + computeDrawStartPos(); + scoreBarHeight = 16f * scaleFactor; } + private void computeDrawStartPos() { + int size = scoreBarDrawStartPos.length; + + float splitScreenWidth = totalWidth / size; + for (int i = 1; i < size - 1; i++) { + scoreBarDrawStartPos[i] = splitScreenWidth * i; + scoreBarDrawStartPos[i] += (splitScreenWidth / 2); + } + if (size != 1) { + scoreBarDrawStartPos[size - 1] = totalWidth; + } else { + scoreBarDrawStartPos[size - 1] = totalWidth / 2; + } + } + public void resize(int width, int height) { totalWidth = width; totalHeight = height; } public void render(ShapeDrawer shapeDrawer, BitmapFont font, Array teamData, float delta) { - float lerpVal = 3.0f; - - float currentWidthPos = 0; float offsetY = totalHeight - scoreBarHeight; float totalScore = 0; for (TeamData td : teamData) { - totalScore += td.score; + totalScore += td.getScore(); } if (totalScore == 0) { @@ -53,36 +69,46 @@ public void render(ShapeDrawer shapeDrawer, BitmapFont font, Array tea Constants.VIEWPORT_DIVIDER_FADE_COLOR, Constants.VIEWPORT_DIVIDER_FADE_COLOR, Color.BLACK, Color.BLACK); for (int i = 0; i < teamData.size; i++) { - float barWidth = ((teamData.get(i).score / totalScore) * totalWidth); - float drawWidth = currentPos[i] + (barWidth - currentPos[i]) * lerpVal * delta; - - shapeDrawer.setColor(teamData.get(i).color); - - if (i == 0) { // First bar - shapeDrawer.filledRectangle(currentWidthPos, offsetY, drawWidth, scoreBarHeight); - scoreBarStartX[i] = currentWidthPos; - } else if (i == teamData.size - 1) { // Last bar - shapeDrawer.filledRectangle(totalWidth - drawWidth, offsetY, drawWidth, scoreBarHeight); // Can draw upto drawWidth or totalWidth. Should be the same - scoreBarStartX[i] = totalWidth - drawWidth; - } else { // Mid bar(s) - //shapeDrawer.filledRectangle(currentWidthPos + (barWidth / 2) - (drawWidth / 2), offsetY, (drawWidth / 2), BAR_HEIGHT); - shapeDrawer.filledRectangle(currentWidthPos + (barWidth / 2), offsetY, -drawWidth / 2, scoreBarHeight); - shapeDrawer.filledRectangle(currentWidthPos + (barWidth / 2), offsetY, drawWidth / 2, scoreBarHeight); - //shapeDrawer.filledRectangle(currentWidthPos + (barWidth / 2) - (drawWidth / 2), offsetY, drawWidth, BAR_HEIGHT); - //TODO: Need to polish this - scoreBarStartX[i] = currentWidthPos; - } - scoreBarWidths[i] = drawWidth; + float barWidth = ((teamData.get(i).getScore() / totalScore) * totalWidth); + scoreBarTargetWidth[i] = barWidth; - currentPos[i] = drawWidth; - currentWidthPos += drawWidth; - } + float drawWidth = scoreBarCurrentWidth[i] + ((scoreBarTargetWidth[i] - scoreBarCurrentWidth[i]) * SCOREBAR_LERP_VALUE * delta); + scoreBarCurrentWidth[i] = drawWidth; + + shapeDrawer.setColor(teamData.get(i).getColor()); + font.setColor(getGoodTextColor(teamData.get(i).getColor())); - for (int i = 0; i < scoreBarWidths.length; i++) { - font.setColor(getGoodTextColor(teamData.get(i).color)); - font.draw(shapeDrawer.getBatch(), String.valueOf(teamData.get(i).score), - scoreBarStartX[i], totalHeight - (scoreBarHeight / 2) + (font.getLineHeight() / 4), - scoreBarWidths[i], Align.center, false); + float barStartX = 0; + for (int j = 0; j < i; j++) { + barStartX += scoreBarTargetWidth[j]; + } + + if (i == 0) { + /* ScoreBar at the left */ + scoreBarDrawStartPos[i] = scoreBarDrawStartPos[i] + ((barStartX - scoreBarDrawStartPos[i]) * SCOREBAR_LERP_VALUE * delta); + + shapeDrawer.filledRectangle(scoreBarDrawStartPos[i], offsetY, drawWidth, scoreBarHeight); + font.draw(shapeDrawer.getBatch(), String.valueOf(teamData.get(i).getScore()), + scoreBarDrawStartPos[i], totalHeight - (scoreBarHeight / 2) + (font.getLineHeight() / 4), + drawWidth, Align.center, false); + } else if (i == teamData.size - 1) { + /* ScoreBar at the right */ + scoreBarDrawStartPos[i] = scoreBarDrawStartPos[i] + ((barStartX + scoreBarTargetWidth[i] - scoreBarDrawStartPos[i]) * SCOREBAR_LERP_VALUE * delta); + + shapeDrawer.filledRectangle(scoreBarDrawStartPos[i], offsetY, -drawWidth, scoreBarHeight); + font.draw(shapeDrawer.getBatch(), String.valueOf(teamData.get(i).getScore()), + scoreBarDrawStartPos[i] - drawWidth, totalHeight - (scoreBarHeight / 2) + (font.getLineHeight() / 4), + drawWidth, Align.center, false); + } else { + /* ScoreBars at the middle */ + scoreBarDrawStartPos[i] = scoreBarDrawStartPos[i] + ((barStartX + (scoreBarTargetWidth[i] / 2) - scoreBarDrawStartPos[i]) * SCOREBAR_LERP_VALUE * delta); + + shapeDrawer.filledRectangle(scoreBarDrawStartPos[i], offsetY, drawWidth / 2, scoreBarHeight); + shapeDrawer.filledRectangle(scoreBarDrawStartPos[i], offsetY, -drawWidth / 2, scoreBarHeight); + font.draw(shapeDrawer.getBatch(), String.valueOf(teamData.get(i).getScore()), + scoreBarDrawStartPos[i] - (drawWidth / 2), totalHeight - (scoreBarHeight / 2) + (font.getLineHeight() / 4), + drawWidth, Align.center, false); + } } } diff --git a/core/src/com/cg/zoned/TeamData.java b/core/src/com/cg/zoned/TeamData.java index 85b00fd..f0073a1 100644 --- a/core/src/com/cg/zoned/TeamData.java +++ b/core/src/com/cg/zoned/TeamData.java @@ -2,17 +2,48 @@ import com.badlogic.gdx.graphics.Color; -public class TeamData { - public Color color; - public int score; +import java.text.DecimalFormat; - public TeamData(Color color, int score) { - this.color = color; - this.score = score; - } +public class TeamData { + private Color color; + private int score; + private double capturePercentage; public TeamData(Color color) { this.color = color; this.score = 0; + this.capturePercentage = 0f; + } + + public void incrementScore() { + score++; + } + + public void incrementScore(int amount) { + score += amount; + } + + public void resetScore() { + score = 0; + } + + public void setCapturePercentage(int total) { + capturePercentage = 100 * ((double) score / total); + } + + public void roundCapturePercentage(DecimalFormat df) { + capturePercentage = Double.parseDouble(df.format(capturePercentage)); + } + + public double getCapturePercentage() { + return capturePercentage; + } + + public Color getColor() { + return color; + } + + public int getScore() { + return score; } } diff --git a/core/src/com/cg/zoned/UITextDisplayer.java b/core/src/com/cg/zoned/UITextDisplayer.java index 9645591..318700b 100644 --- a/core/src/com/cg/zoned/UITextDisplayer.java +++ b/core/src/com/cg/zoned/UITextDisplayer.java @@ -2,7 +2,6 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.utils.viewport.Viewport; @@ -21,12 +20,10 @@ public static void displayFPS(Viewport viewport, Batch batch, BitmapFont font, f font.setColor(Color.RED); } - batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE); batch.begin(); font.draw(batch, "FPS: " + fps, xOffset, viewport.getWorldHeight() - yOffset); batch.end(); - batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); } public static void displayFPS(Viewport viewport, Batch batch, BitmapFont font) { @@ -42,12 +39,10 @@ public static void displayPing(Viewport viewport, Batch batch, BitmapFont font, font.setColor(Color.RED); } - batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE); batch.begin(); font.draw(batch, "Ping: " + ping + " ms", xOffset, viewport.getWorldHeight() - font.getLineHeight() - yOffset); batch.end(); - batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); } public static void displayPing(Viewport viewport, Batch batch, BitmapFont font, int ping) { diff --git a/core/src/com/cg/zoned/Zoned.java b/core/src/com/cg/zoned/Zoned.java index 7aa83fd..06129a5 100644 --- a/core/src/com/cg/zoned/Zoned.java +++ b/core/src/com/cg/zoned/Zoned.java @@ -8,6 +8,7 @@ import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.utils.GdxRuntimeException; +import com.cg.zoned.managers.DiscordRPCBridge; import com.cg.zoned.managers.DiscordRPCManager; import com.cg.zoned.screens.LoadingScreen; @@ -20,12 +21,16 @@ public class Zoned extends Game { private static float SCALE_FACTOR = 1.0f; + public Zoned(DiscordRPCBridge discordRPCBridge) { + super(); + this.discordRPCManager = new DiscordRPCManager(discordRPCBridge); + } + @Override public void create() { Gdx.app.setLogLevel(Gdx.app.LOG_DEBUG); Gdx.input.setCatchKey(Input.Keys.BACK, true); - setUpDiscordRPC(); setScaleFactor(); assets = new Assets(); @@ -67,11 +72,6 @@ public void setAssetManager(AssetManager assetManager) { assets.setAssetManager(assetManager); } - private void setUpDiscordRPC() { - discordRPCManager = new DiscordRPCManager(); - discordRPCManager.initRPC(); - } - @Override public void dispose() { discordRPCManager.shutdownRPC(); diff --git a/core/src/com/cg/zoned/buffers/BufferDirections.java b/core/src/com/cg/zoned/buffers/BufferDirections.java index 6421f0f..cef9a11 100644 --- a/core/src/com/cg/zoned/buffers/BufferDirections.java +++ b/core/src/com/cg/zoned/buffers/BufferDirections.java @@ -1,6 +1,6 @@ package com.cg.zoned.buffers; -import com.cg.zoned.Constants.Direction; +import com.cg.zoned.Player.Direction; public class BufferDirections { public String[] playerNames; diff --git a/core/src/com/cg/zoned/buffers/BufferMapData.java b/core/src/com/cg/zoned/buffers/BufferMapData.java new file mode 100644 index 0000000..022c190 --- /dev/null +++ b/core/src/com/cg/zoned/buffers/BufferMapData.java @@ -0,0 +1,8 @@ +package com.cg.zoned.buffers; + +public class BufferMapData { + public String mapName; + public String mapData; + public int mapHash; + public byte[] mapPreviewData; +} diff --git a/core/src/com/cg/zoned/buffers/BufferNewMap.java b/core/src/com/cg/zoned/buffers/BufferNewMap.java index 92abaaa..e4da02e 100644 --- a/core/src/com/cg/zoned/buffers/BufferNewMap.java +++ b/core/src/com/cg/zoned/buffers/BufferNewMap.java @@ -3,4 +3,5 @@ public class BufferNewMap { public String mapName; public int[] mapExtraParams; + public int mapHash; } diff --git a/core/src/com/cg/zoned/controls/ControlType.java b/core/src/com/cg/zoned/controls/ControlType.java new file mode 100644 index 0000000..04c9f53 --- /dev/null +++ b/core/src/com/cg/zoned/controls/ControlType.java @@ -0,0 +1,15 @@ +package com.cg.zoned.controls; + +public class ControlType { + public String controlName; + public String controlOffTexturePath; + public String controlOnTexturePath; + public ControlTypeEntity controlTypeEntity; + + public ControlType(String controlName, String controlOffTexturePath, String controlOnTexturePath, ControlTypeEntity controlTypeEntity) { + this.controlName = controlName; + this.controlOffTexturePath = controlOffTexturePath; + this.controlOnTexturePath = controlOnTexturePath; + this.controlTypeEntity = controlTypeEntity; + } +} diff --git a/core/src/com/cg/zoned/controls/ControlTypeEntity.java b/core/src/com/cg/zoned/controls/ControlTypeEntity.java new file mode 100644 index 0000000..8ff57ca --- /dev/null +++ b/core/src/com/cg/zoned/controls/ControlTypeEntity.java @@ -0,0 +1,25 @@ +package com.cg.zoned.controls; + +import com.badlogic.gdx.InputAdapter; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.utils.Array; +import com.cg.zoned.Player; + +public class ControlTypeEntity extends InputAdapter { + protected Player[] players; + protected boolean isSplitScreen; + protected Stage stage; + protected float scaleFactor; + protected Array usedTextures; + + public ControlTypeEntity() {} + + public void init(Player[] players, boolean isSplitScreen, Stage stage, float scaleFactor, Array usedTextures) { + this.players = players; + this.isSplitScreen = isSplitScreen; + this.stage = stage; + this.scaleFactor = scaleFactor; + this.usedTextures = usedTextures; + } +} diff --git a/core/src/com/cg/zoned/controls/FlingControlManager.java b/core/src/com/cg/zoned/controls/FlingControlManager.java index 0b59696..5b31baa 100644 --- a/core/src/com/cg/zoned/controls/FlingControlManager.java +++ b/core/src/com/cg/zoned/controls/FlingControlManager.java @@ -3,7 +3,6 @@ import com.badlogic.gdx.Application; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; -import com.badlogic.gdx.InputAdapter; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.scenes.scene2d.Stage; @@ -11,26 +10,21 @@ import com.badlogic.gdx.scenes.scene2d.actions.MoveByAction; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.badlogic.gdx.utils.Array; -import com.cg.zoned.Constants; import com.cg.zoned.GameTouchPoint; import com.cg.zoned.Player; -public class FlingControlManager extends InputAdapter { - private Stage stage; - private Player[] players; - private boolean isSplitScreenMultiplayer; - - private float scaleFactor; +public class FlingControlManager extends ControlTypeEntity { private Texture arrowTexture; private Array clickPoints; - public FlingControlManager(Player[] players, boolean isSplitScreen, Stage stage, float scaleFactor, Array usedTextures) { + public FlingControlManager() { + } + + public void init(Player[] players, boolean isSplitScreen, Stage stage, float scaleFactor, Array usedTextures) { + super.init(players, isSplitScreen, stage, scaleFactor, usedTextures); + this.clickPoints = new Array<>(); - this.players = players; - this.isSplitScreenMultiplayer = isSplitScreen; - this.stage = stage; - this.scaleFactor = scaleFactor; arrowTexture = new Texture(Gdx.files.internal("icons/control_icons/ic_arrow.png")); usedTextures.add(arrowTexture); @@ -40,7 +34,7 @@ public FlingControlManager(Player[] players, boolean isSplitScreen, Stage stage, public boolean touchDown(int screenX, int screenY, int pointer, int button) { if (button == Input.Buttons.LEFT) { int playerIndex = 0; - if (isSplitScreenMultiplayer) { + if (isSplitScreen) { for (int i = 1; i < this.players.length; i++) { if (screenX > ((stage.getWidth() / this.players.length) * i)) { playerIndex++; @@ -117,18 +111,18 @@ public boolean touchUp(int screenX, int screenY, int pointer, int button) { MoveByAction moveAction; if (Math.abs(subPoint.x) > Math.abs(subPoint.y)) { if (subPoint.x > 0) { - player.updatedDirection = Constants.Direction.RIGHT; + player.updatedDirection = Player.Direction.RIGHT; moveAction = Actions.moveBy(moveAnimationDistance, 0f, .2f); } else { - player.updatedDirection = Constants.Direction.LEFT; + player.updatedDirection = Player.Direction.LEFT; moveAction = Actions.moveBy(-moveAnimationDistance, 0f, .2f); } } else { if (subPoint.y > 0) { - player.updatedDirection = Constants.Direction.DOWN; + player.updatedDirection = Player.Direction.DOWN; moveAction = Actions.moveBy(0f, -moveAnimationDistance, .2f); } else { - player.updatedDirection = Constants.Direction.UP; + player.updatedDirection = Player.Direction.UP; moveAction = Actions.moveBy(0f, moveAnimationDistance, .2f); } } diff --git a/core/src/com/cg/zoned/controls/PieMenuControlManager.java b/core/src/com/cg/zoned/controls/PieMenuControlManager.java index 440863e..04cc305 100644 --- a/core/src/com/cg/zoned/controls/PieMenuControlManager.java +++ b/core/src/com/cg/zoned/controls/PieMenuControlManager.java @@ -2,7 +2,6 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; -import com.badlogic.gdx.InputAdapter; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.math.Vector2; @@ -15,33 +14,28 @@ import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Scaling; -import com.cg.zoned.Constants; import com.cg.zoned.Player; import com.cg.zoned.ShapeDrawer; import com.payne.games.piemenu.PieMenu; import java.util.Arrays; -public class PieMenuControlManager extends InputAdapter { - private Stage stage; - private Player[] players; - private boolean isSplitScreenMultiplayer; - +public class PieMenuControlManager extends ControlTypeEntity { private int piemenuRadius = 80; - private float scaleFactor; private PieMenu[] menus; private int[] pointers; private Vector2[] coords; private Image[][] arrowImages; - public PieMenuControlManager(Player[] players, boolean isSplitScreen, Stage stage, float scaleFactor, Array usedTextures) { - this.players = players; - this.isSplitScreenMultiplayer = isSplitScreen; - this.stage = stage; + public PieMenuControlManager() { + } + + public void init(Player[] players, boolean isSplitScreen, Stage stage, float scaleFactor, Array usedTextures) { + super.init(players, isSplitScreen, stage, scaleFactor, usedTextures); + this.menus = new PieMenu[players.length]; this.pointers = new int[players.length]; this.coords = new Vector2[players.length]; - this.scaleFactor = scaleFactor; Arrays.fill(pointers, -1); Arrays.fill(coords, new Vector2()); @@ -96,13 +90,13 @@ public void onHighlightChange(int highlightedIndex) { resetArrowColors(arrowImages[finalI]); arrowImages[finalI][highlightedIndex].setColor(Color.BLACK); if (highlightedIndex == 0) { - players[finalI].updatedDirection = Constants.Direction.UP; + players[finalI].updatedDirection = Player.Direction.UP; } else if (highlightedIndex == 1) { - players[finalI].updatedDirection = Constants.Direction.LEFT; + players[finalI].updatedDirection = Player.Direction.LEFT; } else if (highlightedIndex == 2) { - players[finalI].updatedDirection = Constants.Direction.DOWN; + players[finalI].updatedDirection = Player.Direction.DOWN; } else if (highlightedIndex == 3) { - players[finalI].updatedDirection = Constants.Direction.RIGHT; + players[finalI].updatedDirection = Player.Direction.RIGHT; } } }); @@ -128,7 +122,7 @@ private void resetArrowColors(Image[] arrowImages) { public boolean touchDown(int screenX, int screenY, int pointer, int button) { if (button == Input.Buttons.LEFT) { int playerIndex = 0; - if (isSplitScreenMultiplayer) { + if (isSplitScreen) { for (int i = 1; i < this.players.length; i++) { if (screenX > ((stage.getWidth() / this.players.length) * i)) { playerIndex++; diff --git a/core/src/com/cg/zoned/listeners/ClientLobbyListener.java b/core/src/com/cg/zoned/listeners/ClientLobbyListener.java index 9ddd3e9..cf24a4d 100644 --- a/core/src/com/cg/zoned/listeners/ClientLobbyListener.java +++ b/core/src/com/cg/zoned/listeners/ClientLobbyListener.java @@ -1,6 +1,7 @@ package com.cg.zoned.listeners; import com.cg.zoned.buffers.BufferGameStart; +import com.cg.zoned.buffers.BufferMapData; import com.cg.zoned.buffers.BufferNewMap; import com.cg.zoned.buffers.BufferPlayerData; import com.cg.zoned.buffers.BufferServerRejectedConnection; @@ -25,7 +26,10 @@ public void received(Connection connection, Object object) { clientLobbyConnectionManager.connectionRejected(bsrc.errorMsg); } else if (object instanceof BufferNewMap) { BufferNewMap bnm = (BufferNewMap) object; - clientLobbyConnectionManager.newMapSet(bnm.mapName, bnm.mapExtraParams); + clientLobbyConnectionManager.newMapSet(bnm.mapName, bnm.mapExtraParams, bnm.mapHash); + } else if (object instanceof BufferMapData) { + BufferMapData bmd = (BufferMapData) object; + clientLobbyConnectionManager.downloadMap(bmd.mapName, bmd.mapData, bmd.mapHash, bmd.mapPreviewData); } else if (object instanceof BufferGameStart) { clientLobbyConnectionManager.startGame(); } diff --git a/core/src/com/cg/zoned/listeners/ServerLobbyListener.java b/core/src/com/cg/zoned/listeners/ServerLobbyListener.java index dd512e4..cf0e203 100644 --- a/core/src/com/cg/zoned/listeners/ServerLobbyListener.java +++ b/core/src/com/cg/zoned/listeners/ServerLobbyListener.java @@ -1,6 +1,7 @@ package com.cg.zoned.listeners; import com.cg.zoned.buffers.BufferClientConnect; +import com.cg.zoned.buffers.BufferMapData; import com.cg.zoned.buffers.BufferPlayerData; import com.cg.zoned.managers.ServerLobbyConnectionManager; import com.esotericsoftware.kryonet.Connection; @@ -21,6 +22,9 @@ public void received(Connection connection, Object object) { } else if (object instanceof BufferPlayerData) { BufferPlayerData bpd = (BufferPlayerData) object; serverLobbyConnectionManager.receiveClientData(connection, bpd.nameStrings[0], bpd.whoStrings[0], bpd.readyStrings[0], bpd.colorStrings[0], bpd.startPosStrings[0]); + } else if (object instanceof BufferMapData) { + BufferMapData bmd = (BufferMapData) object; + serverLobbyConnectionManager.serveMap(connection, bmd.mapName); } super.received(connection, object); diff --git a/core/src/com/cg/zoned/managers/AnimationManager.java b/core/src/com/cg/zoned/managers/AnimationManager.java index b9f1a48..74fd09d 100644 --- a/core/src/com/cg/zoned/managers/AnimationManager.java +++ b/core/src/com/cg/zoned/managers/AnimationManager.java @@ -11,7 +11,8 @@ import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.actions.ParallelAction; import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction; -import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.Container; +import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.utils.Array; import com.cg.zoned.Zoned; @@ -171,34 +172,54 @@ public void run() { stage.addAction(fadeOutAnimation); } - public void startVictoryAnimation(final Stage stage, Table[] tableRows) { - for (int i = 0; i < tableRows.length; i++) { - tableRows[i].setTransform(true); - tableRows[i].setOrigin(tableRows[i].getPrefWidth() / 2, tableRows[i].getPrefHeight() / 2); - tableRows[i].setScale(0f); - tableRows[i].getColor().a = 0f; - - ParallelAction fadeZoomOutAnimation = new ParallelAction(); - fadeZoomOutAnimation.addAction(Actions.fadeIn((i + 1) * .2f, Interpolation.smooth)); - fadeZoomOutAnimation.addAction(Actions.scaleTo(1f, 1f, (i + 1) * .2f, Interpolation.smooth)); - - if (i == tableRows.length - 1) { - SequenceAction finalFadeZoomOutAnimation = new SequenceAction(); - finalFadeZoomOutAnimation.addAction(fadeZoomOutAnimation); - finalFadeZoomOutAnimation.addAction(Actions.run(new Runnable() { + public void startScoreBoardAnimation(final Stage stage, Container