Base game & server skeleton

This commit is contained in:
Thomas
2020-08-20 11:41:47 +02:00
parent 7edec4bc22
commit 932b591728
82 changed files with 480 additions and 390 deletions

View File

@@ -11,6 +11,7 @@
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
background-color: #475b6e;
}
</style>

View File

@@ -13,14 +13,26 @@ export default {
data () {
return {
player: {
x: 0,
y: 0,
direction: 0,
walls: []
x: 100,
y: 100,
angle: 0,
targetAngle: 0,
walls: [],
lastWall: 0,
color: 'red'
},
players: [],
mouse: {
x: 0,
y: 0
},
settings: {
playerSize: 10,
playerSpeed: 2,
playerTurnSpeed: 10,
wallSize: 8,
wallUpdate: 5,
arenaSize: 1000
}
}
},
@@ -35,30 +47,177 @@ export default {
mounted () {
this.canvas.width = window.innerWidth
this.canvas.height = window.innerHeight
this.context.fillStyle = 'rgb(200, 0, 0)'
this.context.fillRect(10, 10, 50, 50)
this.context.fillStyle = 'rgba(0, 0, 200, 0.5)'
this.context.fillRect(30, 30, 50, 50)
this.canvas.addEventListener('mousemove', this.mouseEvent)
// setInterval(this.render, 1000 / 60)
setInterval(this.render, 1000 / 60)
setInterval(this.movePlayer, 100)
},
methods: {
render () {
this.renderBorders(this.player.x, this.player.y)
this.renderPlayer()
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)
this.renderBorders()
this.renderPlayer(this.player)
this.renderWalls(this.player.walls, this.player.color)
this.players.forEach(player => {
this.renderPlayer(player)
this.renderWalls(player.walls, player.color)
})
this.renderDebug()
this.checkPlayerColision()
this.updatePlayer()
},
renderBorders (x, y) {
renderBorders () {
this.context.strokeStyle = 'black'
this.context.lineWidth = 1
this.context.strokeRect(this.canvas.width / 2 - x, this.canvas.height / 2 - y, 3000, 3000)
this.context.strokeRect(this.canvas.width / 2 - this.player.x, this.canvas.height / 2 - this.player.y, this.settings.arenaSize, this.settings.arenaSize)
},
renderPlayer () {
this.context.strokeStyle = 'black'
this.context.lineWidth = 3
this.context.strokeRect(this.player.x - 50, this.player.y - 50, this.player.x + 50, this.player.y + 50)
renderPlayer (player) {
this.context.save()
const canvasX = this.canvas.width / 2 + player.x - this.player.x
const canvasY = this.canvas.height / 2 + player.y - this.player.y
this.context.translate(canvasX, canvasY)
this.context.rotate(player.angle)
this.context.fillStyle = player.color
this.context.fillRect(-this.settings.playerSize, -this.settings.playerSize, this.settings.playerSize * 2, this.settings.playerSize * 2)
this.context.translate(0, 0)
this.context.restore()
},
renderWalls (walls, color) {
this.context.beginPath()
this.context.lineWidth = this.settings.wallSize
this.context.strokeStyle = color
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.stroke()
},
renderDebug () {
this.context.beginPath()
const canvasX = this.canvas.width / 2
const canvasY = this.canvas.height / 2
this.context.lineTo(canvasX, canvasY)
this.context.lineTo(this.mouse.x, this.mouse.y)
this.context.lineWidth = 1
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
this.context.beginPath()
this.context.lineTo(canvasX, canvasY)
this.context.lineTo(x, y)
this.context.lineWidth = 1
this.context.strokeStyle = 'yellow'
this.context.stroke()
this.context.beginPath()
this.context.arc(this.mouse.x, this.mouse.y, 25, 0, 2 * Math.PI, false)
this.context.lineWidth = 1
this.context.strokeStyle = 'yellow'
this.context.stroke()
const canvasX2 = this.canvas.width / 2
const canvasY2 = this.canvas.height / 2
this.context.beginPath()
this.context.arc(canvasX2, canvasY2, this.settings.playerSize, 0, 2 * Math.PI, false)
this.context.lineWidth = 1
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('canvasX: ' + canvasX + ' canvasY:' + canvasY, 10, 30)
this.context.fillText('walls: ' + this.player.walls.length, 10, 40)
},
mouseEvent (event) {
var rect = this.canvas.getBoundingClientRect()
this.mouse.x = event.clientX - rect.left
this.mouse.y = event.clientY - rect.top
var dx = this.mouse.x - this.canvas.width / 2
var dy = this.mouse.y - this.canvas.height / 2
this.player.targetAngle = Math.atan2(dy, dx)
},
updatePlayer () {
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)
this.player.angle = this.player.targetAngle
// angle lag
/*
if (this.player.targetAngle !== this.player.angle) {
const delta = this.player.targetAngle - this.player.angle
if (delta < 0) this.player.angle += delta / this.settings.playerTurnSpeed
if (delta > 0) this.player.angle += delta / this.settings.playerTurnSpeed
if (delta <= 0.1 && delta >= -0.1) this.player.angle = this.player.targetAngle
}
*/
},
checkPlayerColision () {
const playerX = this.player.x
const playerY = this.player.y
// BORDERS
if (playerX - this.settings.playerSize < 0 ||
playerX + this.settings.playerSize > this.settings.arenaSize ||
playerY - this.settings.playerSize < 0 ||
playerY + this.settings.playerSize > this.settings.arenaSize
) {
this.context.fillText('DED BORDER', this.canvas.width / 2, this.canvas.height / 2)
}
// WALLS
for (var i = 0; i < this.player.walls.length - 2; i++) {
const wallA = this.player.walls[i]
const wallB = this.player.walls[i + 1]
if (this.isCloseToWall(wallA.x, wallA.y, wallB.x, wallB.y, playerX, playerY, this.settings.playerSize)) {
if (this.isCrossingLine(wallA.x, wallA.y, wallB.x, wallB.y, playerX, playerY, this.settings.playerSize)) {
this.context.fillText('DED WALL OWN', this.canvas.width / 2, this.canvas.height / 2)
this.context.beginPath()
const canvasX = this.canvas.width / 2 + wallA.x - this.player.x
const canvasY = this.canvas.height / 2 + wallA.y - this.player.y
this.context.lineTo(canvasX, canvasY)
const canvasX2 = this.canvas.width / 2 + wallB.x - this.player.x
const canvasY2 = this.canvas.height / 2 + wallB.y - this.player.y
this.context.lineTo(canvasX2, canvasY2)
this.context.lineWidth = this.settings.wallSize
this.context.strokeStyle = 'purple'
this.context.stroke()
}
}
}
},
isCloseToWall (xa, ya, xb, yb, xc, yc, radius) {
var xar = Math.min(xa, xb) - radius
var yar = Math.min(ya, yb) - radius
var xbr = Math.max(xa, xb) + radius
var ybr = Math.max(ya, yb) + radius
return ((xc >= xar && xc <= xbr) && (yc >= yar && yc <= ybr))
},
isCrossingLine (xa, ya, xb, yb, xc, yc, radius) {
var a = xc - xa
var b = xb - xa
var c = yc - ya
var d = yb - ya
var result = (a * d - b * c) / Math.sqrt(Math.pow(xa - xb, 2) + Math.pow(ya - yb, 2))
return result < radius
}
}
}

49
server/.classpath Normal file
View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

39
server/.factorypath Normal file
View File

@@ -0,0 +1,39 @@
<factorypath>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-web/2.3.1.RELEASE/spring-boot-starter-web-2.3.1.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter/2.3.1.RELEASE/spring-boot-starter-2.3.1.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot/2.3.1.RELEASE/spring-boot-2.3.1.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-autoconfigure/2.3.1.RELEASE/spring-boot-autoconfigure-2.3.1.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-logging/2.3.1.RELEASE/spring-boot-starter-logging-2.3.1.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/apache/logging/log4j/log4j-to-slf4j/2.13.3/log4j-to-slf4j-2.13.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/apache/logging/log4j/log4j-api/2.13.3/log4j-api-2.13.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/slf4j/jul-to-slf4j/1.7.30/jul-to-slf4j-1.7.30.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/jakarta/annotation/jakarta.annotation-api/1.3.5/jakarta.annotation-api-1.3.5.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/yaml/snakeyaml/1.26/snakeyaml-1.26.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-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-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/org/springframework/boot/spring-boot-starter-tomcat/2.3.1.RELEASE/spring-boot-starter-tomcat-2.3.1.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/apache/tomcat/embed/tomcat-embed-core/9.0.36/tomcat-embed-core-9.0.36.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/glassfish/jakarta.el/3.0.3/jakarta.el-3.0.3.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.36/tomcat-embed-websocket-9.0.36.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-web/5.2.7.RELEASE/spring-web-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-beans/5.2.7.RELEASE/spring-beans-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-webmvc/5.2.7.RELEASE/spring-webmvc-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-aop/5.2.7.RELEASE/spring-aop-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-context/5.2.7.RELEASE/spring-context-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-expression/5.2.7.RELEASE/spring-expression-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-websocket/2.3.1.RELEASE/spring-boot-starter-websocket-2.3.1.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-messaging/5.2.7.RELEASE/spring-messaging-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-websocket/5.2.7.RELEASE/spring-websocket-5.2.7.RELEASE.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/projectlombok/lombok/1.18.12/lombok-1.18.12.jar" enabled="true" runInBatchMode="false"/>
<factorypathentry kind="VARJAR" id="M2_REPO/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.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/json/json/20200518/json-20200518.jar" enabled="true" runInBatchMode="false"/>
</factorypath>

23
server/.project Normal file
View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>tronio</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8

View File

@@ -0,0 +1,4 @@
eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=true
org.eclipse.jdt.apt.genSrcDir=target/generated-sources/annotations
org.eclipse.jdt.apt.genTestSrcDir=target/generated-test-sources/test-annotations

View File

@@ -0,0 +1,10 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.processAnnotations=enabled
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=11

View File

@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@@ -0,0 +1,29 @@
package gltronic.tronio.business;
import java.io.IOException;
import org.springframework.web.socket.WebSocketSession;
import gltronic.tronio.model.Player;
public class GameManager implements IGameManager {
@Override
public void login(WebSocketSession session) throws InterruptedException, IOException {
// TODO Auto-generated method stub
}
@Override
public void leave(WebSocketSession session) throws InterruptedException, IOException {
// TODO Auto-generated method stub
}
@Override
public void update(WebSocketSession session, Player player) throws InterruptedException, IOException {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,13 @@
package gltronic.tronio.business;
import java.io.IOException;
import org.springframework.web.socket.WebSocketSession;
import gltronic.tronio.model.Player;
public interface IGameManager {
void login(WebSocketSession session) throws InterruptedException, IOException;
void leave(WebSocketSession session) throws InterruptedException, IOException;
void update(WebSocketSession session, Player player) throws InterruptedException, IOException;
}

View File

@@ -1,16 +0,0 @@
package gltronic.tronio.business;
import java.io.IOException;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
public interface IRoomManager {
public void login(WebSocketSession session, String name) throws InterruptedException, IOException;
public void leave(WebSocketSession session);
public void createRoom(WebSocketSession session) throws InterruptedException, IOException;
public void connectRoom(WebSocketSession session, String roomName) throws InterruptedException, IOException;
public void followRTC(WebSocketSession session, TextMessage message) throws InterruptedException, IOException;
public void sendMessage(WebSocketSession session, String type, String message) throws InterruptedException, IOException;
public void sendServerInfos(WebSocketSession session) throws InterruptedException, IOException;
}

View File

@@ -1,117 +0,0 @@
package gltronic.tronio.business;
import java.io.IOException;
import java.util.Random;
import org.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import gltronic.tronio.model.BiMap;
@Service
public class RoomManager implements IRoomManager{
private volatile BiMap<String, WebSocketSession> users = new BiMap<String, WebSocketSession>();
private volatile BiMap<String, String> rooms = new BiMap<String, String>();
public void login(WebSocketSession session, String name) throws InterruptedException, IOException {
if (name == null) {
sendMessage(session, "error", "bad command command");
return;
}
if (users.containsKey(name)) {
sendMessage(session, "login", "false");
return;
}
users.put(name, session);
sendMessage(session, "login", "true");
sendServerInfos(session);
System.err.println("[ROOM] Logged "+name);
}
public void leave(WebSocketSession session) {
String name = users.getKey(session);
users.removeValue(session);
if(rooms.containsValue(name)) rooms.removeValue(name);
}
public void createRoom(WebSocketSession session) throws InterruptedException, IOException {
if (!users.containsValue(session)) {
sendMessage(session, "error", "need login");
return;
}
String userName = users.getKey(session);
if (rooms.containsKey(userName)) {
sendMessage(session, "error", "no multiple room");
return;
}
Random random = new Random();
String roomName = Integer.toString(random.nextInt(9999));
while (roomName.length() < 4) roomName += 0 + roomName;
rooms.put(roomName, userName);
sendMessage(session, "createRoom", roomName);
System.err.println("[ROOM] Created room "+roomName+" by "+userName);
}
public void connectRoom(WebSocketSession session, String roomName) throws InterruptedException, IOException {
if (roomName == null) {
sendMessage(session, "error", "bad command command");
return;
}
if (!users.containsValue(session)) {
sendMessage(session, "error", "need login");
return;
}
if (!rooms.containsKey(roomName)) {
sendMessage(session, "error", "no room");
return;
}
String roomAdmin = rooms.get(roomName);
sendMessage(session, "connectRoom", roomAdmin);
String userName = users.getKey(session);
System.err.println("[ROOM] Connection to room "+roomName+" ("+roomAdmin+") by "+userName);
}
public void followRTC(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
String payload = message.getPayload();
JSONObject jsonObject = new JSONObject(payload);
String target = (String) jsonObject.get("target");
if (target == null) {
sendMessage(session, "error", "no target");
return;
}
WebSocketSession targetSession = users.get(target);
if (targetSession == null) {
sendMessage(session, "error", "unknow target");
return;
}
System.err.println("[ROOM] Foward RTC message");
followMessage(targetSession, message);
}
public void followMessage (WebSocketSession session, TextMessage message) throws IOException {
session.sendMessage(message);
}
public void sendMessage(WebSocketSession session, String type, String message) throws InterruptedException, IOException {
session.sendMessage(new TextMessage("{\"type\":\""+type+"\",\"message\":\""+message+"\"}"));
}
public void sendServerInfos(WebSocketSession session) throws InterruptedException, IOException {
session.sendMessage(new TextMessage("{\"type\":\"serverInfos\",\"userCount\":\""+users.size()+"\",\"roomCount\":\""+rooms.size()+"\"}"));
}
}

View File

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

View File

@@ -0,0 +1,18 @@
package gltronic.tronio.model;
import java.util.Map;
import org.springframework.web.socket.WebSocketSession;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class Game {
private Map<String, Player> players;
private Map<String, WebSocketSession> sessions;
private GameSettings settings;
}

View File

@@ -0,0 +1,5 @@
package gltronic.tronio.model;
public abstract class GameEntity {
}

View File

@@ -0,0 +1,17 @@
package gltronic.tronio.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class GameSettings {
private double playerSize;
private double playerSpeed;
private double playerTurnSpeed;
private double wallSize;
private double wallUpdate;
private double arenaSize;
}

View File

@@ -0,0 +1,22 @@
package gltronic.tronio.model;
import java.util.ArrayList;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class Player {
private String id;
private double x;
private double y;
private double angle;
private double targetAngle;
private ArrayList<Wall> walls;
private int lastWall;
private String color;
}

View File

@@ -0,0 +1,13 @@
package gltronic.tronio.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class Wall {
private double x;
private double y;
}

View File

@@ -1,8 +1,6 @@
package gltronic.tronio.web;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
@@ -12,63 +10,49 @@ import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import gltronic.tronio.business.IRoomManager;
import gltronic.tronio.business.IGameManager;
import gltronic.tronio.business.SocketUtils;
import gltronic.tronio.model.Player;
@Component
public class SocketHandler extends TextWebSocketHandler {
private volatile List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
@Autowired
IRoomManager roomManager;
IGameManager gameManager;
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
public void handleTextMessage(WebSocketSession session, TextMessage message)
throws InterruptedException, IOException {
System.err.println("[WS] message :" + message.getPayload());
String payload = message.getPayload();
JSONObject jsonObject = new JSONObject(payload);
String type = (String) jsonObject.get("type");
switch (type) {
case "serverInfos":
roomManager.sendServerInfos(session);
break;
case "login":
roomManager.login(session, (String) jsonObject.get("name"));
break;
case "createRoom":
roomManager.createRoom(session);
break;
case "connectRoom":
roomManager.connectRoom(session, (String) jsonObject.get("name"));
break;
case "leave":
roomManager.leave(session);
break;
case "offer":
case "answer":
case "candidate":
roomManager.followRTC(session, message);
break;
case "search":
break;
case "alive":
break;
case "update":
gameManager.update(session, (Player) jsonObject.get("update"));
break;
default:
roomManager.sendMessage(session, "error", "unknow command");
SocketUtils.sendMessage(session, "error", "unknow command");
}
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.err.println("[WS] new connection " + this);
sessions.add(session);
gameManager.login(session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus){
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
System.err.println("[WS] connection closed");
sessions.remove(session);
roomManager.leave(session);
try {
gameManager.leave(session);
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
}

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
.invite{text-align:center}.actionButton{margin-left:10px}.controls{text-align:center;max-width:500px}.playerButton{margin-left:10px}.playerVolume{margin-left:30px;margin-right:30px;max-width:150px}.player,.time{text-align:center}.room{margin-top:20px}.roomTitle{padding-bottom:30px;padding-left:25px}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="332.000000pt" height="332.000000pt" viewBox="0 0 332.000000 332.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<g transform="translate(0.000000,332.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1477 3309 c-380 -44 -716 -207 -988 -478 -229 -230 -375 -492 -447
-806 -189 -821 288 -1670 1087 -1935 505 -168 1019 -98 1462 198 399 267 662
705 719 1197 69 603 -220 1216 -735 1559 -314 209 -725 309 -1098 265z m-3
-1261 c49 -277 95 -543 104 -591 8 -48 19 -84 23 -80 6 6 322 700 356 781 4 9
-29 12 -146 12 -83 0 -151 3 -151 8 0 4 25 87 57 185 l57 177 504 0 c399 0
503 -3 500 -12 -3 -7 -141 -372 -308 -810 l-304 -798 -208 0 -208 0 0 -27 c0
-27 35 -320 45 -375 l5 -28 -360 0 -360 0 -5 22 c-12 53 -395 2014 -395 2025
0 10 77 13 353 13 l353 0 88 -502z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1 +0,0 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=stylesheet href=//cdn.materialdesignicons.com/5.4.55/css/materialdesignicons.min.css><!--[if IE]><link rel="icon" href="/favicon.ico"><![endif]--><title>voozik</title><link href=/css/chunk-3fba1bf2.8f336ede.css rel=prefetch><link href=/js/chunk-3fba1bf2.6996f5b8.js rel=prefetch><link href=/css/app.cd6b43b0.css rel=preload as=style><link href=/js/app.2e968650.js rel=preload as=script><link href=/js/chunk-vendors.5317c68e.js rel=preload as=script><link href=/css/app.cd6b43b0.css rel=stylesheet><link rel=icon type=image/png sizes=32x32 href=/img/icons/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=/img/icons/favicon-16x16.png><link rel=manifest href=/manifest.json><meta name=theme-color content=#1f2424><meta name=apple-mobile-web-app-capable content=yes><meta name=apple-mobile-web-app-status-bar-style content=black><meta name=apple-mobile-web-app-title content=Voozik><link rel=apple-touch-icon href=/img/icons/apple-touch-icon-152x152.png><link rel=mask-icon href=/img/icons/safari-pinned-tab.svg color=#1f2424><meta name=msapplication-TileImage content=/img/icons/msapplication-icon-144x144.png><meta name=msapplication-TileColor content=#1f2424></head><body><noscript><strong>We're sorry but voozik doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.5317c68e.js></script><script src=/js/app.2e968650.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"name":"Voozik","short_name":"Voozik","theme_color":"#1f2424","icons":[{"src":"./img/icons/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"./img/icons/android-chrome-512x512.png","sizes":"512x512","type":"image/png"},{"src":"./img/icons/android-chrome-maskable-192x192.png","sizes":"192x192","type":"image/png","purpose":"maskable"},{"src":"./img/icons/android-chrome-maskable-512x512.png","sizes":"512x512","type":"image/png","purpose":"maskable"}],"start_url":".","display":"standalone","background_color":"#000000"}

View File

@@ -1,42 +0,0 @@
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "b04d5f8101dd5cbd687c",
"url": "/css/app.c867eb2f.css"
},
{
"revision": "2d42950f1a3f0d9089ef",
"url": "/css/chunk-3fba1bf2.8f336ede.css"
},
{
"revision": "c5833b37f54a60b621af207ee1748141",
"url": "/fonts/Gravity-Regular.c5833b37.otf"
},
{
"revision": "59e2a4e2813216bfa7e65a1615b868d8",
"url": "/img/logo.59e2a4e2.png"
},
{
"revision": "aabceb7bf90373a57d5c4a4e34ed28dc",
"url": "/index.html"
},
{
"revision": "b04d5f8101dd5cbd687c",
"url": "/js/app.f782d107.js"
},
{
"revision": "2d42950f1a3f0d9089ef",
"url": "/js/chunk-3fba1bf2.bc112002.js"
},
{
"revision": "fc77e62f9c3581249601",
"url": "/js/chunk-vendors.5317c68e.js"
},
{
"revision": "99cb3114213fb04825926e478109ed6c",
"url": "/manifest.json"
},
{
"revision": "b6216d61c03e6ce0c9aea6ca7808f7ca",
"url": "/robots.txt"
}
]);

View File

@@ -1,42 +0,0 @@
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "8b875ef860aa2e2e76e2",
"url": "/css/app.cd6b43b0.css"
},
{
"revision": "f90e093aa485d8cf4f19",
"url": "/css/chunk-3fba1bf2.8f336ede.css"
},
{
"revision": "c5833b37f54a60b621af207ee1748141",
"url": "/fonts/Gravity-Regular.c5833b37.otf"
},
{
"revision": "59e2a4e2813216bfa7e65a1615b868d8",
"url": "/img/logo.59e2a4e2.png"
},
{
"revision": "6e7bdfe12e1b8ed59a5a67417653202d",
"url": "/index.html"
},
{
"revision": "8b875ef860aa2e2e76e2",
"url": "/js/app.2e968650.js"
},
{
"revision": "f90e093aa485d8cf4f19",
"url": "/js/chunk-3fba1bf2.6996f5b8.js"
},
{
"revision": "fc77e62f9c3581249601",
"url": "/js/chunk-vendors.5317c68e.js"
},
{
"revision": "776ab44c1e1c56cad70865f9cce04c7d",
"url": "/manifest.json"
},
{
"revision": "b6216d61c03e6ce0c9aea6ca7808f7ca",
"url": "/robots.txt"
}
]);

View File

@@ -1,2 +0,0 @@
User-agent: *
Disallow:

View File

@@ -1,30 +0,0 @@
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
importScripts(
"/precache-manifest.e77e5c0fa4b0dafa58227bf0df9fd607.js"
);
workbox.core.setCacheNameDetails({prefix: "voozik"});
workbox.core.skipWaiting();
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});