Refactored and cleaned code for Network Games, different gamemanagers for different situations

master
EmaMaker 2020-05-20 19:18:02 +02:00
parent 501a1b1e26
commit db03194bb5
141 changed files with 1045 additions and 759 deletions

0
.gitignore vendored Normal file → Executable file
View File

0
android/AndroidManifest.xml Normal file → Executable file
View File

0
android/assets/data/Untitled.xcf Normal file → Executable file
View File

0
android/assets/data/powerups/Untitled.xcf Normal file → Executable file
View File

0
android/assets/data/powerups/ball_and_chain.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

0
android/assets/data/powerups/ball_and_chain.xcf Normal file → Executable file
View File

0
android/assets/data/powerups/bomb.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

0
android/assets/data/powerups/bomb.xcf Normal file → Executable file
View File

0
android/assets/data/powerups/feather.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
android/assets/data/powerups/slug.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

0
android/assets/data/powerups/slug.xcf Normal file → Executable file
View File

0
android/assets/data/shaders/testshader_frag.glsl Normal file → Executable file
View File

0
android/assets/data/shaders/testshader_vert.glsl Normal file → Executable file
View File

0
android/assets/data/touchscreen_controller.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

4
android/build.gradle Normal file → Executable file
View File

@ -89,8 +89,6 @@ task run(type: Exec) {
commandLine "$adb", 'shell', 'am', 'start', '-n', 'com.emamaker.amazeing/com.emamaker.amazeing.AndroidLauncher'
}
dependencies {
implementation files('/srv/nfs/home/github/amazeing/gdx/lib/kryonet-2.21-all.jar')
}
eclipse.project.name = appName + "-android"

0
android/ic_launcher-web.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

0
android/proguard-rules.pro vendored Normal file → Executable file
View File

0
android/project.properties Normal file → Executable file
View File

0
android/res/drawable-anydpi-v26/ic_launcher.xml Normal file → Executable file
View File

View File

0
android/res/drawable-hdpi/ic_launcher.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

0
android/res/drawable-mdpi/ic_launcher.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

0
android/res/drawable-xhdpi/ic_launcher.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

0
android/res/drawable-xxhdpi/ic_launcher.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

0
android/res/drawable-xxxhdpi/ic_launcher.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

0
android/res/values/color.xml Normal file → Executable file
View File

0
android/res/values/strings.xml Normal file → Executable file
View File

0
android/res/values/styles.xml Normal file → Executable file
View File

0
android/src/com/emamaker/amazeing/AndroidLauncher.java Normal file → Executable file
View File

0
build.gradle Normal file → Executable file
View File

0
core/assets/data/Untitled.xcf Normal file → Executable file
View File

0
core/assets/data/powerups/Untitled.xcf Normal file → Executable file
View File

0
core/assets/data/powerups/ball_and_chain.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

0
core/assets/data/powerups/ball_and_chain.xcf Normal file → Executable file
View File

0
core/assets/data/powerups/bomb.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

0
core/assets/data/powerups/bomb.xcf Normal file → Executable file
View File

0
core/assets/data/powerups/feather.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
core/assets/data/powerups/slug.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

0
core/assets/data/powerups/slug.xcf Normal file → Executable file
View File

0
core/assets/data/shaders/testshader_frag.glsl Normal file → Executable file
View File

0
core/assets/data/shaders/testshader_vert.glsl Normal file → Executable file
View File

0
core/assets/data/touchscreen_controller.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

4
core/build.gradle Normal file → Executable file
View File

@ -1,9 +1,13 @@
apply plugin: "java"
sourceCompatibility = 1.7
dependencies {
implementation files('/srv/nfs/home/github/amazeing/gdx/lib/voxel_engine_lib.jar')
implementation files('/srv/nfs/home/github/amazeing/gdx/lib/kryonet-2.21-all.jar')
}
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
sourceSets.main.java.srcDirs = [ "src/" ]

View File

