Added client socket
This commit is contained in:
7
client/package-lock.json
generated
7
client/package-lock.json
generated
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "tronio",
|
"name": "tron.io",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
@@ -11314,6 +11314,11 @@
|
|||||||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"vuex": {
|
||||||
|
"version": "3.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz",
|
||||||
|
"integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw=="
|
||||||
|
},
|
||||||
"watchpack": {
|
"watchpack": {
|
||||||
"version": "1.7.4",
|
"version": "1.7.4",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz",
|
||||||
|
|||||||
@@ -11,13 +11,13 @@
|
|||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"register-service-worker": "^1.7.1",
|
"register-service-worker": "^1.7.1",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-router": "^3.2.0"
|
"vue-router": "^3.2.0",
|
||||||
|
"vuex": "^3.5.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "~4.4.0",
|
"@vue/cli-plugin-babel": "~4.4.0",
|
||||||
"@vue/cli-plugin-eslint": "~4.4.0",
|
"@vue/cli-plugin-eslint": "~4.4.0",
|
||||||
"@vue/cli-plugin-pwa": "~4.4.0",
|
"@vue/cli-plugin-pwa": "~4.4.0",
|
||||||
"@vue/cli-plugin-router": "~4.4.0",
|
|
||||||
"@vue/cli-service": "~4.4.0",
|
"@vue/cli-service": "~4.4.0",
|
||||||
"@vue/eslint-config-standard": "^5.1.2",
|
"@vue/eslint-config-standard": "^5.1.2",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
|
|||||||
@@ -1,9 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<router-view/>
|
<Game v-if="isSocketConnected"/>
|
||||||
|
<div v-else>
|
||||||
|
<h1>Game loadin mate</h1>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Game from './components/Game'
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
Game
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isSocketConnected () {
|
||||||
|
return this.$store.state.game.socketConnected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<style>
|
<style>
|
||||||
#app {
|
#app {
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="home">
|
<div class="game">
|
||||||
<canvas
|
<canvas
|
||||||
class="game-canvas"
|
class="game-canvas"
|
||||||
ref="canvas">
|
ref="canvas">
|
||||||
@@ -8,32 +8,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { send } from '@/store/socketPlugin'
|
||||||
export default {
|
export default {
|
||||||
name: 'Home',
|
name: 'Game',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
player: {
|
|
||||||
x: 100,
|
|
||||||
y: 100,
|
|
||||||
angle: 0,
|
|
||||||
targetAngle: 0,
|
|
||||||
walls: [],
|
|
||||||
lastWall: 0,
|
|
||||||
color: 'red'
|
|
||||||
},
|
|
||||||
players: [],
|
|
||||||
mouse: {
|
mouse: {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0
|
y: 0
|
||||||
},
|
},
|
||||||
settings: {
|
renderTimer: null
|
||||||
playerSize: 10,
|
|
||||||
playerSpeed: 2,
|
|
||||||
playerTurnSpeed: 10,
|
|
||||||
wallSize: 8,
|
|
||||||
wallUpdate: 5,
|
|
||||||
arenaSize: 1000
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -42,22 +26,30 @@ export default {
|
|||||||
},
|
},
|
||||||
context () {
|
context () {
|
||||||
return this.canvas.getContext('2d')
|
return this.canvas.getContext('2d')
|
||||||
|
},
|
||||||
|
settings () {
|
||||||
|
return this.$store.state.game.settings
|
||||||
|
},
|
||||||
|
player () {
|
||||||
|
return this.$store.state.game.player
|
||||||
|
},
|
||||||
|
players () {
|
||||||
|
return this.$store.state.game.players
|
||||||
|
},
|
||||||
|
isPaused () {
|
||||||
|
return this.$store.state.game.paused
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.canvas.width = window.innerWidth
|
this.canvas.width = window.innerWidth
|
||||||
this.canvas.height = window.innerHeight
|
this.canvas.height = window.innerHeight
|
||||||
this.canvas.addEventListener('mousemove', this.mouseEvent)
|
this.canvas.addEventListener('mousemove', this.mouseEvent)
|
||||||
// setInterval(this.render, 1000 / 60)
|
this.renderTimer = setInterval(this.render, 1000 / 60)
|
||||||
setInterval(this.render, 1000 / 60)
|
|
||||||
setInterval(this.movePlayer, 100)
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
render () {
|
render () {
|
||||||
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)
|
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)
|
||||||
this.renderBorders()
|
this.renderBorders()
|
||||||
this.renderPlayer(this.player)
|
|
||||||
this.renderWalls(this.player.walls, this.player.color)
|
|
||||||
|
|
||||||
this.players.forEach(player => {
|
this.players.forEach(player => {
|
||||||
this.renderPlayer(player)
|
this.renderPlayer(player)
|
||||||
@@ -147,6 +139,7 @@ export default {
|
|||||||
var dy = this.mouse.y - this.canvas.height / 2
|
var dy = this.mouse.y - this.canvas.height / 2
|
||||||
|
|
||||||
this.player.targetAngle = Math.atan2(dy, dx)
|
this.player.targetAngle = Math.atan2(dy, dx)
|
||||||
|
send({ message: this.player, type: 'update' })
|
||||||
},
|
},
|
||||||
updatePlayer () {
|
updatePlayer () {
|
||||||
this.player.lastWall++
|
this.player.lastWall++
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
|
import store from './store'
|
||||||
import './registerServiceWorker'
|
import './registerServiceWorker'
|
||||||
import router from './router'
|
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
router,
|
store,
|
||||||
render: h => h(App)
|
render: h => h(App)
|
||||||
}).$mount('#app')
|
}).$mount('#app')
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
import Vue from 'vue'
|
|
||||||
import VueRouter from 'vue-router'
|
|
||||||
import Home from '../views/Home.vue'
|
|
||||||
|
|
||||||
Vue.use(VueRouter)
|
|
||||||
|
|
||||||
const routes = [
|
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
name: 'Home',
|
|
||||||
component: Home
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const router = new VueRouter({
|
|
||||||
routes
|
|
||||||
})
|
|
||||||
|
|
||||||
export default router
|
|
||||||
69
client/src/store/gameModule.js
Normal file
69
client/src/store/gameModule.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
const state = {
|
||||||
|
player: {
|
||||||
|
x: 100,
|
||||||
|
y: 100,
|
||||||
|
angle: 0,
|
||||||
|
targetAngle: 0,
|
||||||
|
walls: [],
|
||||||
|
lastWall: 0,
|
||||||
|
color: 'red'
|
||||||
|
},
|
||||||
|
players: {
|
||||||
|
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
playerSize: 10,
|
||||||
|
playerSpeed: 2,
|
||||||
|
playerTurnSpeed: 10,
|
||||||
|
wallSize: 8,
|
||||||
|
wallUpdate: 5,
|
||||||
|
arenaSize: 1000
|
||||||
|
},
|
||||||
|
paused: true,
|
||||||
|
socketConnected: false
|
||||||
|
}
|
||||||
|
|
||||||
|
const getters = {
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
socketConnected ({ commit }) {
|
||||||
|
commit('SET_CONNECTED')
|
||||||
|
},
|
||||||
|
login ({ commit }, player) {
|
||||||
|
commit('SET_PLAYER', player)
|
||||||
|
},
|
||||||
|
settings ({ commit }, settings) {
|
||||||
|
commit('SET_SETTINGS', settings)
|
||||||
|
},
|
||||||
|
update ({ commit }, update) {
|
||||||
|
},
|
||||||
|
dead ({ commit }) {
|
||||||
|
},
|
||||||
|
error ({ commit }, error) {
|
||||||
|
alert('Error: ' + error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
SET_PLAYER (state, player) {
|
||||||
|
state.player = player
|
||||||
|
},
|
||||||
|
SET_SETTINGS (state, settings) {
|
||||||
|
state.settings = settings
|
||||||
|
},
|
||||||
|
SET_PAUSE (state) {
|
||||||
|
state.paused = !state.paused
|
||||||
|
},
|
||||||
|
SET_CONNECTED (state) {
|
||||||
|
state.socketConnected = !state.socketConnected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
getters,
|
||||||
|
actions,
|
||||||
|
mutations
|
||||||
|
}
|
||||||
15
client/src/store/index.js
Normal file
15
client/src/store/index.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
import socket from './socketPlugin'
|
||||||
|
import game from './gameModule'
|
||||||
|
|
||||||
|
Vue.use(Vuex)
|
||||||
|
|
||||||
|
export default new Vuex.Store({
|
||||||
|
modules: {
|
||||||
|
game
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
socket()
|
||||||
|
]
|
||||||
|
})
|
||||||
48
client/src/store/socketPlugin.js
Normal file
48
client/src/store/socketPlugin.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
const connection = new WebSocket('ws://localhost:8181/socket')
|
||||||
|
// const connection = new WebSocket('wss://tronio.gltronic.ovh/socket')
|
||||||
|
|
||||||
|
export default function createSocketPlugin () {
|
||||||
|
return store => {
|
||||||
|
connection.onopen = function () {
|
||||||
|
console.log('[WS] connected')
|
||||||
|
store.dispatch('game/socketConnected')
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.onclose = function () {
|
||||||
|
console.log('[WS] closed')
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.onerror = function (error) {
|
||||||
|
console.log('[WS] error ' + error.message)
|
||||||
|
store.dispatch('game/error', 'Connection problem')
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.onmessage = function (message) {
|
||||||
|
console.log('[WS] message', message.data)
|
||||||
|
|
||||||
|
var data = JSON.parse(message.data)
|
||||||
|
|
||||||
|
switch (data.type) {
|
||||||
|
case 'login':
|
||||||
|
store.dispatch('game/login', data.message)
|
||||||
|
break
|
||||||
|
case 'gameSettings':
|
||||||
|
store.dispatch('game/settings', data.message)
|
||||||
|
break
|
||||||
|
case 'gameUpdate':
|
||||||
|
store.dispatch('game/update', data.message)
|
||||||
|
break
|
||||||
|
case 'gamePlayerDead':
|
||||||
|
store.dispatch('game/dead')
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function send (message) {
|
||||||
|
console.log('[WS] send', message)
|
||||||
|
connection.send(JSON.stringify(message))
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import org.springframework.context.annotation.ComponentScan;
|
|||||||
import org.springframework.context.annotation.PropertySource;
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@ComponentScan(basePackages = "gltronic.voozik")
|
@ComponentScan(basePackages = "gltronic.tronio")
|
||||||
@PropertySource("classpath:application.properties")
|
@PropertySource("classpath:application.properties")
|
||||||
public class TronIoApplication {
|
public class TronIoApplication {
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,14 @@ import java.util.Random;
|
|||||||
|
|
||||||
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.Service;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
import gltronic.tronio.model.Game;
|
import gltronic.tronio.model.Game;
|
||||||
import gltronic.tronio.model.Player;
|
import gltronic.tronio.model.Player;
|
||||||
import gltronic.tronio.model.Wall;
|
import gltronic.tronio.model.Wall;
|
||||||
|
|
||||||
|
@Service
|
||||||
public class GameManager implements IGameManager {
|
public class GameManager implements IGameManager {
|
||||||
@Autowired
|
@Autowired
|
||||||
Game game;
|
Game game;
|
||||||
@@ -29,6 +31,7 @@ public class GameManager implements IGameManager {
|
|||||||
game.getPlayers().put(session.getId(), player);
|
game.getPlayers().put(session.getId(), player);
|
||||||
|
|
||||||
SocketUtils.forwardMessage(session, "login", new JSONObject(player));
|
SocketUtils.forwardMessage(session, "login", new JSONObject(player));
|
||||||
|
SocketUtils.forwardMessage(session, "gameSettings", new JSONObject(game.getSettings()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -90,7 +93,7 @@ public class GameManager implements IGameManager {
|
|||||||
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), "dead", "yo dead");
|
SocketUtils.sendMessage(game.getSessions().get(id), "gamePlayerDead", "yo dead");
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|||||||
@@ -1,18 +1,32 @@
|
|||||||
package gltronic.tronio.model;
|
package gltronic.tronio.model;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@NoArgsConstructor
|
@Component
|
||||||
public class Game {
|
public class Game {
|
||||||
private Map<String, Player> players;
|
private Map<String, Player> players;
|
||||||
private Map<String, WebSocketSession> sessions;
|
private Map<String, WebSocketSession> sessions;
|
||||||
private GameSettings settings;
|
private GameSettings settings;
|
||||||
|
|
||||||
|
public Game() {
|
||||||
|
this.players = new HashMap<>();
|
||||||
|
this.sessions = new HashMap<>();
|
||||||
|
this.settings = new GameSettings();
|
||||||
|
|
||||||
|
this.settings.setArenaSize(1000);
|
||||||
|
this.settings.setPlayerSize(10);
|
||||||
|
this.settings.setPlayerSpeed(2);
|
||||||
|
this.settings.setPlayerTurnSpeed(10);
|
||||||
|
this.settings.setWallSize(8);
|
||||||
|
this.settings.setWallUpdate(5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ public class SocketHandler extends TextWebSocketHandler {
|
|||||||
String type = (String) jsonObject.get("type");
|
String type = (String) jsonObject.get("type");
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "update":
|
case "update":
|
||||||
gameManager.updatePlayer(session, (Player) jsonObject.get("update"));
|
gameManager.updatePlayer(session, (Player) jsonObject.get("message"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SocketUtils.sendMessage(session, "error", "unknow command");
|
SocketUtils.sendMessage(session, "error", "unknow command");
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user