bit of cleaning, npm updated, working on character moving, typescript improvements
This commit is contained in:
parent
b7aa4797b6
commit
45d4b69ab3
18
package-lock.json
generated
18
package-lock.json
generated
@ -1765,9 +1765,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.14.0",
|
"version": "20.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.1.tgz",
|
||||||
"integrity": "sha512-5cHBxFGJx6L4s56Bubp4fglrEpmyJypsqI6RgzMfBHWUJQGWAAi8cWcgetEbZXHYXo9C2Fa4EEds/uSyS4cxmA==",
|
"integrity": "sha512-T2MzSGEu+ysB/FkWfqmhV3PLyQlowdptmmgD20C6QxsS8Fmv5SjpZ1ayXaEC0S21/h5UJ9iA6W/5vSNU5l00OA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -3401,9 +3401,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.4.788",
|
"version": "1.4.789",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.788.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.789.tgz",
|
||||||
"integrity": "sha512-ubp5+Ev/VV8KuRoWnfP2QF2Bg+O2ZFdb49DiiNbz2VmgkIqrnyYaqIOqj8A6K/3p1xV0QcU5hBQ1+BmB6ot1OA==",
|
"integrity": "sha512-0VbyiaXoT++Fi2vHGo2ThOeS6X3vgRCWrjPeO2FeIAWL6ItiSJ9BqlH8LfCXe3X1IdcG+S0iLoNaxQWhfZoGzQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@ -4544,9 +4544,9 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/jackspeak": {
|
"node_modules/jackspeak": {
|
||||||
"version": "3.1.2",
|
"version": "3.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.2.3.tgz",
|
||||||
"integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==",
|
"integrity": "sha512-htOzIMPbpLid/Gq9/zaz9SfExABxqRe1sSCdxntlO/aMD6u0issZQiY25n2GKQUtJ02j7z5sfptlAOMpWWOmvw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BlueOak-1.0.0",
|
"license": "BlueOak-1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="game-container">
|
<div class="game-container">
|
||||||
<div class="top-ui">
|
<div class="top-ui"><Hud /></div>
|
||||||
<Hud />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Game :config="gameConfig" class="game" @create="bootGame">
|
<Game :config="gameConfig" class="game" @create="bootGame">
|
||||||
<Scene name="main" @preload="preloadScene" @create="bootScene">
|
<Scene name="main" @preload="preloadScene" @create="bootScene">
|
||||||
@ -57,7 +55,7 @@ const preloadScene = (scene: Phaser.Scene) => {
|
|||||||
scene.load.image('tiles', '/assets/tiles/default.png')
|
scene.load.image('tiles', '/assets/tiles/default.png')
|
||||||
scene.load.image('waypoint', '/assets/waypoint.png')
|
scene.load.image('waypoint', '/assets/waypoint.png')
|
||||||
scene.textures.addBase64(
|
scene.textures.addBase64(
|
||||||
'player',
|
'character',
|
||||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAABeCAYAAAAwnXTzAAAHWUlEQVR4nLVaQUhcRxj+DCuILruHXdbnYkBimkdFdouwFBdWKCWHHkoChragmAo9pKG3ltQGWrGHkEpzS0t7Mgn2EiIYcvQiLurBIF0RYYtbFiK6Lhqyiy4BBXt4+8/OzHvz3ryN/eCx782bN9/8//z/P//MbMvHP/wJXXTMTJ45lR+PT7XothHwQzQ8OIBUpt/2fmLaeq9D7EnYMTN5Njw4ALM3iFC8B0Y6ifZYWKjzKJ1EaSWHienJMy/SCzpkqUy/QNZqJISrPRaGkU7i/p0xpdq1CAHA7A0CAIx0UlnHD6mSkKQLxXu8+iTArWOuhCrUyhWclDZc67hJqWWlTqTt2LCV6aApQj8EMjxVWt0tAgBOD8tNEcjwlDBfOAIKm/jE7NJq8Mvr374b4affjwAAXvzyF7uXG300/4Ddz++8wkj3RRwr2vNUaWklBwBIZfqZWud3XmF+5xU66vd+oCQ8Hp9qmVtdx1p2k5Ee5PdweljGm5dPWb2R7ovCd29ePsWPd8aUhFpWupbdZLH0IL+HqGk1/BunSjm+quCqUpISqBtPHQf5PUZCF8HLXTzHkCddy26y8tPDMmrliu06PSxjYvqJcqrSDm0yKY2nfJH0KmhHmuHBAUZKSDnUc5POFyGRAg1p5Q4A3rO+L0JKL1KZflR3i8gXjpj1eklGaHFLovhchhpWobpbxL3ZJfasIneUkCciEBmlGbVyhQUEI52EgSTux3uY5HMzzvmNjZBmegCOUhEJNQwA5m6R1QvFe5CKW3WdSAVCPmkCgEvXh5gkcupgIInQSg5VjozqlFZyVi60Kovj4IeUNF26PsSSI0I4kWEXJU2yqsOJDMxb3yAU78Hw4IAt1WCEfNJkpJNoNRIArIwsWp8L+VyG3vOgMqpHnedhG8Oo2SVIxZM45TI8qC7FU0v6JaGOoFKzN4hAJCb0tFausDBGjfFxk1BaybFyoJGayGoVCGWLlBtVxU1qvLSSw+lhGaWVHPKFI8cc1aZSUiep5yC/h7XsJlIAG0sqB7gZpFD/zW5ibnUd9++MoT0WtlmrMrSRdGv1BlKZfmEmICLZMPh508mwAoDo7ABQ2cgyKeZW1zE8OCDMhYAVT6NSJneQ32tIqoBSQpKOwEedqNmFQCQGACzMWeUApI7JlsoIzd4gomYXUyUvXePDBhkt2wAgbNQtmiMiQ5LBrFS2UKcPeMnk8XEaL6dFj+AW1NhBfk8YfBmqDI0vzxeOUCtXYKSTgi8yQjnC6OKktGGLMG4QJHRSixcZRReybN5NaCrjy3wvSAF/SzVZa4yQxo8wt7ou5KR+iem7ViMhGKRNwtPDstKk6T0gWiCpToZTO4ywGYNxa5hwUtoQgrgt0ni5BFBP87nnKzeusXIvMEK/FqrTeL5whCvliqA9bSut7hY91w0q1MoV5vwX5JnCrbdEqiLmh0O2cPJF2xhWd4vMJQDgqK8PjytvrZfrb4H1A9wMtwHcIpW+yxeOrLp9faBk9J9nz3HlxjV8cHsMmF2yCPlI4GQwV69eFZ4fLywIHZDrLtB7au/Zc6R+/rUhoc5+WmdnJ7sfHR1V1tvf3xeeP39wG68Xl7H203cNQn7mdsqYebLLly8DALq7u21kOzs7trLXi8vo/OJrtG1kgdklu5W6SetGRuVUh7DwIoeT0gbCiQwAzi0oVMnz17uALPXv35+w9m0ShhMZtuOkgqy6xcVFdr+8vGwjvTe7hM/SX+F4fKolAFj+E4jEEDaA2ZFbglsAliF0dnZie3ubqYxIt7e3Gen+/j4WFhYQ3NrC8YciKd0HAMuHDFgBViYLbm2BjFx2D75D5Ao3w22Yc9FOALB85dJhWbnTezPcBoDzP0UdszfoGfgDx+NTLXMzk2epTD9C77+nrGj2BvEw3jizoJyVUslGYrzquBAlMKORM2uZLBTvQdTsYhd/YEI5rQ4uAA3zdUsZqMFAJIZAJCYQ+Nn5F9xClSoQKOMOJzIIRGKOK1xtwuPxqRbV5g4vQauRUBqXnIi5EhKpfl/9k9kIdeB1SHLuhEDzZxZNEXqReTm+L0J5g6EZ+D4KciNqj4VtsViGloRyiuhkkfyK2A2+JSTnr0Ecr3/nl2CkvY3JFyG/tpe3wKq7RVSfFT3b8GU0tL1FC1GnTQfPTvshBKzEFnA2f6fNPBm+/VCWxG8A9yWhMOdJO06+5kMv0OTLuwMvmfzODdoS8u4ANLdsA5oM3u+CcyM8l/PD/wPnRqi7R+CL0K1R3Uzg3CTUzQLOhZCOGXR2ObT+wENwU5vuloq2hHTI7JVa3B0dQsfM5JlqQav9jyEi9UIo3oO7o0PKVbRWaNMJzHydqNmFUHwPZm8Q96QzRF+zhXz0I4PPCAKRrLXInRXnx6anJ1re5QtHMFGsvwdqANph7VrQ3oxvQuv/F43zishHwzBvAak/HmJi+kl9Aeo807seyTqBl8BIW3PeSWlDiDrn9ldBWo4PYwAmrKyskWIsue4Eq+B6jk9w2yTyu8T7D0vv92u9uVoPAAAAAElFTkSuQmCC'
|
'data:image/png;base64,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'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<TilemapLayer v-if="zoneStore.isLoaded" :tilemap="tileMap" :tileset="zoneStore.getTiles" ref="tilemapLayer" :layerIndex="0" :cull-padding-x="10" :cull-padding-y="10" />
|
<TilemapLayerC v-if="zoneStore.isLoaded" :tilemap="tileMap" :tileset="zoneStore.getTiles" ref="tilemapLayer" :layerIndex="0" :cull-padding-x="10" :cull-padding-y="10" />
|
||||||
<Controls :layer="layer" />
|
<Controls :layer="layer" />
|
||||||
<Character :layer="layer" />
|
<Container v-if="zoneStore.isLoaded && zoneStore.getCharacters.length">
|
||||||
<Container v-if="zoneStore.isLoaded && zoneStore.getCharacters.length > 0">
|
|
||||||
<Character :layer="layer" v-for="character in zoneStore.getCharacters" :key="character.id" :character="character" />
|
<Character :layer="layer" v-for="character in zoneStore.getCharacters" :key="character.id" :character="character" />
|
||||||
</Container>
|
</Container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Container, refObj, TilemapLayer, useScene } from 'phavuer'
|
|
||||||
import Character from '@/components/sprites/Character.vue'
|
|
||||||
import {Character as CharacterType} from '@/types'
|
|
||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
import { onBeforeMount, onMounted, reactive, ref, type Ref, toRaw, watch } from 'vue'
|
|
||||||
import Tileset = Phaser.Tilemaps.Tileset
|
import Tileset = Phaser.Tilemaps.Tileset
|
||||||
|
import TilemapLayer = Phaser.Tilemaps.TilemapLayer
|
||||||
|
import { Container, TilemapLayer as TilemapLayerC, useScene } from 'phavuer'
|
||||||
|
import Character from '@/components/sprites/Character.vue'
|
||||||
|
import {type Character as CharacterType} from '@/types'
|
||||||
|
import { onBeforeMount, ref, type Ref, watch } from 'vue'
|
||||||
import Controls from '@/components/Controls.vue'
|
import Controls from '@/components/Controls.vue'
|
||||||
import { useSocketStore } from '@/stores/socket'
|
import { useSocketStore } from '@/stores/socket'
|
||||||
import { useZoneStore } from '@/stores/zone'
|
import { useZoneStore } from '@/stores/zone'
|
||||||
@ -30,8 +30,8 @@ let zoneData = new Phaser.Tilemaps.MapData({
|
|||||||
format: Phaser.Tilemaps.Formats.ARRAY_2D
|
format: Phaser.Tilemaps.Formats.ARRAY_2D
|
||||||
})
|
})
|
||||||
let tileMap = new Phaser.Tilemaps.Tilemap(scene, zoneData)
|
let tileMap = new Phaser.Tilemaps.Tilemap(scene, zoneData)
|
||||||
let tileset: any = tileMap.addTilesetImage('default', 'tiles')
|
let tileset: Tileset = tileMap.addTilesetImage('default', 'tiles') as Tileset
|
||||||
let layer: typeof TilemapLayer | null = tileMap.createBlankLayer('layer', tileset, 0, config.tile_size.y)
|
let layer: TilemapLayer = tileMap.createBlankLayer('layer', tileset, 0, config.tile_size.y) as TilemapLayer
|
||||||
|
|
||||||
// center camera
|
// center camera
|
||||||
const centerY = (tileMap.height * tileMap.tileHeight) / 2
|
const centerY = (tileMap.height * tileMap.tileHeight) / 2
|
||||||
@ -43,44 +43,37 @@ const zoneStore = useZoneStore()
|
|||||||
const socket = useSocketStore()
|
const socket = useSocketStore()
|
||||||
|
|
||||||
// Watch for changes in the zoneStore and update the layer
|
// Watch for changes in the zoneStore and update the layer
|
||||||
watch(
|
watch(() => zoneStore.tiles, () => {
|
||||||
() => zoneStore.tiles,
|
|
||||||
() => {
|
|
||||||
// @TODO : change to tiles for when loading other maps
|
// @TODO : change to tiles for when loading other maps
|
||||||
zoneStore.getTiles.forEach((row, y) => row.forEach((tile, x) => layer.putTileAt(tile, x, y)))
|
zoneStore.getTiles.forEach((row, y) => row.forEach((tile, x) => layer.putTileAt(tile, x, y)))
|
||||||
},
|
}, { deep: true }
|
||||||
{ deep: true }
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Load the zone from the server
|
// Load the zone from the server
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
socket.getConnection.emit('character:zone:load')
|
socket.getConnection.emit('character:zone:load', {zoneId: socket.character.zoneId})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Listen for the zone event from the server and load the zone
|
// Listen for the zone event from the server and load the zone
|
||||||
socket.getConnection.on('character:zone:load', (data) => {
|
socket.getConnection.on('character:zone:load', (data) => {
|
||||||
console.log('character:zone:load', data)
|
console.log('character:zone:load', data)
|
||||||
zoneStore.loadTiles(data.zone.tiles)
|
zoneStore.loadTiles(data.zone.tiles)
|
||||||
/**
|
|
||||||
* @TODO
|
|
||||||
* bug , when 2nd player joins, the first player is not added to the zone
|
|
||||||
*/
|
|
||||||
|
|
||||||
// console.log(data.players);
|
let characters = data.characters;
|
||||||
// console.log(data.players[1]); // key is user id
|
zoneStore.setCharacters(characters);
|
||||||
//
|
|
||||||
// // remove self from the players list
|
|
||||||
// delete data.players[socket.getConnection.id];
|
|
||||||
//
|
|
||||||
// zoneStore.addPlayers(data.players);
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Listen for player join events
|
// Listen for player join events
|
||||||
socket.getConnection.on('character:zone:character_join', (data: CharacterType) => {
|
socket.getConnection.on('zone:character:join', (data: CharacterType) => {
|
||||||
console.log('character:zone:character_join', data)
|
console.log('character:zone:join', data)
|
||||||
zoneStore.addCharacter(data)
|
zoneStore.addCharacter(data)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Listen for user:disconnect
|
||||||
|
socket.getConnection.on('user:disconnect', (data: CharacterType) => {
|
||||||
|
zoneStore.removeCharacter(data)
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1 tile is 64x32
|
* 1 tile is 64x32
|
||||||
* the zone is 10x10
|
* the zone is 10x10
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<Container>
|
<Container>
|
||||||
|
<!-- @TODO : Text position X must be calculated based on the character name length -->
|
||||||
<Text
|
<Text
|
||||||
:text="props.character?.name ?? socket.character.name"
|
:text="props.character?.name"
|
||||||
:x="position.x - 50"
|
:x="position.x - 40"
|
||||||
:y="position.y - 80"
|
:y="position.y - 80"
|
||||||
:style="{
|
:style="{
|
||||||
fontFamily: 'Helvetica, Arial',
|
fontFamily: 'Helvetica, Arial',
|
||||||
@ -13,91 +14,76 @@
|
|||||||
stroke: '#213547'
|
stroke: '#213547'
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<Sprite ref="sprite" texture="player" :x="position.x" :y="position.y" />
|
<Sprite ref="sprite" texture="character" :x="position.x" :y="position.y" />
|
||||||
</Container>
|
</Container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Container, onPostUpdate, onPreUpdate, Sprite, Text, useScene } from 'phavuer'
|
import { Container, onPostUpdate, onPreUpdate, Sprite, Text, useScene } from 'phavuer'
|
||||||
import { reactive, type Ref, ref } from 'vue'
|
import { onMounted, reactive, type Ref, ref } from 'vue'
|
||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
import { useSocketStore } from '@/stores/socket'
|
import { useSocketStore } from '@/stores/socket'
|
||||||
import {type Character as CharacterT } from '@/types'
|
import { type Character as CharacterT } from '@/types'
|
||||||
|
|
||||||
const socket = useSocketStore()
|
const socket = useSocketStore()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
layer: Phaser.Tilemaps.TilemapLayer,
|
layer: Phaser.Tilemaps.TilemapLayer,
|
||||||
character: {
|
character: Object as () => CharacterT
|
||||||
type: Object as () => CharacterT | undefined,
|
|
||||||
default: undefined
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const scene = useScene()
|
const scene = useScene()
|
||||||
|
const position = reactive({ x: props.character.position_x, y: props.character.position_y })
|
||||||
|
const isSelf = props.character.id === socket.character.id;
|
||||||
|
|
||||||
// onPreUpdate((time, delta) => {
|
onMounted(() => {
|
||||||
// console.log(time, delta);
|
if (isSelf) setupSelf()
|
||||||
// })
|
|
||||||
|
|
||||||
const position = reactive({ x: 0, y: 0 })
|
if (!isSelf) {
|
||||||
|
|
||||||
if (props.character !== undefined) {
|
|
||||||
console.log('character', props.character)
|
|
||||||
position.x = props.character?.position_x
|
|
||||||
position.y = props.character?.position_y
|
|
||||||
}
|
|
||||||
|
|
||||||
const pointer_tile = ref(undefined)
|
|
||||||
|
|
||||||
function onPointerClick(pointer: Phaser.Input.Pointer) {
|
|
||||||
const px = scene.cameras.main.worldView.x + pointer.x
|
|
||||||
const py = scene.cameras.main.worldView.y + pointer.y
|
|
||||||
|
|
||||||
pointer_tile.value = getTile(px, py, props.layer)
|
|
||||||
if (pointer_tile.value) {
|
|
||||||
const worldPoint = props.layer.tileToWorldXY(pointer_tile.value.x, pointer_tile.value.y)
|
|
||||||
position.x = worldPoint.x + config.tile_size.y
|
|
||||||
position.y = worldPoint.y
|
|
||||||
|
|
||||||
socket.getConnection.emit('move', { x: position.x, y: position.y })
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//Directions for player sprites + animations
|
function setupSelf()
|
||||||
if (px < 0 && py > 0) {
|
{
|
||||||
console.log('down left')
|
|
||||||
} else if (px < 0 && py < 0) {
|
|
||||||
console.log('top left')
|
|
||||||
} else if (px > 0 && py > 0) {
|
|
||||||
console.log('down right')
|
|
||||||
} else if (px > 0 && py < 0) {
|
|
||||||
console.log('top right')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!props.character) {
|
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_UP, onPointerClick)
|
scene.input.on(Phaser.Input.Events.POINTER_UP, onPointerClick)
|
||||||
}
|
const pointer_tile = ref(undefined)
|
||||||
|
function onPointerClick(pointer: Phaser.Input.Pointer) {
|
||||||
|
if (!isSelf) return;
|
||||||
|
|
||||||
socket.getConnection.on('character:move', (data: any) => {
|
const px = scene.cameras.main.worldView.x + pointer.x
|
||||||
console.log('character moved', data)
|
const py = scene.cameras.main.worldView.y + pointer.y
|
||||||
|
|
||||||
if (data.id !== props.character?.id) {
|
pointer_tile.value = getTile(px, py, props.layer) as Phaser.Tilemaps.Tile
|
||||||
console.log('not you')
|
if (pointer_tile.value) {
|
||||||
return
|
const worldPoint = props.layer.tileToWorldXY(pointer_tile.value.x, pointer_tile.value.y)
|
||||||
|
const position_x = worldPoint.x + config.tile_size.y
|
||||||
|
const position_y = worldPoint.y
|
||||||
|
socket.getConnection.emit('character:move', { position_x, position_y })
|
||||||
|
}
|
||||||
|
|
||||||
|
//Directions for player sprites + animations
|
||||||
|
if (px < 0 && py > 0) {
|
||||||
|
console.log('down left')
|
||||||
|
} else if (px < 0 && py < 0) {
|
||||||
|
console.log('top left')
|
||||||
|
} else if (px > 0 && py > 0) {
|
||||||
|
console.log('down right')
|
||||||
|
} else if (px > 0 && py < 0) {
|
||||||
|
console.log('top right')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTile(x: number, y: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
|
||||||
|
const tile: Phaser.Tilemaps.Tile = layer.getTileAtWorldXY(x, y)
|
||||||
|
if (!tile) return undefined;
|
||||||
|
return tile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.getConnection.on('character:moved', (data: CharacterT) => {
|
||||||
|
console.log('character:moved', data);
|
||||||
|
if (data.id !== props.character.id) return; // Only update the character that moved
|
||||||
position.x = data.position_x
|
position.x = data.position_x
|
||||||
position.y = data.position_y
|
position.y = data.position_y
|
||||||
})
|
})
|
||||||
|
|
||||||
function getTile(x: number, y: number, layer: Phaser.Tilemaps.TilemapLayer): Phaser.Tilemaps.Tile | undefined {
|
|
||||||
const tile: Phaser.Tilemaps.Tile = layer.getTileAtWorldXY(x, y)
|
|
||||||
|
|
||||||
if (!tile) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
return tile
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import type { Character } from '@/types'
|
|
||||||
|
|
||||||
export default interface IMap {
|
|
||||||
readonly id: number
|
|
||||||
name: string
|
|
||||||
width: number
|
|
||||||
height: number
|
|
||||||
data: any
|
|
||||||
characters: Array<Character> | []
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
import type IMap from '@/engine/Map/IMap'
|
|
||||||
import Player from '@/engine/Player/Player'
|
|
||||||
import type { Character } from '@/types'
|
|
||||||
|
|
||||||
export default class Map implements IMap {
|
|
||||||
id: number
|
|
||||||
name: string
|
|
||||||
width: number
|
|
||||||
height: number
|
|
||||||
data: any
|
|
||||||
characters: Character[]
|
|
||||||
|
|
||||||
constructor(id: number, name: string, width: number, height: number, data: any, characters: Character[]) {
|
|
||||||
this.id = id
|
|
||||||
this.name = name
|
|
||||||
this.width = width
|
|
||||||
this.height = height
|
|
||||||
this.data = data
|
|
||||||
this.characters = characters
|
|
||||||
}
|
|
||||||
|
|
||||||
public addCharacter(character: Character) {
|
|
||||||
this.characters.push(character)
|
|
||||||
}
|
|
||||||
|
|
||||||
public removeCharacter(character: Character) {
|
|
||||||
this.characters = this.characters.filter((c: Character) => c.id !== character.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
public moveCharacter(character: Character, x: number, y: number) {
|
|
||||||
const index = this.characters.findIndex((c: Character) => c.id === character.id)
|
|
||||||
this.characters[index].position_x = x
|
|
||||||
this.characters[index].position_y = y
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
export default interface IPlayer {
|
|
||||||
readonly id: number
|
|
||||||
name: string
|
|
||||||
coords: {
|
|
||||||
x: number
|
|
||||||
y: number
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
import type IPlayer from '@/engine/Player/IPlayer'
|
|
||||||
|
|
||||||
export default class Player implements IPlayer {
|
|
||||||
id: number
|
|
||||||
name: string
|
|
||||||
coords: { x: number; y: number }
|
|
||||||
|
|
||||||
constructor(id: number, name: string, coords: { x: number; y: number }) {
|
|
||||||
this.id = id
|
|
||||||
this.name = name
|
|
||||||
this.coords = coords
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,6 @@ import { io, Socket } from 'socket.io-client'
|
|||||||
import { useCookies } from '@vueuse/integrations/useCookies'
|
import { useCookies } from '@vueuse/integrations/useCookies'
|
||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
import type { Character, User } from '@/types'
|
import type { Character, User } from '@/types'
|
||||||
import { useNotificationStore } from '@/stores/notifications'
|
|
||||||
|
|
||||||
export const useSocketStore: StoreDefinition = defineStore('socket', {
|
export const useSocketStore: StoreDefinition = defineStore('socket', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user