1
0
forked from noxious/client

bit of cleaning, npm updated, working on character moving, typescript improvements

This commit is contained in:
Dennis Postma 2024-06-04 17:23:51 +02:00
parent b7aa4797b6
commit 45d4b69ab3
9 changed files with 80 additions and 170 deletions

18
package-lock.json generated
View File

@ -1765,9 +1765,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "20.14.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.0.tgz",
"integrity": "sha512-5cHBxFGJx6L4s56Bubp4fglrEpmyJypsqI6RgzMfBHWUJQGWAAi8cWcgetEbZXHYXo9C2Fa4EEds/uSyS4cxmA==",
"version": "20.14.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.1.tgz",
"integrity": "sha512-T2MzSGEu+ysB/FkWfqmhV3PLyQlowdptmmgD20C6QxsS8Fmv5SjpZ1ayXaEC0S21/h5UJ9iA6W/5vSNU5l00OA==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -3401,9 +3401,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.4.788",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.788.tgz",
"integrity": "sha512-ubp5+Ev/VV8KuRoWnfP2QF2Bg+O2ZFdb49DiiNbz2VmgkIqrnyYaqIOqj8A6K/3p1xV0QcU5hBQ1+BmB6ot1OA==",
"version": "1.4.789",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.789.tgz",
"integrity": "sha512-0VbyiaXoT++Fi2vHGo2ThOeS6X3vgRCWrjPeO2FeIAWL6ItiSJ9BqlH8LfCXe3X1IdcG+S0iLoNaxQWhfZoGzQ==",
"dev": true,
"license": "ISC"
},
@ -4544,9 +4544,9 @@
"license": "ISC"
},
"node_modules/jackspeak": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz",
"integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==",
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.2.3.tgz",
"integrity": "sha512-htOzIMPbpLid/Gq9/zaz9SfExABxqRe1sSCdxntlO/aMD6u0issZQiY25n2GKQUtJ02j7z5sfptlAOMpWWOmvw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {

View File

@ -1,8 +1,6 @@
<template>
<div class="game-container">
<div class="top-ui">
<Hud />
</div>
<div class="top-ui"><Hud /></div>
<Game :config="gameConfig" class="game" @create="bootGame">
<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('waypoint', '/assets/waypoint.png')
scene.textures.addBase64(
'player',
'character',
'data:image/png;base64,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'
)
}

View File

