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

master
EmaMaker 2020-04-21 18:58:30 +02:00
parent 40bdc9a594
commit 5b512c77bb
5 changed files with 110 additions and 84 deletions

View File

@ -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<MazePlayer> toDelete = new ArrayList<MazePlayer>();
public void generateMaze(Set<MazePlayer> 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;

View File

@ -42,7 +42,7 @@ public class GameClient {
Hashtable<String, MazePlayerRemote> remotePlayers = new Hashtable<>();
// Hashtable<String, MazePlayerLocal> localPlayers = new Hashtable<>();
MazePlayerLocal player;
ArrayList<MazePlayer> players = new ArrayList<MazePlayer>();
volatile HashSet<String> 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<MazePlayer>(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)

View File

@ -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();
}

View File

@ -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) {

View File

@ -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