diff --git a/client/src/components/Game.vue b/client/src/components/Game.vue
index cbe50fd..87f50ef 100644
--- a/client/src/components/Game.vue
+++ b/client/src/components/Game.vue
@@ -53,13 +53,13 @@ export default {
this.players.forEach(player => {
this.renderPlayer(player)
- this.renderWalls(player.walls, player.color)
+ this.renderWalls(player)
})
- this.renderDebug()
+ this.renderDebug(this.player)
- this.checkPlayerColision()
- this.updatePlayer()
+ // this.checkPlayerColision()
+ this.updatePlayer(this.player)
},
renderBorders () {
this.context.strokeStyle = 'black'
@@ -80,19 +80,19 @@ export default {
this.context.restore()
},
- renderWalls (walls, color) {
+ renderWalls (player) {
this.context.beginPath()
this.context.lineWidth = this.settings.wallSize
- this.context.strokeStyle = color
- walls.forEach(wall => {
+ this.context.strokeStyle = player.color
+ player.walls.forEach(wall => {
const canvasX = this.canvas.width / 2 + wall.x - this.player.x
const canvasY = this.canvas.height / 2 + wall.y - this.player.y
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()
},
- renderDebug () {
+ renderDebug (player) {
this.context.beginPath()
const canvasX = this.canvas.width / 2
const canvasY = this.canvas.height / 2
@@ -102,8 +102,8 @@ export default {
this.context.strokeStyle = 'blue'
this.context.stroke()
- const x = canvasX + 30 * Math.cos(this.player.angle) * 2
- const y = canvasY + 30 * Math.sin(this.player.angle) * 2
+ const x = canvasX + 30 * Math.cos(player.angle) * 2
+ const y = canvasY + 30 * Math.sin(player.angle) * 2
this.context.beginPath()
this.context.lineTo(canvasX, canvasY)
this.context.lineTo(x, y)
@@ -125,10 +125,10 @@ export default {
this.context.strokeStyle = 'purple'
this.context.stroke()
- this.context.fillText('player x: ' + this.player.x + ' y:' + this.player.y, 10, 10)
- this.context.fillText('a:' + this.player.angle + ' a_t' + this.player.targetAngle, 10, 20)
+ this.context.fillText('player x: ' + player.x + ' y:' + player.y, 10, 10)
+ this.context.fillText('a:' + player.angle + ' a_t' + player.targetAngle, 10, 20)
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) {
var rect = this.canvas.getBoundingClientRect()
@@ -141,17 +141,19 @@ export default {
this.player.targetAngle = Math.atan2(dy, dx)
send({ message: this.player, type: 'update' })
},
- updatePlayer () {
+ updatePlayer (player) {
+ /*
this.player.lastWall++
if (this.player.lastWall > this.settings.wallUpdate) {
this.player.walls.push({ x: this.player.x, y: this.player.y })
this.player.lastWall = 0
}
+ */
- this.player.x += this.settings.playerSpeed * Math.cos(this.player.angle)
- this.player.y += this.settings.playerSpeed * Math.sin(this.player.angle)
+ player.x += this.settings.playerSpeed * Math.cos(player.angle)
+ player.y += this.settings.playerSpeed * Math.sin(player.angle)
- this.player.angle = this.player.targetAngle
+ player.angle = player.targetAngle
// angle lag
/*
if (this.player.targetAngle !== this.player.angle) {
diff --git a/client/src/store/gameModule.js b/client/src/store/gameModule.js
index 364f7df..937f3bf 100644
--- a/client/src/store/gameModule.js
+++ b/client/src/store/gameModule.js
@@ -4,8 +4,6 @@ const state = {
y: 100,
angle: 0,
targetAngle: 0,
- walls: [],
- lastWall: 0,
color: 'red'
},
players: {
@@ -37,8 +35,10 @@ const actions = {
commit('SET_SETTINGS', settings)
},
update ({ commit }, update) {
+ commit('SET_PLAYERS', update)
},
- dead ({ commit }) {
+ dead ({ commit }, player) {
+ commit('SET_PLAYER', player)
},
error ({ commit }, error) {
alert('Error: ' + error)
@@ -49,6 +49,9 @@ const mutations = {
SET_PLAYER (state, player) {
state.player = player
},
+ SET_PLAYERS (state, players) {
+ state.players = players
+ },
SET_SETTINGS (state, settings) {
state.settings = settings
},
diff --git a/client/src/store/socketPlugin.js b/client/src/store/socketPlugin.js
index cc36243..73a0f45 100644
--- a/client/src/store/socketPlugin.js
+++ b/client/src/store/socketPlugin.js
@@ -33,7 +33,7 @@ export default function createSocketPlugin () {
store.dispatch('game/update', data.message)
break
case 'gamePlayerDead':
- store.dispatch('game/dead')
+ store.dispatch('game/dead', data.message)
break
default:
break
diff --git a/server/.factorypath b/server/.factorypath
index 30583c9..2e7aef0 100644
--- a/server/.factorypath
+++ b/server/.factorypath
@@ -14,7 +14,6 @@
-
@@ -36,4 +35,5 @@
+
diff --git a/server/pom.xml b/server/pom.xml
index 7ca1408..60e8c9e 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -50,6 +50,12 @@
json
20200518
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.11.2
+
+
diff --git a/server/src/main/java/gltronic/tronio/TronIoApplication.java b/server/src/main/java/gltronic/tronio/TronIoApplication.java
index 781e7e4..a14c5c4 100644
--- a/server/src/main/java/gltronic/tronio/TronIoApplication.java
+++ b/server/src/main/java/gltronic/tronio/TronIoApplication.java
@@ -2,10 +2,15 @@ package gltronic.tronio;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@SpringBootApplication
+@EnableScheduling
@ComponentScan(basePackages = "gltronic.tronio")
@PropertySource("classpath:application.properties")
public class TronIoApplication {
@@ -14,4 +19,15 @@ public class TronIoApplication {
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;
+ }
+
}
diff --git a/server/src/main/java/gltronic/tronio/business/GameManager.java b/server/src/main/java/gltronic/tronio/business/GameManager.java
index a2d51ae..7dab49a 100644
--- a/server/src/main/java/gltronic/tronio/business/GameManager.java
+++ b/server/src/main/java/gltronic/tronio/business/GameManager.java
@@ -4,8 +4,11 @@ import java.io.IOException;
import java.util.ArrayList;
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.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.WebSocketSession;
@@ -24,14 +27,17 @@ public class GameManager implements IGameManager {
SocketUtils.sendMessage(session, "error", "cant login twice");
return;
}
-
+
Player player = initPlayer(new Player());
game.getSessions().put(session.getId(), session);
game.getPlayers().put(session.getId(), player);
- SocketUtils.forwardMessage(session, "login", new JSONObject(player));
- SocketUtils.forwardMessage(session, "gameSettings", new JSONObject(game.getSettings()));
+ System.out.println("[GAME] Player " + session.getId() + " logged in | status: " + player.getX() + " " + player.getY() + " " + player.getColor());
+
+ 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
@@ -48,14 +54,16 @@ public class GameManager implements IGameManager {
}
@Override
+ @Scheduled(fixedDelay = 1000 / 60)
public void step() throws InterruptedException, IOException {
// CHECK OUT OF BORDERS & COLISIONS
game.getPlayers().forEach((id, player) -> {
// OUT OF BORDERS
- if (player.getX() - game.getSettings().getPlayerSize() < 0 ||
- player.getX() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize() ||
- player.getY() - game.getSettings().getPlayerSize() < 0 ||
- player.getY() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize()) {
+ if (player.getX() - game.getSettings().getPlayerSize() < 0
+ || player.getX() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize()
+ || player.getY() - game.getSettings().getPlayerSize() < 0
+ || player.getY() + game.getSettings().getPlayerSize() > game.getSettings().getArenaSize()) {
+ System.out.println("[GAME] border");
killPlayer(id);
return;
}
@@ -65,8 +73,12 @@ public class GameManager implements IGameManager {
for (var i = 0; i < player2.getWalls().size() - 2; i++) {
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())) {
- if (this.isCrossingLine(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(),
+ 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);
return;
}
@@ -88,12 +100,21 @@ public class GameManager implements IGameManager {
player.setX(player.getX() + game.getSettings().getPlayerSpeed() * Math.cos(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);
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) {
@@ -120,8 +141,8 @@ public class GameManager implements IGameManager {
double x = game.getSettings().getArenaSize() * (0.25 + Math.random() * 0.5);
double y = game.getSettings().getArenaSize() * (0.25 + Math.random() * 0.5);
- player.setAngle(0);
- player.setTargetAngle(0);
+ // player.setAngle(0);
+ // player.setTargetAngle(0);
player.setLastWall(0);
player.setWalls(new ArrayList());
player.setColor(String.format("#%06x", rand.nextInt(0xffffff + 1)));
diff --git a/server/src/main/java/gltronic/tronio/business/SocketUtils.java b/server/src/main/java/gltronic/tronio/business/SocketUtils.java
index d070d46..0fb79cd 100644
--- a/server/src/main/java/gltronic/tronio/business/SocketUtils.java
+++ b/server/src/main/java/gltronic/tronio/business/SocketUtils.java
@@ -2,7 +2,6 @@ package gltronic.tronio.business;
import java.io.IOException;
-import org.json.JSONObject;
import org.springframework.web.socket.TextMessage;
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 {
- session.sendMessage(new TextMessage("{\"type\":\"" + type + "\",\"message\": " + message.toString() + " }"));
+ session.sendMessage(new TextMessage("{\"type\":\"" + type + "\",\"message\": " + object + " }"));
} catch (IOException e) {
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) -> {
- forwardMessage(session, type, message);
+ sendObject(session, type, message);
});
}
}
\ No newline at end of file
diff --git a/server/src/main/java/gltronic/tronio/model/Player.java b/server/src/main/java/gltronic/tronio/model/Player.java
index 7b4150c..64ee2d3 100644
--- a/server/src/main/java/gltronic/tronio/model/Player.java
+++ b/server/src/main/java/gltronic/tronio/model/Player.java
@@ -2,6 +2,8 @@ package gltronic.tronio.model;
import java.util.ArrayList;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@@ -9,13 +11,20 @@ import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
public class Player {
- private double x;
- private double y;
- private double angle;
- private double targetAngle;
- private ArrayList walls;
- private int lastWall;
+
private String color;
+ private double x;
+
+ private double y;
+
+ private double angle;
+
+ private double targetAngle;
+
+ private ArrayList walls;
+
+ private int lastWall;
}
\ No newline at end of file
diff --git a/server/src/main/java/gltronic/tronio/web/SocketHandler.java b/server/src/main/java/gltronic/tronio/web/SocketHandler.java
index 1d2222f..6e7bec8 100644
--- a/server/src/main/java/gltronic/tronio/web/SocketHandler.java
+++ b/server/src/main/java/gltronic/tronio/web/SocketHandler.java
@@ -2,6 +2,8 @@ package gltronic.tronio.web;
import java.io.IOException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -23,15 +25,17 @@ public class SocketHandler extends TextWebSocketHandler {
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message)
throws InterruptedException, IOException {
- System.err.println("[WS] message :" + message.getPayload());
+ // System.err.println("[WS] message :" + 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) {
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;
default:
SocketUtils.sendMessage(session, "error", "unknow command");
diff --git a/server/target/classes/gltronic/tronio/TronIoApplication.class b/server/target/classes/gltronic/tronio/TronIoApplication.class
index 43c49f2..6bd2fe1 100644
Binary files a/server/target/classes/gltronic/tronio/TronIoApplication.class and b/server/target/classes/gltronic/tronio/TronIoApplication.class differ
diff --git a/server/target/classes/gltronic/tronio/business/GameManager.class b/server/target/classes/gltronic/tronio/business/GameManager.class
index a1ae6b7..5202f6d 100644
Binary files a/server/target/classes/gltronic/tronio/business/GameManager.class and b/server/target/classes/gltronic/tronio/business/GameManager.class differ
diff --git a/server/target/classes/gltronic/tronio/business/SocketUtils.class b/server/target/classes/gltronic/tronio/business/SocketUtils.class
index df04686..6619551 100644
Binary files a/server/target/classes/gltronic/tronio/business/SocketUtils.class and b/server/target/classes/gltronic/tronio/business/SocketUtils.class differ
diff --git a/server/target/classes/gltronic/tronio/model/Player.class b/server/target/classes/gltronic/tronio/model/Player.class
index a7ccc47..f3042f6 100644
Binary files a/server/target/classes/gltronic/tronio/model/Player.class and b/server/target/classes/gltronic/tronio/model/Player.class differ
diff --git a/server/target/classes/gltronic/tronio/web/SocketHandler.class b/server/target/classes/gltronic/tronio/web/SocketHandler.class
index 9dfba34..888b790 100644
Binary files a/server/target/classes/gltronic/tronio/web/SocketHandler.class and b/server/target/classes/gltronic/tronio/web/SocketHandler.class differ
diff --git a/test.json b/test.json
new file mode 100644
index 0000000..0c35ed8
--- /dev/null
+++ b/test.json
@@ -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
+ }
+ ]
+}
\ No newline at end of file