diff --git a/core/src/com/emamaker/amazeing/manager/GameManager.java b/core/src/com/emamaker/amazeing/manager/GameManager.java index 43f0cb3..163b73c 100644 --- a/core/src/com/emamaker/amazeing/manager/GameManager.java +++ b/core/src/com/emamaker/amazeing/manager/GameManager.java @@ -38,7 +38,7 @@ public class GameManager { mazeGen = new MazeGenerator(main, MazeSettings.MAZEX, MazeSettings.MAZEZ); } - ArrayList toDelete = new ArrayList(); +// ArrayList toDelete = new ArrayList(); public void generateMaze(Set pl, int todraw[][]) { main.setScreen(null); @@ -48,25 +48,31 @@ public class GameManager { // Only add new players and dispose the old ones // Check if actually there are players to be deleted if (pl != null) { - for (MazePlayer p : players) - if (!pl.contains(p)) - toDelete.add(p); - // Check if new players have to be added - for (MazePlayer p : pl) - if (!players.contains(p)) - players.add(p); - - // Fianlly delete players. A separated step is needed to remove the risk of a - // ConcurrentModificationException - for (MazePlayer p : toDelete) { - p.dispose(); - players.remove(p); - } - toDelete.clear(); +// destroyPlayers(); +// players.addAll(p); + for(MazePlayer p : players) + if(!p.isDisposed()) + p.dispose(); + players.clear(); + players.addAll(pl); +// for (MazePlayer p : players) +// if (!pl.contains(p)) +// toDelete.add(p); +// +// // Check if new players have to be added +// for (MazePlayer p : pl) +// if (!players.contains(p)) +// players.add(p); +// +// // Fianlly delete players. A separated step is needed to remove the risk of a +// // ConcurrentModificationException +// for (MazePlayer p : toDelete) { +// p.dispose(); +// players.remove(p); +// } +// toDelete.clear(); } -// destroyPlayers(); -// players.addAll(p); for (int i = 0; i < MazeSettings.MAZEX; i++) { for (int j = 0; j < 2; j++) { @@ -102,7 +108,7 @@ public class GameManager { main.world.modelBatch.begin(main.world.cam); if (players != null) { for (MazePlayer p : players) { - if (getShowGame()) + if (getShowGame() && !p.isDisposed()) p.render(main.world.modelBatch, main.world.environment); anyoneWon = false; @@ -120,7 +126,7 @@ public class GameManager { System.out.println("Game Finished! " + type); if (type == GameType.LOCAL) { main.setScreen(main.uiManager.playersScreen); - }else if(type == GameType.SERVER) { + } else if (type == GameType.SERVER) { main.uiManager.preGameScreen.setGameType(GameType.SERVER); main.setScreen(main.uiManager.preGameScreen); } @@ -211,6 +217,8 @@ public class GameManager { public void dispose() { for (MazePlayer p : players) - p.dispose(); + if (!p.isDisposed()) + p.dispose(); + players.clear(); } } diff --git a/core/src/com/emamaker/amazeing/manager/network/GameClient.java b/core/src/com/emamaker/amazeing/manager/network/GameClient.java index 559b382..3c7f8a2 100644 --- a/core/src/com/emamaker/amazeing/manager/network/GameClient.java +++ b/core/src/com/emamaker/amazeing/manager/network/GameClient.java @@ -136,9 +136,8 @@ public class GameClient { } public void disconnected(Connection connection) { - for (MazePlayerRemote p : remotePlayers.values()) { - p.dispose(); - } + toRemove.addAll(remotePlayers.keySet()); + toRemove.add(uuid); } }); @@ -168,8 +167,10 @@ public class GameClient { } toAdd.clear(); for (String s : toRemove) { - remotePlayers.get(s).dispose(); - remotePlayers.remove(s); + if (remotePlayers.get(s) != null) { + remotePlayers.get(s).dispose(); + remotePlayers.remove(s); + }else if(s.equals(uuid)) player.dispose(); } toRemove.clear(); } catch (Exception e) { @@ -245,6 +246,20 @@ public class GameClient { public void stop() { if (clientRunning) { + RemovePlayer request = new RemovePlayer(); + request.uuid = uuid; + client.sendTCP(request); + + for (MazePlayer p : remotePlayers.values()) + if (!p.isDisposed()) + p.dispose(); + for (MazePlayer p : players) + if (!p.isDisposed()) + p.dispose(); + + remotePlayers.clear(); + players.clear(); + client.stop(); clientRunning = false; } diff --git a/core/src/com/emamaker/amazeing/manager/network/GameServer.java b/core/src/com/emamaker/amazeing/manager/network/GameServer.java index a96031e..00a716a 100644 --- a/core/src/com/emamaker/amazeing/manager/network/GameServer.java +++ b/core/src/com/emamaker/amazeing/manager/network/GameServer.java @@ -80,6 +80,7 @@ public class GameServer { response.uuid = connection.uuid; System.out.println("Server received connection request! Giving client UUID " + connection.uuid); c.sendTCP(response); + } else if (object instanceof LoginAO2) { // Ignore is there's no uuid or it's different from the login message one if (connection.uuid == null || !connection.uuid.equals(((LoginAO2) object).uuid)) @@ -90,7 +91,7 @@ public class GameServer { // Otherwise add a new player and notify all clients about it remotePlayers.put(((LoginAO2) object).uuid, new MazePlayerRemote(main, ((LoginAO2) object).uuid, false)); - + AddNewPlayer response = new AddNewPlayer(); response.uuid = ((LoginAO2) object).uuid; @@ -112,7 +113,9 @@ public class GameServer { if (connection.uuid == null || !connection.uuid.equals(((RemovePlayer) object).uuid)) return; // Otherwise remove the player and notify all clients about it - remotePlayers.get(((RemovePlayer) object).uuid).dispose(); + if (remotePlayers.get(((RemovePlayer) object).uuid) != null) { + remotePlayers.get(((RemovePlayer) object).uuid).dispose(); + } remotePlayers.remove(((RemovePlayer) object).uuid); System.out.println("Client with UUID " + connection.uuid + " is leaving the server :("); @@ -139,9 +142,10 @@ public class GameServer { public void disconnected(Connection c) { ConnectionPlayer connection = (ConnectionPlayer) c; if (connection.uuid != null) { - remotePlayers.get(connection.uuid).dispose(); + if (remotePlayers.get(connection.uuid) != null) { + remotePlayers.get(connection.uuid).dispose(); + } remotePlayers.remove(connection.uuid); - RemovePlayer remove = new RemovePlayer(); remove.uuid = connection.uuid; server.sendToAllTCP(remove); @@ -191,7 +195,7 @@ public class GameServer { this.gameManager = new GameManager(main, GameType.SERVER); this.gameManager.generateMaze(new HashSet(remotePlayers.values())); endGameCalled = false; - + StartGame request = new StartGame(); request.map = this.gameManager.mazeGen.runLenghtEncode(); server.sendToAllTCP(request); @@ -245,8 +249,11 @@ public class GameServer { public void stop() { for (MazePlayerRemote p : remotePlayers.values()) - p.dispose(); + if (!p.isDisposed()) + p.dispose(); + remotePlayers.clear(); if (serverRunning) { + main.client.stop(); server.stop(); serverRunning = false; } diff --git a/core/src/com/emamaker/amazeing/maze/MazeGenerator.java b/core/src/com/emamaker/amazeing/maze/MazeGenerator.java index d1d0ca1..9e078cd 100755 --- a/core/src/com/emamaker/amazeing/maze/MazeGenerator.java +++ b/core/src/com/emamaker/amazeing/maze/MazeGenerator.java @@ -243,8 +243,8 @@ public class MazeGenerator { 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] == 1) + main.world.worldManager.setCell(i, 1, j, CellId.ID_LEAVES); if (todraw[i][j] == 2) { WINX = i; WINZ = j; diff --git a/core/src/com/emamaker/amazeing/player/MazePlayer.java b/core/src/com/emamaker/amazeing/player/MazePlayer.java index 3361093..d089468 100644 --- a/core/src/com/emamaker/amazeing/player/MazePlayer.java +++ b/core/src/com/emamaker/amazeing/player/MazePlayer.java @@ -15,10 +15,11 @@ import com.badlogic.gdx.graphics.g3d.utils.MeshPartBuilder; import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder; import com.badlogic.gdx.math.Quaternion; import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.utils.Disposable; import com.emamaker.amazeing.AMazeIng; import com.emamaker.voxelengine.physics.GameObject; -public abstract class MazePlayer { +public abstract class MazePlayer implements Disposable { AMazeIng main; @@ -33,6 +34,7 @@ public abstract class MazePlayer { public GameObject obj; String name = ""; boolean disposing = false; + boolean disposed = false; boolean playing = false; boolean show = true; @@ -42,6 +44,7 @@ public abstract class MazePlayer { MazePlayer(Game main_, boolean s) { this(main_, String.valueOf((char) (65 + rand.nextInt(26))), s); disposing = false; + disposed = false; playing = false; } @@ -77,10 +80,11 @@ public abstract class MazePlayer { } public void setTransform(float x, float y, float z, float i, float j, float k, float l) { - if (!disposing ) { + if (!disposing) { pos.set(x, y, z); rot.set(i, j, k, l); - if(show) instance.transform.set(x, y, z, i, j, k, l); + if (show) + instance.transform.set(x, y, z, i, j, k, l); } } @@ -113,10 +117,22 @@ public abstract class MazePlayer { public void update() { } + @Override public void dispose() { - playing =false; + playing = false; + if (!disposed) { + disposing = true; + if (show) + mazePlayerModel.dispose(); + disposing = false; + } + disposed = true; } + public boolean isDisposed() { + return disposed; + } + public boolean isPlaying() { return playing; } diff --git a/core/src/com/emamaker/amazeing/player/MazePlayerLocal.java b/core/src/com/emamaker/amazeing/player/MazePlayerLocal.java index 26f6062..8a8a5c6 100644 --- a/core/src/com/emamaker/amazeing/player/MazePlayerLocal.java +++ b/core/src/com/emamaker/amazeing/player/MazePlayerLocal.java @@ -149,6 +149,7 @@ public class MazePlayerLocal extends MazePlayer { public void update() { inputs(); } + @Override public Vector3 getPos() { if (!disposing) { @@ -178,13 +179,13 @@ public class MazePlayerLocal extends MazePlayer { @Override public void dispose() { + super.dispose(); disposing = true; main.world.dynamicsWorld.removeAction(characterController); main.world.dynamicsWorld.removeCollisionObject(ghostObject); characterController.dispose(); ghostObject.dispose(); ghostShape.dispose(); - mazePlayerModel.dispose(); disposing = false; } diff --git a/core/src/com/emamaker/amazeing/ui/screens/PreGameScreen.java b/core/src/com/emamaker/amazeing/ui/screens/PreGameScreen.java index 01220df..a6cdf44 100644 --- a/core/src/com/emamaker/amazeing/ui/screens/PreGameScreen.java +++ b/core/src/com/emamaker/amazeing/ui/screens/PreGameScreen.java @@ -1,7 +1,5 @@ package com.emamaker.amazeing.ui.screens; -import java.util.Arrays; - import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Screen; import com.badlogic.gdx.graphics.GL20; @@ -27,6 +25,7 @@ public class PreGameScreen implements Screen { Label[] labels; MazePlayer[] players, tmp; + int nPlayers, nPlayersOld; // GameType we are runnig. assuming server for default. If client, the StartGame // button shouldn't appear @@ -44,7 +43,9 @@ public class PreGameScreen implements Screen { labels = new Label[MazeSettings.MAXPLAYERS]; players = new MazePlayer[MazeSettings.MAXPLAYERS]; - tmp = new MazePlayer[MazeSettings.MAXPLAYERS]; +// tmp = new MazePlayer[MazeSettings.MAXPLAYERS]; + nPlayers = 0; + nPlayersOld = 0; stage = new Stage(new ScreenViewport()); Container tableContainer = new Container
(); @@ -62,8 +63,9 @@ public class PreGameScreen implements Screen { TextButton helpBtn = new TextButton("?", uiManager.skin); TextButton playBtn = new TextButton("Start the match!", uiManager.skin); - if(type == GameType.CLIENT) instLab.setText("Waiting for server to start the game..."); - + if (type == GameType.CLIENT) + instLab.setText("Waiting for server to start the game..."); + // Labels to know if players joined for (int i = 0; i < labels.length; i++) { labels[i] = new Label("-- empty slot --", uiManager.skin); @@ -74,7 +76,13 @@ public class PreGameScreen implements Screen { @Override public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { hide(); - uiManager.main.setScreen(type == GameType.SERVER ? uiManager.srvLaunchScreen : uiManager.srvJoinScreen); + if (type == GameType.SERVER) { + uiManager.main.server.stop(); + uiManager.main.setScreen(uiManager.srvLaunchScreen); + } else if (type == GameType.CLIENT) { + uiManager.main.client.stop(); + uiManager.main.setScreen(uiManager.srvJoinScreen); + } return true; } }); @@ -150,18 +158,20 @@ public class PreGameScreen implements Screen { // Constantly update player labels, comparing with the remote players present on // server - tmp = type == GameType.SERVER - ? Arrays.copyOf(uiManager.main.server.remotePlayers.values().toArray(), - uiManager.main.server.remotePlayers.values().size(), MazePlayer[].class) - : Arrays.copyOf(uiManager.main.client.players.toArray(), uiManager.main.client.players.size(), - MazePlayer[].class); - if (!(Arrays.equals(players, tmp))) { + nPlayers = type == GameType.SERVER ? uiManager.main.server.remotePlayers.values().size() + : uiManager.main.client.players.size(); +// tmp = type == GameType.SERVER +// ? Arrays.copyOf(uiManager.main.server.remotePlayers.values().toArray(), +// uiManager.main.server.remotePlayers.values().size(), MazePlayer[].class) +// : Arrays.copyOf(uiManager.main.client.players.toArray(), uiManager.main.client.players.size(), +// MazePlayer[].class); + if (nPlayers != nPlayersOld) { // Update Labels - for (int i = 0; i < tmp.length; i++) { - players[i] = tmp[i]; - labels[i].setText(players[i].getName()); + for (int i = 0; i < labels.length; i++) { + labels[i].setText(i < nPlayers ? "-- Player Ready! --" : "-- empty slot --" ); } } + nPlayersOld = nPlayers; } public void setGameType(GameType t) { diff --git a/core/src/com/emamaker/amazeing/ui/screens/ServerLaunchScreen.java b/core/src/com/emamaker/amazeing/ui/screens/ServerLaunchScreen.java index 5eecd7f..81bb56d 100644 --- a/core/src/com/emamaker/amazeing/ui/screens/ServerLaunchScreen.java +++ b/core/src/com/emamaker/amazeing/ui/screens/ServerLaunchScreen.java @@ -13,7 +13,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextArea; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.viewport.ScreenViewport; -import com.emamaker.amazeing.manager.GameType; import com.emamaker.amazeing.ui.UIManager; public class ServerLaunchScreen implements Screen {