From 0e49ffd01b6459b372ebc8afd99467f885f6d59d Mon Sep 17 00:00:00 2001 From: Erik Onarheim Date: Mon, 13 Jan 2025 11:29:15 -0600 Subject: [PATCH] batman: fireworks working --- .gitignore | 11 + .nvmrc | 1 + favicon.ico | Bin 0 -> 4418 bytes index.html | 13 + package-lock.json | 1009 +++++++++++++++++ package.json | 34 + playwright.config.ts | 92 ++ public/images/sword.png | Bin 0 -> 370 bytes readme.md | 17 + renovate.json | 10 + src/files.d.ts | 1 + src/firework.ts | 88 ++ src/level.ts | 52 + src/main.ts | 31 + src/player.ts | 86 ++ src/resources.ts | 14 + src/style.css | 5 + src/vite-env.d.ts | 1 + tests/main.spec.ts | 7 + ...in-page-looks-correct-1-chromium-linux.png | Bin 0 -> 7005 bytes ...in-page-looks-correct-1-chromium-win32.png | Bin 0 -> 7005 bytes tsconfig.json | 19 + vite.config.js | 39 + 23 files changed, 1530 insertions(+) create mode 100644 .gitignore create mode 100644 .nvmrc create mode 100644 favicon.ico create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 playwright.config.ts create mode 100644 public/images/sword.png create mode 100644 readme.md create mode 100644 renovate.json create mode 100644 src/files.d.ts create mode 100644 src/firework.ts create mode 100644 src/level.ts create mode 100644 src/main.ts create mode 100644 src/player.ts create mode 100644 src/resources.ts create mode 100644 src/style.css create mode 100644 src/vite-env.d.ts create mode 100644 tests/main.spec.ts create mode 100644 tests/main.spec.ts-snapshots/main-page-looks-correct-1-chromium-linux.png create mode 100644 tests/main.spec.ts-snapshots/main-page-looks-correct-1-chromium-win32.png create mode 100644 tsconfig.json create mode 100644 vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56fec5b --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local +test/images/actual.png +test/images/diff-*.png +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..b087cc9 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22.13.0 \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8e1e5e8db8bd7462b9b909eace61803a17c3ae9a GIT binary patch literal 4418 zcmeH{u};G<5QeW}=){185L?Q|fDkJyZ-BCOf+5cVQfCy2i97)hkp+p7C+OBk=-8p^ z_5OrEG8UA@P9xQhzW(+(&hI;?5gFMvxe)xy)rrWNh+G;I+DfE4q&o0F0sZfND2k%{rn~Dx_4n=1 zJpS58?EHt~@9%^4fO0PBek-8g?b8%|Jhm+5Nx^!g4ID2evv{WKhjE9l>?W|W1wfy( Rmc>{Vtd3eXra)&#*R~8MA65VW literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..74111b9 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + + Excalibur + Vite + + + + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..1de4923 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1009 @@ +{ + "name": "sample-fireworks", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "sample-fireworks", + "version": "0.0.0", + "dependencies": { + "excalibur": "0.30.3" + }, + "devDependencies": { + "@playwright/test": "^1.49.1", + "@types/node": "^22.10.2", + "typescript": "5.7.3", + "vite": "6.0.7" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@playwright/test": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", + "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.49.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.4.tgz", + "integrity": "sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.4.tgz", + "integrity": "sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.4.tgz", + "integrity": "sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.4.tgz", + "integrity": "sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.4.tgz", + "integrity": "sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.4.tgz", + "integrity": "sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.4.tgz", + "integrity": "sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.4.tgz", + "integrity": "sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.4.tgz", + "integrity": "sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.4.tgz", + "integrity": "sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.4.tgz", + "integrity": "sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.4.tgz", + "integrity": "sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.4.tgz", + "integrity": "sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.4.tgz", + "integrity": "sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.4.tgz", + "integrity": "sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.4.tgz", + "integrity": "sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.4.tgz", + "integrity": "sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.4.tgz", + "integrity": "sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "22.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz", + "integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/excalibur": { + "version": "0.30.3", + "resolved": "https://registry.npmjs.org/excalibur/-/excalibur-0.30.3.tgz", + "integrity": "sha512-RUP3qQ6tFe9BJxvqh6p/I0B9rKMu+KGlHZruJyVOohiYUtCP0LsRgkVHxezvWtWsvCElVBL4PeCooE4KPlIldA==", + "license": "BSD-2-Clause" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/playwright": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", + "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.49.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", + "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.27.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.4.tgz", + "integrity": "sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.27.4", + "@rollup/rollup-android-arm64": "4.27.4", + "@rollup/rollup-darwin-arm64": "4.27.4", + "@rollup/rollup-darwin-x64": "4.27.4", + "@rollup/rollup-freebsd-arm64": "4.27.4", + "@rollup/rollup-freebsd-x64": "4.27.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.27.4", + "@rollup/rollup-linux-arm-musleabihf": "4.27.4", + "@rollup/rollup-linux-arm64-gnu": "4.27.4", + "@rollup/rollup-linux-arm64-musl": "4.27.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.27.4", + "@rollup/rollup-linux-riscv64-gnu": "4.27.4", + "@rollup/rollup-linux-s390x-gnu": "4.27.4", + "@rollup/rollup-linux-x64-gnu": "4.27.4", + "@rollup/rollup-linux-x64-musl": "4.27.4", + "@rollup/rollup-win32-arm64-msvc": "4.27.4", + "@rollup/rollup-win32-ia32-msvc": "4.27.4", + "@rollup/rollup-win32-x64-msvc": "4.27.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, + "node_modules/vite": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.7.tgz", + "integrity": "sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..fa9e25d --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "sample-fireworks", + "version": "0.0.0", + "description": "", + "main": "src/main.ts", + "scripts": { + "dev": "vite", + "start": "vite", + "build": "tsc && vite build", + "serve": "vite preview", + "test": "npm run build && npx playwright test", + "test:integration-update": "npx playwright test --update-snapshots" + }, + "repository": {}, + "keywords": [ + "excalibur", + "excaliburjs", + "vite", + "game-engine" + ], + "author": "", + "license": "", + "bugs": {}, + "homepage": "", + "dependencies": { + "excalibur": "0.30.3" + }, + "devDependencies": { + "@playwright/test": "^1.49.1", + "@types/node": "^22.10.2", + "typescript": "5.7.3", + "vite": "6.0.7" + } +} \ No newline at end of file diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..903466e --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,92 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// import dotenv from 'dotenv'; +// import path from 'path'; +// dotenv.config({ path: path.resolve(__dirname, '.env') }); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './tests', + webServer: { + command: 'npm run serve', + timeout: 240 * 1000, // linux takes a long time + url: 'http://localhost:4173', + reuseExistingServer: !process.env.CI, + stdout: 'ignore', + stderr: 'pipe', + }, + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + // baseURL: 'http://127.0.0.1:3000', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'], + launchOptions: { + args: ["--no-sandbox", '--disable-web-security', "--use-angle=gl"] + } + }, + }, + + // { + // name: 'firefox', + // use: { ...devices['Desktop Firefox'] }, + // }, + + // { + // name: 'webkit', + // use: { ...devices['Desktop Safari'] }, + // }, + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + // { + // name: 'Google Chrome', + // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + // webServer: { + // command: 'npm run start', + // url: 'http://127.0.0.1:3000', + // reuseExistingServer: !process.env.CI, + // }, +}); diff --git a/public/images/sword.png b/public/images/sword.png new file mode 100644 index 0000000000000000000000000000000000000000..3c303d20a18ce42a1d8064a68af037c0fa47e2f3 GIT binary patch literal 370 zcmV-&0ge8NP)z7ff*6Krk02QA)|v0ZZOm}z-S=z9j={(8KK?hDsH!UPF`dBE01i0dZl~)4M3N+p zMpK^Wg2r8FIF4iO{-P*w9B>?W$muAGaGawKxW$hD>U3F_(mKmBLF0hqxI0d#X)0(O zaKOzuZo+9A2OP)UcACZk$MNRbtp}2`+v8i*0KF zozpZ9ICH#xROcTSI!)t%GsoNC)m6vUsB>Pu+tWDUfSYyvFzIVIea1a$y;{z+?>n8Z z#+~P=1Maiqbxwz2D6KcQm(b05HOz6q0k_NXI;UwIaKPRA9;b1@0sotP0roj|TBbrl Q{{R3007*qoM6N<$f=QFD+5i9m literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..b0ec326 --- /dev/null +++ b/readme.md @@ -0,0 +1,17 @@ +# Excalibur TypeScript & Vite template + +Check out the full documentation @ https://excaliburjs.com + +You can use the excalibur cli to generate this template + +```sh +npm create excalibur +``` + +## Getting Started + +1. [Generate a repository](https://github.com/excaliburjs/template-ts-vite/generate) from this template +2. Modify the `package.json` with your own details +3. Run `npm install` to install dependencies +4. Run `npm run dev` to start the Vite server! +5. Have fun! diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..771f866 --- /dev/null +++ b/renovate.json @@ -0,0 +1,10 @@ +{ + "extends": [ + "config:base" + ], + "commitMessagePrefix": "chore:", + "automerge": true, + "major": { + "automerge": false + } +} \ No newline at end of file diff --git a/src/files.d.ts b/src/files.d.ts new file mode 100644 index 0000000..20e8a08 --- /dev/null +++ b/src/files.d.ts @@ -0,0 +1 @@ +declare module "*.png"; \ No newline at end of file diff --git a/src/firework.ts b/src/firework.ts new file mode 100644 index 0000000..afbc8d1 --- /dev/null +++ b/src/firework.ts @@ -0,0 +1,88 @@ +import { Actor, BodyComponent, Color, CoordPlane, coroutine, CoroutineGenerator, Entity, GpuParticleEmitter, MotionComponent, ParticleEmitter, Random, Scene, TransformComponent, vec, Vector } from "excalibur"; + +export class Firework extends Actor { + random: Random; + trail: GpuParticleEmitter; + explosion: GpuParticleEmitter; + explosion2: GpuParticleEmitter; + life: number; + body: BodyComponent; + + constructor(pos: Vector, life: number, random: Random) { + super({ name: "Firework" }) + this.random = random; + this.pos = pos; + this.acc = vec(0, 800); + + this.body = new BodyComponent(); + this.life = life; + + this.trail = new GpuParticleEmitter({ + isEmitting: false, + emitRate: 70, + particle: { + life: 1000, + endColor: Color.White, + beginColor: Color.White, + minSpeed: 10, + maxSpeed: 30, + startSize: 3, + endSize: 0, + fade: true, + acc: vec(0, 50), + } + }); + + this.explosion = new GpuParticleEmitter({ + isEmitting: false, + particle: { + life: 2000, + fade: true, + startSize: 5, + endSize: 2, + minSpeed: 10, + maxSpeed: 200, + acc: vec(0, 100), + beginColor: Color.Red, + endColor: Color.Yellow + } + }); + this.explosion2 = new GpuParticleEmitter({ + isEmitting: false, + particle: { + life: 1000, + fade: true, + startSize: 5, + endSize: 2, + minSpeed: 10, + maxSpeed: 200, + acc: vec(0, 100), + beginColor: Color.White, + endColor: Color.Purple + } + }); + + this.addChild(this.trail); + this.addChild(this.explosion); + this.addChild(this.explosion2); + } + + launch() { + coroutine(this.scene!.engine, (function*(this: Firework) { + this.vel = vec(this.random.floating(-200, 200), this.random.floating(-800, -1000)); + this.trail.isEmitting = true; + while (this.life > 0) { + const elapsed = yield; + this.life -= elapsed; + if (this.vel.y >= 0) { + break; + } + } + this.trail.isEmitting = false; + this.explosion.emitParticles(500); + this.explosion2.emitParticles(500); + + } as CoroutineGenerator).bind(this)) + } + +} diff --git a/src/level.ts b/src/level.ts new file mode 100644 index 0000000..f1a3e6c --- /dev/null +++ b/src/level.ts @@ -0,0 +1,52 @@ +import { DefaultLoader, Engine, ExcaliburGraphicsContext, Random, Scene, SceneActivationContext, vec } from "excalibur"; +import { Player } from "./player"; +import { Firework } from "./firework"; + +export class MyLevel extends Scene { + override onInitialize(engine: Engine): void { + const random = new Random(1337); + // Scene.onInitialize is where we recommend you perform the composition for your game + const player = new Player(); + this.add(player); // Actors need to be added to a scene to be drawn + const firework = new Firework(vec(400, 600), 2000, random); + this.add(firework); + firework.launch(); + + this.input.pointers.on('down', () => { + const firework = new Firework(vec(400, 600), 2000, random); + this.add(firework); + firework.launch(); + }); + } + + override onPreLoad(loader: DefaultLoader): void { + // Add any scene specific resources to load + } + + override onActivate(context: SceneActivationContext): void { + // Called when Excalibur transitions to this scene + // Only 1 scene is active at a time + + } + + override onDeactivate(context: SceneActivationContext): void { + // Called when Excalibur transitions away from this scene + // Only 1 scene is active at a time + } + + override onPreUpdate(engine: Engine, elapsedMs: number): void { + // Called before anything updates in the scene + } + + override onPostUpdate(engine: Engine, elapsedMs: number): void { + // Called after everything updates in the scene + } + + override onPreDraw(ctx: ExcaliburGraphicsContext, elapsedMs: number): void { + // Called before Excalibur draws to the screen + } + + override onPostDraw(ctx: ExcaliburGraphicsContext, elapsedMs: number): void { + // Called after Excalibur draws to the screen + } +} diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..1d00e75 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,31 @@ +import { Color, DisplayMode, Engine, FadeInOut } from "excalibur"; +import { loader } from "./resources"; +import { MyLevel } from "./level"; + +// Goal is to keep main.ts small and just enough to configure the engine + +const game = new Engine({ + width: 800, // Logical width and height in game pixels + height: 600, + displayMode: DisplayMode.FitScreenAndFill, // Display mode tells excalibur how to fill the window + pixelArt: true, // pixelArt will turn on the correct settings to render pixel art without jaggies or shimmering artifacts + scenes: { + start: MyLevel + }, + // physics: { + // solver: SolverStrategy.Realistic, + // substep: 5 // Sub step the physics simulation for more robust simulations + // }, + // fixedUpdateTimestep: 16 // Turn on fixed update timestep when consistent physic simulation is important +}); + +game.start('start', { // name of the start scene 'start' + loader, // Optional loader (but needed for loading images/sounds) + inTransition: new FadeInOut({ // Optional in transition + duration: 1000, + direction: 'in', + color: Color.ExcaliburBlue + }) +}).then(() => { + // Do something after the game starts +}); \ No newline at end of file diff --git a/src/player.ts b/src/player.ts new file mode 100644 index 0000000..af9863d --- /dev/null +++ b/src/player.ts @@ -0,0 +1,86 @@ +import { Actor, Collider, CollisionContact, Engine, Side, vec } from "excalibur"; +import { Resources } from "./resources"; + +// Actors are the main unit of composition you'll likely use, anything that you want to draw and move around the screen +// is likely built with an actor + +// They contain a bunch of useful components that you might use +// actor.transform +// actor.motion +// actor.graphics +// actor.body +// actor.collider +// actor.actions +// actor.pointer + + +export class Player extends Actor { + constructor() { + super({ + // Giving your actor a name is optional, but helps in debugging using the dev tools or debug mode + // https://github.com/excaliburjs/excalibur-extension/ + // Chrome: https://chromewebstore.google.com/detail/excalibur-dev-tools/dinddaeielhddflijbbcmpefamfffekc + // Firefox: https://addons.mozilla.org/en-US/firefox/addon/excalibur-dev-tools/ + name: 'Player', + pos: vec(150, 150), + width: 100, + height: 100, + // anchor: vec(0, 0), // Actors default center colliders and graphics with anchor (0.5, 0.5) + // collisionType: CollisionType.Active, // Collision Type Active means this participates in collisions read more https://excaliburjs.com/docs/collisiontypes + }); + + } + + override onInitialize() { + // Generally recommended to stick logic in the "On initialize" + // This runs before the first update + // Useful when + // 1. You need things to be loaded like Images for graphics + // 2. You need excalibur to be initialized & started + // 3. Deferring logic to run time instead of constructor time + // 4. Lazy instantiation + this.graphics.add(Resources.Sword.toSprite()); + + // Actions are useful for scripting common behavior, for example patrolling enemies + this.actions.delay(2000); + this.actions.repeatForever(ctx => { + ctx.moveBy({offset: vec(100, 0), duration: 1000}); + ctx.moveBy({offset: vec(0, 100), duration: 1000}); + ctx.moveBy({offset: vec(-100, 0), duration: 1000}); + ctx.moveBy({offset: vec(0, -100), duration: 1000}); + }); + + // Sometimes you want to click on an actor! + this.on('pointerdown', evt => { + // Pointer events tunnel in z order from the screen down, you can cancel them! + // if (true) { + // evt.cancel(); + // } + console.log('You clicked the actor @', evt.worldPos.toString()); + }); + } + + override onPreUpdate(engine: Engine, elapsedMs: number): void { + // Put any update logic here runs every frame before Actor builtins + } + + override onPostUpdate(engine: Engine, elapsedMs: number): void { + // Put any update logic here runs every frame after Actor builtins + } + + override onPreCollisionResolve(self: Collider, other: Collider, side: Side, contact: CollisionContact): void { + // Called before a collision is resolved, if you want to opt out of this specific collision call contact.cancel() + } + + override onPostCollisionResolve(self: Collider, other: Collider, side: Side, contact: CollisionContact): void { + // Called every time a collision is resolved and overlap is solved + } + + override onCollisionStart(self: Collider, other: Collider, side: Side, contact: CollisionContact): void { + // Called when a pair of objects are in contact + } + + override onCollisionEnd(self: Collider, other: Collider, side: Side, lastContact: CollisionContact): void { + // Called when a pair of objects separates + } +} diff --git a/src/resources.ts b/src/resources.ts new file mode 100644 index 0000000..b2fbf78 --- /dev/null +++ b/src/resources.ts @@ -0,0 +1,14 @@ +import { ImageSource, Loader } from "excalibur"; + +// It is convenient to put your resources in one place +export const Resources = { + Sword: new ImageSource("./images/sword.png") // Vite public/ directory serves the root images +} as const; // the 'as const' is a neat typescript trick to get strong typing on your resources. +// So when you type Resources.Sword -> ImageSource + +// We build a loader and add all of our resources to the boot loader +// You can build your own loader by extending DefaultLoader +export const loader = new Loader(); +for (const res of Object.values(Resources)) { + loader.addResource(res); +} diff --git a/src/style.css b/src/style.css new file mode 100644 index 0000000..b29ef89 --- /dev/null +++ b/src/style.css @@ -0,0 +1,5 @@ +@media (prefers-color-scheme: dark) { + body { + background-color: black; + } +} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tests/main.spec.ts b/tests/main.spec.ts new file mode 100644 index 0000000..33dbbee --- /dev/null +++ b/tests/main.spec.ts @@ -0,0 +1,7 @@ +import { test, expect } from '@playwright/test'; + +test('main page looks correct', async ({ page }) => { + await page.goto('http://localhost:4173/'); + await page.click('#excalibur-play'); + await expect(page).toHaveScreenshot(); +}); \ No newline at end of file diff --git a/tests/main.spec.ts-snapshots/main-page-looks-correct-1-chromium-linux.png b/tests/main.spec.ts-snapshots/main-page-looks-correct-1-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..224a7a1bdecb6e7d22ef9f84611ac276af10d0d5 GIT binary patch literal 7005 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 literal 0 HcmV?d00001 diff --git a/tests/main.spec.ts-snapshots/main-page-looks-correct-1-chromium-win32.png b/tests/main.spec.ts-snapshots/main-page-looks-correct-1-chromium-win32.png new file mode 100644 index 0000000000000000000000000000000000000000..224a7a1bdecb6e7d22ef9f84611ac276af10d0d5 GIT binary patch literal 7005 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 literal 0 HcmV?d00001 diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..023efde --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ESNext", "DOM"], + "moduleResolution": "Node", + "strict": true, + "skipLibCheck": true, + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "noEmit": true, + "noUnusedLocals": true, + "noUnusedParameters": false, + "noImplicitReturns": true + }, + "include": ["./src"] +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..36c3515 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,39 @@ +import { defineConfig } from "vite"; + +// if you use tiled maps +// there is a collision between react w/ typescript .tsx +// and tiled tileset files .tsx +// this forces vite to not interpret tsx as react +const tiledPlugin = () => { + return { + name: 'tiled-tileset-plugin', + resolveId: { + order: 'pre', + handler(sourceId, importer, options) { + if (!sourceId.endsWith(".tsx")) return; + return { id: 'tileset:' + sourceId, external: 'relative' } + } + } + }; +} + +export default defineConfig({ + base: './', // optionally give a base path, useful for itch.io to serve relative instead of the default absolut + plugins: [tiledPlugin()], // hint vite that tiled tilesets should be treated as external + // currently excalibur plugins are commonjs + // this forces vite to keep things from bundling ESM together with commonjs + optimizeDeps: { + exclude: ["excalibur"], + }, + build: { + assetsInlineLimit: 0, // excalibur cannot handle inlined xml in prod mode + sourcemap: true, + // Vite uses rollup currently for prod builds so a separate config is needed + // to keep vite from bundling ESM together with commonjs + rollupOptions: { + output: { + format: 'umd' + } + } + } +});