@ -1,19 +1,19 @@
<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" />
<Character :layer="layer" />
<Container v-if="zoneStore.isLoaded && zoneStore.getCharacters.length > 0">
<Container v-if="zoneStore.isLoaded && zoneStore.getCharacters.length">
<Character :layer="layer" v-for="character in zoneStore.getCharacters" :key="character.id" :character="character" />
</Container>
</template>
<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 { onBeforeMount, onMounted, reactive, ref, type Ref, toRaw, watch } from 'vue'
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 { useSocketStore } from '@/stores/socket'
import { useZoneStore } from '@/stores/zone'
@ -30,8 +30,8 @@ let zoneData = new Phaser.Tilemaps.MapData({
format: Phaser.Tilemaps.Formats.ARRAY_2D
})
let tileMap = new Phaser.Tilemaps.Tilemap(scene, zoneData)
let tileset: any = tileMap.addTilesetImage('default', 'tiles')
let layer: typeof TilemapLayer | null = tileMap.createBlankLayer('layer', tileset, 0, config.tile_size.y)
let tileset: Tileset = tileMap.addTilesetImage('default', 'tiles') as Tileset
let layer: TilemapLayer = tileMap.createBlankLayer('layer', tileset, 0, config.tile_size.y) as TilemapLayer
// center camera
const centerY = (tileMap.height * tileMap.tileHeight) / 2
@ -43,44 +43,37 @@ const zoneStore = useZoneStore()
const socket = useSocketStore()
// Watch for changes in the zoneStore and update the layer
watch(
() => zoneStore.tiles,
() => {
watch(() => zoneStore.tiles, () => {
// @TODO : change to tiles for when loading other maps
zoneStore.getTiles.forEach((row, y) => row.forEach((tile, x) => layer.putTileAt(tile, x, y)))
},
{ deep: true }
}, { deep: true }
)
// Load the zone from the server
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
socket.getConnection.on('character:zone:load', (data) => {
console.log('character:zone:load', data)
zoneStore.loadTiles(data.zone.tiles)
/**
* @TODO
* bug , when 2nd player joins, the first player is not added to the zone
*/
// console.log(data.players);
// console.log(data.players[1]); // key is user id
//
// // remove self from the players list
// delete data.players[socket.getConnection.id];
//
// zoneStore.addPlayers(data.players);
let characters = data.characters;
zoneStore.setCharacters(characters);
})
// Listen for player join events
socket.getConnection.on('character:zone:character_join', (data: CharacterType) => {
console.log('character:zone:character_join', data)
socket.getConnection.on('zone:character:join', (data: CharacterType) => {
console.log('character:zone:join', data)
zoneStore.addCharacter(data)
})
// Listen for user:disconnect
socket.getConnection.on('user:disconnect', (data: CharacterType) => {
zoneStore.removeCharacter(data)
})
/**
* 1 tile is 64x32
* the zone is 10x10

View File

@ -1,8 +1,9 @@
<template>
<Container>
<!-- @TODO : Text position X must be calculated based on the character name length -->
<Text
:text="props.character?.name ?? socket.character.name"
:x="position.x - 50"
:text="props.character?.name"
:x="position.x - 40"
:y="position.y - 80"
:style="{
fontFamily: 'Helvetica, Arial',
@ -13,13 +14,13 @@
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>
</template>
<script lang="ts" setup>
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 { useSocketStore } from '@/stores/socket'
import { type Character as CharacterT } from '@/types'
@ -28,39 +29,36 @@ const socket = useSocketStore()
const props = defineProps({
layer: Phaser.Tilemaps.TilemapLayer,
character: {
type: Object as () => CharacterT | undefined,
default: undefined
}
character: Object as () => CharacterT
})
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) => {
// console.log(time, delta);
// })
onMounted(() => {
if (isSelf) setupSelf()
const position = reactive({ x: 0, y: 0 })
if (props.character !== undefined) {
console.log('character', props.character)
position.x = props.character?.position_x
position.y = props.character?.position_y
if (!isSelf) {
}
});
function setupSelf()
{
scene.input.on(Phaser.Input.Events.POINTER_UP, onPointerClick)
const pointer_tile = ref(undefined)
function onPointerClick(pointer: Phaser.Input.Pointer) {
if (!isSelf) return;
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)
pointer_tile.value = getTile(px, py, props.layer) as Phaser.Tilemaps.Tile
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 })
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
@ -75,29 +73,17 @@ function onPointerClick(pointer: Phaser.Input.Pointer) {
}
}
if (!props.character) {
scene.input.on(Phaser.Input.Events.POINTER_UP, onPointerClick)
}
socket.getConnection.on('character:move', (data: any) => {
console.log('character moved', data)
if (data.id !== props.character?.id) {
console.log('not you')
return
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.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>

View File

@ -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> | []
}

View File

@ -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
}
}

View File

@ -1,8 +0,0 @@
export default interface IPlayer {
readonly id: number
name: string
coords: {
x: number
y: number
}
}

View File

@ -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
}
}

View File

@ -3,7 +3,6 @@ import { io, Socket } from 'socket.io-client'
import { useCookies } from '@vueuse/integrations/useCookies'
import config from '@/config'
import type { Character, User } from '@/types'
import { useNotificationStore } from '@/stores/notifications'
export const useSocketStore: StoreDefinition = defineStore('socket', {
state: () => ({