From 5b512c77bbe5483b94a240db050938a558265a50 Mon Sep 17 00:00:00 2001 From: EmaMaker Date: Tue, 21 Apr 2020 18:58:30 +0200 Subject: [PATCH] Server now starts a client locally to play. Fixed run length encoding bug. Fixed issues with map generation, however there seem to be still issues with dimensions --- .../amazeing/manager/GameManager.java | 69 ++++++++-------- .../amazeing/manager/network/GameClient.java | 22 +++-- .../amazeing/manager/network/GameServer.java | 4 + .../emamaker/amazeing/maze/MazeGenerator.java | 82 ++++++++++--------- .../amazeing/player/MazePlayerLocal.java | 17 +++- 5 files changed, 110 insertions(+), 84 deletions(-) diff --git a/core/src/com/emamaker/amazeing/manager/GameManager.java b/core/src/com/emamaker/amazeing/manager/GameManager.java index d221aee..448b6ea 100644 --- a/core/src/com/emamaker/amazeing/manager/GameManager.java +++ b/core/src/com/emamaker/amazeing/manager/GameManager.java @@ -37,41 +37,7 @@ public class GameManager { } boolean anyoneWon = false; - - public void update() { - if (gameStarted) { - main.world.cam.position.set(mazeGen.w / 2, (MazeSettings.MAZEX + MazeSettings.MAZEZ) * 0.45f, - mazeGen.h / 2); - main.world.cam.lookAt(MazeSettings.MAZEX / 2, 0, MazeSettings.MAZEX / 2); - main.world.cam.update(); - if (getShowGame()) - main.world.render(); - - main.world.modelBatch.begin(main.world.cam); - if (players != null) { - for (MazePlayer p : players) { - if (getShowGame()) - p.render(main.world.modelBatch, main.world.environment); - - anyoneWon = false; - if(type != GameType.CLIENT) { - if (checkWin(p)) { - anyoneWon = true; - gameStarted = false; - break; - } - } - } - } - - if (anyoneWon) - main.setScreen(main.uiManager.playersScreen); - main.world.modelBatch.end(); - } - } - ArrayList toDelete = new ArrayList(); - public void generateMaze(Set pl, int todraw[][]) { main.setScreen(null); anyoneWon = false; @@ -110,6 +76,7 @@ public class GameManager { mazeGen.setMazeSize(MazeSettings.MAZEX, MazeSettings.MAZEZ); mazeGen.generateMaze(); + mazeGen.runLenghtEncode(); if (type != GameType.CLIENT) { spreadPlayers(); @@ -119,9 +86,41 @@ public class GameManager { if (todraw != null && showGame == true) { mazeGen.show(todraw); } - } + public void update() { + if (gameStarted) { + main.world.cam.position.set(mazeGen.w / 2, (MazeSettings.MAZEX + MazeSettings.MAZEZ) * 0.45f, + mazeGen.h / 2); + main.world.cam.lookAt(MazeSettings.MAZEX / 2, 0, MazeSettings.MAZEX / 2); + main.world.cam.update(); + if (getShowGame()) + main.world.render(); + + main.world.modelBatch.begin(main.world.cam); + if (players != null) { + for (MazePlayer p : players) { + if (getShowGame()) + p.render(main.world.modelBatch, main.world.environment); + + anyoneWon = false; + if(type != GameType.CLIENT) { + if (checkWin(p)) { + anyoneWon = true; + gameStarted = false; + break; + } + } + } + } + + if (anyoneWon) + main.setScreen(main.uiManager.playersScreen); + main.world.modelBatch.end(); + } + } + + public void spreadPlayers() { for (MazePlayer p : players) { int x = 1, z = 1; diff --git a/core/src/com/emamaker/amazeing/manager/network/GameClient.java b/core/src/com/emamaker/amazeing/manager/network/GameClient.java index 10d2a7e..35af636 100644 --- a/core/src/com/emamaker/amazeing/manager/network/GameClient.java +++ b/core/src/com/emamaker/amazeing/manager/network/GameClient.java @@ -42,7 +42,7 @@ public class GameClient { Hashtable remotePlayers = new Hashtable<>(); // Hashtable localPlayers = new Hashtable<>(); MazePlayerLocal player; - + ArrayList players = new ArrayList(); volatile HashSet toAdd = new HashSet<>(); @@ -97,10 +97,10 @@ public class GameClient { } else if (object instanceof NetworkCommon.UpdatePlayerTransformServer) { NetworkCommon.UpdatePlayerTransformServer s = (NetworkCommon.UpdatePlayerTransformServer) object; System.out.println("Received a forced position update for self!"); - if(s.uuid.equals(uuid)) { + if (s.uuid.equals(uuid)) { player.setPlaying(); player.setTransform(s.tx, s.ty, s.tz, s.rx, s.ry, s.rz, s.rw); - }else { + } else { remotePlayers.get(s.uuid).setPlaying(); remotePlayers.get(s.uuid).setTransform(s.tx, s.ty, s.tz, s.rx, s.ry, s.rz, s.rw); } @@ -108,7 +108,8 @@ public class GameClient { UpdatePlayerTransform msg = (UpdatePlayerTransform) object; if (!msg.uuid.equals(uuid)) { remotePlayers.get(msg.uuid).setPlaying(); - remotePlayers.get(msg.uuid).setTransform(msg.tx, msg.ty, msg.tz, msg.rx, msg.ry, msg.rz, msg.rw); + remotePlayers.get(msg.uuid).setTransform(msg.tx, msg.ty, msg.tz, msg.rx, msg.ry, msg.rz, + msg.rw); System.out.println("R: " + msg.tx + ", " + msg.ty + ", " + msg.tz); System.out.println("Updating remote player with uuid " + msg.uuid.toString()); } @@ -174,11 +175,14 @@ public class GameClient { // players.add(p); players.add(player); - - main.getScreen().hide(); - main.setScreen(null); - for(MazePlayer p : players) p.setPlaying(); + if (main.getScreen() != null) { + main.getScreen().hide(); + main.setScreen(null); + } + + for (MazePlayer p : players) + p.setPlaying(); System.out.println(Arrays.toString(players.toArray())); gameManager.generateMaze(new HashSet(players)); @@ -186,7 +190,7 @@ public class GameClient { } if (!map.equals("")) { System.out.println("Setting map"); - gameManager.mazeGen.runLenghtDecode(map); + gameManager.mazeGen.show(gameManager.mazeGen.runLenghtDecode(map)); map = ""; } if (gameManager != null) diff --git a/core/src/com/emamaker/amazeing/manager/network/GameServer.java b/core/src/com/emamaker/amazeing/manager/network/GameServer.java index e6c73a8..7bf1be7 100644 --- a/core/src/com/emamaker/amazeing/manager/network/GameServer.java +++ b/core/src/com/emamaker/amazeing/manager/network/GameServer.java @@ -139,6 +139,10 @@ public class GameServer { server.bind(port); server.start(); System.out.println("Server registered and running on port " + port); + + //Also launch the client to have a player play on host + main.client.start("localhost", port); + System.out.println("Local client ready to play!"); } catch (IOException e) { e.printStackTrace(); } diff --git a/core/src/com/emamaker/amazeing/maze/MazeGenerator.java b/core/src/com/emamaker/amazeing/maze/MazeGenerator.java index 761a094..ba9102e 100755 --- a/core/src/com/emamaker/amazeing/maze/MazeGenerator.java +++ b/core/src/com/emamaker/amazeing/maze/MazeGenerator.java @@ -31,10 +31,10 @@ public class MazeGenerator { } public void setMazeSize(int w_, int h_) { - w = w_; - h = h_; - W = (w - 1) / 2; - H = (h - 1) / 2; + w = w_ - 1; + h = h_ - 1; + W = w / 2; + H = h / 2; cellsGrid = new Cell[W][H]; todraw = new int[w][h]; @@ -135,65 +135,70 @@ public class MazeGenerator { * placed. We'll normally use a number for the count of equal blocks next to * each other We'll use letters instead for the todraw[][] numbers to represent * the different block, starting from A (Ascii 65) and adding the todraw[x][y] - * index to the ascii value of A. - * To even simplify decoding, the count number is encoded in a letter too, starting from - * a (Ascii 97), so that every count takes up just to characters. + * index to the ascii value of A. To even simplify decoding, the count number is + * encoded in a letter too, starting from a (Ascii 97), so that every count + * takes up just to characters. * */ public String runLenghtEncode() { // todraw[x][y], where row number is x and the index of the block in that row is // y - int currentBlock = 0; int count = 0; String s = ""; for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { - if(todraw[i][j] != currentBlock || j == h-1) { - s+=String.valueOf((char)(97+count))+String.valueOf((char)(65+currentBlock)); - count = 1; - currentBlock = todraw[i][j]; - }else { + // https://www.geeksforgeeks.org/run-length-encoding/ + count = 1; + while (j < h - 1 && todraw[i][j] == todraw[i][j + 1]) { count++; + j++; } + s += String.valueOf((char)(count + 97)); + s += String.valueOf((char)(todraw[i][j] + 65)); +// System.out.println("Got block " + todraw[i][j] + " for " + count + "times"); } - +// System.out.println("Going next column"); s += "-"; } - + System.out.println(s); return s; } /* - * Run length decodes the maze received from the server. - * We know that the block types start from A (Ascii 65), so we can simply subtract 65 - * We know that the block count start from a (Ascii 97), so we can simply subtract 97 - * from the current index and get the block type, repeated for how many times the count number says + * Run length decodes the maze received from the server. We know that the block + * types start from A (Ascii 65), so we can simply subtract 65 We know that the + * block count start from a (Ascii 97), so we can simply subtract 97 from the + * current index and get the block type, repeated for how many times the count + * number says */ public int[][] runLenghtDecode(String s) { int[][] todraw_ = null; - int count, type, totalcount = 0; - - //Split the various rows + int count, type, totalcount = 0, width = 0; + + // Split the various rows String[] rows = s.split("-"); System.out.println(Arrays.deepToString(rows)); - //Mazes are always squares - setMazeSize(rows.length, rows.length); - //Temporarely patch to the calculation errors in setMazeSize - todraw_=new int[rows.length][rows.length]; - - for(int i = 0; i < rows.length; i++) { + + count = ((int) (rows[0].charAt(0))) - 97; + width += count; + + // Mazes are always squares + setMazeSize(width + 1, rows.length + 1); + // Temporarely patch to the calculation errors in setMazeSize + todraw_ = new int[w][h]; + + for (int i = 0; i < width; i++) { totalcount = 0; - for(int j = 0; j < rows[i].length(); j+=2) { + for (int j = 0; j < rows[i].length(); j += 2) { count = ((int) (rows[i].charAt(j))) - 97; - type = ((int) (rows[i].charAt(j+1))) - 65; - - for(int k = totalcount; k < totalcount+count; k++) { + type = ((int) (rows[i].charAt(j + 1))) - 65; + + for (int k = totalcount; k < totalcount + count; k++) { todraw_[i][k] = type; } totalcount += count; } } - show(todraw_); return todraw_; } @@ -231,15 +236,15 @@ public class MazeGenerator { show(todraw); } - + public void show(int[][] todraw_) { for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { todraw[i][j] = todraw_[i][j]; main.world.worldManager.setCell(i, 1, j, CellId.ID_AIR); - + main.world.worldManager.setCell(i, 0, j, CellId.ID_GRASS); - + if (todraw[i][j] == 1) main.world.worldManager.setCell(i, 1, j, CellId.ID_LEAVES); if (todraw[i][j] == 2) @@ -259,7 +264,10 @@ public class MazeGenerator { } int cellAt(int x, int y) { - return todraw[x][y]; + if (x < w && y < h) + return todraw[x][y]; + else + return 1; } public boolean occupiedSpot(int x, int y) { diff --git a/core/src/com/emamaker/amazeing/player/MazePlayerLocal.java b/core/src/com/emamaker/amazeing/player/MazePlayerLocal.java index ee0467b..2a0a4a5 100644 --- a/core/src/com/emamaker/amazeing/player/MazePlayerLocal.java +++ b/core/src/com/emamaker/amazeing/player/MazePlayerLocal.java @@ -102,14 +102,19 @@ public class MazePlayerLocal extends MazePlayer { ((btDiscreteDynamicsWorld) (main.world.dynamicsWorld)).addAction(characterController); } + boolean pressed = false; + public void inputs() { + pressed = false; // If the left or right key is pressed, rotate the character and update its // physics update accordingly. if (Gdx.input.isKeyPressed(ksx)) { + pressed = true; characterTransform.rotate(0, 1, 0, 2.5f); ghostObject.setWorldTransform(characterTransform); } if (Gdx.input.isKeyPressed(kdx)) { + pressed = true; characterTransform.rotate(0, 1, 0, -2.5f); ghostObject.setWorldTransform(characterTransform); } @@ -118,10 +123,14 @@ public class MazePlayerLocal extends MazePlayer { // Set the walking direction accordingly (either forward or backward) walkDirection.set(0, 0, 0); - if (Gdx.input.isKeyPressed(kup)) + if (Gdx.input.isKeyPressed(kup)) { + pressed = true; walkDirection.add(characterDirection); - if (Gdx.input.isKeyPressed(kdown)) + } + if (Gdx.input.isKeyPressed(kdown)) { + pressed = false; walkDirection.add(-characterDirection.x, -characterDirection.y, -characterDirection.z); + } walkDirection.scl(3f * Gdx.graphics.getDeltaTime()); // And update the character controller characterController.setWalkDirection(walkDirection); @@ -129,12 +138,14 @@ public class MazePlayerLocal extends MazePlayer { // And fetch the new transformation of the character (this will make the model // be rendered correctly) ghostObject.getWorldTransform(characterTransform); + + if (pressed) + main.client.updateLocalPlayer(this); } @Override public void update() { inputs(); - main.client.updateLocalPlayer(this); } @Override