@ -1,14 +1,12 @@
package com.emamaker.amazeing;
import java.util.Random;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.graphics.FPSLogger;
import com.badlogic.gdx.physics.bullet.Bullet;
import com.emamaker.amazeing.manager.GameManager;
import com.emamaker.amazeing.manager.GameType;
import com.emamaker.amazeing.manager.managers.GameManager;
import com.emamaker.amazeing.manager.managers.GameManagerLocal;
import com.emamaker.amazeing.manager.network.GameClient;
import com.emamaker.amazeing.manager.network.GameServer;
import com.emamaker.amazeing.maze.settings.MazeSettings;
@ -16,6 +14,8 @@ import com.emamaker.amazeing.player.powerups.PowerUps;
import com.emamaker.amazeing.ui.UIManager;
import com.emamaker.voxelengine.VoxelWorld;
import java.util.Random;
public class AMazeIng extends Game {
public VoxelWorld world = new VoxelWorld();
@ -25,7 +25,8 @@ public class AMazeIng extends Game {
Random rand = new Random();
public UIManager uiManager;
public GameManager gameManager, currentGameManager;
public GameManager currentGameManager;
public GameManagerLocal gameManager;
public MazeSettings settings;
public InputMultiplexer multiplexer = new InputMultiplexer();
@ -34,9 +35,9 @@ public class AMazeIng extends Game {
public GameClient client;
static AMazeIng game;
public static Platform PLATFORM;
public AMazeIng(Platform p) {
PLATFORM = p;
}
@ -49,7 +50,7 @@ public class AMazeIng extends Game {
Bullet.init();
// Set windowed resolution
Gdx.graphics.setWindowedMode(1280, 720);
Gdx.graphics.setWindowedMode(640, 480);
// Enable on-screen keyboard for mobile devices
// Gdx.input.setOnscreenKeyboardVisible(true);
@ -77,12 +78,12 @@ public class AMazeIng extends Game {
public void setupGameManager() {
System.out.println("Setup Game Managers");
gameManager = new GameManager(this, GameType.LOCAL);
gameManager = new GameManagerLocal();
server = new GameServer(this);
client = new GameClient(this);
server = new GameServer();
client = new GameClient();
}
public void setupPowerUps() {
System.out.println("Setting up PowerUps");
new PowerUps();
@ -93,8 +94,7 @@ public class AMazeIng extends Game {
super.render();
server.update();
client.update();
if (gameManager != null)
gameManager.update();
gameManager.update();
}
@Override
@ -126,13 +126,15 @@ public class AMazeIng extends Game {
return game;
}
public static boolean isDesktop(){
public static boolean isDesktop() {
return PLATFORM == Platform.DESKTOP;
}
public static boolean isMobile(){
public static boolean isMobile() {
return PLATFORM == Platform.ANDROID || PLATFORM == Platform.IOS;
}
public static boolean isIOS(){
public static boolean isIOS() {
return PLATFORM == Platform.IOS;
}

0
core/src/com/emamaker/amazeing/manager/GameType.java Normal file → Executable file
View File

View File

@ -1,8 +1,4 @@
package com.emamaker.amazeing.manager;
import java.util.ArrayList;
import java.util.Random;
import java.util.Set;
package com.emamaker.amazeing.manager.managers;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.math.Vector3;
@ -10,16 +6,20 @@ import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.emamaker.amazeing.AMazeIng;
import com.emamaker.amazeing.AMazeIng.Platform;
import com.emamaker.amazeing.manager.GameType;
import com.emamaker.amazeing.maze.MazeGenerator;
import com.emamaker.amazeing.maze.settings.MazeSettings;
import com.emamaker.amazeing.player.MazePlayer;
import com.emamaker.amazeing.player.MazePlayerLocal;
import com.emamaker.amazeing.player.powerups.PowerUp;
import com.emamaker.amazeing.player.powerups.PowerUps;
import com.emamaker.amazeing.ui.screens.PreGameScreen;
import com.emamaker.voxelengine.block.CellId;
import com.emamaker.voxelengine.player.Player;
import java.util.ArrayList;
import java.util.Random;
import java.util.Set;
public class GameManager {
AMazeIng main;
@ -56,6 +56,7 @@ public class GameManager {
main.setScreen(null);
AMazeIng.getMain().multiplexer.removeProcessor(stage);
AMazeIng.getMain().multiplexer.addProcessor(stage);
anyoneWon = false;
@ -70,7 +71,7 @@ public class GameManager {
if (!players.contains(p))
players.add(p);
// Fianlly delete players. A separated step is needed to remove the risk of a
// Finally delete players. A separated step is needed to remove the risk of a
// ConcurrentModificationException
for (MazePlayer p : toDelete) {
p.dispose();
@ -95,110 +96,128 @@ public class GameManager {
mazeGen.setMazeSize(MazeSettings.MAZEX, MazeSettings.MAZEZ);
mazeGen.generateMaze();
if (type != GameType.CLIENT) {
spreadPlayers();
mazeGen.setupEndPoint();
powerups.clear();
spawnPowerUps();
}
if (todraw != null && showGame == true) {
mazeGen.show(todraw);
}
resetCamera();
gameStarted = true;
stage.clear();
if (AMazeIng.PLATFORM == Platform.ANDROID)
for (MazePlayer p : players) {
if (p instanceof MazePlayerLocal)
stage.addActor(((MazePlayerLocal) p).tctrl);
stage.addActor(((MazePlayerLocal) p).touchpadPowerUp);
}
}
AMazeIng.getMain().multiplexer.addProcessor(stage);
public void addTouchScreenInput() {
if (getShowGame()) {
stage.clear();
if (AMazeIng.PLATFORM == Platform.ANDROID)
for (MazePlayer p : players) {
if (p instanceof MazePlayerLocal)
stage.addActor(((MazePlayerLocal) p).tctrl);
stage.addActor(((MazePlayerLocal) p).touchpadPowerUp);
}
}
}
public void hudUpdate() {
resetCamera();
setCamera(new Vector3(MazeSettings.MAZEX / 2, (MazeSettings.MAZEX + MazeSettings.MAZEZ) * 0.45f,
MazeSettings.MAZEZ / 2 - 1), new Vector3(0, -90, 0));
stage.act();
stage.draw();
}
public void renderWorld() {
main.world.render();
}
public void renderPowerUps() {
for (PowerUp p : powerups)
p.render(main.world.modelBatch, main.world.environment);
}
public void renderPlayers() {
for (MazePlayer p : players)
renderPlayer(p);
}
public void updatePlayers() {
for (MazePlayer p : players)
updatePlayer(p);
}
public void renderPlayer(MazePlayer p) {
if (getShowGame())
p.render(main.world.modelBatch, main.world.environment);
}
public void updatePlayer(MazePlayer p) {
p.update();
}
public boolean checkPowerUp(MazePlayer p, PowerUp p1) {
return (int) p1.getPosition().x == (int) p.getPos().x && (int) p1.getPosition().z == (int) p.getPos().z;
}
public void assignPowerUps() {
if (players != null && !players.isEmpty())
for (MazePlayer p : players)
assignPowerUp(p);
}
public void assignPowerUp(MazePlayer p) {
PowerUp pup = null;
for (PowerUp p1 : powerups) {
if (checkPowerUp(p, p1)) {
pup = p1;
p.currentPowerUp = pup;
break;
}
}
if (pup != null)
powerups.remove(pup);
}
public void checkWin() {
for (MazePlayer p : players)
if (checkWin(p))
setFinished();
}
public void setFinished() {
anyoneWon = true;
gameStarted = false;
}
public boolean getFinished() {
return anyoneWon;
}
public void update() {
main.currentGameManager = this;
generalUpdate();
if (gameStarted && !anyoneWon) {
pup = null;
if (getShowGame()) {
main.world.render();
resetCamera();
setCamera(new Vector3(mazeGen.w / 2, (MazeSettings.MAZEX + MazeSettings.MAZEZ) * 0.45f, mazeGen.h / 2),
new Vector3(0, -90, 0));
stage.act();
stage.draw();
}
main.world.modelBatch.begin(main.world.cam);
if (getShowGame())
for (PowerUp p : powerups)
p.render(main.world.modelBatch, main.world.environment);
if (players != null) {
for (MazePlayer p : players) {
if (!p.isDisposed()) {
// Check if there's a power-up in the same spot, if so give it to the player
for (PowerUp p1 : powerups)
if ((int) p1.getPosition().x == (int) p.getPos().x
&& (int) p1.getPosition().z == (int) p.getPos().z) {
pup = p1;
p.currentPowerUp = pup;
break;
}
if (pup != null)
powerups.remove(pup);
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) {
System.out.println("Game Finished! " + type);
if (type == GameType.LOCAL) {
main.setScreen(main.uiManager.playersScreen);
} else if (type == GameType.SERVER) {
((PreGameScreen) main.uiManager.preGameScreen).setGameType(GameType.SERVER);
main.setScreen(main.uiManager.preGameScreen);
}
}
main.world.modelBatch.end();
inGameUpdate();
checkWin();
}
}
public void generalUpdate() {
}
public void inGameUpdate() {
if (players != null) {
updatePlayers();
}
}
public void spreadPlayers() {
for (MazePlayer p : players) {
int x = 1, z = 1;
do {
x = (Math.abs(rand.nextInt() - 1) % (mazeGen.w));
z = (Math.abs(rand.nextInt() - 1) % (mazeGen.h));
// System.out.println(
// thereIsPlayerInPos(x, z) + " - " + mazeGen.occupiedSpot(x, z) + " --- " + x + ", " + z);
x = (Math.abs(rand.nextInt() - 1) % (MazeGenerator.w));
z = (Math.abs(rand.nextInt() - 1) % (MazeGenerator.h));
} while (thereIsPlayerInPos(x, z) || mazeGen.occupiedSpot(x, z));
p.setPlaying();
p.setPos(x + 0.5f, 2f, z + 0.5f);
System.out.println(p.getPos().x + ", " + p.getPos().z);
}
}
@ -208,8 +227,8 @@ public class GameManager {
PowerUp p = PowerUps.pickRandomPU();
int x = 1, z = 1;
do {
x = (Math.abs(rand.nextInt() - 1) % (mazeGen.w));
z = (Math.abs(rand.nextInt() - 1) % (mazeGen.h));
x = (Math.abs(rand.nextInt() - 1) % (MazeGenerator.w));
z = (Math.abs(rand.nextInt() - 1) % (MazeGenerator.h));
} while (thereIsPlayerInPos(x, z) || mazeGen.occupiedSpot(x, z) || thereIsPowerUpInPos(x, z));
p.setPosition(x + 0.5f, 1.25f, z + 0.5f);
powerups.add(p);
@ -218,6 +237,24 @@ public class GameManager {
}
public void clearPowerUps() {
for (PowerUp p : powerups)
p.dispose();
powerups.clear();
}
public String getPowerUpNameByPos(int x, int z) {
PowerUp p = getPowerUpByPos(x, z);
return p == null ? "" : p.name;
}
public PowerUp getPowerUpByPos(int x, int z) {
for (PowerUp p : powerups)
if ((int) p.getPosition().x == x || (int) p.getPosition().z == z)
return p;
return null;
}
Player generateNewPlayer(int kup, int kdown, int ksx, int kdx) {
return generateNewPlayer(kup, kdown, ksx, kdx, "");
}
@ -225,8 +262,8 @@ public class GameManager {
Player generateNewPlayer(int kup, int kdown, int ksx, int kdx, String name) {
int x, z;
do {
x = (Math.abs(rand.nextInt() - 1) % (mazeGen.w));
z = (Math.abs(rand.nextInt() - 1) % (mazeGen.h));
x = (Math.abs(rand.nextInt() - 1) % (MazeGenerator.w));
z = (Math.abs(rand.nextInt() - 1) % (MazeGenerator.h));
} while (thereIsPlayerInPos(x, z) || mazeGen.occupiedSpot(x, z));
if (name.equalsIgnoreCase(""))
return new Player(kup, kdown, ksx, kdx, x + 0.5f, 4f, z + 0.5f);
@ -296,7 +333,7 @@ public class GameManager {
main.world.cam.update();
}
boolean getShowGame() {
protected boolean getShowGame() {
return showGame;
}

View File

@ -0,0 +1,53 @@
package com.emamaker.amazeing.manager.managers;
import java.util.Set;
import com.emamaker.amazeing.AMazeIng;
import com.emamaker.amazeing.manager.GameType;
import com.emamaker.amazeing.player.MazePlayer;
import com.emamaker.amazeing.ui.screens.PreGameScreen;
public class GameManagerClient extends GameManager {
public GameManagerClient() {
super(AMazeIng.getMain(), GameType.CLIENT);
}
@Override
public void generateMaze(Set<MazePlayer> pl, int todraw[][]) {
super.generateMaze(pl, todraw);
}
@Override
public void update() {
super.update();
}
@Override
public void inGameUpdate() {
super.inGameUpdate();
renderWorld();
hudUpdate();
main.world.modelBatch.begin(main.world.cam);
renderPlayers();
renderPowerUps();
main.world.modelBatch.end();
if (getFinished()) {
main.setScreen(main.uiManager.preGameScreen);
}
}
//Protecting against myself since this feature doesn't exist yet
@Override
public void assignPowerUps() {
}
@Override
public void checkWin() { }
}

View File

@ -0,0 +1,47 @@
package com.emamaker.amazeing.manager.managers;
import java.util.Set;
import com.emamaker.amazeing.AMazeIng;
import com.emamaker.amazeing.manager.GameType;
import com.emamaker.amazeing.player.MazePlayer;
public class GameManagerLocal extends GameManager {
public GameManagerLocal() {
super(AMazeIng.getMain(), GameType.LOCAL);
}
@Override
public void generateMaze(Set<MazePlayer> pl, int todraw[][]) {
super.generateMaze(pl, todraw);
spreadPlayers();
mazeGen.setupEndPoint();
clearPowerUps();
spawnPowerUps();
if (todraw != null && getShowGame())
mazeGen.show(todraw);
}
@Override
public void inGameUpdate() {
super.inGameUpdate();
assignPowerUps();
renderWorld();
hudUpdate();
main.world.modelBatch.begin(main.world.cam);
renderPlayers();
renderPowerUps();
main.world.modelBatch.end();
if (getFinished())
main.setScreen(main.uiManager.playersScreen);
}
}

View File

@ -0,0 +1,59 @@
package com.emamaker.amazeing.manager.managers;
import java.util.Set;
import com.emamaker.amazeing.AMazeIng;
import com.emamaker.amazeing.manager.GameType;
import com.emamaker.amazeing.player.MazePlayer;
import com.emamaker.amazeing.ui.screens.PreGameScreen;
public class GameManagerServer extends GameManager {
public GameManagerServer() {
super(AMazeIng.getMain(), GameType.SERVER);
}
@Override
public void generateMaze(Set<MazePlayer> pl, int todraw[][]) {
super.generateMaze(pl, todraw);
spreadPlayers();
mazeGen.setupEndPoint();
powerups.clear();
spawnPowerUps();
if (todraw != null && getShowGame())
mazeGen.show(todraw);
}
@Override
public void inGameUpdate() {
super.inGameUpdate();
assignPowerUps();
renderWorld();
hudUpdate();
main.world.modelBatch.begin(main.world.cam);
renderPlayers();
renderPowerUps();
main.world.modelBatch.end();
if (getFinished()) {
((PreGameScreen) main.uiManager.preGameScreen).setGameType(GameType.SERVER);
main.setScreen(main.uiManager.preGameScreen);
}
}
//Protecting against myself since this feature doesn't exist yet
@Override
public void assignPowerUps() {
}
}

View File

@ -3,294 +3,298 @@ package com.emamaker.amazeing.manager.network;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import com.badlogic.gdx.math.Quaternion;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.ui.Touchpad;
import com.emamaker.amazeing.AMazeIng;
import com.emamaker.amazeing.manager.GameManager;
import com.emamaker.amazeing.manager.GameType;
import com.emamaker.amazeing.manager.managers.GameManagerClient;
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;
import com.emamaker.amazeing.manager.network.NetworkCommon.StartGame;
import com.emamaker.amazeing.manager.network.NetworkCommon.UpdateMap;
import com.emamaker.amazeing.manager.network.NetworkCommon.UpdatePlayerTransform;
import com.emamaker.amazeing.manager.network.NetworkCommon.UpdateSettings;
import com.emamaker.amazeing.manager.network.NetworkCommon.UpdatePlayerTransformServer;
import com.emamaker.amazeing.maze.settings.MazeSettings;
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.emamaker.amazeing.ui.screens.PreGameScreen;
import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
public class GameClient {
public class GameClient extends NetworkHandler {
public AMazeIng main;
volatile boolean clientRunning = false;
Client client;
String addr;
public String addr;
public int port;
boolean updateMobilePlayers = false;
boolean startGame = false;
boolean showPreGame = false;
boolean updateMobilePlayers = false;
String map = "";
// 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;
public GameClient(AMazeIng main_) {
main = main_;
}
ArrayList<String> localPlayers = new ArrayList<String>();
// Returns true if the server started successfully
public boolean start(String addr_, int port_) {
port = port_;
addr = addr_;
clientRunning = true;
startGame = false;
client = new Client();
client.start();
NetworkCommon.register(client);
client.addListener(new Listener() {
public void connected(Connection connection) {
}
public void received(Connection connection, Object object) {
if (object instanceof LoginAO2) {
localPlrQueue.get(0).uuid = ((LoginAO2) object).uuid;
toAdd.add("Local" + localPlrQueue.get(0).uuid);
client.sendTCP(object);
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
// thread to it
showPreGame = true;
} else if (object instanceof AddNewPlayer) {
AddNewPlayer msg = (AddNewPlayer) object;
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 (players.containsKey(msg.uuid)) {
toRemove.add(msg.uuid);
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 (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 (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;
System.out.println("Map update!");
} else if (object instanceof StartGame) {
startGame = true;
map = ((StartGame) object).map;
System.out.println("Starting the online game!");
} else if (object instanceof EndGame) {
System.out.println("EndGame Received!");
if (gameManager != null) {
gameManager.gameStarted = false;
gameManager.anyoneWon = true;
showPreGame = true;
}
} else if (object instanceof UpdateSettings) {
System.out.println("Update received for setting n." + ((UpdateSettings) object).index);
if (!main.server.isRunning()) {
MazeSettings.settings.get(((UpdateSettings) object).index)
.parseOptionString(((UpdateSettings) object).value);
}else {
System.out.println("Ignoring settings update since we are running on a server");
}
//We don't mind if we are client or server, just set the flag to update pregamescreen
showPreGame = true;
}
}
public void disconnected(Connection connection) {
toRemove.addAll(players.keySet());
}
});
port = port_;
running = true;
try {
client.connect(5000, addr, port);
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 (
client = new Client();
IOException ex) {
ex.printStackTrace();
// For consistency, the classes to be sent over the network are
// registered by the same method for both the client and server.
NetworkCommon.register(client);
client.start();
client.addListener(connectionListener);
client.connect(5000, addr, port, port + 1);
gameManager = new GameManagerClient();
if (AMazeIng.isMobile())
updateMobilePlayers = false;
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
// Update must be called from Main thread and used for applications on main
// thread
MazePlayerLocal p;
@Override
public boolean startGame() {
return false;
}
@Override
public void stop() {
if (running) {
for (String s : players.keySet()) {
if (players.get(s) instanceof MazePlayerLocal) {
RemovePlayer request = new RemovePlayer();
request.uuid = s;
client.sendTCP(request);
}
players.get(s).dispose();
}
players.clear();
client.stop();
running = false;
}
}
@Override
public void onLoginAO(Connection c) {
}
@Override
public void onLoginAO2(Connection c) {
String uuid = ((LoginAO2) message).uuid;
System.out.println(
"Server has responded with uuid " + uuid + ", assigning it to the first local player in queue");
// Accept uuid
if (!localPlrQueue.isEmpty()) {
players.put(uuid, localPlrQueue.get(0));
players.get(uuid).uuid = uuid;
localPlrQueue.remove(0);
localPlayers.add(uuid);
// Resend message to notify that uuid has been accepted
client.sendTCP(message);
}
}
@Override
public void onConnectionRefused(Connection c) {
}
@Override
public void onAddNewPlayer(Connection c) {
String uuid = ((AddNewPlayer) message).uuid;
if (!players.containsKey(uuid)) {
MazePlayerRemote player = new MazePlayerRemote(uuid);
players.put(uuid, player);
}
}
@Override
public void onRemovePlayer(Connection c) {
String uuid = ((RemovePlayer) message).uuid;
// Remove the player from the server
if (players.containsKey(uuid)) {
players.remove(uuid);
System.out.println("Player with UUID " + uuid + " is leaving the game :(");
}
}
@Override
public void onUpdateTransform(Connection c) {
String uuid = ((UpdatePlayerTransform) message).uuid;
if (players.containsKey(uuid) && !localPlayers.contains(uuid)) {
System.out.println("Updating player with uuid " + uuid);
players.get(uuid).setPos(((UpdatePlayerTransform) message).tx, ((UpdatePlayerTransform) message).ty,
((UpdatePlayerTransform) message).tz);
}
}
@Override
public void onUpdateTransformServer(Connection c) {
String uuid = ((UpdatePlayerTransformServer) message).uuid;
if (players.containsKey(uuid)) {
players.get(uuid).setPos(((UpdatePlayerTransformServer) message).tx,
((UpdatePlayerTransformServer) message).ty, ((UpdatePlayerTransformServer) message).tz);
}
}
@Override
public void onStartGame(Connection c) {
startGame = true;
map = ((StartGame) message).map;
}
@Override
public void onEndGame(Connection c) {
gameManager.setFinished();
}
@Override
public void onUpdateMap(Connection c) {
}
@Override
public void onUpdateSettings(Connection c) {
}
@Override
public void onConnected(Connection c) {
}
@Override
public void update() {
if (clientRunning) {
try {
for (String s : toAdd) {
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", "")));
}
}
super.update();
if (gameManager != null) {
if (!gameManager.gameStarted) {
checkForNewPlayers();
if (startGame) {
gameManager.generateMaze(new HashSet<MazePlayer>(players.values()));
startGame = false;
}
toAdd.clear();
for (String s : toRemove) {
if (players.containsKey(s)) {
players.get(s).dispose();
players.remove(s);
}
}
toRemove.clear();
} catch (Exception e) {
}
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
// In this way server host is shown the start game button.
if (!main.server.isRunning())
((PreGameScreen) main.uiManager.preGameScreen).setGameType(GameType.CLIENT);
main.setScreen(main.uiManager.preGameScreen);
showPreGame = false;
}
if (startGame) {
gameManager = new GameManager(main, GameType.CLIENT);
if (main.getScreen() != null) {
main.getScreen().hide();
main.setScreen(null);
}
for (MazePlayer p : players.values())
p.setPlaying();
gameManager.generateMaze(new HashSet<MazePlayer>(players.values()));
startGame = false;
}
if (gameManager != null) {
gameManager.update();
if (gameManager.gameStarted) {
} else {
if (!gameManager.anyoneWon) {
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
if(AMazeIng.PLATFORM == AMazeIng.Platform.DESKTOP) {
// Search for keyboard players (WASD and ARROWS) on Desktop
if (PlayerUtils.wasdPressed()) {
p = PlayerUtils.getPlayerWithKeys(new HashSet<>(players.values()), PlayerUtils.WASDKEYS);
if (p != null) {
RemovePlayer msg = new RemovePlayer();
msg.uuid = p.uuid;
client.sendTCP(msg);
} else {
localPlrQueue.add(new MazePlayerLocal(PlayerUtils.WASDKEYS));
client.sendTCP(new LoginAO());
}
}
if (PlayerUtils.arrowsPressed()) {
p = PlayerUtils.getPlayerWithKeys(new HashSet<>(players.values()), PlayerUtils.ARROWKEYS);
if (p != null) {
RemovePlayer msg = new RemovePlayer();
msg.uuid = p.uuid;
client.sendTCP(msg);
} else {
localPlrQueue.add(new MazePlayerLocal( PlayerUtils.ARROWKEYS));
client.sendTCP(new LoginAO());
}
}
}else{
//Search for mobile players
if(updateMobilePlayers){
for(int i = 0; i < MazeSettings.MAXPLAYERS; i++) {
p = PlayerUtils.getPlayerWithTouchCtrl(i, new HashSet<>(players.values()));
if(i < MazeSettings.MAXPLAYERS_MOBILE){
//if yhe player wasn't there before, but wants to join: add it
if(p == null) {
localPlrQueue.add(new MazePlayerLocal(new Touchpad(0f, main.uiManager.skin), i));
client.sendTCP(new NetworkCommon.LoginAO());
}
}else {
//The player was there before, but has left: remove it
if (p != null && players.containsValue(p)) {
NetworkCommon.RemovePlayer msg = new NetworkCommon.RemovePlayer();
msg.uuid = p.uuid;
client.sendTCP(msg);
}
//Otherwise just do nothing
}
}
updateMobilePlayers = false;
}
for (String s : players.keySet())
if (localPlayers.contains(s))
updateLocalPlayerToServer((MazePlayerLocal) players.get(s));
}
}
}
}
public void updateLocalPlayer(MazePlayerLocal p) {
if (this.gameManager != null && this.gameManager.gameStarted && clientRunning && p.isPlaying()) {
/* CHECKING FOR NEW PLAYERS */
MazePlayerLocal p;
ArrayList<MazePlayerLocal> localPlrQueue = new ArrayList<MazePlayerLocal>();
private void checkForNewPlayers() {
checkForNewPlayersDesktop();
checkForNewPlayersMobile();
}
private void checkForNewPlayersDesktop() {
if (AMazeIng.isDesktop()) {
// Search for keyboard players (WASD and ARROWS) on Desktop
if (PlayerUtils.wasdPressed()) {
p = PlayerUtils.getPlayerWithKeys(new HashSet<>(players.values()), PlayerUtils.WASDKEYS);
if (p != null) {
RemovePlayer msg = new RemovePlayer();
msg.uuid = p.uuid;
client.sendTCP(msg);
} else {
localPlrQueue.add(new MazePlayerLocal(PlayerUtils.WASDKEYS));
client.sendTCP(new LoginAO());
}
}
if (PlayerUtils.arrowsPressed()) {
p = PlayerUtils.getPlayerWithKeys(new HashSet<>(players.values()), PlayerUtils.ARROWKEYS);
if (p != null) {
RemovePlayer msg = new RemovePlayer();
msg.uuid = p.uuid;
client.sendTCP(msg);
} else {
localPlrQueue.add(new MazePlayerLocal(PlayerUtils.ARROWKEYS));
client.sendTCP(new LoginAO());
}
}
}
}
private void checkForNewPlayersMobile() {
if (AMazeIng.isMobile()) {
// Search for mobile players
if (updateMobilePlayers) {
for (int i = 0; i < MazeSettings.MAXPLAYERS; i++) {
p = PlayerUtils.getPlayerWithTouchCtrl(i, new HashSet<>(players.values()));
if (i < MazeSettings.MAXPLAYERS_MOBILE) {
// if yhe player wasn't there before, but wants to join: add it
if (p == null) {
localPlrQueue.add(new MazePlayerLocal(new Touchpad(0f, main.uiManager.skin), i));
client.sendTCP(new NetworkCommon.LoginAO());
}
} else {
// The player was there before, but has left: remove it
if (p != null && players.containsValue(p)) {
NetworkCommon.RemovePlayer msg = new NetworkCommon.RemovePlayer();
msg.uuid = p.uuid;
client.sendTCP(msg);
}
// Otherwise just do nothing
}
}
updateMobilePlayers = false;
}
}
}
@Override
public void onAddPowerUp(Connection c) {
// TODO Auto-generated method stub
}
@Override
public void onRemovePowerUp(Connection c) {
// TODO Auto-generated method stub
}
@Override
public void onAssignPowerUp(Connection c) {
// TODO Auto-generated method stub
}
@Override
public void onStartUsingPowerUp(Connection c) {
// TODO Auto-generated method stub
}
@Override
public void onEndUsingPowerUp(Connection c) {
}
public void updateLocalPlayerToServer(MazePlayerLocal p) {
if (this.gameManager != null && this.gameManager.gameStarted) {
UpdatePlayerTransform pu = new UpdatePlayerTransform();
Vector3 pos = p.ghostObject.getWorldTransform().getTranslation(new Vector3());
Quaternion rot = p.ghostObject.getWorldTransform().getRotation(new Quaternion());
@ -303,38 +307,7 @@ public class GameClient {
pu.rw = rot.w;
pu.uuid = p.uuid;
client.sendTCP(pu);
}
}
public void requestUpdateMap(int[][] tmpMap) {
}
public void setUpdateMobilePlayers(){
updateMobilePlayers = true;
}
public boolean isRunning() {
return clientRunning;
}
public void stop() {
if (clientRunning) {
for (String s : players.keySet()) {
if (players.get(s) instanceof MazePlayerLocal) {
RemovePlayer request = new RemovePlayer();
request.uuid = s;
client.sendTCP(request);
}
players.get(s).dispose();
}
players.clear();
client.stop();
clientRunning = false;
client.sendUDP(pu);
}
}

View File

@ -1,303 +1,200 @@
package com.emamaker.amazeing.manager.network;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.UUID;
import com.badlogic.gdx.math.Quaternion;
import com.badlogic.gdx.math.Vector3;
import com.emamaker.amazeing.AMazeIng;
import com.emamaker.amazeing.manager.GameManager;
import com.emamaker.amazeing.manager.GameType;
import com.emamaker.amazeing.manager.managers.GameManagerServer;
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;
import com.emamaker.amazeing.manager.network.NetworkCommon.StartGame;
import com.emamaker.amazeing.manager.network.NetworkCommon.UpdateMap;
import com.emamaker.amazeing.manager.network.NetworkCommon.UpdatePlayerTransform;
import com.emamaker.amazeing.manager.network.NetworkCommon.UpdateSettings;
import com.emamaker.amazeing.maze.settings.MazeSettings;
import com.emamaker.amazeing.player.MazePlayer;
import com.emamaker.amazeing.player.MazePlayerRemote;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
public class GameServer {
public class GameServer extends NetworkHandler {
public AMazeIng main;
Server server;
volatile boolean serverRunning = false;
boolean endGameCalled = false;
public int port;
UUID uuid;
// Returns true if the server started successfully
public boolean start(int port_) {
port = port_;
running = true;
try {
server = new Server();
// For consistency, the classes to be sent over the network are
// registered by the same method for both the client and server.
NetworkCommon.register(server);
server.addListener(connectionListener);
server.bind(port, port + 1);
server.start();
public GameManager gameManager;
Server server;
gameManager = new GameManagerServer();
// Hashtable of remote players present in the match. This will be used to update
// other players' transform when server reports about it
public Hashtable<String, MazePlayerRemote> remotePlayers = new Hashtable<>();
System.out.println("Server registered and running on port " + port);
return true;
public GameServer(AMazeIng main_) {
main = main_;
uuid = UUID.randomUUID();
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
@Override
public void onLoginAO(Connection c) {
if (players.size() < MazeSettings.MAXPLAYERS) {
String uuid = UUID.randomUUID().toString();
System.out.println("Client requested adding new player, giving it uuid " + uuid);
LoginAO2 response = new LoginAO2();
response.uuid = uuid;
c.sendTCP(response);
}
}
// 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
@Override
public void onLoginAO2(Connection c) {
String uuid = ((LoginAO2) message).uuid;
if (!players.containsKey(uuid)) {
MazePlayerRemote player = new MazePlayerRemote(uuid);
players.put(uuid, player);
AddNewPlayer response = new AddNewPlayer();
for (String s : remotePlayers.keySet()) {
response.uuid = s;
server.sendToAllTCP(response);
}
// Update everyone about the new player
AddNewPlayer response = new AddNewPlayer();
response.uuid = uuid;
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();
}
};
@Override
public void onConnectionRefused(Connection c) {
}
// For consistency, the classes to be sent over the network are
// registered by the same method for both the client and server.
NetworkCommon.register(server);
@Override
public void onAddNewPlayer(Connection c) {
}
server.addListener(new Listener() {
public void received(Connection c, Object object) {
ConnectionPlayer connection = (ConnectionPlayer) c;
@Override
public void onRemovePlayer(Connection c) {
String uuid = ((RemovePlayer) message).uuid;
// Remove the player from the server
if (players.containsKey(uuid)) {
players.remove(uuid);
System.out.println("Player with UUID " + uuid + " is leaving the game :(");
// And update everyone about it
server.sendToAllTCP(message);
}
}
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
connection.uuid = UUID.randomUUID().toString();
@Override
public void onUpdateTransform(Connection c) {
String uuid = ((UpdatePlayerTransform) message).uuid;
if(players.containsKey(uuid)) {
players.get(uuid).setPos(((UpdatePlayerTransform) message).tx, ((UpdatePlayerTransform) message).ty, ((UpdatePlayerTransform) message).tz);
server.sendToAllUDP(message);
}
}
LoginAO2 response = new LoginAO2();
response.uuid = connection.uuid;
System.out.println("Server received connection request! Giving client UUID " + connection.uuid);
c.sendTCP(response);
@Override
public void onUpdateTransformServer(Connection c) {
}
} else if (object instanceof LoginAO2) {
// Ignore is there's no uuid or it's different from the login message one
// If there's still space left for players to join
if (remotePlayers.values().size() < MazeSettings.MAXPLAYERS) {
remotePlayers.put(((LoginAO2) object).uuid,
new MazePlayerRemote(((LoginAO2) object).uuid, false));
@Override
public void onStartGame(Connection c) {
}
updateSettingForClient(c);
@Override
public void onEndGame(Connection c) {
}
System.out.println("Client with UUID " + ((LoginAO2) object).uuid
+ " is connected and ready to play :)");
@Override
public void onUpdateMap(Connection c) {
}
AddNewPlayer response = new AddNewPlayer();
response.uuid = ((LoginAO2) object).uuid;
server.sendToAllTCP(response);
@Override
public void onUpdateSettings(Connection c) {
}
} else {
// Send connection refused
c.sendTCP(new ConnectionRefused());
}
@Override
public void stop() {
for (MazePlayer p : players.values())
p.dispose();
players.clear();
if (isRunning()) {
main.client.stop();
server.stop();
running = false;
}
}
} else if (object instanceof RemovePlayer) {
// Otherwise remove the player and notify all clients about it
if (remotePlayers.containsKey(((RemovePlayer) object).uuid.toString())) {
remotePlayers.get(((RemovePlayer) object).uuid).dispose();
remotePlayers.remove(((RemovePlayer) object).uuid);
@Override
public void onConnected(Connection c) {
System.out.println("New client connected, updating him about the others!");
for (String s : players.keySet()) {
AddNewPlayer request = new AddNewPlayer();
request.uuid = s;
c.sendTCP(request);
}
}
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");
}
} else if (object instanceof UpdatePlayerTransform) {
UpdatePlayerTransform transform = (UpdatePlayerTransform) object;
if (gameManager.gameStarted) {
// Otherwise Update the transport and notify clients about it
MazePlayerRemote player = remotePlayers.get((transform.uuid));
player.setTransform(transform.tx, transform.ty, transform.tz, transform.rx, transform.ry,
transform.rz, transform.rw);
updatePlayer(transform.uuid, remotePlayers.get(transform.uuid), false);
System.out.println("Updating client " + connection.uuid + " position!");
}
}
}
@Override
public void onAddPowerUp(Connection c) {
}
public void disconnected(Connection c) {
ConnectionPlayer connection = (ConnectionPlayer) c;
if (connection.uuid != null) {
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);
}
}
});
@Override
public void onRemovePowerUp(Connection c) {
}
server.bind(port);
server.start();
System.out.println("Server registered and running on port " + port);
@Override
public void onAssignPowerUp(Connection c) {
}
// 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;
else {
server.stop();
return false;
}
@Override
public void onStartUsingPowerUp(Connection c) {
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
@Override
public void onEndUsingPowerUp(Connection c) {
}
// Update must be called from Main thread and used for applications on main
// thread, such as spawning new players
public void update() {
if (serverRunning) {
if (gameManager != null) {
gameManager.update();
if (gameManager.anyoneWon && !endGameCalled) {
server.sendToAllTCP(new EndGame());
endGameCalled = true;
}
}
}
}
@Override
public boolean startGame() {
if(!players.isEmpty()) {
this.gameManager.generateMaze(new HashSet<MazePlayer>(players.values()));
StartGame response = new StartGame();
response.map = this.gameManager.mazeGen.runLenghtEncode();
server.sendToAllTCP(response);
for(String s : players.keySet()) {
Object pu = updatePlayer(s, players.get(s), true);
server.sendToAllTCP(pu);
}
return true;
}
return false;
}
// Once the server has started accepting connections from other players, the
// host should decide when to start the gmae
// A proper ui should be added, but for now we can just start the game without
// showing any players and just show the map across all the clients
public boolean startGame() {
if (serverRunning) {
update();
if (!remotePlayers.isEmpty()) {
// Start game stuff
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);
if (gameManager.gameStarted)
for (String p : remotePlayers.keySet())
updatePlayer(p, remotePlayers.get(p), true);
if (main.getScreen() != null) {
main.getScreen().hide();
main.setScreen(null);
}
return true;
} else System.out.println("No players have joined yet");
} else {
System.out.println("Server not started yet, game cannot start");
}
return false;
}
public void updatePlayer(String uuid, MazePlayerRemote p, boolean force) {
if (serverRunning && this.gameManager != null && this.gameManager.gameStarted) {
if (force) {
NetworkCommon.UpdatePlayerTransformServer pu = new NetworkCommon.UpdatePlayerTransformServer();
Vector3 pos = p.getPos();
Quaternion rot = p.getRotation();
pu.tx = pos.x;
pu.ty = pos.y;
pu.tz = pos.z;
pu.rx = rot.x;
pu.ry = rot.y;
pu.rz = rot.z;
pu.rw = rot.w;
pu.uuid = uuid;
System.out.println("Forcing position update to all clients for player " + uuid);
server.sendToAllTCP(pu);
} else {
UpdatePlayerTransform pu = new UpdatePlayerTransform();
Vector3 pos = p.getPos();
Quaternion rot = p.getRotation();
pu.tx = pos.x;
pu.ty = pos.y;
pu.tz = pos.z;
pu.rx = rot.x;
pu.ry = rot.y;
pu.rz = rot.z;
pu.rw = rot.w;
pu.uuid = uuid;
System.out.println("Sending position update to all clients for player " + uuid);
server.sendToAllTCP(pu);
}
}
}
public void stop() {
for (MazePlayerRemote p : remotePlayers.values())
if (!p.isDisposed())
p.dispose();
remotePlayers.clear();
if (serverRunning) {
main.client.stop();
server.stop();
serverRunning = false;
}
}
public boolean isRunning() {
return serverRunning;
}
UpdateSettings s = new UpdateSettings();
// Send updates about settings to the clients
public void updateSettingForAll() {
if (isRunning())
for (int i = 0; i < MazeSettings.settings.size(); i++) {
s.index = i;
s.value = MazeSettings.settings.get(i).getOptionString();
server.sendToAllTCP(s);
}
}
public void updateSettingForClient(Connection c) {
if (isRunning())
for (int i = 0; i < MazeSettings.settings.size(); i++) {
s.index = i;
s.value = MazeSettings.settings.get(i).getOptionString();
c.sendTCP(s);
}
}
@Override
public void update() {
super.update();
if(gameManager != null) {
if(gameManager.anyoneWon) server.sendToAllUDP(new EndGame());
}
}
@Override
public void periodicGameUpdate() {
UpdateMap response = new UpdateMap();
response.map = gameManager.mazeGen.runLenghtEncode();
server.sendToAllUDP(response);
}
}
class ConnectionPlayer extends Connection {
public String uuid;
}

View File

@ -1,6 +1,7 @@
package com.emamaker.amazeing.manager.network;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.EndPoint;
public class NetworkCommon {
@ -13,7 +14,6 @@ public class NetworkCommon {
kryo.register(LoginAO.class);
kryo.register(LoginAO2.class);
kryo.register(ConnectionRefused.class);
kryo.register(LoginUUID.class);
kryo.register(AddNewPlayer.class);
kryo.register(RemovePlayer.class);
kryo.register(UpdatePlayerTransform.class);
@ -22,6 +22,12 @@ public class NetworkCommon {
kryo.register(EndGame.class);
kryo.register(UpdateMap.class);
kryo.register(UpdateSettings.class);
kryo.register(Present.class);
kryo.register(AddPowerUp.class);
kryo.register(RemovePowerUp.class);
kryo.register(AssignPowerUp.class);
kryo.register(StartUsingPowerUp.class);
kryo.register(EndUsingPowerUp.class);
}
//Login stuff
@ -35,9 +41,6 @@ public class NetworkCommon {
public static class ConnectionRefused {
String uuid;
}
public static class LoginUUID {
String uuid;
}
//Player stuff
public static class AddNewPlayer {
@ -55,6 +58,26 @@ public class NetworkCommon {
float tx, ty, tz, rx, ry, rz, rw;
}
//PowerUp stuff
public static class AddPowerUp {
String name;
float x,z;
}
public static class RemovePowerUp {
String uuid;
float x,z;
}
public static class AssignPowerUp {
String name, uuid;
}
public static class StartUsingPowerUp {
String name, uuid;
}
public static class EndUsingPowerUp {
String name, uuid;
}
//Game
public static class StartGame{
//Use this to notify clients of a newly started game
//A Run-lenght-encoded representation of the map can be appended, this can be avoided but it's not recommended
@ -74,4 +97,12 @@ public class NetworkCommon {
String value;
}
public static class Present{
}
}
class ConnectionPlayer extends Connection {
public String uuid;
}

View File

@ -0,0 +1,175 @@
package com.emamaker.amazeing.manager.network;
import java.util.Hashtable;
import com.badlogic.gdx.math.Quaternion;
import com.badlogic.gdx.math.Vector3;
import com.emamaker.amazeing.AMazeIng;
import com.emamaker.amazeing.manager.managers.GameManager;
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.LoginAO;
import com.emamaker.amazeing.manager.network.NetworkCommon.LoginAO2;
import com.emamaker.amazeing.manager.network.NetworkCommon.RemovePlayer;
import com.emamaker.amazeing.manager.network.NetworkCommon.StartGame;
import com.emamaker.amazeing.manager.network.NetworkCommon.UpdateMap;
import com.emamaker.amazeing.manager.network.NetworkCommon.UpdatePlayerTransform;
import com.emamaker.amazeing.manager.network.NetworkCommon.UpdatePlayerTransformServer;
import com.emamaker.amazeing.player.MazePlayer;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
public abstract class NetworkHandler {
public Hashtable<String, MazePlayer> players = new Hashtable<String, MazePlayer>();
public GameManager gameManager;
public AMazeIng main = AMazeIng.getMain();
int port;
boolean running = false;
long time = 0;
int UPDATE_PERIOD = 2000;
/*
* Since Kryonet defaults the use of a TCP port: Login UUID negotation, game
* starting and ending, player adding and removal settings update are done using
* TCP since we can't afford to lose packets on them, and they're done in a
* phase of the game when there's few UPD traffic if not at all Player Transform
* Updates and map updates will be done in UDP, since there can be a lot in a
* short period of time and they're not essential to the game (meaning some
* updates can be skipped)
*/
public abstract void onLoginAO(Connection c);
public abstract void onLoginAO2(Connection c);
public abstract void onConnectionRefused(Connection c);
public abstract void onAddNewPlayer(Connection c);
public abstract void onRemovePlayer(Connection c);
public abstract void onUpdateTransform(Connection c);
public abstract void onUpdateTransformServer(Connection c);
public abstract void onStartGame(Connection c);
public abstract void onEndGame(Connection c);
public abstract void onUpdateMap(Connection c);
public abstract void onUpdateSettings(Connection c);
public abstract void onConnected(Connection c);
public abstract void onAddPowerUp(Connection c);
public abstract void onRemovePowerUp(Connection c);
public abstract void onAssignPowerUp(Connection c);
public abstract void onStartUsingPowerUp(Connection c);
public abstract void onEndUsingPowerUp(Connection c);
Object message;
public void onReceived(Connection c, Object object) {
message = object;
if (object instanceof LoginAO)
onLoginAO(c);
else if (object instanceof LoginAO2)
onLoginAO2(c);
else if (object instanceof ConnectionRefused)
onConnectionRefused(c);
else if (object instanceof UpdatePlayerTransform)
onUpdateTransform(c);
else if (object instanceof UpdatePlayerTransformServer)
onUpdateTransformServer(c);
else if (object instanceof StartGame)
onStartGame(c);
else if (object instanceof EndGame)
onEndGame(c);
else if (object instanceof UpdateMap)
onUpdateMap(c);
else if (object instanceof AddNewPlayer)
onAddNewPlayer(c);
else if (object instanceof RemovePlayer)
onRemovePlayer(c);
}
Listener connectionListener = new Listener() {
public void received(com.esotericsoftware.kryonet.Connection arg0, Object arg1) {
onReceived(arg0, arg1);
};
public void connected(com.esotericsoftware.kryonet.Connection arg0) {
onConnected(arg0);
};
};
public void update() {
if (gameManager != null && gameManager.gameStarted)
gameManager.update();
if (gameManager != null && System.currentTimeMillis() - time > UPDATE_PERIOD) {
if (gameManager.gameStarted)
periodicGameUpdate();
else
periodicNonGameUpdate();
time = System.currentTimeMillis();
}
}
public void periodicGameUpdate() {
}
public void periodicNonGameUpdate() {
}
public boolean isRunning() {
return running;
}
public abstract boolean startGame();
public abstract void stop();
public Object updatePlayer(String uuid, MazePlayer p, boolean force) {
if (force) {
NetworkCommon.UpdatePlayerTransformServer pu = new NetworkCommon.UpdatePlayerTransformServer();
Vector3 pos = p.getPos();
Quaternion rot = p.getRotation();
pu.tx = pos.x;
pu.ty = pos.y;
pu.tz = pos.z;
pu.rx = rot.x;
pu.ry = rot.y;
pu.rz = rot.z;
pu.rw = rot.w;
pu.uuid = uuid;
System.out.println("Forcing position update to all clients for player " + uuid);
return pu;
} else {
UpdatePlayerTransform pu = new UpdatePlayerTransform();
Vector3 pos = p.getPos();
Quaternion rot = p.getRotation();
pu.tx = pos.x;
pu.ty = pos.y;
pu.tz = pos.z;
pu.rx = rot.x;
pu.ry = rot.y;
pu.rz = rot.z;
pu.rw = rot.w;
pu.uuid = uuid;
System.out.println("Sending position update to all clients for player " + uuid);
return pu;
}
}
}

View File

@ -1,12 +1,12 @@
package com.emamaker.amazeing.maze;
import java.util.ArrayList;
import java.util.Random;
import com.emamaker.amazeing.AMazeIng;
import com.emamaker.amazeing.maze.settings.MazeSettings;
import com.emamaker.voxelengine.block.CellId;
import java.util.ArrayList;
import java.util.Random;
public class MazeGenerator {
AMazeIng main;
@ -254,7 +254,6 @@ public class MazeGenerator {
WINX = i;
WINZ = j;
System.out.println("Win position in: " + i + ", " + j);
main.world.worldManager.setCell(i, 0, j, CellId.ID_WOOD);
}
}
@ -268,7 +267,7 @@ public class MazeGenerator {
public void requestChangeToMap(int[][] todraw_) {
if(AMazeIng.getMain().client.isRunning()) {
AMazeIng.getMain().client.requestUpdateMap(todraw_);
// AMazeIng.getMain().client.requestUpdateMap(todraw_);
}else {
show(todraw_);
}

View File

@ -1,7 +1,5 @@
package com.emamaker.amazeing.maze.settings;
import java.util.Arrays;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
@ -10,6 +8,8 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.emamaker.amazeing.ui.UIManager;
import java.util.Arrays;
public class MazeSetting {
/*This object holds whatever is needed for a single setting to be changed, this includes:

View File

View File

View File

@ -1,9 +1,9 @@
package com.emamaker.amazeing.maze.settings;
import java.util.ArrayList;
import com.emamaker.amazeing.AMazeIng;
import java.util.ArrayList;
public class MazeSettings {
// This must only hold public static variables to eventually their getters and

87
core/src/com/emamaker/amazeing/player/MazePlayer.java Normal file → Executable file
View File

@ -1,7 +1,5 @@
package com.emamaker.amazeing.player;
import java.util.Random;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.g3d.Environment;
@ -19,6 +17,8 @@ import com.emamaker.amazeing.AMazeIng;
import com.emamaker.amazeing.player.powerups.PowerUp;
import com.emamaker.voxelengine.physics.GameObject;
import java.util.Random;
public abstract class MazePlayer implements Disposable {
AMazeIng main;
@ -33,13 +33,15 @@ public abstract class MazePlayer implements Disposable {
static int meshAttr = VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal;
public GameObject obj;
String name = "";
boolean disposing = false;
boolean disposed = false;
boolean playing = false;
boolean built = false;
boolean show = true;
boolean initedPhysics = false;
boolean toUpdatePos = false;
public String uuid;
public PowerUp currentPowerUp;
public float baseSpeed = 3f;
public float baseTurnSpeed = 2.5f;
public float speedMult = 1f;
@ -51,17 +53,14 @@ public abstract class MazePlayer implements Disposable {
MazePlayer(boolean s) {
this(String.valueOf((char) (65 + rand.nextInt(26))), s);
disposing = false;
disposed = false;
playing = false;
}
MazePlayer(String name, boolean s) {
main = AMazeIng.getMain();
show = s;
setName(name);
if (show)
buildModel();
built = false;
}
public Vector3 getPos() {
@ -72,23 +71,19 @@ public abstract class MazePlayer implements Disposable {
return rot;
}
public void setPlaying() {
disposing = false;
playing = true;
}
public void setPos(Vector3 v) {
if (!disposing)
setPos(v.x, v.y, v.z);
setPos(v.x, v.y, v.z);
}
public void setPos(float x, float y, float z) {
if (!disposing)
setTransform(x, y, z, 0, 0, 0, 0);
if (!disposed) {
pos.set(x, y, z);
toUpdatePos = true;
}
}
public void setTransform(float x, float y, float z, float i, float j, float k, float l) {
if (!disposing && !disposed) {
if (!disposed) {
pos.set(x, y, z);
rot.set(i, j, k, l);
if (show)
@ -96,6 +91,13 @@ public abstract class MazePlayer implements Disposable {
}
}
protected void updateFromTmpPos() {
if (toUpdatePos && initedPhysics) {
setTransform(pos.x, pos.y, pos.z, 0, 0, 0, 0);
toUpdatePos = false;
}
}
public void setName(String name_) {
this.name = name_;
}
@ -104,14 +106,6 @@ public abstract class MazePlayer implements Disposable {
return name;
}
public void render(ModelBatch b, Environment e) {
if (!disposing && ! disposed && playing) {
update();
if (show)
b.render(instance, e);
}
}
@SuppressWarnings("deprecation")
public void buildModel() {
modelBuilder.begin();
@ -122,13 +116,34 @@ public abstract class MazePlayer implements Disposable {
instance = new ModelInstance(mazePlayerModel);
}
public void initPhysics() {
initedPhysics = true;
}
public void update() {
speed = baseSpeed * speedMult;
turnSpeed = baseTurnSpeed * speedMult;
if(currentPowerUp != null && currentPowerUp.continousEffect) usePowerUp();
updateFromTmpPos();
if (currentPowerUp != null && currentPowerUp.continousEffect && currentPowerUp.beingUsed)
usePowerUp();
}
public void render(ModelBatch b, Environment e) {
if (!disposed && show) {
if (!built) {
buildModel();
initPhysics();
built = true;
}
updateFromTmpPos();
b.render(instance, e);
}
}
public void usePowerUp() {
if (currentPowerUp != null && !currentPowerUp.beingUsed)
if (currentPowerUp.usePowerUp(this))
@ -137,22 +152,14 @@ public abstract class MazePlayer implements Disposable {
@Override
public void dispose() {
playing = false;
if (!disposed) {
disposing = true;
if (show)
if (show && built)
mazePlayerModel.dispose();
disposing = false;
}
disposed = true;
}
public boolean isDisposed() {
return disposed;
}
public boolean isPlaying() {
return playing;
}
}

View File

@ -73,7 +73,6 @@ public class MazePlayerLocal extends MazePlayer {
this.starty = starty;
this.startz = startz;
initPhysics();
}
public MazePlayerLocal(Controller ctrl_) {
@ -96,7 +95,6 @@ public class MazePlayerLocal extends MazePlayer {
this.starty = starty;
this.startz = startz;
initPhysics();
}
public MazePlayerLocal(Touchpad ctrl_, int p) {
@ -127,10 +125,10 @@ public class MazePlayerLocal extends MazePlayer {
touchpadPressed = false;
touchpadPowerUp = new TextButton("No object to use", AMazeIng.getMain().uiManager.skin);
tctrl.setSize(Gdx.graphics.getHeight() / 6f, Gdx.graphics.getHeight() / 6f);
touchpadPowerUp.setSize(Gdx.graphics.getHeight() / 6f, Gdx.graphics.getHeight() / 12f);
tctrl.addListener(new InputListener() {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
@ -169,16 +167,17 @@ public class MazePlayerLocal extends MazePlayer {
} else if (tctrlPosition == 2) {
tctrl.setPosition(Gdx.graphics.getWidth() - tctrl.getWidth() * 1.5f,
Gdx.graphics.getHeight() - tctrl.getHeight() * 1.5f);
touchpadPowerUp.setPosition(Gdx.graphics.getWidth() - tctrl.getWidth() * 1.5f, Gdx.graphics.getHeight() - tctrl.getHeight() *2.25f);
touchpadPowerUp.setPosition(Gdx.graphics.getWidth() - tctrl.getWidth() * 1.5f,
Gdx.graphics.getHeight() - tctrl.getHeight() * 2.25f);
} else if (tctrlPosition == 3) {
tctrl.setPosition(tctrl.getWidth() / 2, Gdx.graphics.getHeight() - tctrl.getHeight() * 1.5f);
touchpadPowerUp.setPosition(tctrl.getWidth() / 2, Gdx.graphics.getHeight() - tctrl.getHeight() * 2.25f);
}
initPhysics();
}
public void initPhysics() {
super.initPhysics();
characterTransform = instance.transform; // Set by reference
characterTransform.set(startx, starty, startz, 0, 0, 0, 0);
@ -211,8 +210,8 @@ public class MazePlayerLocal extends MazePlayer {
else
inputTouchscreen();
if (pressed)
main.client.updateLocalPlayer(this);
// if (pressed)
// main.client.updateLocalPlayer(this);
}
public void inputController() {
@ -250,7 +249,8 @@ public class MazePlayerLocal extends MazePlayer {
public void inputTouchscreen() {
if (touchpadPressed) {
touchpadPowerUp.setText("No object to use");
if(currentPowerUp != null) touchpadPowerUp.setText(currentPowerUp.name.toUpperCase() + "!");
if (currentPowerUp != null)
touchpadPowerUp.setText(currentPowerUp.name.toUpperCase() + "!");
// characterTransform.rotate(0, 1, 0, angle-oldAngle);
// ghostObject.setWorldTransform(characterTransform);
@ -280,31 +280,29 @@ public class MazePlayerLocal extends MazePlayer {
@Override
public void update() {
super.update();
inputs();
if(initedPhysics) inputs();
}
@Override
public Vector3 getPos() {
if (!disposing) {
return ghostObject.getWorldTransform().getTranslation(new Vector3());
}
return null;
protected void updateFromTmpPos() {
super.updateFromTmpPos();
if(initedPhysics) pos.set(ghostObject.getWorldTransform().getTranslation(new Vector3()));
}
@Override
public void setPos(Vector3 v) {
this.setPos(v.x, v.y, v.z);
}
@Override
public void setPos(float x, float y, float z) {
if (!disposing)
setTransform(x, y, z, 0, 0, 0, 0);
}
// @Override
// public void setPos(Vector3 v) {
// this.setPos(v.x, v.y, v.z);
// }
//
// @Override
// public void setPos(float x, float y, float z) {
// if (!disposed)
// setTransform(x, y, z, 0, 0, 0, 0);
// }
@Override
public void setTransform(float x, float y, float z, float i, float j, float k, float l) {
if (!disposing) {
if (!disposed && initedPhysics) {
characterTransform.set(x, y, z, i, j, k, l);
ghostObject.setWorldTransform(characterTransform);
}
@ -313,7 +311,6 @@ public class MazePlayerLocal extends MazePlayer {
@Override
public void dispose() {
super.dispose();
disposing = true;
if (!isDisposed()) {
main.world.dynamicsWorld.removeAction(characterController);
main.world.dynamicsWorld.removeCollisionObject(ghostObject);
@ -322,7 +319,6 @@ public class MazePlayerLocal extends MazePlayer {
ghostShape.dispose();
disposed = true;
}
disposing = false;
}
}

View File

@ -1,9 +1,9 @@
package com.emamaker.amazeing.player;
import java.util.Random;
import com.emamaker.amazeing.AMazeIng;
import java.util.Random;
public class MazePlayerRemote extends MazePlayer{
/*Remote controlled player to show other players on the server*/

8
core/src/com/emamaker/amazeing/player/PlayerUtils.java Normal file → Executable file
View File

@ -1,14 +1,14 @@
package com.emamaker.amazeing.player;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.controllers.Controller;
import com.emamaker.amazeing.maze.settings.MazeSettings;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class PlayerUtils {
public static int[] WASDKEYS = {Keys.W, Keys.S, Keys.A, Keys.D, Keys.SPACE};

View File

@ -13,15 +13,16 @@ import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;
import com.badlogic.gdx.graphics.g3d.model.Node;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Disposable;
import com.emamaker.amazeing.AMazeIng;
import com.emamaker.amazeing.player.MazePlayer;
public class PowerUp {
public class PowerUp implements Disposable {
public String name;
Texture texture;
public boolean beingUsed, continousEffect;
public boolean beingUsed, continousEffect, built;
ModelBuilder modelBuilder = new ModelBuilder();
ModelInstance instance;
@ -48,9 +49,7 @@ public class PowerUp {
blendingAttribute.destFunction = GL20.GL_ONE_MINUS_SRC_ALPHA;
beingUsed = false;
spawnQuad();
setPosition(0, 3, 0);
built = false;
}
@SuppressWarnings("deprecation")
@ -72,11 +71,15 @@ public class PowerUp {
}
public void render(ModelBatch b, Environment e) {
if (!built) {
spawnQuad();
built = true;
}
b.render(instance, e);
}
public void setPosition(float x, float y, float z) {
instance.transform.set(x, y, z, 0, 0, 0, 0);
if(built) instance.transform.set(x, y, z, 0, 0, 0, 0);
}
public void setPosition(Vector3 v) {
@ -84,7 +87,7 @@ public class PowerUp {
}
public Vector3 getPosition() {
return instance.transform.getTranslation(new Vector3());
return built ? instance.transform.getTranslation(new Vector3()) : Vector3.Zero;
}
// Return true if the effect has been resolved
@ -92,6 +95,11 @@ public class PowerUp {
// System.out.println(this.name + "!");
return true;
}
@Override
public void dispose() {
quadModel.dispose();
}
}
class PowerUpTemporized extends PowerUp {
@ -99,17 +107,15 @@ class PowerUpTemporized extends PowerUp {
long time = 0, startTime = 0;
boolean used = false;
public PowerUpTemporized(String name_, Texture texture_, boolean cont, float secs_) {
this(name_, texture_, cont, secs_, 1, 1);
}
public PowerUpTemporized(String name_, Texture texture_, boolean cont, float secs_, float scaleX, float scaleZ) {
super(name_, texture_, cont, scaleX, scaleZ);
this.time = (long) (secs_*1000);
this.time = (long) (secs_ * 1000);
startTime = 0;
}
@Override
public boolean usePowerUp(MazePlayer player) {
@ -129,13 +135,13 @@ class PowerUpTemporized extends PowerUp {
return true;
}
}
public void temporizedEffect(MazePlayer player) {
beingUsed = true;
}
public void temporizedEffectExpired(MazePlayer player) {
beingUsed = false;
}
}

View File

View File

View File

View File

0
core/src/com/emamaker/amazeing/ui/UIManager.java Normal file → Executable file
View File

View File

View File

@ -1,8 +1,5 @@
package com.emamaker.amazeing.ui.screens;
import java.util.ArrayList;
import java.util.HashSet;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox;
@ -20,6 +17,9 @@ import com.emamaker.amazeing.player.MazePlayerLocal;
import com.emamaker.amazeing.player.PlayerUtils;
import com.emamaker.amazeing.ui.UIManager;
import java.util.ArrayList;
import java.util.HashSet;
public class PlayerChooseScreen extends MyScreen {
Label[] labels;

View File

@ -122,7 +122,7 @@ public class PreGameScreen extends MyScreen {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
buildTable();
AMazeIng.getMain().client.setUpdateMobilePlayers();
// AMazeIng.getMain().client.setUpdateMobilePlayers();
return true;
}
@ -213,7 +213,7 @@ public class PreGameScreen extends MyScreen {
instLab.setText(type.toString() + ": Waiting for players to join...");
// Constantly update player labels, comparing with the remote players present on
// server
nPlayers = type == GameType.SERVER ? uiManager.main.server.remotePlayers.values().size()
nPlayers = type == GameType.SERVER ? uiManager.main.server.players.size()
: uiManager.main.client.players.size();
if(AMazeIng.isMobile()) nPlayers -= MazeSettings.MAXPLAYERS_MOBILE;

View File

View File

@ -107,7 +107,7 @@ public class ServerLaunchScreen extends MyScreen {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
try {
if(uiManager.main.server.startServer(Integer.valueOf(srvPort.getText()))) {
if(uiManager.main.server.start(Integer.valueOf(srvPort.getText())) && uiManager.main.client.start("localhost", Integer.valueOf(srvPort.getText()))) {
// If the server and the client have been started successfully, we can show the
// joining screen
MazeSettings.setPlayers.setOptions(MazeSettings.maxPlayersDesktop, 3);

View File

@ -140,7 +140,7 @@ public class SettingsScreen extends MyScreen {
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
//If we are running server, we must send update to clients
AMazeIng.getMain().server.updateSettingForAll();
// AMazeIng.getMain().server.updateSettingForAll();
hide();
uiManager.main.setScreen(prevScreen == null ? uiManager.titleScreen : prevScreen);

View File

@ -1 +0,0 @@
Subproject commit 4a8f6a52c8cb62361909813042ff99d61bd98611

0
desktop/assets/data/Untitled.xcf Normal file → Executable file
View File

0
desktop/assets/data/powerups/Untitled.xcf Normal file → Executable file
View File

0
desktop/assets/data/powerups/ball_and_chain.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

0
desktop/assets/data/powerups/ball_and_chain.xcf Normal file → Executable file
View File

0
desktop/assets/data/powerups/bomb.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

0
desktop/assets/data/powerups/bomb.xcf Normal file → Executable file
View File

0
desktop/assets/data/powerups/feather.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
desktop/assets/data/powerups/slug.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

0
desktop/assets/data/powerups/slug.xcf Normal file → Executable file
View File

0
desktop/assets/data/shaders/testshader_frag.glsl Normal file → Executable file
View File

0
desktop/assets/data/shaders/testshader_vert.glsl Normal file → Executable file
View File

0
desktop/assets/data/touchscreen_controller.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

0
desktop/build.gradle Normal file → Executable file
View File

View File

2
gradle.properties Normal file → Executable file
View File

@ -1,3 +1,5 @@
org.gradle.daemon=true
org.gradle.jvmargs=-Xms128m -Xmx1500m
org.gradle.configureondemand=false
android.enableJetifier=true
android.useAndroidX=true

BIN
gradle/wrapper/gradle-5.4.1-bin.zip vendored Normal file

Binary file not shown.

0
gradle/wrapper/gradle-wrapper.jar vendored Normal file → Executable file
View File

3
gradle/wrapper/gradle-wrapper.properties vendored Normal file → Executable file
View File

@ -1,5 +1,6 @@
#Wed May 20 00:14:06 CEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip

0
gradlew.bat vendored Normal file → Executable file
View File

0
ios/Info.plist.xml Normal file → Executable file
View File

Some files were not shown because too many files have changed in this diff Show More