1
0
forked from noxious/client

Sprite manager front- and backend logics

This commit is contained in:
Dennis Postma 2024-07-24 22:32:14 +02:00
parent 026165cff3
commit ffe97312c9
18 changed files with 242 additions and 118 deletions

118
package-lock.json generated
View File

@ -2204,39 +2204,39 @@
} }
}, },
"node_modules/@vue/compiler-core": { "node_modules/@vue/compiler-core": {
"version": "3.4.33", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.33.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.34.tgz",
"integrity": "sha512-MoIREbkdPQlnGfSKDMgzTqzqx5nmEjIc0ydLVYlTACGBsfvOJ4tHSbZXKVF536n6fB+0eZaGEOqsGThPpdvF5A==", "integrity": "sha512-Z0izUf32+wAnQewjHu+pQf1yw00EGOmevl1kE+ljjjMe7oEfpQ+BI3/JNK7yMB4IrUsqLDmPecUrpj3mCP+yJQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.24.7", "@babel/parser": "^7.24.7",
"@vue/shared": "3.4.33", "@vue/shared": "3.4.34",
"entities": "^4.5.0", "entities": "^4.5.0",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"source-map-js": "^1.2.0" "source-map-js": "^1.2.0"
} }
}, },
"node_modules/@vue/compiler-dom": { "node_modules/@vue/compiler-dom": {
"version": "3.4.33", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.33.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.34.tgz",
"integrity": "sha512-GzB8fxEHKw0gGet5BKlpfXEqoBnzSVWwMnT+dc25wE7pFEfrU/QsvjZMP9rD4iVXHBBoemTct8mN0GJEI6ZX5A==", "integrity": "sha512-3PUOTS1h5cskdOJMExCu2TInXuM0j60DRPpSCJDqOCupCfUZCJoyQmKtRmA8EgDNZ5kcEE7vketamRZfrEuVDw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-core": "3.4.33", "@vue/compiler-core": "3.4.34",
"@vue/shared": "3.4.33" "@vue/shared": "3.4.34"
} }
}, },
"node_modules/@vue/compiler-sfc": { "node_modules/@vue/compiler-sfc": {
"version": "3.4.33", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.33.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.34.tgz",
"integrity": "sha512-7rk7Vbkn21xMwIUpHQR4hCVejwE6nvhBOiDgoBcR03qvGqRKA7dCBSsHZhwhYUsmjlbJ7OtD5UFIyhP6BY+c8A==", "integrity": "sha512-x6lm0UrM03jjDXTPZgD9Ad8bIVD1ifWNit2EaWQIZB5CULr46+FbLQ5RpK7AXtDHGjx9rmvC7QRCTjsiGkAwRw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.24.7", "@babel/parser": "^7.24.7",
"@vue/compiler-core": "3.4.33", "@vue/compiler-core": "3.4.34",
"@vue/compiler-dom": "3.4.33", "@vue/compiler-dom": "3.4.34",
"@vue/compiler-ssr": "3.4.33", "@vue/compiler-ssr": "3.4.34",
"@vue/shared": "3.4.33", "@vue/shared": "3.4.34",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"magic-string": "^0.30.10", "magic-string": "^0.30.10",
"postcss": "^8.4.39", "postcss": "^8.4.39",
@ -2244,13 +2244,13 @@
} }
}, },
"node_modules/@vue/compiler-ssr": { "node_modules/@vue/compiler-ssr": {
"version": "3.4.33", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.33.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.34.tgz",
"integrity": "sha512-0WveC9Ai+eT/1b6LCV5IfsufBZ0HP7pSSTdDjcuW302tTEgoBw8rHVHKPbGUtzGReUFCRXbv6zQDDgucnV2WzQ==", "integrity": "sha512-8TDBcLaTrFm5rnF+Qm4BlliaopJgqJ28Nsrc80qazynm5aJO+Emu7y0RWw34L8dNnTRdcVBpWzJxhGYzsoVu4g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.4.33", "@vue/compiler-dom": "3.4.34",
"@vue/shared": "3.4.33" "@vue/shared": "3.4.34"
} }
}, },
"node_modules/@vue/devtools-api": { "node_modules/@vue/devtools-api": {
@ -2369,53 +2369,53 @@
} }
}, },
"node_modules/@vue/reactivity": { "node_modules/@vue/reactivity": {
"version": "3.4.33", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.33.tgz", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.34.tgz",
"integrity": "sha512-B24QIelahDbyHipBgbUItQblbd4w5HpG3KccL+YkGyo3maXyS253FzcTR3pSz739OTphmzlxP7JxEMWBpewilA==", "integrity": "sha512-ua+Lo+wBRlBEX9TtgPOShE2JwIO7p6BTZ7t1KZVPoaBRfqbC7N3c8Mpzicx173fXxx5VXeU6ykiHo7WgLzJQDA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/shared": "3.4.33" "@vue/shared": "3.4.34"
} }
}, },
"node_modules/@vue/runtime-core": { "node_modules/@vue/runtime-core": {
"version": "3.4.33", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.33.tgz", "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.34.tgz",
"integrity": "sha512-6wavthExzT4iAxpe8q37/rDmf44nyOJGISJPxCi9YsQO+8w9v0gLCFLfH5TzD1V1AYrTAdiF4Y1cgUmP68jP6w==", "integrity": "sha512-PXhkiRPwcPGJ1BnyBZFI96GfInCVskd0HPNIAZn7i3YOmLbtbTZpB7/kDTwC1W7IqdGPkTVC63IS7J2nZs4Ebg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/reactivity": "3.4.33", "@vue/reactivity": "3.4.34",
"@vue/shared": "3.4.33" "@vue/shared": "3.4.34"
} }
}, },
"node_modules/@vue/runtime-dom": { "node_modules/@vue/runtime-dom": {
"version": "3.4.33", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.33.tgz", "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.34.tgz",
"integrity": "sha512-iHsMCUSFJ+4z432Bn9kZzHX+zOXa6+iw36DaVRmKYZpPt9jW9riF32SxNwB124i61kp9+AZtheQ/mKoJLerAaQ==", "integrity": "sha512-dXqIe+RqFAK2Euak4UsvbIupalrhc67OuQKpD7HJ3W2fv8jlqvI7szfBCsAEcE8o/wyNpkloxB6J8viuF/E3gw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/reactivity": "3.4.33", "@vue/reactivity": "3.4.34",
"@vue/runtime-core": "3.4.33", "@vue/runtime-core": "3.4.34",
"@vue/shared": "3.4.33", "@vue/shared": "3.4.34",
"csstype": "^3.1.3" "csstype": "^3.1.3"
} }
}, },
"node_modules/@vue/server-renderer": { "node_modules/@vue/server-renderer": {
"version": "3.4.33", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.33.tgz", "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.34.tgz",
"integrity": "sha512-jTH0d6gQcaYideFP/k0WdEu8PpRS9MF8d0b6SfZzNi+ap972pZ0TNIeTaESwdOtdY0XPVj54XEJ6K0wXxir4fw==", "integrity": "sha512-GeyEUfMVRZMD/mZcNONEqg7MiU10QQ1DB3O/Qr6+8uXpbwdlmVgQ5Qs1/ZUAFX1X2UUtqMoGrDRbxdWfOJFT7Q==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-ssr": "3.4.33", "@vue/compiler-ssr": "3.4.34",
"@vue/shared": "3.4.33" "@vue/shared": "3.4.34"
}, },
"peerDependencies": { "peerDependencies": {
"vue": "3.4.33" "vue": "3.4.34"
} }
}, },
"node_modules/@vue/shared": { "node_modules/@vue/shared": {
"version": "3.4.33", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.33.tgz", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.34.tgz",
"integrity": "sha512-aoRY0jQk3A/cuvdkodTrM4NMfxco8n55eG4H7ML/CRy7OryHfiqvug4xrCBBMbbN+dvXAetDDwZW9DXWWjBntA==", "integrity": "sha512-x5LmiRLpRsd9KTjAB8MPKf0CDPMcuItjP0gbNqFCIgL1I8iYp4zglhj9w9FPCdIbHG2M91RVeIbArFfFTz9I3A==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vue/test-utils": { "node_modules/@vue/test-utils": {
@ -5705,9 +5705,9 @@
} }
}, },
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.4.39", "version": "8.4.40",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz",
"integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -7178,16 +7178,16 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/vue": { "node_modules/vue": {
"version": "3.4.33", "version": "3.4.34",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.33.tgz", "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.34.tgz",
"integrity": "sha512-VdMCWQOummbhctl4QFMcW6eNtXHsFyDlX60O/tsSQuCcuDOnJ1qPOhhVla65Niece7xq/P2zyZReIO5mP+LGTQ==", "integrity": "sha512-VZze05HWlA3ItreQ/ka7Sx7PoD0/3St8FEiSlSTVgb6l4hL+RjtP2/8g5WQBzZgyf8WG2f+g1bXzC7zggLhAJA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.4.33", "@vue/compiler-dom": "3.4.34",
"@vue/compiler-sfc": "3.4.33", "@vue/compiler-sfc": "3.4.34",
"@vue/runtime-dom": "3.4.33", "@vue/runtime-dom": "3.4.34",
"@vue/server-renderer": "3.4.33", "@vue/server-renderer": "3.4.34",
"@vue/shared": "3.4.33" "@vue/shared": "3.4.34"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "*" "typescript": "*"
@ -7542,9 +7542,9 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/yaml": { "node_modules/yaml": {
"version": "2.4.5", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
"integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"bin": { "bin": {

View File

@ -0,0 +1 @@
<svg id="Layer_1" enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m241.287 111.469-105.931-43.752v80.246c0 43.397-24.289 81.227-59.986 100.612l56.221 187.401h109.697v-324.507z"/><path d="m376.644 147.963v-80.246l-105.931 43.752v324.508h109.697l56.221-187.401c-35.698-19.386-59.987-57.216-59.987-100.613z"/><path d="m150.069 503.655h211.862c8.126 0 14.713-6.587 14.713-14.713v-23.54h-241.288v23.54c0 8.126 6.587 14.713 14.713 14.713z"/><path d="m371.685 37.929-15.732-23.141c-4.156-6.113-12.197-8.194-18.793-4.858-20.884 10.563-51.667 15.564-81.16 15.564s-60.276-5-81.16-15.564c-6.596-3.336-14.637-1.255-18.793 4.858l-15.732 23.141 115.685 47.779z"/><path d="m105.931 147.963v-88.63h-20.952c-46.932 0-84.979 38.046-84.979 84.979v73.917c0 8.126 6.587 14.713 14.713 14.713h6.239c46.932 0 84.979-38.047 84.979-84.979z"/><path d="m427.021 59.333h-20.952v88.63c0 46.933 38.046 84.979 84.979 84.979h6.239c8.126 0 14.713-6.587 14.713-14.713v-73.918c0-46.932-38.046-84.978-84.979-84.978z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1 @@
<svg id="Layer_1" enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m305.353 476.567c0 12.389-10.044 22.433-22.433 22.433s-22.433-10.044-22.433-22.433v-153.097c0-2.292-1.87-4.161-4.161-4.161h-.652c-2.291 0-4.161 1.869-4.161 4.161v153.097c0 12.389-10.044 22.433-22.433 22.433-12.39 0-22.433-10.044-22.433-22.433 0-98.782 0-205.018 0-304.282-.001-2.292-1.87-4.16-4.161-4.16h-.652c-2.292 0-4.161 1.869-4.161 4.161v117.143c0 9.704-7.867 17.571-17.57 17.571-9.704 0-17.571-7.867-17.571-17.571 0-45.684 0-81.367 0-127.051 0-27.539 22.461-50 50-50h86.937c27.539 0 50 22.461 50 50v127.051c0 9.704-7.867 17.571-17.571 17.571s-17.571-7.867-17.571-17.571c0-42.381 0-74.762 0-117.143 0-2.292-1.869-4.161-4.161-4.161h-.653c-2.291 0-4.16 1.869-4.161 4.16.001 99.263.001 205.499.001 304.282zm-49.353-463.567c23.788 0 43.072 19.284 43.072 43.072s-19.284 43.072-43.072 43.072-43.072-19.284-43.072-43.072 19.284-43.072 43.072-43.072z" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1 @@
<svg id="Layer_1" enable-background="new 0 0 100 100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><g><g><path d="m41.09 22.29c2.99 0 5.41-2.42 5.41-5.39 0-2.99-2.42-5.41-5.41-5.41-2.98 0-5.4 2.42-5.4 5.41.01 2.97 2.42 5.39 5.4 5.39"/></g><g><path d="m86.6 31.45-10.83-7.21s2.64-5.91.66-5.91c-8.43 8.43-21.99 22.74-21.99 22.74h-8.04v-5.9l8.39 1.91c1.4.32 2.8-.55 3.12-1.97.31-1.4-.57-2.79-1.97-3.11l-9.54-2.36v-.61c0-2.99-2.42-5.41-5.41-5.41s-5.4 2.42-5.4 5.41v12.03h-16.77c-4.39 0-7.32 3.57-7.32 7.96v13.19s0 1.85 1.86 1.85c1.69 0 1.88-1.85 1.88-1.85l2.72-12.38 1.52-5.17-1 15.67-1.96 4.63v19.98c0 1.97 1.62 3.57 3.59 3.57 1.98 0 3.57-1.6 3.57-3.57v-17.3l3.54-5.56v5.94l7.91 18.62c.97 1.73 3.15 2.33 4.87 1.36s2.34-3.15 1.35-4.87l-6.77-16.14 3.24-5.54h18.09v23.51c0 1.97 1.6 3.57 3.57 3.57s3.58-1.6 3.58-3.57v-18.15c1.61 3.15 3.16 6.18 3.16 6.18l-2.18 10.36c-.41 1.93.83 3.82 2.76 4.23s3.84-.83 4.25-2.76l2.39-11.38-7.15-18.08 4.98-10.16c.81.22 1.68.35 2.58.35 4.52 0 8.33-3.1 9.37-7.32l.88.16c1.51.28 3.11-.41 3.91-1.84 1.03-1.78.37-4.09-1.41-5.1zm-12.74 12.12c-.57 0-1.14-.06-1.68-.19l3.33-6.62 5.73 1.1c-.84 3.29-3.83 5.71-7.38 5.71z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path d="M318.72,293.065c-12.87-7.03-27.63-11.02-43.32-11.02h-37.29c-16.13,0-31.27,4.22-44.38,11.61
c-27.57,15.52-46.19,45.07-46.19,78.96v27.94h218.43v-27.94C365.97,338.285,346.87,308.425,318.72,293.065z"/>
</g>
</g>
<g>
<g>
<path d="M421.7,257.225h-31c-18.1,0-34.97,5.35-49.12,14.57c6.8,4.46,13.19,9.67,19.08,15.56c22.77,22.77,35.31,53.05,35.31,85.26
v13.14H512v-38.23C512,297.735,471.49,257.225,421.7,257.225z"/>
</g>
</g>
<g>
<g>
<path d="M121.3,257.225h-31c-49.79,0-90.3,40.51-90.3,90.3v38.23h117.54v-13.14c0-32.21,12.55-62.49,35.32-85.26
c5.67-5.67,11.8-10.71,18.32-15.06C156.88,262.775,139.73,257.225,121.3,257.225z"/>
</g>
</g>
<g>
<g>
<path d="M406.153,121.416c-0.159,0-0.324,0.001-0.484,0.003c-33.558,0.277-60.622,29.282-60.33,64.655
c0.291,35.205,27.565,63.652,60.906,63.652c0.16,0,0.324-0.001,0.484-0.003c16.455-0.136,31.81-7.068,43.238-19.521
c11.162-12.164,17.232-28.192,17.093-45.134C466.769,149.863,439.495,121.416,406.153,121.416z"/>
</g>
</g>
<g>
<g>
<path d="M105.754,121.416c-0.159,0-0.324,0.001-0.484,0.003c-33.558,0.277-60.622,29.282-60.33,64.655
c0.29,35.205,27.565,63.652,60.906,63.652c0.16,0,0.324-0.001,0.484-0.003c16.454-0.136,31.81-7.068,43.238-19.521
c11.163-12.164,17.233-28.192,17.093-45.134C166.37,149.863,139.096,121.416,105.754,121.416z"/>
</g>
</g>
<g>
<g>
<path d="M256.76,111.445c-38.69,0-70.16,33.25-70.16,74.13c0,29.54,16.44,55.1,40.17,67c9.1,4.57,19.27,7.12,29.99,7.12
c10.72,0,20.89-2.55,29.99-7.12c23.73-11.9,40.17-37.46,40.17-67C326.92,144.695,295.45,111.445,256.76,111.445z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1 @@
<svg id="Layer_1" enable-background="new 0 0 506.061 506.061" height="512" viewBox="0 0 506.061 506.061" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m241.967 104.205c24.767 8.896 57.306 13.795 91.622 13.795s66.855-4.899 91.622-13.795c37.919-13.62 45.878-32.1 45.878-45.205s-7.959-31.585-45.878-45.205c-24.766-8.896-57.305-13.795-91.622-13.795s-66.855 4.899-91.622 13.795c-37.919 13.62-45.878 32.1-45.878 45.205s7.959 31.585 45.878 45.205z"/><path d="m333.59 148c-30.51 0-60.006-3.625-84.958-10.33l115.228 60.384c6.91 3.621 12.789 9.023 17.004 15.623 4.591 7.193 7.108 15.699 7.108 24.236v165.595c13.642-2.294 26.262-5.459 37.308-9.427 37.861-13.599 45.809-32.102 45.809-45.229v-234.924c-9.039 6.763-20.705 13.112-35.737 18.511-27.937 10.035-64.078 15.561-101.762 15.561z"/><path d="m203.435 147.855c-4.361-2.285-9.564-2.285-13.926 0 0 0-111.519 58.44-139.954 73.341l146.924 76.577 147.069-76.494z"/><path d="m211.472 506.061 138.479-72.786c4.933-2.592 8.021-7.705 8.021-13.277 0 0 0-134.738 0-172.405l-146.5 76.198z"/><path d="m34.972 419.998c0 5.572 3.089 10.685 8.021 13.277l138.479 72.786v-182.28l-146.5-76.356z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<svg id="Capa_1" enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m276.663 202.758-.084.225h-126.502c-18.363 0-35.456 5.528-49.714 15h-40.363c-16.542 0-30-13.458-30-30s13.458-30 30-30h45c8.284 0 15-6.716 15-15s-6.716-15-15-15h-45c-33.084 0-60 26.916-60 60s26.916 60 60 60h12.115c-7.7 13.266-12.115 28.665-12.115 45.077v187.923c0 8.284 6.716 15 15 15h60c8.284 0 15-6.716 15-15v-126.592l137 12.305v115.287c0 8.284 6.716 15 15 15h60c8.284 0 15-6.716 15-15v-142.514l18.483-92.417z"/><path d="m497 112.983h-45.262c-2.436-22.897-21.816-41-45.688-41h-25.169l-9.184-45c-3.005-14.719-23.508-16.321-28.755-2.234l-55.811 149.894 114.311 42.613 2.855-14.273h32.703c41.355 0 75-33.645 75-75 0-8.284-6.716-15-15-15z"/></g></svg>

After

Width:  |  Height:  |  Size: 795 B

View File

@ -0,0 +1 @@
<svg id="bold" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m9.25 0h-7.5c-.965 0-1.75.785-1.75 1.75v4.5c0 .965.785 1.75 1.75 1.75h7.5c.965 0 1.75-.785 1.75-1.75v-4.5c0-.965-.785-1.75-1.75-1.75z"/><path d="m9.25 10h-7.5c-.965 0-1.75.785-1.75 1.75v10.5c0 .965.785 1.75 1.75 1.75h7.5c.965 0 1.75-.785 1.75-1.75v-10.5c0-.965-.785-1.75-1.75-1.75z"/><path d="m22.25 16h-7.5c-.965 0-1.75.785-1.75 1.75v4.5c0 .965.785 1.75 1.75 1.75h7.5c.965 0 1.75-.785 1.75-1.75v-4.5c0-.965-.785-1.75-1.75-1.75z"/><path d="m22.25 0h-7.5c-.965 0-1.75.785-1.75 1.75v10.5c0 .965.785 1.75 1.75 1.75h7.5c.965 0 1.75-.785 1.75-1.75v-10.5c0-.965-.785-1.75-1.75-1.75z"/></g></svg>

After

Width:  |  Height:  |  Size: 730 B

View File

@ -0,0 +1 @@
<svg height="512" viewBox="0 0 64 64" width="512" xmlns="http://www.w3.org/2000/svg"><g id="Fullscreen-Arrow-Arrows-Direction-User_Interface" data-name="Fullscreen-Arrow-Arrows-Direction-User Interface"><path d="m61 45v14a2.006 2.006 0 0 1 -2 2h-14a3 3 0 0 1 0-6h5.76l-14.51-14.51a3 3 0 0 1 4.24-4.24l14.51 14.51v-5.76a3 3 0 0 1 6 0z"/><path d="m61 5v14a3 3 0 0 1 -6 0v-5.76l-14.51 14.51a3 3 0 1 1 -4.24-4.24l14.51-14.51h-5.76a3 3 0 0 1 0-6h14a2.006 2.006 0 0 1 2 2z"/><path d="m27.75 23.51a3 3 0 1 1 -4.24 4.24l-14.51-14.51v5.76a3 3 0 0 1 -6 0v-14a2.006 2.006 0 0 1 2-2h14a3 3 0 0 1 0 6h-5.76z"/><path d="m27.75 36.25a2.994 2.994 0 0 1 0 4.24l-14.51 14.51h5.76a3 3 0 0 1 0 6h-14a2.006 2.006 0 0 1 -2-2v-14a3 3 0 0 1 6 0v5.76l14.51-14.51a3 3 0 0 1 4.24 0z"/></g></svg>

After

Width:  |  Height:  |  Size: 768 B

View File

@ -0,0 +1 @@
<svg id="icons" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m3.71 21.71 5.29-5.3v4.59a1 1 0 0 0 2 0v-7a1 1 0 0 0 -1-1h-7a1 1 0 0 0 0 2h4.59l-5.3 5.29a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0z"/><path d="m21.71 2.29a1 1 0 0 0 -1.42 0l-5.29 5.3v-4.59a1 1 0 0 0 -2 0v7a1 1 0 0 0 1 1h7a1 1 0 0 0 0-2h-4.59l5.3-5.29a1 1 0 0 0 0-1.42z"/></svg>

After

Width:  |  Height:  |  Size: 375 B

View File

@ -1,11 +1,11 @@
<template> <template>
<div class="border border-gray-300 rounded mb-4"> <div class="border border-gray-300 rounded mb-4">
<button @click="toggle" class="w-full p-3 bg-gray-100 rounded hover:bg-gray-200 text-left cursor-pointer transition-colors duration-200 ease-in-out"> <div @click="toggle" class="w-[98%] p-3 bg-gray-100 bg-opacity-50 rounded hover:bg-gray-200 text-left text-white font-default cursor-pointer transition-colors duration-200 ease-in-out">
{{ props.title }} <slot name="header" />
</button> </div>
<transition enter-active-class="transition-all duration-300 ease-in-out" leave-active-class="transition-all duration-300 ease-in-out" enter-from-class="opacity-0 max-h-0" enter-to-class="opacity-100 max-h-96" leave-from-class="opacity-100 max-h-96" leave-to-class="opacity-0 max-h-0"> <transition enter-active-class="transition-all duration-300 ease-in-out" leave-active-class="transition-all duration-300 ease-in-out" enter-from-class="opacity-0 max-h-0" enter-to-class="opacity-100 max-h-96" leave-from-class="opacity-100 max-h-96" leave-to-class="opacity-0 max-h-0">
<div v-if="isOpen" class="p-3 overflow-hidden"> <div v-if="isOpen" class="p-3 overflow-hidden">
<slot></slot> <slot name="content" />
</div> </div>
</transition> </transition>
</div> </div>
@ -19,8 +19,4 @@ const isOpen = ref(false)
const toggle = () => { const toggle = () => {
isOpen.value = !isOpen.value isOpen.value = !isOpen.value
} }
const props = defineProps({
title: String
})
</script> </script>

View File

@ -1,5 +1,5 @@
<template> <template>
<Modal :isModalOpen="gameStore.isGmPanelOpen" @modal:close="() => gameStore.toggleGmPanel()" :modal-width="1000" :modal-height="650"> <Modal :isModalOpen="gameStore.isGmPanelOpen" @modal:close="() => gameStore.toggleGmPanel()" :modal-width="1000" :modal-height="650" :can-full-screen="true">
<template #modalHeader> <template #modalHeader>
<h3 class="m-0 font-medium shrink-0">GM Panel</h3> <h3 class="m-0 font-medium shrink-0">GM Panel</h3>
<div class="flex gap-1.5 flex-wrap"> <div class="flex gap-1.5 flex-wrap">

View File

@ -4,6 +4,9 @@
<div @mousedown="startDrag" class="cursor-move p-2.5 flex justify-between items-center border-solid border-0 border-b border-cyan-200"> <div @mousedown="startDrag" class="cursor-move p-2.5 flex justify-between items-center border-solid border-0 border-b border-cyan-200">
<slot name="modalHeader" /> <slot name="modalHeader" />
<div class="flex gap-2.5"> <div class="flex gap-2.5">
<button @click="toggleFullScreen" class="w-5 h-5 m-0 p-0 relative hover:scale-110 transition-transform duration-300 ease-in-out" v-if="canFullScreen">
<img :alt="isFullScreen ? 'exit full-screen' : 'full-screen'" draggable="false" :src="isFullScreen ? '/assets/icons/minimize.svg' : '/assets/icons/full-screen.svg'" class="w-full h-full invert" />
</button>
<button @click="close" v-if="closable" class="w-5 h-5 m-0 p-0 relative hover:rotate-180 transition-transform duration-300 ease-in-out"> <button @click="close" v-if="closable" class="w-5 h-5 m-0 p-0 relative hover:rotate-180 transition-transform duration-300 ease-in-out">
<img alt="close" draggable="false" src="/assets/icons/close-button-white.svg" class="w-full h-full" /> <img alt="close" draggable="false" src="/assets/icons/close-button-white.svg" class="w-full h-full" />
</button> </button>
@ -11,7 +14,7 @@
</div> </div>
<div class="overflow-hidden grow"> <div class="overflow-hidden grow">
<slot name="modalBody" /> <slot name="modalBody" />
<img v-if="isResizable" src="/assets/icons/resize-icon.svg" alt="resize" class="absolute bottom-0 right-0 w-5 h-5 cursor-nwse-resize invert-[60%]" @mousedown="startResize" /> <img v-if="isResizable && !isFullScreen" src="/assets/icons/resize-icon.svg" alt="resize" class="absolute bottom-0 right-0 w-5 h-5 cursor-nwse-resize invert-[60%]" @mousedown="startResize" />
</div> </div>
<div v-if="$slots.modalFooter" class="px-5 min-h-12 flex justify-end gap-7.5 items-center border-solid border-t border-cyan-200"> <div v-if="$slots.modalFooter" class="px-5 min-h-12 flex justify-end gap-7.5 items-center border-solid border-t border-cyan-200">
<slot name="modalFooter" /> <slot name="modalFooter" />
@ -36,6 +39,10 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: true default: true
}, },
canFullScreen: {
type: Boolean,
default: false
},
modalWidth: { modalWidth: {
type: Number, type: Number,
default: 500 default: 500
@ -58,6 +65,7 @@ const minWidth = ref(200)
const minHeight = ref(100) const minHeight = ref(100)
const isResizing = ref(false) const isResizing = ref(false)
const isDragging = ref(false) const isDragging = ref(false)
const isFullScreen = ref(false)
let startX = 0 let startX = 0
let startY = 0 let startY = 0
@ -65,12 +73,13 @@ let initialX = 0
let initialY = 0 let initialY = 0
let startWidth = 0 let startWidth = 0
let startHeight = 0 let startHeight = 0
let preFullScreenState = { x: 0, y: 0, width: 0, height: 0 }
const modalStyle = computed(() => ({ const modalStyle = computed(() => ({
top: `${y.value}px`, top: isFullScreen.value ? '0' : `${y.value}px`,
left: `${x.value}px`, left: isFullScreen.value ? '0' : `${x.value}px`,
width: `${width.value}px`, width: isFullScreen.value ? '100vw' : `${width.value}px`,
height: `${height.value}px`, height: isFullScreen.value ? '100vh' : `${height.value}px`,
maxWidth: '100vw', maxWidth: '100vw',
maxHeight: '100vh' maxHeight: '100vh'
})) }))
@ -80,6 +89,7 @@ function close() {
} }
function startResize(event: MouseEvent) { function startResize(event: MouseEvent) {
if (isFullScreen.value) return
isResizing.value = true isResizing.value = true
startWidth = width.value - event.clientX startWidth = width.value - event.clientX
startHeight = height.value - event.clientY startHeight = height.value - event.clientY
@ -87,7 +97,7 @@ function startResize(event: MouseEvent) {
} }
function resizeModal(event: MouseEvent) { function resizeModal(event: MouseEvent) {
if (!isResizing.value) return if (!isResizing.value || isFullScreen.value) return
const newWidth = Math.min(startWidth + event.clientX, window.innerWidth) const newWidth = Math.min(startWidth + event.clientX, window.innerWidth)
const newHeight = Math.min(startHeight + event.clientY, window.innerHeight) const newHeight = Math.min(startHeight + event.clientY, window.innerHeight)
width.value = Math.max(newWidth, minWidth.value) width.value = Math.max(newWidth, minWidth.value)
@ -100,6 +110,7 @@ function stopResize() {
} }
function startDrag(event: MouseEvent) { function startDrag(event: MouseEvent) {
if (isFullScreen.value) return
isDragging.value = true isDragging.value = true
startX = event.clientX startX = event.clientX
startY = event.clientY startY = event.clientY
@ -109,7 +120,7 @@ function startDrag(event: MouseEvent) {
} }
function drag(event: MouseEvent) { function drag(event: MouseEvent) {
if (!isDragging.value) return if (!isDragging.value || isFullScreen.value) return
const dx = event.clientX - startX const dx = event.clientX - startX
const dy = event.clientY - startY const dy = event.clientY - startY
x.value = initialX + dx x.value = initialX + dx
@ -122,11 +133,13 @@ function stopDrag() {
} }
function adjustPosition() { function adjustPosition() {
if (isFullScreen.value) return
x.value = Math.max(0, Math.min(x.value, window.innerWidth - width.value)) x.value = Math.max(0, Math.min(x.value, window.innerWidth - width.value))
y.value = Math.max(0, Math.min(y.value, window.innerHeight - height.value)) y.value = Math.max(0, Math.min(y.value, window.innerHeight - height.value))
} }
function handleResize() { function handleResize() {
if (isFullScreen.value) return
width.value = Math.min(width.value, window.innerWidth) width.value = Math.min(width.value, window.innerWidth)
height.value = Math.min(height.value, window.innerHeight) height.value = Math.min(height.value, window.innerHeight)
adjustPosition() adjustPosition()
@ -139,6 +152,21 @@ function initializePosition() {
y.value = (window.innerHeight - height.value) / 2 y.value = (window.innerHeight - height.value) / 2
} }
function toggleFullScreen() {
if (isFullScreen.value) {
// Exit full-screen
x.value = preFullScreenState.x
y.value = preFullScreenState.y
width.value = preFullScreenState.width
height.value = preFullScreenState.height
isFullScreen.value = false
} else {
// Enter full-screen
preFullScreenState = { x: x.value, y: y.value, width: width.value, height: height.value }
isFullScreen.value = true
}
}
watch( watch(
() => props.isModalOpen, () => props.isModalOpen,
(value) => { (value) => {

View File

@ -14,40 +14,58 @@
</div> </div>
<div class="m-2.5 px-2.5 block"> <div class="m-2.5 px-2.5 block">
<button class="btn-cyan px-4 py-1.5 flex-1 sm:flex-none sm:min-w-24 mb-5" type="button" @click.prevent="addNewImage">New IMG</button> <button class="btn-cyan px-4 py-1.5 flex-1 sm:flex-none sm:min-w-24 mb-5" type="button" @click.prevent="addNewImage">New IMG</button>
<Accordion v-for="image in spriteImages" :key="image.id" :title="image.name"> <Accordion v-for="image in spriteImages" :key="image.id">
<form class="flex gap-2.5 flex-wrap" @submit.prevent="saveSprite"> <template #header>
<div class="w-full flex flex-col mb-5"> <div class="flex items-center">
<label class="mb-1.5 font-titles" for="name">Name</label> {{ image.name }}
<input v-model="image.name" class="input-cyan" type="text" name="name" placeholder="Wall #1" /> <div class="ml-auto flex gap-2">
<label for="upload-asset" class="text-sm bg-cyan/50 border border-solid border-white/25 rounded drop-shadow-20 p-1.5 inline-flex items-center justify-center hover:bg-cyan hover:cursor-pointer">
<input class="hidden" id="upload-asset" ref="objectUploadField" type="file" accept="image/png" />
Set image
</label>
<button class="btn-bordeaux px-4 py-1.5 flex-1 sm:flex-none sm:min-w-24" type="button" @click.prevent="() => spriteImages.splice(spriteImages.indexOf(image), 1)">Remove</button>
</div>
</div> </div>
<div class="w-[calc(50%_-_5px)] flex flex-col mb-5"> </template>
<label class="mb-1.5 font-titles" for="origin-x">Origin X</label> <template #content>
<input v-model.number="image.origin_x" class="input-cyan" type="number" step="any" name="origin-x" placeholder="Origin X" /> <form class="flex gap-2.5 flex-wrap" @submit.prevent="saveSprite">
</div> <div class="w-[calc(50%_-_5px)] flex flex-col mb-5">
<div class="w-[calc(50%_-_5px)] flex flex-col mb-5"> <label class="mb-1.5 font-titles" for="name">Name</label>
<label class="mb-1.5 font-titles" for="origin-y">Origin Y</label> <input v-model="image.name" class="input-cyan" type="text" name="name" placeholder="Wall #1" />
<input v-model.number="image.origin_y" class="input-cyan" type="number" step="any" name="origin-y" placeholder="Origin Y" /> </div>
</div> <div class="w-[calc(50%_-_5px)] flex flex-col mb-5">
<div class="w-full flex flex-col mb-5"> <label class="mb-1.5 font-titles" for="action">Action</label>
<label class="mb-1.5 font-titles" for="frame-speed">Frame speed</label> <input v-model="image.action" class="input-cyan" type="text" name="action" placeholder="Action" />
<input v-model.number="image.frameSpeed" class="input-cyan" type="number" step="any" name="frame-speed" placeholder="Frame speed" /> </div>
</div> <div class="w-[calc(50%_-_5px)] flex flex-col mb-5">
<div class="w-[calc(50%_-_5px)] flex flex-col mb-5"> <label class="mb-1.5 font-titles" for="origin-x">Origin X</label>
<label class="mb-1.5 font-titles" for="frame-width">Frame width</label> <input v-model.number="image.origin_x" class="input-cyan" type="number" step="any" name="origin-x" placeholder="Origin X" />
<input v-model.number="image.frameWidth" class="input-cyan" type="number" step="any" name="frame-width" placeholder="Frame width" /> </div>
</div> <div class="w-[calc(50%_-_5px)] flex flex-col mb-5">
<div class="w-[calc(50%_-_5px)] flex flex-col mb-5"> <label class="mb-1.5 font-titles" for="origin-y">Origin Y</label>
<label class="mb-1.5 font-titles" for="frame-height">Frame height</label> <input v-model.number="image.origin_y" class="input-cyan" type="number" step="any" name="origin-y" placeholder="Origin Y" />
<input v-model.number="image.frameHeight" class="input-cyan" type="number" step="any" name="frame-height" placeholder="Frame height" /> </div>
</div> <div class="w-full flex flex-col mb-5">
<div class="w-full flex flex-col mb-5"> <label class="mb-1.5 font-titles" for="frame-speed">Frame speed</label>
<label class="mb-1.5 font-titles" for="is-looping">Is looping</label> <input v-model.number="image.frameSpeed" class="input-cyan" type="number" step="any" name="frame-speed" placeholder="Frame speed" />
<select v-model="image.isLooping" class="input-cyan" name="is-looping"> </div>
<option :value="false">No</option> <div class="w-[calc(50%_-_5px)] flex flex-col mb-5">
<option :value="true">Yes</option> <label class="mb-1.5 font-titles" for="frame-width">Frame width</label>
</select> <input v-model.number="image.frameWidth" class="input-cyan" type="number" step="any" name="frame-width" placeholder="Frame width" />
</div> </div>
</form> <div class="w-[calc(50%_-_5px)] flex flex-col mb-5">
<label class="mb-1.5 font-titles" for="frame-height">Frame height</label>
<input v-model.number="image.frameHeight" class="input-cyan" type="number" step="any" name="frame-height" placeholder="Frame height" />
</div>
<div class="w-full flex flex-col mb-5">
<label class="mb-1.5 font-titles" for="is-looping">Is looping</label>
<select v-model="image.isLooping" class="input-cyan" name="is-looping">
<option :value="false">No</option>
<option :value="true">Yes</option>
</select>
</div>
</form>
</template>
</Accordion> </Accordion>
</div> </div>
</div> </div>
@ -106,7 +124,7 @@ function saveSprite() {
const updatedSprite = { const updatedSprite = {
id: selectedSprite.value.id, id: selectedSprite.value.id,
name: spriteName.value, name: spriteName.value,
spriteImages: selectedSprite.value.spriteImages spriteImages: spriteImages.value
} }
gameStore.connection?.emit('gm:sprite:update', updatedSprite, (response: boolean) => { gameStore.connection?.emit('gm:sprite:update', updatedSprite, (response: boolean) => {

View File

@ -1,4 +1,4 @@
const dev: boolean = false const dev: boolean = true
export default { export default {
name: 'New Quest', name: 'New Quest',

View File

@ -1,6 +1,6 @@
<template> <template>
<GmTools v-if="isLoaded && gameStore.character?.role === 'gm'" /> <GmTools v-if="gameStore.character?.role === 'gm'" />
<GmPanel v-if="isLoaded && gameStore.character?.role === 'gm'" /> <GmPanel v-if="gameStore.character?.role === 'gm'" />
<div class="flex justify-center items-center h-dvh p-8 relative"> <div class="flex justify-center items-center h-dvh p-8 relative">
<div v-if="!zoneEditorStore.active"> <div v-if="!zoneEditorStore.active">
@ -18,11 +18,11 @@
</Game> </Game>
</div> </div>
<div v-if="zoneEditorStore.active"> <div v-if="zoneEditorStore.active">
<Game :config="gameConfig" @create="createGame"> <!-- <Game :config="gameConfig" @create="createGame">-->
<Scene name="main" @preload="preloadScene" @create="createScene"> <!-- <Scene name="main" @preload="preloadScene" @create="createScene">-->
<ZoneEditor v-if="isLoaded" :key="zoneEditorStore.zone?.id ?? 0" /> <!-- <ZoneEditor v-if="isLoaded" :key="zoneEditorStore.zone?.id ?? 0" />-->
</Scene> <!-- </Scene>-->
</Game> <!-- </Game>-->
</div> </div>
</div> </div>
</template> </template>
@ -129,6 +129,7 @@ const preloadScene = (scene: Phaser.Scene) => {
'character', 'character',
'data:image/png;base64,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' 'data:image/png;base64,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'
) )
scene.textures.addImage('character', '/assets/avatar/default/idle.png')
scene.load.spritesheet('characterW', '/assets/avatar/default/walk.png', { frameWidth: 36, frameHeight: 94 }) scene.load.spritesheet('characterW', '/assets/avatar/default/walk.png', { frameWidth: 36, frameHeight: 94 })
} }

View File

@ -4,7 +4,7 @@ import type { Zone, Object, Tile, ZoneObject } from '@/types'
export const useZoneEditorStore = defineStore('zoneEditor', { export const useZoneEditorStore = defineStore('zoneEditor', {
state: () => ({ state: () => ({
active: false, active: true,
zone: null as Zone | null, zone: null as Zone | null,
tool: 'move', tool: 'move',
drawMode: 'tile', drawMode: 'tile',