diff --git a/frontend/prebuild/src/app/game/websocket.ts b/frontend/prebuild/src/app/game/websocket.ts index 30fe6e0..cea9bea 100644 --- a/frontend/prebuild/src/app/game/websocket.ts +++ b/frontend/prebuild/src/app/game/websocket.ts @@ -52,9 +52,7 @@ export class GameWebsocket { location.reload(); } if (json.playerlocs) { - console.log(`Drawing player locations...`); for (let playerLoc of json.playerlocs) { - console.log(`Got playerloc ${playerLoc}`); this.whiteboard.drawSquare(playerLoc); } } diff --git a/game-service/src/main/java/org/libertybikes/game/core/ClientMessage.java b/game-service/src/main/java/org/libertybikes/game/core/ClientMessage.java index 3eea6f2..817cb50 100644 --- a/game-service/src/main/java/org/libertybikes/game/core/ClientMessage.java +++ b/game-service/src/main/java/org/libertybikes/game/core/ClientMessage.java @@ -3,6 +3,8 @@ */ package org.libertybikes.game.core; +import javax.json.bind.Jsonb; +import javax.json.bind.JsonbBuilder; import javax.json.bind.annotation.JsonbProperty; /** @@ -11,6 +13,8 @@ import javax.json.bind.annotation.JsonbProperty; */ public class ClientMessage { + private static final Jsonb jsonb = JsonbBuilder.create(); + public static enum GameEvent { GAME_START, GAME_PAUSE, @@ -27,7 +31,7 @@ public class ClientMessage { @Override public String toString() { - return "{ direction=" + direction + ", playerjoined=" + playerJoinedId + ", event=" + event + " }"; + return jsonb.toJson(this); } } diff --git a/game-service/src/main/java/org/libertybikes/game/core/GameRound.java b/game-service/src/main/java/org/libertybikes/game/core/GameRound.java index 7ef0f46..ec89dc3 100644 --- a/game-service/src/main/java/org/libertybikes/game/core/GameRound.java +++ b/game-service/src/main/java/org/libertybikes/game/core/GameRound.java @@ -21,21 +21,20 @@ public class GameRound implements Runnable { OPEN, FULL, RUNNING, FINISHED } + public static final int GAME_TICK_SPEED = 50; public static final int GAME_SIZE = 600; - public static final int GAME_SPEED = 50; + + private static final Random r = new Random(); public final String id; public final String nextRoundId; public Set players = new HashSet(); - public State state = State.OPEN; - boolean[][] board = new boolean[121][121]; - AtomicBoolean gameRunning = new AtomicBoolean(false); - AtomicBoolean paused = new AtomicBoolean(false); - - private static final Random r = new Random(); + private boolean[][] board = new boolean[121][121]; + private AtomicBoolean gameRunning = new AtomicBoolean(false); + private AtomicBoolean paused = new AtomicBoolean(false); // Get a string of 6 random uppercase letters (A-Z) private static String getRandomId() { @@ -57,45 +56,55 @@ public class GameRound implements Runnable { public void addPlayer(Player p) { players.add(p); System.out.println("Player " + players.size() + " has joined."); - for (Player cur : players) - broadcastLocation(cur); - broadcastPlayerList(players); + broadcastPlayerLocations(); + broadcastPlayerList(); } public void removePlayer(Player p) { p.disconnect(); System.out.println(p.playerName + " disconnected."); - broadcastPlayerList(players); + broadcastPlayerList(); } @Override public void run() { - for (int i = 0; i < GAME_SIZE / Player.PLAYER_SIZE + 1; i++) { + for (int i = 0; i < GAME_SIZE / Player.PLAYER_SIZE + 1; i++) Arrays.fill(board[i], true); - } gameRunning.set(true); System.out.println("Starting round: " + id); while (gameRunning.get()) { while (!paused.get()) { - delay(GAME_SPEED); - for (Player p : players) { - if (p.isAlive) { - if (p.movePlayer()) { - broadcastLocation(p); - } else { - // Since someone died, check for winning player - checkForWinner(p); - broadcastPlayerList(players); - } - } - } + delay(GAME_TICK_SPEED); + gameTick(); } - delay(500); // don't thrash for pausing + delay(500); // don't thrash when game is paused } System.out.println("Finished round: " + id); } + private void gameTick() { + // Move all living players forward 1 + boolean playerStatusChange = false; + boolean playersMoved = false; + for (Player p : players) { + if (p.isAlive) { + if (p.movePlayer(board)) { + playersMoved = true; + } else { + // Since someone died, check for winning player + checkForWinner(p); + playerStatusChange = true; + } + } + } + + if (playersMoved) + broadcastPlayerLocations(); + if (playerStatusChange) + broadcastPlayerList(); + } + private void delay(long ms) { try { Thread.sleep(ms); @@ -103,13 +112,16 @@ public class GameRound implements Runnable { } } - private void broadcastLocation(Player p) { - String json = p.toJson(); - for (Player player : players) - player.sendTextToClient(json); + private void broadcastPlayerLocations() { + JsonArrayBuilder arr = Json.createArrayBuilder(); + for (Player p : players) + arr.add(p.toJson()); + String playerLocations = Json.createObjectBuilder().add("playerlocs", arr).build().toString(); + for (Player client : players) + client.sendTextToClient(playerLocations); } - private void broadcastPlayerList(Set players) { + private void broadcastPlayerList() { JsonArrayBuilder array = Json.createArrayBuilder(); for (Player p : players) { array.add(Json.createObjectBuilder() @@ -144,7 +156,7 @@ public class GameRound implements Runnable { for (Player p : players) if (STATUS.Connected == p.getStatus()) p.setStatus(STATUS.Alive); - broadcastPlayerList(players); + broadcastPlayerList(); if (!gameRunning.get()) { try { ExecutorService exec = InitialContext.doLookup("java:comp/DefaultManagedExecutorService"); diff --git a/game-service/src/main/java/org/libertybikes/game/core/Player.java b/game-service/src/main/java/org/libertybikes/game/core/Player.java index 97d11c2..0b8d1a6 100644 --- a/game-service/src/main/java/org/libertybikes/game/core/Player.java +++ b/game-service/src/main/java/org/libertybikes/game/core/Player.java @@ -28,24 +28,23 @@ public class Player { } public static final int PLAYER_SIZE = 5; - private final GameRound game; + private Session client; public final String color; public DIRECTION direction = DIRECTION.RIGHT; + private DIRECTION lastDirection = null; public int x; public int y; public String playerName; public boolean isAlive = true; private STATUS playerStatus = STATUS.Connected; - public Player(GameRound g, Session client, String color) { - this.game = g; + public Player(Session client, String color) { this.color = color; this.client = client; } - public Player(GameRound g, Session client, String color, int xstart, int ystart) { - this.game = g; + public Player(Session client, String color, int xstart, int ystart) { this.color = color; this.client = client; x = xstart; @@ -53,8 +52,8 @@ public class Player { } public String toJson() { - // {"shape":"square","color":"#FF0000","coords":{"x":251,"y":89}} - StringBuffer sb = new StringBuffer("{\"shape\":\"square\",\"color\":\""); + // {"color":"#FF0000","coords":{"x":251,"y":89}} + StringBuffer sb = new StringBuffer("{\"color\":\""); sb.append(this.color); sb.append("\",\"coords\":{\"x\":"); sb.append(this.x); @@ -64,22 +63,35 @@ public class Player { return sb.toString(); } - public void setDirection(DIRECTION dir) { - direction = dir; + public void setDirection(DIRECTION newDirection) { + // Make sure the player doesn't move backwards on themselves + if (lastDirection != null) { + if (newDirection == DIRECTION.UP && lastDirection == DIRECTION.DOWN) + return; + else if (newDirection == DIRECTION.DOWN && lastDirection == DIRECTION.UP) + return; + else if (newDirection == DIRECTION.LEFT && lastDirection == DIRECTION.RIGHT) + return; + else if (newDirection == DIRECTION.RIGHT && lastDirection == DIRECTION.LEFT) + return; + } + + direction = newDirection; } public DIRECTION getDrirection() { return direction; } - private boolean checkPosition(int x, int y) { - int realXPosition = x / PLAYER_SIZE; - int realYPosition = y / PLAYER_SIZE; - return game.board[realXPosition][realYPosition]; - } + /** + * Move a player forward one space in whatever direction they are facing currently. + * + * @return True if the player is still alive after moving forward one space. False otherwise. + */ + public boolean movePlayer(boolean[][] board) { + // Consume the space the player was in before the move + board[x / PLAYER_SIZE][y / PLAYER_SIZE] = false; - public boolean movePlayer() { - game.board[x / PLAYER_SIZE][y / PLAYER_SIZE] = false; switch (direction) { case UP: if (y - PLAYER_SIZE >= 0) @@ -98,11 +110,14 @@ public class Player { x -= PLAYER_SIZE; break; } - boolean checkResult = checkPosition(x, y); - if (!checkResult) { + + // Check if the player is now dead after moving + boolean spaceAvailable = board[x / PLAYER_SIZE][y / PLAYER_SIZE]; + if (!spaceAvailable) { setStatus(STATUS.Dead); } - return checkResult; + lastDirection = direction; + return isAlive; } public void sendTextToClient(String message) { diff --git a/game-service/src/main/java/org/libertybikes/game/core/PlayerFactory.java b/game-service/src/main/java/org/libertybikes/game/core/PlayerFactory.java index a8ea3c2..a9990ae 100644 --- a/game-service/src/main/java/org/libertybikes/game/core/PlayerFactory.java +++ b/game-service/src/main/java/org/libertybikes/game/core/PlayerFactory.java @@ -38,7 +38,7 @@ public class PlayerFactory { public static Player initNextPlayer(GameRound g, Session client, String name) { PlayerData data = startingData[g.players.size()]; - Player p = new Player(g, client, data.color, data.x, data.y); + Player p = new Player(client, data.color, data.x, data.y); p.direction = data.dir; p.playerName = name; return p;