Added leaderboard, music & respawn screen

This commit is contained in:
Thomas
2020-09-03 16:13:04 +02:00
parent 4d542c1091
commit 832e55c0a3
20 changed files with 259 additions and 113 deletions

View File

@@ -17,6 +17,7 @@ import org.springframework.web.socket.WebSocketSession;
import gltronic.tronio.model.Game;
import gltronic.tronio.model.GameUpdate;
import gltronic.tronio.model.Player;
import gltronic.tronio.model.PlayerState;
import gltronic.tronio.model.Wall;
@Service
@@ -33,6 +34,7 @@ public class GameManager implements IGameManager {
Player player = initPlayer(new Player());
player.setName(name);
player.setBestScore(0);
game.getSessions().put(session.getId(), session);
game.getPlayers().put(session.getId(), player);
@@ -58,7 +60,7 @@ public class GameManager implements IGameManager {
}
@Override
@Scheduled(fixedDelay = 1000 / 120)
@Scheduled(fixedDelay = 1000 / 60)
public void step() throws InterruptedException, IOException {
Instant currentTime = Instant.now();
Duration durationSinceLastUpdate = Duration.between(game.getLastUpdate(), currentTime);
@@ -66,6 +68,8 @@ public class GameManager implements IGameManager {
// CHECK OUT OF BORDERS & COLISIONS
game.getPlayers().forEach((id, player) -> {
if (!player.getState().equals(PlayerState.ALIVE)) return;
// OUT OF BORDERS
if (player.getX() - game.getSettings().getPlayerSize() < 0
|| player.getX() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize()
@@ -75,21 +79,32 @@ public class GameManager implements IGameManager {
killPlayer(id);
return;
}
/*
// BORDER WRAP
if (player.getX() - game.getSettings().getPlayerSize() < 0) player.setX(game.getSettings().getPlayerSize());
else if (player.getX() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize()) player.setX(0);
else if (player.getY() - game.getSettings().getPlayerSize() < 0) player.setY(game.getSettings().getPlayerSize());
else if (player.getY() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize()) player.setY(0);
*/
// COLLISIONS
game.getPlayers().forEach((id2, player2) -> {
if (!player2.getState().equals(PlayerState.ALIVE)) return;
for (var i = 0; i < player2.getWalls().size() - 2; i++) {
// Pour evité la collision avec un mur venant d'être placé par le même joueur
if (id.equals(id2) && i >= player2.getWalls().size() - 4) break;
if (id.equals(id2) && i >= player2.getWalls().size() - 2) break;
Wall wallA = player2.getWalls().get(i);
Wall wallB = player2.getWalls().get(i + 1);
if (isCloseToWall(wallA.getX(), wallA.getY(), wallB.getX(), wallB.getY(), player.getX(), player.getY(),
game.getSettings().getPlayerSize())) {
System.out.println("[GAME] close to wall");
System.out.println("[GAME] " + player.getName() + " close to wall");
if (this.isCrossingLine(wallA.getX(), wallA.getY(), wallB.getX(), wallB.getY(), player.getX(),
player.getY(), game.getSettings().getPlayerSize())) {
System.out.println("[GAME] touch da wall");
System.out.println("[GAME] " + player.getName() + " killed by " + player2.getName());
if (!player.equals(player2)) player2.setScore(player.getScore() + 300);
killPlayer(id);
return;
}
@@ -100,6 +115,8 @@ public class GameManager implements IGameManager {
// ADD WALLS & MOVE PLAYER
game.getPlayers().forEach((id, player) -> {
if (!player.getState().equals(PlayerState.ALIVE)) return;
// On cherche le nombre de pas pour atteindre les 60 up/s
long tickToSimulate = ( durationSinceLastUpdate.toMillis() * 120 ) / 1000;
@@ -108,6 +125,7 @@ public class GameManager implements IGameManager {
player.setLastWall(player.getLastWall() + 1);
if (player.getLastWall() > game.getSettings().getWallUpdate()) {
player.getWalls().add(new Wall(player.getX(), player.getY()));
player.setScore(player.getScore() + 1);
player.setLastWall(0);
}
@@ -129,11 +147,13 @@ public class GameManager implements IGameManager {
private void killPlayer(String id) {
Player player = game.getPlayers().get(id);
initPlayer(player);
if (player.getBestScore() < player.getScore()) player.setBestScore(player.getScore());
player.setState(PlayerState.DEAD);
System.out.println("[GAME] Player " + player.getName() + " (" + id + ") is dead | status: " + player.getX() + " " + player.getY() + " " + player.getColor());
try {
SocketUtils.sendObject(game.getSessions().get(id), "gamePlayerDead",
new ObjectMapper().writeValueAsString(player));
SocketUtils.sendObject(game.getSessions().get(id), "gamePlayerDead", new ObjectMapper().writeValueAsString(player));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
@@ -166,7 +186,22 @@ public class GameManager implements IGameManager {
player.setColor(String.format("#%06x", rand.nextInt(0xffffff + 1)));
player.setX(x);
player.setY(y);
player.setScore(0);
player.setState(PlayerState.ALIVE);
return player;
}
@Override
public void respawn(WebSocketSession session) throws InterruptedException, IOException {
Player player = game.getPlayers().get(session.getId());
initPlayer(player);
player.setState(PlayerState.ALIVE);
try {
SocketUtils.sendObject(session, "gamePlayerSpawn", new ObjectMapper().writeValueAsString(player));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}

View File

@@ -10,6 +10,7 @@ public interface IGameManager {
void login(WebSocketSession session, String name) throws InterruptedException, IOException;
void leave(WebSocketSession session) throws InterruptedException, IOException;
void updatePlayer(WebSocketSession session, Player player) throws InterruptedException, IOException;
void respawn(WebSocketSession session) throws InterruptedException, IOException;
void step() throws InterruptedException, IOException;
}

View File

@@ -16,6 +16,7 @@ import lombok.Setter;
public class Game {
private Map<String, Player> players;
private Map<String, WebSocketSession> sessions;
private Map<String, Integer> leaderboard;
private GameSettings settings;
private boolean updateNeeded;
private Instant lastUpdate;
@@ -25,6 +26,7 @@ public class Game {
this.lastUpdate = Instant.now();
this.players = new HashMap<>();
this.sessions = new HashMap<>();
this.leaderboard = new HashMap<>();
this.settings = new GameSettings();
}
}

View File

@@ -16,9 +16,9 @@ public class GameSettings {
public GameSettings () {
this.arenaSize = 1000;
this.playerSize = 10;
this.playerSpeed = 2;
this.playerSpeed = 2.3;
this.playerTurnSpeed = 10;
this.wallSize = 8;
this.wallUpdate = 5;
this.wallUpdate = 20;
}
}

View File

@@ -17,6 +17,12 @@ public class Player {
private String color;
private int score;
private int bestScore;
private PlayerState state;
private double x;
private double y;

View File

@@ -0,0 +1,5 @@
package gltronic.tronio.model;
public enum PlayerState {
ALIVE, DEAD, PAUSED
}

View File

@@ -35,6 +35,9 @@ public class SocketHandler extends TextWebSocketHandler {
case "login":
gameManager.login(session, rootObject.getString("message"));
break;
case "respawn":
gameManager.respawn(session);
break;
case "update":
Player player = new ObjectMapper().readValue(rootObject.get("message").toString(), Player.class);
gameManager.updatePlayer(session, player);