Added Tauri config, updated character hair location logic (WIP)

This commit is contained in:
Dennis Postma 2025-02-19 01:04:47 +01:00
parent ed992e1c2d
commit 0e3a0e3dba
29 changed files with 5503 additions and 24 deletions

200
package-lock.json generated
View File

@ -25,6 +25,7 @@
},
"devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.4.0",
"@tauri-apps/cli": "^2.2.7",
"@tsconfig/node20": "^20.1.4",
"@types/jsdom": "^21.1.7",
"@types/node": "^20.14.11",
@ -1748,6 +1749,205 @@
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
"license": "MIT"
},
"node_modules/@tauri-apps/cli": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.2.7.tgz",
"integrity": "sha512-ZnsS2B4BplwXP37celanNANiIy8TCYhvg5RT09n72uR/o+navFZtGpFSqljV8fy1Y4ixIPds8FrGSXJCN2BerA==",
"dev": true,
"license": "Apache-2.0 OR MIT",
"bin": {
"tauri": "tauri.js"
},
"engines": {
"node": ">= 10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.2.7",
"@tauri-apps/cli-darwin-x64": "2.2.7",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.2.7",
"@tauri-apps/cli-linux-arm64-gnu": "2.2.7",
"@tauri-apps/cli-linux-arm64-musl": "2.2.7",
"@tauri-apps/cli-linux-x64-gnu": "2.2.7",
"@tauri-apps/cli-linux-x64-musl": "2.2.7",
"@tauri-apps/cli-win32-arm64-msvc": "2.2.7",
"@tauri-apps/cli-win32-ia32-msvc": "2.2.7",
"@tauri-apps/cli-win32-x64-msvc": "2.2.7"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.2.7.tgz",
"integrity": "sha512-54kcpxZ3X1Rq+pPTzk3iIcjEVY4yv493uRx/80rLoAA95vAC0c//31Whz75UVddDjJfZvXlXZ3uSZ+bnCOnt0A==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.2.7.tgz",
"integrity": "sha512-Vgu2XtBWemLnarB+6LqQeLanDlRj7CeFN//H8bVVdjbNzxcSxsvbLYMBP8+3boa7eBnjDrqMImRySSgL6IrwTw==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.2.7.tgz",
"integrity": "sha512-+Clha2iQAiK9zoY/KKW0KLHkR0k36O78YLx5Sl98tWkwI3OBZFg5H5WT1plH/4sbZIS2aLFN6dw58/JlY9Bu/g==",
"cpu": [
"arm"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.2.7.tgz",
"integrity": "sha512-Z/Lp4SQe6BUEOays9BQAEum2pvZF4w9igyXijP+WbkOejZx4cDvarFJ5qXrqSLmBh7vxrdZcLwoLk9U//+yQrg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.7.tgz",
"integrity": "sha512-+8HZ+txff/Y3YjAh80XcLXcX8kpGXVdr1P8AfjLHxHdS6QD4Md+acSxGTTNbplmHuBaSHJvuTvZf9tU1eDCTDg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.2.7.tgz",
"integrity": "sha512-ahlSnuCnUntblp9dG7/w5ZWZOdzRFi3zl0oScgt7GF4KNAOEa7duADsxPA4/FT2hLRa0SvpqtD4IYFvCxoVv3Q==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.7.tgz",
"integrity": "sha512-+qKAWnJRSX+pjjRbKAQgTdFY8ecdcu8UdJ69i7wn3ZcRn2nMMzOO2LOMOTQV42B7/Q64D1pIpmZj9yblTMvadA==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.2.7.tgz",
"integrity": "sha512-aa86nRnrwT04u9D9fhf5JVssuAZlUCCc8AjqQjqODQjMd4BMA2+d4K9qBMpEG/1kVh95vZaNsLogjEaqSTTw4A==",
"cpu": [
"arm64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.2.7.tgz",
"integrity": "sha512-EiJ5/25tLSQOSGvv+t6o3ZBfOTKB5S3vb+hHQuKbfmKdRF0XQu2YPdIi1CQw1DU97ZAE0Dq4frvnyYEKWgMzVQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.2.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.2.7.tgz",
"integrity": "sha512-ZB8Kw90j8Ld+9tCWyD2fWCYfIrzbQohJ4DJSidNwbnehlZzP7wAz6Z3xjsvUdKtQ3ibtfoeTqVInzCCEpI+pWg==",
"cpu": [
"x64"
],
"dev": true,
"license": "Apache-2.0 OR MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tsconfig/node20": {
"version": "20.1.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz",

View File

@ -19,8 +19,8 @@
"axios": "^1.7.9",
"dexie": "^4.0.11",
"phaser": "^3.88.2",
"phavuer": "^0.16.5",
"phaser3-rex-plugins": "^1.80.13",
"phavuer": "^0.16.5",
"pinia": "^2.3.1",
"sharp": "^0.33.5",
"socket.io-client": "^4.8.1",
@ -31,6 +31,7 @@
},
"devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.4.0",
"@tauri-apps/cli": "^2.2.7",
"@tsconfig/node20": "^20.1.4",
"@types/jsdom": "^21.1.7",
"@types/node": "^20.14.11",

4
src-tauri/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Generated by Cargo
# will have compiled files and executables
/target/
/gen/schemas

5149
src-tauri/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

25
src-tauri/Cargo.toml Normal file
View File

@ -0,0 +1,25 @@
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2021"
rust-version = "1.77.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2.0.4", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
log = "0.4"
tauri = { version = "2.2.4", features = [] }
tauri-plugin-log = "2.0.0-rc"

3
src-tauri/build.rs Normal file
View File

@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

View File

@ -0,0 +1,11 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "enables the default permissions",
"windows": [
"main"
],
"permissions": [
"core:default"
]
}

BIN
src-tauri/icons/128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
src-tauri/icons/32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
src-tauri/icons/icon.icns Normal file

Binary file not shown.

BIN
src-tauri/icons/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
src-tauri/icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

16
src-tauri/src/lib.rs Normal file
View File

@ -0,0 +1,16 @@
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
if cfg!(debug_assertions) {
app.handle().plugin(
tauri_plugin_log::Builder::default()
.level(log::LevelFilter::Info)
.build(),
)?;
}
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

6
src-tauri/src/main.rs Normal file
View File

@ -0,0 +1,6 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
app_lib::run();
}

37
src-tauri/tauri.conf.json Normal file
View File

@ -0,0 +1,37 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "noxious",
"version": "0.1.0",
"identifier": "com.noxious.app",
"build": {
"frontendDist": "../dist",
"devUrl": "http://localhost:5173",
"beforeDevCommand": "npm run dev",
"beforeBuildCommand": "npm run build-only"
},
"app": {
"windows": [
{
"title": "Noxious",
"width": 800,
"height": 600,
"resizable": true,
"fullscreen": false
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}

View File

@ -2,7 +2,7 @@
<Container ref="characterContainer" :x="currentPositionX" :y="currentPositionY" :depth="isometricDepth">
<ChatBubble :mapCharacter="props.mapCharacter" />
<HealthBar :mapCharacter="props.mapCharacter" />
<CharacterHair :mapCharacter="props.mapCharacter" />
<CharacterHair :mapCharacter="props.mapCharacter" v-if="currentSpriteHeight > 0" :spriteHeight="currentSpriteHeight" />
<Sprite ref="characterSprite" :origin-y="1" :flipX="isFlippedX" />
</Container>
</template>
@ -17,7 +17,7 @@ import { useSoundComposable } from '@/composables/useSoundComposable'
import { useGameStore } from '@/stores/gameStore'
import { useMapStore } from '@/stores/mapStore'
import { Container, Sprite, useScene } from 'phavuer'
import { onMounted, onUnmounted, watch } from 'vue'
import { onMounted, onUnmounted, ref, watch } from 'vue'
const props = defineProps<{
tileMap: Phaser.Tilemaps.Tilemap
@ -28,7 +28,11 @@ const gameStore = useGameStore()
const mapStore = useMapStore()
const scene = useScene()
const { characterContainer, characterSprite, currentPositionX, currentPositionY, isometricDepth, isFlippedX, updatePosition, playAnimation, updateSprite, initializeSprite, cleanup } = useCharacterSpriteComposable(scene, props.tileMap, props.mapCharacter)
const { characterContainer, characterSprite, getSpriteHeightByAction, currentPositionX, currentPositionY, isometricDepth, isFlippedX, updatePosition, playAnimation, updateSprite, initializeSprite, cleanup } = useCharacterSpriteComposable(
scene,
props.tileMap,
props.mapCharacter
)
const { playSound, stopSound } = useSoundComposable()
const handlePositionUpdate = (newValues: any, oldValues: any) => {
@ -43,6 +47,8 @@ const handlePositionUpdate = (newValues: any, oldValues: any) => {
}
}
const currentSpriteHeight = ref(0)
/**
* Plays walk sound when character is moving
*/
@ -91,6 +97,8 @@ watch(
onMounted(async () => {
await initializeSprite()
currentSpriteHeight.value = await getSpriteHeightByAction('idle_left_up')
if (props.mapCharacter.character.id === gameStore.character!.id) {
scene.cameras.main.startFollow(characterContainer.value as Phaser.GameObjects.Container)
}

View File

@ -11,7 +11,8 @@ import { Image, useScene } from 'phavuer'
import { computed, onMounted, ref } from 'vue'
const props = defineProps<{
mapCharacter: MapCharacter
mapCharacter: MapCharacter,
spriteHeight: number
}>()
const gameStore = useGameStore()
@ -29,15 +30,12 @@ const texture = computed(() => {
const isFlippedX = computed(() => [6, 4].includes(props.mapCharacter.character.rotation ?? 0))
const imageProps = computed(() => {
const direction = [0, 6].includes(props.mapCharacter.character.rotation ?? 0) ? 'back' : 'front'
const spriteAction = sprite.value?.spriteActions?.find((spriteAction) => spriteAction.action === direction)
return {
depth: 9999,
originX: Number(spriteAction?.originX) ?? 0,
originY: Number(spriteAction?.originY) ?? 0,
originX: 0.5,
originY: 0.32 / 1.8, // 32 height
flipX: isFlippedX.value,
texture: texture.value
texture: texture.value,
y: -props.spriteHeight
}
})
@ -45,13 +43,13 @@ onMounted(async () => {
if (!props.mapCharacter.character.characterHair) return
const characterHairStorage = new CharacterHairStorage()
const spriteId = await characterHairStorage.getSpriteId(props.mapCharacter.character.characterHair)
if (!spriteId) return
const _hairSpriteId = await characterHairStorage.getSpriteId(props.mapCharacter.character.characterHair)
if (!_hairSpriteId) return
hairSpriteId.value = spriteId
hairSpriteId.value = _hairSpriteId
const spriteStorage = new SpriteStorage()
sprite.value = await spriteStorage.getById(spriteId)
sprite.value = await spriteStorage.getById(_hairSpriteId)
await loadSpriteTextures(scene, spriteId)
await loadSpriteTextures(scene, _hairSpriteId)
})
</script>

View File

@ -1,9 +1,9 @@
import config from '@/application/config'
import { Direction } from '@/application/enums'
import { type MapCharacter } from '@/application/types'
import { type MapCharacter, type SpriteAction } from '@/application/types'
import { calculateIsometricDepth, tileToWorldX, tileToWorldY } from '@/services/mapService'
import { loadSpriteTextures } from '@/services/textureService'
import { CharacterTypeStorage } from '@/storage/storages'
import { CharacterTypeStorage, SpriteStorage } from '@/storage/storages'
import { refObj } from 'phavuer'
import { computed, ref } from 'vue'
@ -72,7 +72,7 @@ export function useCharacterSpriteComposable(scene: Phaser.Scene, tilemap: Phase
// Add new listener
characterSprite.value.on(Phaser.Animations.Events.ANIMATION_COMPLETE, () => {
characterSprite.value!.setFrame(0)
characterSprite.value!.setTexture(charTexture.value)
characterSprite.value!.setTexture(spriteSpriteActionId.value)
})
characterSprite.value.anims.play(
@ -96,11 +96,27 @@ export function useCharacterSpriteComposable(scene: Phaser.Scene, tilemap: Phase
return [0, 6].includes(mapCharacter.character.rotation ?? 0) ? 'left_up' : 'right_down'
})
const getSpriteHeightByAction = async (action: string = '') => {
if (!characterSpriteId.value) return 0
const spriteStorage = new SpriteStorage()
const sprite = await spriteStorage.getById(characterSpriteId.value)
let actionWithDirection = `${currentAction.value}_${currentDirection.value}`
if (action) actionWithDirection = action
return sprite?.spriteActions?.find(
(spriteAction: SpriteAction) => spriteAction.action === actionWithDirection
)?.frameHeight ?? 0
}
const spriteHeight = computed(() =>
getSpriteHeightByAction(currentAction.value)
)
const currentAction = computed(() => {
return mapCharacter.isMoving ? 'walk' : 'idle'
})
const charTexture = computed(() => {
const spriteSpriteActionId = computed(() => {
const spriteId = characterSpriteId.value ?? 'idle_right_down'
return `${spriteId}-${currentAction.value}_${currentDirection.value}`
})
@ -109,11 +125,11 @@ export function useCharacterSpriteComposable(scene: Phaser.Scene, tilemap: Phase
if (!characterSprite.value) return
if (mapCharacter.isMoving) {
characterSprite.value.anims.play(charTexture.value, true)
characterSprite.value.anims.play(spriteSpriteActionId.value, true)
} else {
characterSprite.value.anims.stop()
characterSprite.value.setFrame(0)
characterSprite.value.setTexture(charTexture.value)
characterSprite.value.setTexture(spriteSpriteActionId.value)
}
}
@ -130,7 +146,7 @@ export function useCharacterSpriteComposable(scene: Phaser.Scene, tilemap: Phase
}
if (characterSprite.value) {
characterSprite.value.setTexture(charTexture.value)
characterSprite.value.setTexture(spriteSpriteActionId.value)
characterSprite.value.setFlipX(isFlippedX.value)
}
@ -146,10 +162,15 @@ export function useCharacterSpriteComposable(scene: Phaser.Scene, tilemap: Phase
characterContainer,
characterSpriteId,
characterSprite,
spriteHeight,
currentAction,
spriteSpriteActionId,
currentPositionX,
currentPositionY,
currentDirection,
isometricDepth,
isFlippedX,
getSpriteHeightByAction,
updatePosition,
playAnimation,
calcDirection,