Multiplayer: multiple players can join a server from the same machine now

master
EmaMaker 2020-04-27 23:14:48 +02:00
parent b43a438f07
commit ecea59c095
12 changed files with 280 additions and 223 deletions

View File

@ -29,9 +29,13 @@ public class AMazeIng extends Game {
/* Local manager for local games and server host in multiplayer games */
public GameServer server;
public GameClient client;
static AMazeIng game;
@Override
public void create() {
game = this;
// Bullet init for physics
Bullet.init();
@ -99,5 +103,9 @@ public class AMazeIng extends Game {
public void resume() {
world.resume();
}
public static AMazeIng getMain() {
return game;
}
}

View File

@ -44,7 +44,6 @@ public class GameManager {
main.setScreen(null);
anyoneWon = false;
gameStarted = true;
// Only add new players and dispose the old ones
// Check if actually there are players to be deleted
if (pl != null) {
@ -94,6 +93,8 @@ public class GameManager {
if (todraw != null && showGame == true) {
mazeGen.show(todraw);
}
gameStarted = true;
}
public void update() {

View File

@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.math.Quaternion;
import com.badlogic.gdx.math.Vector3;
@ -13,6 +14,7 @@ import com.emamaker.amazeing.manager.GameManager;
import com.emamaker.amazeing.manager.GameType;
import com.emamaker.amazeing.manager.network.NetworkCommon.AddNewPlayer;
import com.emamaker.amazeing.manager.network.NetworkCommon.EndGame;
import com.emamaker.amazeing.manager.network.NetworkCommon.JustConnected;
import com.emamaker.amazeing.manager.network.NetworkCommon.LoginAO;
import com.emamaker.amazeing.manager.network.NetworkCommon.LoginAO2;
import com.emamaker.amazeing.manager.network.NetworkCommon.RemovePlayer;
@ -22,6 +24,7 @@ import com.emamaker.amazeing.manager.network.NetworkCommon.UpdatePlayerTransform
import com.emamaker.amazeing.player.MazePlayer;
import com.emamaker.amazeing.player.MazePlayerLocal;
import com.emamaker.amazeing.player.MazePlayerRemote;
import com.emamaker.amazeing.player.PlayerUtils;
import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
@ -38,20 +41,15 @@ public class GameClient {
boolean showPreGame = false;
String map = "";
// Hashtable of remote players present in the match. This will be used to update
// other players' transform when server reports about it
Hashtable<String, MazePlayerRemote> remotePlayers = new Hashtable<>();
// Hashtable<String, MazePlayerLocal> localPlayers = new Hashtable<>();
MazePlayerLocal player;
public ArrayList<MazePlayer> players = new ArrayList<MazePlayer>();
// Hashtable of players present in the match
public Hashtable<String, MazePlayer> players = new Hashtable<>();
ArrayList<MazePlayer> localPlrQueue = new ArrayList<MazePlayer>();
volatile HashSet<String> toAdd = new HashSet<>();
volatile HashSet<String> toRemove = new HashSet<>();
public GameManager gameManager;
Client client;
// UUID is represented using a string, for kryonet ease of use
String uuid = "";
public GameClient(AMazeIng main_) {
main = main_;
@ -65,9 +63,6 @@ public class GameClient {
startGame = false;
client = new Client();
client.start();
uuid = "";
player = new MazePlayerLocal(main, Keys.W, Keys.S, Keys.A, Keys.D);
remotePlayers.clear();
NetworkCommon.register(client);
@ -77,9 +72,11 @@ public class GameClient {
public void received(Connection connection, Object object) {
if (object instanceof LoginAO2) {
uuid = ((LoginAO2) object).uuid;
localPlrQueue.get(0).uuid = ((LoginAO2) object).uuid;
toAdd.add("Local" + localPlrQueue.get(0).uuid);
client.sendTCP(object);
System.out.println("Received UUID " + uuid.toString() + " from server, giving confirmation!");
System.out.println("Received UUID " + localPlrQueue.get(0).uuid + " for player " + localPlrQueue.get(0) + " giving confirmation");
// When we receive the connection accept from the server, we can show the
// pre-game screen listing the players' names, setting this flag to let the main
@ -87,36 +84,30 @@ public class GameClient {
showPreGame = true;
} else if (object instanceof AddNewPlayer) {
AddNewPlayer msg = (AddNewPlayer) object;
if ((!msg.uuid.equals(uuid))) {
toAdd.add(msg.uuid);
System.out
.println("Remote player with uuid " + msg.uuid.toString() + " has joined the game :)");
if (!players.containsKey(msg.uuid) && !toAdd.contains("Local"+msg.uuid)) {
toAdd.add("Remote" + msg.uuid);
System.out.println("Remote player with uuid " + msg.uuid.toString() + " has joined the game :)");
}
} else if (object instanceof RemovePlayer) {
RemovePlayer msg = (RemovePlayer) object;
if ((!msg.uuid.equals(uuid))) {
if (players.containsKey(msg.uuid)) {
toRemove.add(msg.uuid);
System.out
.println("Remote player with uuid " + msg.uuid.toString() + " is leaving the game :(");
System.out.println("Player with uuid " + msg.uuid.toString() + " is leaving the game :(");
}else {
System.out.println("Player remove received, but I don't know that player :/");
}
} 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)) {
player.setPlaying();
player.setTransform(s.tx, s.ty, s.tz, s.rx, s.ry, s.rz, s.rw);
} 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);
if (players.containsKey(s.uuid)) {
players.get(s.uuid).setPlaying();
players.get(s.uuid).setTransform(s.tx, s.ty, s.tz, s.rx, s.ry, s.rz, s.rw);
}
} else if (object instanceof UpdatePlayerTransform) {
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);
// System.out.println("R: " + msg.tx + ", " + msg.ty + ", " + msg.tz);
// System.out.println("Updating remote player with uuid " + msg.uuid.toString());
if (players.containsKey(msg.uuid) && players.get(msg.uuid) instanceof MazePlayerRemote) {
players.get(msg.uuid).setPlaying();
players.get(msg.uuid).setTransform(msg.tx, msg.ty, msg.tz, msg.rx, msg.ry, msg.rz, msg.rw);
}
} else if (object instanceof UpdateMap) {
map = ((UpdateMap) object).map;
@ -136,23 +127,21 @@ public class GameClient {
}
public void disconnected(Connection connection) {
toRemove.addAll(remotePlayers.keySet());
toRemove.add(uuid);
toRemove.addAll(players.keySet());
}
});
try {
client.connect(5000, addr, port);
if (uuid.equals("")) {
client.sendTCP(new LoginAO());
System.out.println("Connecting to server...");
} else {
System.out.println("Already connected, to need to connect again");
}
System.out.println("Connecting to server...");
//Tell the server you just connected, but still no players have to be add
client.sendTCP(new JustConnected());
return true;
// Server communication after connection can go here, or in
// Listener#connected().
} catch (IOException ex) {
} catch (
IOException ex) {
ex.printStackTrace();
}
return false;
@ -160,35 +149,37 @@ public class GameClient {
// Update must be called from Main thread and used for applications on main
// thread
MazePlayerLocal p;
public void update() {
if (clientRunning) {
try {
for (String s : toAdd) {
if (!s.equals(uuid))
remotePlayers.put(s, new MazePlayerRemote(main, s));
if (!(players.containsKey(s.replace("Local", "")) || players.containsKey(s.replace("Remote", "")))) {
if (s.startsWith("Local")) {
// System.out.println(s + " | " + s.replace("Local", "") + " | " + localPlrQueue.get(0).uuid);
if (localPlrQueue.get(0) != null) {
players.put(s.replace("Local", ""), localPlrQueue.get(0));
System.out.println("Added local player " + localPlrQueue.get(0));
localPlrQueue.remove(0);
}
} else if (s.startsWith("Remote")) {
players.put(s.replace("Remote", ""), new MazePlayerRemote(s.replace("Remote", "")));
}
}
}
toAdd.clear();
for (String s : toRemove) {
if (remotePlayers.get(s) != null) {
remotePlayers.get(s).dispose();
remotePlayers.remove(s);
}else if(s.equals(uuid)) player.dispose();
if (players.containsKey(s)) {
players.get(s).dispose();
players.remove(s);
}
}
toRemove.clear();
} catch (Exception e) {
}
for (MazePlayerRemote p : remotePlayers.values())
if (!players.contains(p))
players.add(p);
// for (MazePlayerLocal p : localPlayers.values())
// if (!players.contains(p))
// players.add(p);
if (!players.contains(player))
players.add(player);
if (showPreGame) {
// We are taking care of specifying what type of game we are running. Server is
// the server is running in the same instance, client if not
@ -196,7 +187,6 @@ public class GameClient {
if (!main.server.isRunning())
main.uiManager.preGameScreen.setGameType(GameType.CLIENT);
main.setScreen(main.uiManager.preGameScreen);
System.out.println("Game ended!");
showPreGame = false;
}
@ -208,19 +198,56 @@ public class GameClient {
main.setScreen(null);
}
for (MazePlayer p : players)
for (MazePlayer p : players.values())
p.setPlaying();
gameManager.generateMaze(new HashSet<MazePlayer>(players));
gameManager.generateMaze(new HashSet<MazePlayer>(players.values()));
startGame = false;
}
if (!map.equals("")) {
System.out.println("Setting map");
gameManager.mazeGen.show(gameManager.mazeGen.runLenghtDecode(map));
map = "";
}
if (gameManager != null)
if (gameManager != null) {
gameManager.update();
if (gameManager.gameStarted) {
if (!map.equals("")) {
System.out.println("Setting map");
gameManager.mazeGen.show(gameManager.mazeGen.runLenghtDecode(map));
map = "";
}
}
}
if (gameManager == null || (gameManager != null && !gameManager.gameStarted)) {
// Consantly search for new players to be added
// First search for keyboard players (WASD and ARROWS)
if (Gdx.input.isKeyJustPressed(Keys.W) || Gdx.input.isKeyJustPressed(Keys.A)
|| Gdx.input.isKeyJustPressed(Keys.S) || Gdx.input.isKeyJustPressed(Keys.D)) {
p = PlayerUtils.getPlayerWithKeys(new HashSet<>(players.values()), Keys.W, Keys.S, Keys.A, Keys.D);
if (p != null) {
RemovePlayer msg = new RemovePlayer();
msg.uuid = p.uuid;
client.sendTCP(msg);
System.out.println("I should be deleting local player with uuid " + p.uuid);
} else {
localPlrQueue.add(new MazePlayerLocal(Keys.W, Keys.S, Keys.A, Keys.D));
client.sendTCP(new LoginAO());
}
}
if (Gdx.input.isKeyJustPressed(Keys.UP) || Gdx.input.isKeyJustPressed(Keys.LEFT)
|| Gdx.input.isKeyJustPressed(Keys.DOWN) || Gdx.input.isKeyJustPressed(Keys.RIGHT)) {
p = PlayerUtils.getPlayerWithKeys(new HashSet<>(players.values()), Keys.UP, Keys.DOWN, Keys.LEFT,
Keys.RIGHT);
if (p != null) {
RemovePlayer msg = new RemovePlayer();
msg.uuid = p.uuid;
client.sendTCP(msg);
} else {
localPlrQueue.add(new MazePlayerLocal(Keys.UP, Keys.DOWN, Keys.LEFT, Keys.RIGHT));
client.sendTCP(new LoginAO());
}
}
}
}
}
@ -236,7 +263,7 @@ public class GameClient {
pu.ry = rot.y;
pu.rz = rot.z;
pu.rw = rot.w;
pu.uuid = uuid;
pu.uuid = p.uuid;
client.sendTCP(pu);
}
@ -248,18 +275,16 @@ public class GameClient {
public void stop() {
if (clientRunning) {
RemovePlayer request = new RemovePlayer();
request.uuid = uuid;
client.sendTCP(request);
for (String s : players.keySet()) {
if (players.get(s) instanceof MazePlayerLocal) {
RemovePlayer request = new RemovePlayer();
request.uuid = s;
client.sendTCP(request);
}
for (MazePlayer p : remotePlayers.values())
if (!p.isDisposed())
p.dispose();
for (MazePlayer p : players)
if (!p.isDisposed())
p.dispose();
players.get(s).dispose();
}
remotePlayers.clear();
players.clear();
client.stop();

View File

@ -13,6 +13,7 @@ import com.emamaker.amazeing.manager.GameType;
import com.emamaker.amazeing.manager.network.NetworkCommon.AddNewPlayer;
import com.emamaker.amazeing.manager.network.NetworkCommon.ConnectionRefused;
import com.emamaker.amazeing.manager.network.NetworkCommon.EndGame;
import com.emamaker.amazeing.manager.network.NetworkCommon.JustConnected;
import com.emamaker.amazeing.manager.network.NetworkCommon.LoginAO;
import com.emamaker.amazeing.manager.network.NetworkCommon.LoginAO2;
import com.emamaker.amazeing.manager.network.NetworkCommon.RemovePlayer;
@ -46,13 +47,21 @@ public class GameServer {
uuid = UUID.randomUUID();
}
//Returns true if the server started successfully
// Returns true if the server started successfully
public boolean startServer(int port_) {
port = port_;
serverRunning = true;
try {
server = new Server() {
protected Connection newConnection() {
// Notify connection about previously connected clients
AddNewPlayer response = new AddNewPlayer();
for (String s : remotePlayers.keySet()) {
response.uuid = s;
server.sendToAllTCP(response);
}
// By providing our own connection implementation, we can store per
// connection state without a connection ID to state look up.
return new ConnectionPlayer();
@ -67,11 +76,16 @@ public class GameServer {
public void received(Connection c, Object object) {
ConnectionPlayer connection = (ConnectionPlayer) c;
if (object instanceof LoginAO) {
// Ignore this if player already is in the list
if (connection.uuid != null)
return;
if(object instanceof JustConnected) {
//Notify the newly connected client about all other clients already present here
System.out.println("New client just connected, updating it with info about other clients!");
AddNewPlayer response = new AddNewPlayer();
for (String s : remotePlayers.keySet()) {
response.uuid = s;
c.sendTCP(response);
System.out.println("Updated about: " + s);
}
}else if (object instanceof LoginAO) {
// Give player its UUID and wait for response. Once the LoginAO2 response is
// received, move the
// UUID to the list of players, create a new one and notify clients about it
@ -84,51 +98,35 @@ public class GameServer {
} 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))
return;
// If there's still space left for players to join
if (remotePlayers.values().size() < MazeSettings.MAXPLAYERS) {
// 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;
new MazePlayerRemote(((LoginAO2) object).uuid, false));
System.out.println(
"Client with UUID " + response.uuid + " is connected and ready to play :)");
"Client with UUID " + ((LoginAO2) object).uuid + " is connected and ready to play :)");
AddNewPlayer response = new AddNewPlayer();
response.uuid = ((LoginAO2) object).uuid;
server.sendToAllTCP(response);
for (String s : remotePlayers.keySet()) {
response.uuid = s;
c.sendTCP(response);
}
} else {
// Send connection refused
c.sendTCP(new ConnectionRefused());
}
} else if (object instanceof RemovePlayer) {
// Ignore is there's no uuid or it's different from the login message one
if (connection.uuid == null || !connection.uuid.equals(((RemovePlayer) object).uuid))
return;
// Otherwise remove the player and notify all clients about it
if (remotePlayers.get(((RemovePlayer) object).uuid) != null) {
if (remotePlayers.containsKey(((RemovePlayer) object).uuid.toString())) {
remotePlayers.get(((RemovePlayer) object).uuid).dispose();
remotePlayers.remove(((RemovePlayer) object).uuid);
System.out.println("Client with UUID " + connection.uuid + " is leaving the server :(");
server.sendToAllTCP(object);
}else {
System.out.println("Server received delete message for player with UUID " + connection.uuid + " but player wasn't playing");
}
remotePlayers.remove(((RemovePlayer) object).uuid);
System.out.println("Client with UUID " + connection.uuid + " is leaving the server :(");
server.sendToAllTCP(object);
} else if (object instanceof UpdatePlayerTransform) {
UpdatePlayerTransform transform = (UpdatePlayerTransform) object;
// Ignore is there's no uuid or it's different from the login message one
if (connection.uuid == null || !connection.uuid.equals(transform.uuid))
return;
if (gameManager.gameStarted) {
// Otherwise Update the transport and notify clients about it
MazePlayerRemote player = remotePlayers.get((transform.uuid));
@ -158,14 +156,15 @@ public class GameServer {
server.start();
System.out.println("Server registered and running on port " + port);
// Also launch the client to have a player play on host. We return the result of starting, so server doesn't start if local client has problems
// Also launch the client to have a player play on host. We return the result of
// starting, so server doesn't start if local client has problems
if (main.client.start("localhost", port))
return true;
return true;
else {
server.stop();
return false;
}
} catch (IOException e) {
e.printStackTrace();
}

View File

@ -9,6 +9,7 @@ public class NetworkCommon {
// This registers objects that are going to be sent over the network.
static public void register(EndPoint endPoint) {
Kryo kryo = endPoint.getKryo();
kryo.register(JustConnected.class);
kryo.register(LoginAO.class);
kryo.register(LoginAO2.class);
kryo.register(ConnectionRefused.class);
@ -23,6 +24,8 @@ public class NetworkCommon {
}
//Login stuff
static public class JustConnected {
}
static public class LoginAO {
}
static public class LoginAO2 {

View File

@ -19,7 +19,7 @@ public class MazeGenerator {
public int w, h, W, H;
public int EP_DIST = 5;
public int WINX, WINZ;
public int WINX = Integer.MAX_VALUE, WINZ = Integer.MAX_VALUE;
public MazeGenerator(AMazeIng game) {
this(game, 20, 20);
@ -153,9 +153,7 @@ public class MazeGenerator {
}
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);
@ -175,7 +173,6 @@ public class MazeGenerator {
// Split the various rows
String[] rows = s.split("-");
System.out.println(Arrays.deepToString(rows));
count = ((int) (rows[0].charAt(0))) - 97;
width += count;

View File

@ -2,7 +2,6 @@ package com.emamaker.amazeing.player;
import java.util.Random;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.g3d.Environment;
@ -37,19 +36,20 @@ public abstract class MazePlayer implements Disposable {
boolean disposed = false;
boolean playing = false;
boolean show = true;
public String uuid;
Vector3 pos = new Vector3();
Quaternion rot = new Quaternion();
MazePlayer(Game main_, boolean s) {
this(main_, String.valueOf((char) (65 + rand.nextInt(26))), s);
MazePlayer(boolean s) {
this(String.valueOf((char) (65 + rand.nextInt(26))), s);
disposing = false;
disposed = false;
playing = false;
}
MazePlayer(Game main_, String name, boolean s) {
main = (AMazeIng) main_;
MazePlayer(String name, boolean s) {
main = AMazeIng.getMain();
show = s;
setName(name);
if (show)
@ -80,7 +80,7 @@ public abstract class MazePlayer implements Disposable {
}
public void setTransform(float x, float y, float z, float i, float j, float k, float l) {
if (!disposing) {
if (!disposing && !disposed) {
pos.set(x, y, z);
rot.set(i, j, k, l);
if (show)
@ -97,7 +97,7 @@ public abstract class MazePlayer implements Disposable {
}
public void render(ModelBatch b, Environment e) {
if (!disposing && playing) {
if (!disposing && ! disposed && playing) {
update();
if (show)
b.render(instance, e);

View File

@ -1,6 +1,5 @@
package com.emamaker.amazeing.player;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.controllers.Controller;
import com.badlogic.gdx.math.Matrix4;
@ -32,21 +31,26 @@ public class MazePlayerLocal extends MazePlayer {
public int kup, kdown, ksx, kdx;
float startx, starty, startz;
public MazePlayerLocal(Game main_, int up_, int down_, int sx_, int dx_) {
this(main_, up_, down_, sx_, dx_, 0, 0, 0);
// Give keys in up, down, left, right order
public MazePlayerLocal(int... keys) {
this(keys[0], keys[1], keys[2], keys[3]);
}
public MazePlayerLocal(Game main_, int up_, int down_, int sx_, int dx_, String name) {
this(main_, up_, down_, sx_, dx_, 0, 0, 0, name);
public MazePlayerLocal(int up_, int down_, int sx_, int dx_) {
this(up_, down_, sx_, dx_, 0, 0, 0);
}
public MazePlayerLocal(Game main_, int up_, int down_, int sx_, int dx_, float startx, float starty, float startz) {
this(main_, up_, down_, sx_, dx_, startx, starty, startz, String.valueOf((char) (65 + rand.nextInt(26))));
public MazePlayerLocal(int up_, int down_, int sx_, int dx_, String name) {
this(up_, down_, sx_, dx_, 0, 0, 0, name);
}
public MazePlayerLocal(Game main_, int up_, int down_, int sx_, int dx_, float startx, float starty, float startz,
public MazePlayerLocal(int up_, int down_, int sx_, int dx_, float startx, float starty, float startz) {
this(up_, down_, sx_, dx_, startx, starty, startz, String.valueOf((char) (65 + rand.nextInt(26))));
}
public MazePlayerLocal(int up_, int down_, int sx_, int dx_, float startx, float starty, float startz,
String name) {
super(main_, name, true);
super(name, true);
this.kup = up_;
this.kdown = down_;
this.ksx = sx_;
@ -59,20 +63,20 @@ public class MazePlayerLocal extends MazePlayer {
initPhysics();
}
public MazePlayerLocal(Game main_, Controller ctrl_) {
this(main_, ctrl_, 0, 0, 0);
public MazePlayerLocal(Controller ctrl_) {
this(ctrl_, 0, 0, 0);
}
public MazePlayerLocal(Game main_, Controller ctrl_, String name) {
this(main_, ctrl_, 0, 0, 0, name);
public MazePlayerLocal(Controller ctrl_, String name) {
this(ctrl_, 0, 0, 0, name);
}
public MazePlayerLocal(Game main_, Controller crtl_, float startx, float starty, float startz) {
this(main_, crtl_, startx, starty, startz, String.valueOf((char) (65 + rand.nextInt(26))));
public MazePlayerLocal(Controller crtl_, float startx, float starty, float startz) {
this(crtl_, startx, starty, startz, String.valueOf((char) (65 + rand.nextInt(26))));
}
public MazePlayerLocal(Game main_, Controller ctrl_, float startx, float starty, float startz, String name) {
super(main_, true);
public MazePlayerLocal(Controller ctrl_, float startx, float starty, float startz, String name) {
super(true);
this.ctrl = ctrl_;
this.startx = startx;
@ -139,10 +143,8 @@ public class MazePlayerLocal extends MazePlayer {
// be rendered correctly)
ghostObject.getWorldTransform(characterTransform);
if (pressed) {
System.out.println("Player in: " + getPos());
if (pressed)
main.client.updateLocalPlayer(this);
}
}
@Override

View File

@ -2,7 +2,6 @@ package com.emamaker.amazeing.player;
import java.util.Random;
import com.badlogic.gdx.Game;
import com.emamaker.amazeing.AMazeIng;
public class MazePlayerRemote extends MazePlayer{
@ -13,16 +12,15 @@ public class MazePlayerRemote extends MazePlayer{
AMazeIng main;
//UUID is stored a string, for kryonet ease of use
public String uuid;
boolean disposing = false;
public MazePlayerRemote(Game main_, String u) {
this(main_, u, true);
public MazePlayerRemote(String u) {
this(u, true);
}
public MazePlayerRemote(Game main_, String u, boolean b) {
super(main_, b);
public MazePlayerRemote( String u, boolean b) {
super(b);
uuid = u;
}

View File

@ -0,0 +1,71 @@
package com.emamaker.amazeing.player;
import java.util.Set;
import com.badlogic.gdx.controllers.Controller;
import com.emamaker.amazeing.maze.settings.MazeSettings;
public class PlayerUtils {
/*Utility function to add and remove players from arrays when organizing as game*/
public static boolean togglePlayer(MazePlayerLocal p, Set<MazePlayer> players) {
if (alreadyAddedPlayer(p, players)) {
p.dispose();
players.remove(p);
return false;
}
if (players.size() < MazeSettings.MAXPLAYERS) {
players.add(p);
return true;
}
return false;
}
public static boolean togglePlayerWithKeys(Set<MazePlayer> players, int... keys) {
if (alreadyAddedPlayerWithKeys(players, keys)) {
players.remove(getPlayerWithKeys(players, keys));
return false;
}
if (players.size() < MazeSettings.MAXPLAYERS) {
players.add(new MazePlayerLocal(keys));
return true;
}
return false;
}
public static boolean alreadyAddedPlayerWithKeys(Set<MazePlayer> players, int... keys) {
return getPlayerWithKeys(players, keys) != null;
}
public static boolean alreadyAddedPlayer(MazePlayerLocal p, Set<MazePlayer> players) {
return players.contains(p);
}
public static MazePlayerLocal getPlayerWithKeys(Set<MazePlayer> players, int... keys) {
for (MazePlayer p : players) {
if (p instanceof MazePlayerLocal) {
for (int k : keys) {
if (((MazePlayerLocal) p).kup == k || ((MazePlayerLocal) p).kdown == k
|| ((MazePlayerLocal) p).ksx == k || ((MazePlayerLocal) p).kdx == k)
return (MazePlayerLocal) p;
}
}
}
return null;
}
public static boolean alreadyAddedPlayerWithCtrl(Controller ctrl, Set<MazePlayer> players) {
return getPlayerWithCtrl(ctrl, players) != null;
}
public static MazePlayerLocal getPlayerWithCtrl(Controller ctrl, Set<MazePlayer> players) {
for (MazePlayer p : players) {
if (p instanceof MazePlayerLocal) {
if (((MazePlayerLocal) p).ctrl == ctrl)
return (MazePlayerLocal) p;
}
}
return null;
}
}

View File

@ -1,11 +1,11 @@
package com.emamaker.amazeing.ui.screens;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.HashSet;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.controllers.Controller;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
@ -20,6 +20,7 @@ import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.emamaker.amazeing.maze.settings.MazeSettings;
import com.emamaker.amazeing.player.MazePlayer;
import com.emamaker.amazeing.player.MazePlayerLocal;
import com.emamaker.amazeing.player.PlayerUtils;
import com.emamaker.amazeing.ui.UIManager;
public class PlayerChooseScreen implements Screen {
@ -30,7 +31,7 @@ public class PlayerChooseScreen implements Screen {
Label[] labels;
int currentLabel = 0;
HashMap<MazePlayer, Label> players = new HashMap<MazePlayer, Label>();
ArrayList<MazePlayer> players = new ArrayList<MazePlayer>();
Screen thisScreen;
@ -160,7 +161,7 @@ public class PlayerChooseScreen implements Screen {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if (!players.isEmpty()) {
hide();
uiManager.main.gameManager.generateMaze(players.keySet());
uiManager.main.gameManager.generateMaze(new HashSet<>(players));
}
return true;
}
@ -186,8 +187,7 @@ public class PlayerChooseScreen implements Screen {
for (int i = 0; i < labels.length; i++) {
labels[i] = new Label("-- empty slot --", uiManager.skin);
}
/* BUILD UP TABLE */
Table firstRowTable = new Table();
@ -231,81 +231,29 @@ public class PlayerChooseScreen implements Screen {
// Consantly search for new players to be added
// First search for keyboard players (WASD and ARROWS)
if (Gdx.input.isKeyJustPressed(Keys.W) || Gdx.input.isKeyJustPressed(Keys.A)
|| Gdx.input.isKeyJustPressed(Keys.S) || Gdx.input.isKeyJustPressed(Keys.D)) {
p = getPlayerWithKeys(Keys.W, Keys.S, Keys.A, Keys.D);
if (p == null)
p = new MazePlayerLocal(uiManager.main, Keys.W, Keys.S, Keys.A, Keys.D);
togglePlayer(p);
}
|| Gdx.input.isKeyJustPressed(Keys.S) || Gdx.input.isKeyJustPressed(Keys.D))
PlayerUtils.togglePlayerWithKeys(new HashSet<>(players), Keys.W, Keys.S, Keys.A, Keys.D);
if (Gdx.input.isKeyJustPressed(Keys.UP) || Gdx.input.isKeyJustPressed(Keys.LEFT)
|| Gdx.input.isKeyJustPressed(Keys.DOWN) || Gdx.input.isKeyJustPressed(Keys.RIGHT)) {
p = getPlayerWithKeys(Keys.UP, Keys.DOWN, Keys.LEFT, Keys.RIGHT);
if (p == null)
p = new MazePlayerLocal(uiManager.main, Keys.UP, Keys.DOWN, Keys.LEFT, Keys.RIGHT);
togglePlayer(p);
}
|| Gdx.input.isKeyJustPressed(Keys.DOWN) || Gdx.input.isKeyJustPressed(Keys.RIGHT))
PlayerUtils.togglePlayerWithKeys(new HashSet<>(players), Keys.UP, Keys.DOWN, Keys.LEFT, Keys.RIGHT);
// for (Controller c : Controllers.getControllers()) {
// if (c.getButton(Xbox.Y)) {
// System.out.println(c.getButton(Xbox.A));
// if (c.getButton(Xbox.Y)) {
// p = getPlayerWithCtrl(c);
// if (p == null)
// p = new MazePlayerLocal(uiManager.main, c);
// togglePlayer(p);
// }
// }
//Update labels
for(int i = 0; i < labels.length; i++) {
labels[i].setText(i < players.size() ? "-- Player Ready! --" : "-- empty slot --" );
// Update labels
for (int i = 0; i < labels.length; i++) {
labels[i].setText(i < players.size() ? "-- Player Ready! --" : "-- empty slot --");
}
}
public void togglePlayer(MazePlayerLocal p) {
try {
if (alreadyAddedPlayer(p))
players.remove(p);
else
players.put(p, labels[players.size()]);
} catch (Exception e) {
System.out.println("All players already joined");
}
}
public boolean alreadyAddedPlayerWithKeys(int... keys) {
return getPlayerWithKeys(keys) != null;
}
public boolean alreadyAddedPlayer(MazePlayerLocal p) {
return players.containsKey(p);
}
public MazePlayerLocal getPlayerWithKeys(int... keys) {
for (MazePlayer p : players.keySet()) {
if (p instanceof MazePlayerLocal) {
for (int k : keys) {
if (((MazePlayerLocal) p).kup == k || ((MazePlayerLocal) p).kdown == k
|| ((MazePlayerLocal) p).ksx == k || ((MazePlayerLocal) p).kdx == k)
return (MazePlayerLocal) p;
}
}
}
return null;
}
public boolean alreadyAddedPlayerWithCtrl(Controller ctrl) {
return getPlayerWithCtrl(ctrl) != null;
}
public MazePlayerLocal getPlayerWithCtrl(Controller ctrl) {
for (MazePlayer p : players.keySet()) {
if (p instanceof MazePlayerLocal) {
if (((MazePlayerLocal) p).ctrl == ctrl)
return (MazePlayerLocal) p;
}
}
return null;
}
@Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);

View File

@ -14,6 +14,7 @@ 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 ServerJoinScreen implements Screen {
@ -92,7 +93,11 @@ public class ServerJoinScreen implements Screen {
connectBtn.addListener(new InputListener() {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if (!uiManager.main.client.start(srvIp.getText(), Integer.valueOf(srvPort.getText())))
if (uiManager.main.client.start(srvIp.getText(), Integer.valueOf(srvPort.getText()))) {
hide();
uiManager.preGameScreen.setGameType(uiManager.main.server.isRunning() ? GameType.SERVER : GameType.CLIENT);
uiManager.main.setScreen(uiManager.preGameScreen);
}else
failDlg.show(stage);
return true;
}