Refining multiplayer: Fixed visualization of current number of players, not using player names. TODO: Multiple players from the same machine

master
EmaMaker 2020-04-25 14:20:31 +02:00
parent 01f38a09cb
commit fb708dfd9c
8 changed files with 111 additions and 55 deletions

View File

@ -38,7 +38,7 @@ public class GameManager {
mazeGen = new MazeGenerator(main, MazeSettings.MAZEX, MazeSettings.MAZEZ);
}
ArrayList<MazePlayer> toDelete = new ArrayList<MazePlayer>();
// ArrayList<MazePlayer> toDelete = new ArrayList<MazePlayer>();
public void generateMaze(Set<MazePlayer> 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();
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<Table> tableContainer = new Container<Table>();
@ -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) {

View File

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