103 lines
2.4 KiB
Vue

<script lang="ts">
import { defineComponent, PropType } from 'vue';
interface Player {
id: number,
name: string
}
interface Model {
yourId: number,
players: Player[]
}
function getPlayer(model: Model, id: number): Player | undefined {
return model.players.find(player => player.id === id)
}
/*
Handles all game business. Sends (local) player input to the server for distribution.
Receives player input from the server and manages state accordingly.
*/
export default defineComponent({
props: {
ws: { type: WebSocket, required: true },
model: { type: Object as PropType<Model>, required: true }
},
data() {
return {
chatMessages: [] as string[],
playerName: '',
chatMessage: ''
}
},
created() {
this.ws.addEventListener('message', (ev) => {
const message = JSON.parse(ev.data)
const payload = message.payload
console.log(`Message from player ${message.from}:`)
console.log(payload)
switch (payload.type) {
case 'join':
this.model.players.push({
id: message.from,
name: ''
})
break
case 'leave':
this.model.players = this.model.players.filter(player => player.id !== message.from)
break
case 'chat':
this.chatMessages.push(payload.message)
break
case 'set-name':
getPlayer(this.model, message.from)!.name = payload.name
break
}
})
},
methods: {
setName() {
this.ws.send(JSON.stringify({
type: 'set-name',
name: this.playerName
}))
},
sendChat() {
if (this.chatMessage === '') {
return
}
this.ws.send(JSON.stringify({
type: 'chat',
message: this.chatMessage
}))
this.chatMessage = ''
}
}
})
</script>
<template>
<pre>{{ JSON.stringify(model, null, 2) }}</pre>
<h1>I am #{{ model.yourId }}</h1>
<form @submit.prevent="setName">
<input v-model="playerName" placeholder="enter your name...">
<button >set name</button>
</form>
<form @submit.prevent="sendChat">
<input v-model="chatMessage">
<button>Post</button>
</form>
<h2>players</h2>
<ul v-if="model">
<li v-for="player in model.players" :key="player.id">{{ player.name }}#{{ player.id }}</li>
</ul>
<h2>chat</h2>
<ul v-if="model">
<li v-for="message in chatMessages">{{ message }}</li>
</ul>
</template>