Files
Tron.io/client/src/components/Game.vue
2020-09-09 20:50:15 +02:00

178 lines
5.3 KiB
Vue

<template>
<div class="game">
<b-modal v-model="playerIsDead">
<h1 class="title">DED</h1>
<h2 class="title">Score: {{player.score}}</h2>
<h3 class="subtitle">Best score: {{player.bestScore}}</h3>
<b-button @click="respawn">Respawn</b-button>
</b-modal>
<canvas
class="game-canvas"
ref="canvas">
</canvas>
</div>
</template>
<script>
import { send } from '@/store/socketPlugin'
import { render } from '@/game/render.js'
import { sound } from '@/game/sound.js'
export default {
name: 'Game',
data () {
return {
mouse: {
x: 0,
y: 0
},
camera: {
x: 0,
y: 0
},
stats: {
totalWalls: 0,
lastUpdateTime: 0,
lastFrame: 0
},
renderTimer: null
}
},
computed: {
canvas () {
return this.$refs.canvas
},
context () {
return this.canvas.getContext('2d')
},
settings () {
return this.$store.state.game.settings
},
player () {
return this.$store.state.game.player
},
players () {
const pastUpdate = this.$store.state.game.updates[0]
const nextUpdate = this.$store.state.game.updates[1]
if (pastUpdate === undefined) return []
if (pastUpdate.players === undefined) return []
if (nextUpdate === undefined) return pastUpdate.players
return nextUpdate.players
/*
const currentTime = Date.now() / 1000
const dt = (currentTime - pastUpdate.time) / (nextUpdate.time - pastUpdate.time)
return pastUpdate.players.map(player => this.interpolatePlayer(player, nextUpdate.players.find(nextPlayer => player.color === nextPlayer.color), dt))
*/
},
isPaused () {
return this.$store.state.game.paused
},
leaderboard () {
return this.$store.state.game.leaderboard
},
playerIsDead () {
if (this.player.state === 'DEAD') sound.explosion()
return this.player.state === 'DEAD'
}
},
mounted () {
this.setCanvasSize()
this.canvas.addEventListener('mousemove', this.mouseEvent)
this.canvas.addEventListener('touchmove', this.touchEvent)
this.canvas.addEventListener('resize', this.setCanvasSize)
// this.renderTimer = setInterval(this.render, 1000 / 120)
this.render()
},
methods: {
render () {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height)
render.borders(this.context, this.canvas, this.camera, this.settings)
if (!this.players) return
this.stats.totalWalls = 0
this.players.forEach(player => {
if (player.color === this.player.color) {
this.camera.x = player.x
this.camera.y = player.y
}
if (player.state === 'DEAD') this.context.globalAlpha = 0.1
render.wallsBezier(this.context, this.canvas, this.camera, this.settings, player)
if (player.name === 'e' || player.name === 'q' || player.name === 'r' || player.name === 't') render.playerFace(this.context, this.canvas, this.camera, this.settings, player, player.name)
else render.player(this.context, this.canvas, this.camera, this.settings, player)
if (player.state === 'DEAD') this.context.globalAlpha = 1
this.stats.totalWalls += player.walls.length
})
render.leaderboard(this.context, this.canvas, this.leaderboard)
render.mouse(this.context, this.mouse, this.player)
render.debug(this.context, this.camera, this.mouse, this.canvas, this.stats)
this.stats.lastFrame = performance.now()
const nextUpdate = this.$store.state.game.updates[1]
if (nextUpdate !== undefined) this.stats.lastUpdateTime = nextUpdate.time
requestAnimationFrame(this.render, this.canvas)
},
mouseEvent (event) {
var rect = this.canvas.getBoundingClientRect()
this.mouse.x = event.clientX - rect.left
this.mouse.y = event.clientY - rect.top
this.sendAngleUpdate()
},
touchEvent (event) {
var rect = this.canvas.getBoundingClientRect()
this.mouse.x = event.touch[0].clientX - rect.left
this.mouse.y = event.touch[0].clientY - rect.top
this.sendAngleUpdate()
},
sendAngleUpdate () {
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)
this.player.angle = this.player.targetAngle
send({ message: this.player, type: 'update' })
},
updatePlayer (player) {
player.x += this.settings.playerSpeed * Math.cos(player.angle)
player.y += this.settings.playerSpeed * Math.sin(player.angle)
player.angle = player.targetAngle
},
interpolatePlayer (pastPlayer, nextPlayer, dt) {
var player = {}
player.color = pastPlayer.color
player.walls = pastPlayer.walls
player.lastWall = pastPlayer.lastWall
player.x = pastPlayer.x + (nextPlayer.x - pastPlayer.x) * dt
player.y = pastPlayer.y + (nextPlayer.y - pastPlayer.y) * dt
player.angle = pastPlayer.angle + (nextPlayer.angle - pastPlayer.angle) * dt
player.targetAngle = pastPlayer.targetAngle + (nextPlayer.targetAngle - pastPlayer.targetAngle) * dt
return player
},
setCanvasSize () {
this.canvas.width = window.innerWidth
this.canvas.height = window.innerHeight
},
respawn () {
send({ type: 'respawn' })
}
}
}
</script>