JSON serial change & working basic gameplay

This commit is contained in:
Thomas
2020-08-27 11:10:00 +02:00
parent e2e4495f02
commit cec5fca5c4
16 changed files with 131 additions and 52 deletions

View File

@@ -53,13 +53,13 @@ export default {
this.players.forEach(player => { this.players.forEach(player => {
this.renderPlayer(player) this.renderPlayer(player)
this.renderWalls(player.walls, player.color) this.renderWalls(player)
}) })
this.renderDebug() this.renderDebug(this.player)
this.checkPlayerColision() // this.checkPlayerColision()
this.updatePlayer() this.updatePlayer(this.player)
}, },
renderBorders () { renderBorders () {
this.context.strokeStyle = 'black' this.context.strokeStyle = 'black'
@@ -80,19 +80,19 @@ export default {
this.context.restore() this.context.restore()
}, },
renderWalls (walls, color) { renderWalls (player) {
this.context.beginPath() this.context.beginPath()
this.context.lineWidth = this.settings.wallSize this.context.lineWidth = this.settings.wallSize
this.context.strokeStyle = color this.context.strokeStyle = player.color
walls.forEach(wall => { player.walls.forEach(wall => {
const canvasX = this.canvas.width / 2 + wall.x - this.player.x const canvasX = this.canvas.width / 2 + wall.x - this.player.x
const canvasY = this.canvas.height / 2 + wall.y - this.player.y const canvasY = this.canvas.height / 2 + wall.y - this.player.y
this.context.lineTo(canvasX, canvasY) this.context.lineTo(canvasX, canvasY)
}) })
this.context.lineTo(this.canvas.width / 2, this.canvas.height / 2) this.context.lineTo(this.canvas.width / 2 + player.x - this.player.x, this.canvas.height / 2 + player.y - this.player.y)
this.context.stroke() this.context.stroke()
}, },
renderDebug () { renderDebug (player) {
this.context.beginPath() this.context.beginPath()
const canvasX = this.canvas.width / 2 const canvasX = this.canvas.width / 2
const canvasY = this.canvas.height / 2 const canvasY = this.canvas.height / 2
@@ -102,8 +102,8 @@ export default {
this.context.strokeStyle = 'blue' this.context.strokeStyle = 'blue'
this.context.stroke() this.context.stroke()
const x = canvasX + 30 * Math.cos(this.player.angle) * 2 const x = canvasX + 30 * Math.cos(player.angle) * 2
const y = canvasY + 30 * Math.sin(this.player.angle) * 2 const y = canvasY + 30 * Math.sin(player.angle) * 2
this.context.beginPath() this.context.beginPath()
this.context.lineTo(canvasX, canvasY) this.context.lineTo(canvasX, canvasY)
this.context.lineTo(x, y) this.context.lineTo(x, y)
@@ -125,10 +125,10 @@ export default {
this.context.strokeStyle = 'purple' this.context.strokeStyle = 'purple'
this.context.stroke() this.context.stroke()
this.context.fillText('player x: ' + this.player.x + ' y:' + this.player.y, 10, 10) this.context.fillText('player x: ' + player.x + ' y:' + player.y, 10, 10)
this.context.fillText('a:' + this.player.angle + ' a_t' + this.player.targetAngle, 10, 20) this.context.fillText('a:' + player.angle + ' a_t' + player.targetAngle, 10, 20)
this.context.fillText('canvasX: ' + canvasX + ' canvasY:' + canvasY, 10, 30) this.context.fillText('canvasX: ' + canvasX + ' canvasY:' + canvasY, 10, 30)
this.context.fillText('walls: ' + this.player.walls.length, 10, 40) this.context.fillText('walls: ' + player.walls.length, 10, 40)
}, },
mouseEvent (event) { mouseEvent (event) {
var rect = this.canvas.getBoundingClientRect() var rect = this.canvas.getBoundingClientRect()
@@ -141,17 +141,19 @@ export default {
this.player.targetAngle = Math.atan2(dy, dx) this.player.targetAngle = Math.atan2(dy, dx)
send({ message: this.player, type: 'update' }) send({ message: this.player, type: 'update' })
}, },
updatePlayer () { updatePlayer (player) {
/*
this.player.lastWall++ this.player.lastWall++
if (this.player.lastWall > this.settings.wallUpdate) { if (this.player.lastWall > this.settings.wallUpdate) {
this.player.walls.push({ x: this.player.x, y: this.player.y }) this.player.walls.push({ x: this.player.x, y: this.player.y })
this.player.lastWall = 0 this.player.lastWall = 0
} }
*/
this.player.x += this.settings.playerSpeed * Math.cos(this.player.angle) player.x += this.settings.playerSpeed * Math.cos(player.angle)
this.player.y += this.settings.playerSpeed * Math.sin(this.player.angle) player.y += this.settings.playerSpeed * Math.sin(player.angle)
this.player.angle = this.player.targetAngle player.angle = player.targetAngle
// angle lag // angle lag
/* /*
if (this.player.targetAngle !== this.player.angle) { if (this.player.targetAngle !== this.player.angle) {

View File

@@ -4,8 +4,6 @@ const state = {
y: 100, y: 100,
angle: 0, angle: 0,
targetAngle: 0, targetAngle: 0,
walls: [],
lastWall: 0,
color: 'red' color: 'red'
}, },
players: { players: {
@@ -37,8 +35,10 @@ const actions = {
commit('SET_SETTINGS', settings) commit('SET_SETTINGS', settings)
}, },
update ({ commit }, update) { update ({ commit }, update) {
commit('SET_PLAYERS', update)
}, },
dead ({ commit }) { dead ({ commit }, player) {
commit('SET_PLAYER', player)
}, },
error ({ commit }, error) { error ({ commit }, error) {
alert('Error: ' + error) alert('Error: ' + error)
@@ -49,6 +49,9 @@ const mutations = {
SET_PLAYER (state, player) { SET_PLAYER (state, player) {
state.player = player state.player = player
}, },
SET_PLAYERS (state, players) {
state.players = players
},
SET_SETTINGS (state, settings) { SET_SETTINGS (state, settings) {
state.settings = settings state.settings = settings
}, },

View File

@@ -33,7 +33,7 @@ export default function createSocketPlugin () {
store.dispatch('game/update', data.message) store.dispatch('game/update', data.message)
break break
case 'gamePlayerDead': case 'gamePlayerDead':
store.dispatch('game/dead') store.dispatch('game/dead', data.message)
break break
default: default:
break break

View File

@@ -14,7 +14,6 @@
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-json/2.3.1.RELEASE/spring-boot-starter-json-2.3.1.RELEASE.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-json/2.3.1.RELEASE/spring-boot-starter-json-2.3.1.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-databind/2.11.0/jackson-databind-2.11.0.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-databind/2.11.0/jackson-databind-2.11.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-annotations/2.11.0/jackson-annotations-2.11.0.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-annotations/2.11.0/jackson-annotations-2.11.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-core/2.11.0/jackson-core-2.11.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.11.0/jackson-datatype-jdk8-2.11.0.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.11.0/jackson-datatype-jdk8-2.11.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.11.0/jackson-datatype-jsr310-2.11.0.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.11.0/jackson-datatype-jsr310-2.11.0.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/module/jackson-module-parameter-names/2.11.0/jackson-module-parameter-names-2.11.0.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/module/jackson-module-parameter-names/2.11.0/jackson-module-parameter-names-2.11.0.jar" enabled="true" runInBatchMode="false"/>
@@ -36,4 +35,5 @@
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-core/5.2.7.RELEASE/spring-core-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-core/5.2.7.RELEASE/spring-core-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-jcl/5.2.7.RELEASE/spring-jcl-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-jcl/5.2.7.RELEASE/spring-jcl-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/json/json/20200518/json-20200518.jar" enabled="true" runInBatchMode="false"/> <factorypathentry kind="VARJAR" id="M2_REPO/org/json/json/20200518/json-20200518.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-core/2.11.2/jackson-core-2.11.2.jar" enabled="true" runInBatchMode="false"/>
</factorypath> </factorypath>

View File

@@ -50,6 +50,12 @@
<artifactId>json</artifactId> <artifactId>json</artifactId>
<version>20200518</version> <version>20200518</version>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.2</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -2,10 +2,15 @@ package gltronic.tronio;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@SpringBootApplication @SpringBootApplication
@EnableScheduling
@ComponentScan(basePackages = "gltronic.tronio") @ComponentScan(basePackages = "gltronic.tronio")
@PropertySource("classpath:application.properties") @PropertySource("classpath:application.properties")
public class TronIoApplication { public class TronIoApplication {
@@ -14,4 +19,15 @@ public class TronIoApplication {
SpringApplication.run(TronIoApplication.class, args); SpringApplication.run(TronIoApplication.class, args);
} }
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(2);
scheduler.setThreadNamePrefix("scheduled-task-");
scheduler.setDaemon(true);
return scheduler;
}
} }

View File

@@ -4,8 +4,11 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import org.json.JSONObject; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
@@ -24,14 +27,17 @@ public class GameManager implements IGameManager {
SocketUtils.sendMessage(session, "error", "cant login twice"); SocketUtils.sendMessage(session, "error", "cant login twice");
return; return;
} }
Player player = initPlayer(new Player()); Player player = initPlayer(new Player());
game.getSessions().put(session.getId(), session); game.getSessions().put(session.getId(), session);
game.getPlayers().put(session.getId(), player); game.getPlayers().put(session.getId(), player);
SocketUtils.forwardMessage(session, "login", new JSONObject(player)); System.out.println("[GAME] Player " + session.getId() + " logged in | status: " + player.getX() + " " + player.getY() + " " + player.getColor());
SocketUtils.forwardMessage(session, "gameSettings", new JSONObject(game.getSettings()));
SocketUtils.sendObject(session, "login", new ObjectMapper().writeValueAsString(player));
SocketUtils.sendObject(session, "gameSettings", new ObjectMapper().writeValueAsString(game.getSettings()));
SocketUtils.sendObject(session, "gameUpdate", new ObjectMapper().writeValueAsString(game.getPlayers().values()));
} }
@Override @Override
@@ -48,14 +54,16 @@ public class GameManager implements IGameManager {
} }
@Override @Override
@Scheduled(fixedDelay = 1000 / 60)
public void step() throws InterruptedException, IOException { public void step() throws InterruptedException, IOException {
// CHECK OUT OF BORDERS & COLISIONS // CHECK OUT OF BORDERS & COLISIONS
game.getPlayers().forEach((id, player) -> { game.getPlayers().forEach((id, player) -> {
// OUT OF BORDERS // OUT OF BORDERS
if (player.getX() - game.getSettings().getPlayerSize() < 0 || if (player.getX() - game.getSettings().getPlayerSize() < 0
player.getX() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize() || || player.getX() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize()
player.getY() - game.getSettings().getPlayerSize() < 0 || || player.getY() - game.getSettings().getPlayerSize() < 0
player.getY() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize()) { || player.getY() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize()) {
System.out.println("[GAME] border");
killPlayer(id); killPlayer(id);
return; return;
} }
@@ -65,8 +73,12 @@ public class GameManager implements IGameManager {
for (var i = 0; i < player2.getWalls().size() - 2; i++) { for (var i = 0; i < player2.getWalls().size() - 2; i++) {
Wall wallA = player2.getWalls().get(i); Wall wallA = player2.getWalls().get(i);
Wall wallB = player2.getWalls().get(i + 1); Wall wallB = player2.getWalls().get(i + 1);
if (isCloseToWall(wallA.getX(), wallA.getY(), wallB.getX(), wallB.getY(), player.getX(), player.getY(), game.getSettings().getPlayerSize())) { if (isCloseToWall(wallA.getX(), wallA.getY(), wallB.getX(), wallB.getY(), player.getX(), player.getY(),
if (this.isCrossingLine(wallA.getX(), wallA.getY(), wallB.getX(), wallB.getY(), player.getX(), player.getY(), game.getSettings().getPlayerSize())) { game.getSettings().getPlayerSize())) {
System.out.println("[GAME] 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");
killPlayer(id); killPlayer(id);
return; return;
} }
@@ -88,12 +100,21 @@ public class GameManager implements IGameManager {
player.setX(player.getX() + game.getSettings().getPlayerSpeed() * Math.cos(player.getAngle())); player.setX(player.getX() + game.getSettings().getPlayerSpeed() * Math.cos(player.getAngle()));
player.setY(player.getY() + game.getSettings().getPlayerSpeed() * Math.sin(player.getAngle())); player.setY(player.getY() + game.getSettings().getPlayerSpeed() * Math.sin(player.getAngle()));
}); });
SocketUtils.broadcast(game, "gameUpdate", new ObjectMapper().writeValueAsString(game.getPlayers().values()));
} }
private void killPlayer (String id) { private void killPlayer(String id) {
Player player = game.getPlayers().get(id); Player player = game.getPlayers().get(id);
initPlayer(player); initPlayer(player);
SocketUtils.sendMessage(game.getSessions().get(id), "gamePlayerDead", "yo dead"); System.out.println("[GAME] Player " + id + " is dead | status: " + player.getX() + " " + player.getY() + " " + player.getColor());
try {
SocketUtils.sendObject(game.getSessions().get(id), "gamePlayerDead",
new ObjectMapper().writeValueAsString(player));
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
private boolean isCloseToWall (double xa, double ya, double xb, double yb, double xc, double yc, double radius) { private boolean isCloseToWall (double xa, double ya, double xb, double yb, double xc, double yc, double radius) {
@@ -120,8 +141,8 @@ public class GameManager implements IGameManager {
double x = game.getSettings().getArenaSize() * (0.25 + Math.random() * 0.5); double x = game.getSettings().getArenaSize() * (0.25 + Math.random() * 0.5);
double y = game.getSettings().getArenaSize() * (0.25 + Math.random() * 0.5); double y = game.getSettings().getArenaSize() * (0.25 + Math.random() * 0.5);
player.setAngle(0); // player.setAngle(0);
player.setTargetAngle(0); // player.setTargetAngle(0);
player.setLastWall(0); player.setLastWall(0);
player.setWalls(new ArrayList<Wall>()); player.setWalls(new ArrayList<Wall>());
player.setColor(String.format("#%06x", rand.nextInt(0xffffff + 1))); player.setColor(String.format("#%06x", rand.nextInt(0xffffff + 1)));

View File

@@ -2,7 +2,6 @@ package gltronic.tronio.business;
import java.io.IOException; import java.io.IOException;
import org.json.JSONObject;
import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
@@ -17,17 +16,17 @@ public class SocketUtils {
} }
} }
public static void forwardMessage(WebSocketSession session, String type, JSONObject message) { public static void sendObject(WebSocketSession session, String type, String object) {
try { try {
session.sendMessage(new TextMessage("{\"type\":\"" + type + "\",\"message\": " + message.toString() + " }")); session.sendMessage(new TextMessage("{\"type\":\"" + type + "\",\"message\": " + object + " }"));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void broadcast(Game game, String type, JSONObject message) { public static void broadcast(Game game, String type, String message) {
game.getSessions().forEach((id, session) -> { game.getSessions().forEach((id, session) -> {
forwardMessage(session, type, message); sendObject(session, type, message);
}); });
} }
} }

View File

@@ -2,6 +2,8 @@ package gltronic.tronio.model;
import java.util.ArrayList; import java.util.ArrayList;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@@ -9,13 +11,20 @@ import lombok.Setter;
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Player { public class Player {
private double x;
private double y;
private double angle;
private double targetAngle;
private ArrayList<Wall> walls;
private int lastWall;
private String color; private String color;
private double x;
private double y;
private double angle;
private double targetAngle;
private ArrayList<Wall> walls;
private int lastWall;
} }

View File

@@ -2,6 +2,8 @@ package gltronic.tronio.web;
import java.io.IOException; import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.json.JSONObject; import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -23,15 +25,17 @@ public class SocketHandler extends TextWebSocketHandler {
@Override @Override
public void handleTextMessage(WebSocketSession session, TextMessage message) public void handleTextMessage(WebSocketSession session, TextMessage message)
throws InterruptedException, IOException { throws InterruptedException, IOException {
System.err.println("[WS] message :" + message.getPayload()); // System.err.println("[WS] message :" + message.getPayload());
String payload = message.getPayload(); String payload = message.getPayload();
JSONObject jsonObject = new JSONObject(payload); JSONObject rootObject = new JSONObject(payload);
String type = (String) jsonObject.get("type"); String type = rootObject.getString("type");
switch (type) { switch (type) {
case "update": case "update":
gameManager.updatePlayer(session, (Player) jsonObject.get("message")); Player player = new ObjectMapper().readValue(rootObject.get("message").toString(), Player.class);
gameManager.updatePlayer(session, player);
break; break;
default: default:
SocketUtils.sendMessage(session, "error", "unknow command"); SocketUtils.sendMessage(session, "error", "unknow command");

19
test.json Normal file
View File

@@ -0,0 +1,19 @@
{
"type":"gameUpdate",
"message": [
{
"color":"#0deeff",
"x":361.69764869823257,
"y":427.9410817135364,
"angle":0.0,
"targetAngle":0.0,
"walls":[
{"x":323.69764869823257,"y":427.9410817135364},
{"x":335.69764869823257,"y":427.9410817135364},
{"x":347.69764869823257,"y":427.9410817135364},
{"x":359.69764869823257,"y":427.9410817135364}
],
"lastWall":0
}
]
}