[READ-ONLY] Mirror of https://github.com/excaliburjs/sample-fireworks. Example making fireworks with GPU Particles in Excalibur excaliburjs.com/sample-fireworks/
excalibur excaliburjs sample
0

Configure Feed

Select the types of activity you want to include in your feed.

batman: fireworks working

Erik Onarheim (Jan 17, 2025, 1:38 PM -0600) 0e49ffd0 5a27c0b9

+1530
+11
.gitignore
··· 1 + node_modules 2 + .DS_Store 3 + dist 4 + dist-ssr 5 + *.local 6 + test/images/actual.png 7 + test/images/diff-*.png 8 + /test-results/ 9 + /playwright-report/ 10 + /blob-report/ 11 + /playwright/.cache/
+1
.nvmrc
··· 1 + 22.13.0
favicon.ico

This is a binary file and will not be displayed.

+13
index.html
··· 1 + <!DOCTYPE html> 2 + <html lang="en"> 3 + <head> 4 + <meta charset="UTF-8" /> 5 + <link rel="icon" href="favicon.ico" /> 6 + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 + <link rel="stylesheet" href="./src/style.css"> 8 + <title>Excalibur + Vite</title> 9 + </head> 10 + <body> 11 + <script type="module" src="./src/main.ts"></script> 12 + </body> 13 + </html>
+1009
package-lock.json
··· 1 + { 2 + "name": "sample-fireworks", 3 + "version": "0.0.0", 4 + "lockfileVersion": 3, 5 + "requires": true, 6 + "packages": { 7 + "": { 8 + "name": "sample-fireworks", 9 + "version": "0.0.0", 10 + "dependencies": { 11 + "excalibur": "0.30.3" 12 + }, 13 + "devDependencies": { 14 + "@playwright/test": "^1.49.1", 15 + "@types/node": "^22.10.2", 16 + "typescript": "5.7.3", 17 + "vite": "6.0.7" 18 + } 19 + }, 20 + "node_modules/@esbuild/aix-ppc64": { 21 + "version": "0.24.2", 22 + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", 23 + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", 24 + "cpu": [ 25 + "ppc64" 26 + ], 27 + "dev": true, 28 + "license": "MIT", 29 + "optional": true, 30 + "os": [ 31 + "aix" 32 + ], 33 + "engines": { 34 + "node": ">=18" 35 + } 36 + }, 37 + "node_modules/@esbuild/android-arm": { 38 + "version": "0.24.2", 39 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", 40 + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", 41 + "cpu": [ 42 + "arm" 43 + ], 44 + "dev": true, 45 + "license": "MIT", 46 + "optional": true, 47 + "os": [ 48 + "android" 49 + ], 50 + "engines": { 51 + "node": ">=18" 52 + } 53 + }, 54 + "node_modules/@esbuild/android-arm64": { 55 + "version": "0.24.2", 56 + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", 57 + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", 58 + "cpu": [ 59 + "arm64" 60 + ], 61 + "dev": true, 62 + "license": "MIT", 63 + "optional": true, 64 + "os": [ 65 + "android" 66 + ], 67 + "engines": { 68 + "node": ">=18" 69 + } 70 + }, 71 + "node_modules/@esbuild/android-x64": { 72 + "version": "0.24.2", 73 + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", 74 + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", 75 + "cpu": [ 76 + "x64" 77 + ], 78 + "dev": true, 79 + "license": "MIT", 80 + "optional": true, 81 + "os": [ 82 + "android" 83 + ], 84 + "engines": { 85 + "node": ">=18" 86 + } 87 + }, 88 + "node_modules/@esbuild/darwin-arm64": { 89 + "version": "0.24.2", 90 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", 91 + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", 92 + "cpu": [ 93 + "arm64" 94 + ], 95 + "dev": true, 96 + "license": "MIT", 97 + "optional": true, 98 + "os": [ 99 + "darwin" 100 + ], 101 + "engines": { 102 + "node": ">=18" 103 + } 104 + }, 105 + "node_modules/@esbuild/darwin-x64": { 106 + "version": "0.24.2", 107 + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", 108 + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", 109 + "cpu": [ 110 + "x64" 111 + ], 112 + "dev": true, 113 + "license": "MIT", 114 + "optional": true, 115 + "os": [ 116 + "darwin" 117 + ], 118 + "engines": { 119 + "node": ">=18" 120 + } 121 + }, 122 + "node_modules/@esbuild/freebsd-arm64": { 123 + "version": "0.24.2", 124 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", 125 + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", 126 + "cpu": [ 127 + "arm64" 128 + ], 129 + "dev": true, 130 + "license": "MIT", 131 + "optional": true, 132 + "os": [ 133 + "freebsd" 134 + ], 135 + "engines": { 136 + "node": ">=18" 137 + } 138 + }, 139 + "node_modules/@esbuild/freebsd-x64": { 140 + "version": "0.24.2", 141 + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", 142 + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", 143 + "cpu": [ 144 + "x64" 145 + ], 146 + "dev": true, 147 + "license": "MIT", 148 + "optional": true, 149 + "os": [ 150 + "freebsd" 151 + ], 152 + "engines": { 153 + "node": ">=18" 154 + } 155 + }, 156 + "node_modules/@esbuild/linux-arm": { 157 + "version": "0.24.2", 158 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", 159 + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", 160 + "cpu": [ 161 + "arm" 162 + ], 163 + "dev": true, 164 + "license": "MIT", 165 + "optional": true, 166 + "os": [ 167 + "linux" 168 + ], 169 + "engines": { 170 + "node": ">=18" 171 + } 172 + }, 173 + "node_modules/@esbuild/linux-arm64": { 174 + "version": "0.24.2", 175 + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", 176 + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", 177 + "cpu": [ 178 + "arm64" 179 + ], 180 + "dev": true, 181 + "license": "MIT", 182 + "optional": true, 183 + "os": [ 184 + "linux" 185 + ], 186 + "engines": { 187 + "node": ">=18" 188 + } 189 + }, 190 + "node_modules/@esbuild/linux-ia32": { 191 + "version": "0.24.2", 192 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", 193 + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", 194 + "cpu": [ 195 + "ia32" 196 + ], 197 + "dev": true, 198 + "license": "MIT", 199 + "optional": true, 200 + "os": [ 201 + "linux" 202 + ], 203 + "engines": { 204 + "node": ">=18" 205 + } 206 + }, 207 + "node_modules/@esbuild/linux-loong64": { 208 + "version": "0.24.2", 209 + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", 210 + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", 211 + "cpu": [ 212 + "loong64" 213 + ], 214 + "dev": true, 215 + "license": "MIT", 216 + "optional": true, 217 + "os": [ 218 + "linux" 219 + ], 220 + "engines": { 221 + "node": ">=18" 222 + } 223 + }, 224 + "node_modules/@esbuild/linux-mips64el": { 225 + "version": "0.24.2", 226 + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", 227 + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", 228 + "cpu": [ 229 + "mips64el" 230 + ], 231 + "dev": true, 232 + "license": "MIT", 233 + "optional": true, 234 + "os": [ 235 + "linux" 236 + ], 237 + "engines": { 238 + "node": ">=18" 239 + } 240 + }, 241 + "node_modules/@esbuild/linux-ppc64": { 242 + "version": "0.24.2", 243 + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", 244 + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", 245 + "cpu": [ 246 + "ppc64" 247 + ], 248 + "dev": true, 249 + "license": "MIT", 250 + "optional": true, 251 + "os": [ 252 + "linux" 253 + ], 254 + "engines": { 255 + "node": ">=18" 256 + } 257 + }, 258 + "node_modules/@esbuild/linux-riscv64": { 259 + "version": "0.24.2", 260 + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", 261 + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", 262 + "cpu": [ 263 + "riscv64" 264 + ], 265 + "dev": true, 266 + "license": "MIT", 267 + "optional": true, 268 + "os": [ 269 + "linux" 270 + ], 271 + "engines": { 272 + "node": ">=18" 273 + } 274 + }, 275 + "node_modules/@esbuild/linux-s390x": { 276 + "version": "0.24.2", 277 + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", 278 + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", 279 + "cpu": [ 280 + "s390x" 281 + ], 282 + "dev": true, 283 + "license": "MIT", 284 + "optional": true, 285 + "os": [ 286 + "linux" 287 + ], 288 + "engines": { 289 + "node": ">=18" 290 + } 291 + }, 292 + "node_modules/@esbuild/linux-x64": { 293 + "version": "0.24.2", 294 + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", 295 + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", 296 + "cpu": [ 297 + "x64" 298 + ], 299 + "dev": true, 300 + "license": "MIT", 301 + "optional": true, 302 + "os": [ 303 + "linux" 304 + ], 305 + "engines": { 306 + "node": ">=18" 307 + } 308 + }, 309 + "node_modules/@esbuild/netbsd-arm64": { 310 + "version": "0.24.2", 311 + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", 312 + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", 313 + "cpu": [ 314 + "arm64" 315 + ], 316 + "dev": true, 317 + "license": "MIT", 318 + "optional": true, 319 + "os": [ 320 + "netbsd" 321 + ], 322 + "engines": { 323 + "node": ">=18" 324 + } 325 + }, 326 + "node_modules/@esbuild/netbsd-x64": { 327 + "version": "0.24.2", 328 + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", 329 + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", 330 + "cpu": [ 331 + "x64" 332 + ], 333 + "dev": true, 334 + "license": "MIT", 335 + "optional": true, 336 + "os": [ 337 + "netbsd" 338 + ], 339 + "engines": { 340 + "node": ">=18" 341 + } 342 + }, 343 + "node_modules/@esbuild/openbsd-arm64": { 344 + "version": "0.24.2", 345 + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", 346 + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", 347 + "cpu": [ 348 + "arm64" 349 + ], 350 + "dev": true, 351 + "license": "MIT", 352 + "optional": true, 353 + "os": [ 354 + "openbsd" 355 + ], 356 + "engines": { 357 + "node": ">=18" 358 + } 359 + }, 360 + "node_modules/@esbuild/openbsd-x64": { 361 + "version": "0.24.2", 362 + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", 363 + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", 364 + "cpu": [ 365 + "x64" 366 + ], 367 + "dev": true, 368 + "license": "MIT", 369 + "optional": true, 370 + "os": [ 371 + "openbsd" 372 + ], 373 + "engines": { 374 + "node": ">=18" 375 + } 376 + }, 377 + "node_modules/@esbuild/sunos-x64": { 378 + "version": "0.24.2", 379 + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", 380 + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", 381 + "cpu": [ 382 + "x64" 383 + ], 384 + "dev": true, 385 + "license": "MIT", 386 + "optional": true, 387 + "os": [ 388 + "sunos" 389 + ], 390 + "engines": { 391 + "node": ">=18" 392 + } 393 + }, 394 + "node_modules/@esbuild/win32-arm64": { 395 + "version": "0.24.2", 396 + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", 397 + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", 398 + "cpu": [ 399 + "arm64" 400 + ], 401 + "dev": true, 402 + "license": "MIT", 403 + "optional": true, 404 + "os": [ 405 + "win32" 406 + ], 407 + "engines": { 408 + "node": ">=18" 409 + } 410 + }, 411 + "node_modules/@esbuild/win32-ia32": { 412 + "version": "0.24.2", 413 + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", 414 + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", 415 + "cpu": [ 416 + "ia32" 417 + ], 418 + "dev": true, 419 + "license": "MIT", 420 + "optional": true, 421 + "os": [ 422 + "win32" 423 + ], 424 + "engines": { 425 + "node": ">=18" 426 + } 427 + }, 428 + "node_modules/@esbuild/win32-x64": { 429 + "version": "0.24.2", 430 + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", 431 + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", 432 + "cpu": [ 433 + "x64" 434 + ], 435 + "dev": true, 436 + "license": "MIT", 437 + "optional": true, 438 + "os": [ 439 + "win32" 440 + ], 441 + "engines": { 442 + "node": ">=18" 443 + } 444 + }, 445 + "node_modules/@playwright/test": { 446 + "version": "1.49.1", 447 + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", 448 + "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", 449 + "dev": true, 450 + "license": "Apache-2.0", 451 + "dependencies": { 452 + "playwright": "1.49.1" 453 + }, 454 + "bin": { 455 + "playwright": "cli.js" 456 + }, 457 + "engines": { 458 + "node": ">=18" 459 + } 460 + }, 461 + "node_modules/@rollup/rollup-android-arm-eabi": { 462 + "version": "4.27.4", 463 + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.4.tgz", 464 + "integrity": "sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==", 465 + "cpu": [ 466 + "arm" 467 + ], 468 + "dev": true, 469 + "optional": true, 470 + "os": [ 471 + "android" 472 + ] 473 + }, 474 + "node_modules/@rollup/rollup-android-arm64": { 475 + "version": "4.27.4", 476 + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.4.tgz", 477 + "integrity": "sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==", 478 + "cpu": [ 479 + "arm64" 480 + ], 481 + "dev": true, 482 + "optional": true, 483 + "os": [ 484 + "android" 485 + ] 486 + }, 487 + "node_modules/@rollup/rollup-darwin-arm64": { 488 + "version": "4.27.4", 489 + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.4.tgz", 490 + "integrity": "sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==", 491 + "cpu": [ 492 + "arm64" 493 + ], 494 + "dev": true, 495 + "optional": true, 496 + "os": [ 497 + "darwin" 498 + ] 499 + }, 500 + "node_modules/@rollup/rollup-darwin-x64": { 501 + "version": "4.27.4", 502 + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.4.tgz", 503 + "integrity": "sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==", 504 + "cpu": [ 505 + "x64" 506 + ], 507 + "dev": true, 508 + "optional": true, 509 + "os": [ 510 + "darwin" 511 + ] 512 + }, 513 + "node_modules/@rollup/rollup-freebsd-arm64": { 514 + "version": "4.27.4", 515 + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.4.tgz", 516 + "integrity": "sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==", 517 + "cpu": [ 518 + "arm64" 519 + ], 520 + "dev": true, 521 + "optional": true, 522 + "os": [ 523 + "freebsd" 524 + ] 525 + }, 526 + "node_modules/@rollup/rollup-freebsd-x64": { 527 + "version": "4.27.4", 528 + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.4.tgz", 529 + "integrity": "sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==", 530 + "cpu": [ 531 + "x64" 532 + ], 533 + "dev": true, 534 + "optional": true, 535 + "os": [ 536 + "freebsd" 537 + ] 538 + }, 539 + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 540 + "version": "4.27.4", 541 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.4.tgz", 542 + "integrity": "sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==", 543 + "cpu": [ 544 + "arm" 545 + ], 546 + "dev": true, 547 + "optional": true, 548 + "os": [ 549 + "linux" 550 + ] 551 + }, 552 + "node_modules/@rollup/rollup-linux-arm-musleabihf": { 553 + "version": "4.27.4", 554 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.4.tgz", 555 + "integrity": "sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==", 556 + "cpu": [ 557 + "arm" 558 + ], 559 + "dev": true, 560 + "optional": true, 561 + "os": [ 562 + "linux" 563 + ] 564 + }, 565 + "node_modules/@rollup/rollup-linux-arm64-gnu": { 566 + "version": "4.27.4", 567 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.4.tgz", 568 + "integrity": "sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==", 569 + "cpu": [ 570 + "arm64" 571 + ], 572 + "dev": true, 573 + "optional": true, 574 + "os": [ 575 + "linux" 576 + ] 577 + }, 578 + "node_modules/@rollup/rollup-linux-arm64-musl": { 579 + "version": "4.27.4", 580 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.4.tgz", 581 + "integrity": "sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==", 582 + "cpu": [ 583 + "arm64" 584 + ], 585 + "dev": true, 586 + "optional": true, 587 + "os": [ 588 + "linux" 589 + ] 590 + }, 591 + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 592 + "version": "4.27.4", 593 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.4.tgz", 594 + "integrity": "sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==", 595 + "cpu": [ 596 + "ppc64" 597 + ], 598 + "dev": true, 599 + "optional": true, 600 + "os": [ 601 + "linux" 602 + ] 603 + }, 604 + "node_modules/@rollup/rollup-linux-riscv64-gnu": { 605 + "version": "4.27.4", 606 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.4.tgz", 607 + "integrity": "sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==", 608 + "cpu": [ 609 + "riscv64" 610 + ], 611 + "dev": true, 612 + "optional": true, 613 + "os": [ 614 + "linux" 615 + ] 616 + }, 617 + "node_modules/@rollup/rollup-linux-s390x-gnu": { 618 + "version": "4.27.4", 619 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.4.tgz", 620 + "integrity": "sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==", 621 + "cpu": [ 622 + "s390x" 623 + ], 624 + "dev": true, 625 + "optional": true, 626 + "os": [ 627 + "linux" 628 + ] 629 + }, 630 + "node_modules/@rollup/rollup-linux-x64-gnu": { 631 + "version": "4.27.4", 632 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.4.tgz", 633 + "integrity": "sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==", 634 + "cpu": [ 635 + "x64" 636 + ], 637 + "dev": true, 638 + "optional": true, 639 + "os": [ 640 + "linux" 641 + ] 642 + }, 643 + "node_modules/@rollup/rollup-linux-x64-musl": { 644 + "version": "4.27.4", 645 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.4.tgz", 646 + "integrity": "sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==", 647 + "cpu": [ 648 + "x64" 649 + ], 650 + "dev": true, 651 + "optional": true, 652 + "os": [ 653 + "linux" 654 + ] 655 + }, 656 + "node_modules/@rollup/rollup-win32-arm64-msvc": { 657 + "version": "4.27.4", 658 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.4.tgz", 659 + "integrity": "sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==", 660 + "cpu": [ 661 + "arm64" 662 + ], 663 + "dev": true, 664 + "optional": true, 665 + "os": [ 666 + "win32" 667 + ] 668 + }, 669 + "node_modules/@rollup/rollup-win32-ia32-msvc": { 670 + "version": "4.27.4", 671 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.4.tgz", 672 + "integrity": "sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==", 673 + "cpu": [ 674 + "ia32" 675 + ], 676 + "dev": true, 677 + "optional": true, 678 + "os": [ 679 + "win32" 680 + ] 681 + }, 682 + "node_modules/@rollup/rollup-win32-x64-msvc": { 683 + "version": "4.27.4", 684 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.4.tgz", 685 + "integrity": "sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==", 686 + "cpu": [ 687 + "x64" 688 + ], 689 + "dev": true, 690 + "optional": true, 691 + "os": [ 692 + "win32" 693 + ] 694 + }, 695 + "node_modules/@types/estree": { 696 + "version": "1.0.6", 697 + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", 698 + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 699 + "dev": true 700 + }, 701 + "node_modules/@types/node": { 702 + "version": "22.10.5", 703 + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz", 704 + "integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==", 705 + "dev": true, 706 + "license": "MIT", 707 + "dependencies": { 708 + "undici-types": "~6.20.0" 709 + } 710 + }, 711 + "node_modules/esbuild": { 712 + "version": "0.24.2", 713 + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", 714 + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", 715 + "dev": true, 716 + "hasInstallScript": true, 717 + "license": "MIT", 718 + "bin": { 719 + "esbuild": "bin/esbuild" 720 + }, 721 + "engines": { 722 + "node": ">=18" 723 + }, 724 + "optionalDependencies": { 725 + "@esbuild/aix-ppc64": "0.24.2", 726 + "@esbuild/android-arm": "0.24.2", 727 + "@esbuild/android-arm64": "0.24.2", 728 + "@esbuild/android-x64": "0.24.2", 729 + "@esbuild/darwin-arm64": "0.24.2", 730 + "@esbuild/darwin-x64": "0.24.2", 731 + "@esbuild/freebsd-arm64": "0.24.2", 732 + "@esbuild/freebsd-x64": "0.24.2", 733 + "@esbuild/linux-arm": "0.24.2", 734 + "@esbuild/linux-arm64": "0.24.2", 735 + "@esbuild/linux-ia32": "0.24.2", 736 + "@esbuild/linux-loong64": "0.24.2", 737 + "@esbuild/linux-mips64el": "0.24.2", 738 + "@esbuild/linux-ppc64": "0.24.2", 739 + "@esbuild/linux-riscv64": "0.24.2", 740 + "@esbuild/linux-s390x": "0.24.2", 741 + "@esbuild/linux-x64": "0.24.2", 742 + "@esbuild/netbsd-arm64": "0.24.2", 743 + "@esbuild/netbsd-x64": "0.24.2", 744 + "@esbuild/openbsd-arm64": "0.24.2", 745 + "@esbuild/openbsd-x64": "0.24.2", 746 + "@esbuild/sunos-x64": "0.24.2", 747 + "@esbuild/win32-arm64": "0.24.2", 748 + "@esbuild/win32-ia32": "0.24.2", 749 + "@esbuild/win32-x64": "0.24.2" 750 + } 751 + }, 752 + "node_modules/excalibur": { 753 + "version": "0.30.3", 754 + "resolved": "https://registry.npmjs.org/excalibur/-/excalibur-0.30.3.tgz", 755 + "integrity": "sha512-RUP3qQ6tFe9BJxvqh6p/I0B9rKMu+KGlHZruJyVOohiYUtCP0LsRgkVHxezvWtWsvCElVBL4PeCooE4KPlIldA==", 756 + "license": "BSD-2-Clause" 757 + }, 758 + "node_modules/fsevents": { 759 + "version": "2.3.3", 760 + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 761 + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 762 + "dev": true, 763 + "hasInstallScript": true, 764 + "optional": true, 765 + "os": [ 766 + "darwin" 767 + ], 768 + "engines": { 769 + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 770 + } 771 + }, 772 + "node_modules/nanoid": { 773 + "version": "3.3.8", 774 + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", 775 + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", 776 + "dev": true, 777 + "funding": [ 778 + { 779 + "type": "github", 780 + "url": "https://github.com/sponsors/ai" 781 + } 782 + ], 783 + "bin": { 784 + "nanoid": "bin/nanoid.cjs" 785 + }, 786 + "engines": { 787 + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 788 + } 789 + }, 790 + "node_modules/picocolors": { 791 + "version": "1.1.1", 792 + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 793 + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 794 + "dev": true 795 + }, 796 + "node_modules/playwright": { 797 + "version": "1.49.1", 798 + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", 799 + "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", 800 + "dev": true, 801 + "license": "Apache-2.0", 802 + "dependencies": { 803 + "playwright-core": "1.49.1" 804 + }, 805 + "bin": { 806 + "playwright": "cli.js" 807 + }, 808 + "engines": { 809 + "node": ">=18" 810 + }, 811 + "optionalDependencies": { 812 + "fsevents": "2.3.2" 813 + } 814 + }, 815 + "node_modules/playwright-core": { 816 + "version": "1.49.1", 817 + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", 818 + "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", 819 + "dev": true, 820 + "license": "Apache-2.0", 821 + "bin": { 822 + "playwright-core": "cli.js" 823 + }, 824 + "engines": { 825 + "node": ">=18" 826 + } 827 + }, 828 + "node_modules/playwright/node_modules/fsevents": { 829 + "version": "2.3.2", 830 + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 831 + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 832 + "dev": true, 833 + "hasInstallScript": true, 834 + "optional": true, 835 + "os": [ 836 + "darwin" 837 + ], 838 + "engines": { 839 + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 840 + } 841 + }, 842 + "node_modules/postcss": { 843 + "version": "8.4.49", 844 + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", 845 + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", 846 + "dev": true, 847 + "funding": [ 848 + { 849 + "type": "opencollective", 850 + "url": "https://opencollective.com/postcss/" 851 + }, 852 + { 853 + "type": "tidelift", 854 + "url": "https://tidelift.com/funding/github/npm/postcss" 855 + }, 856 + { 857 + "type": "github", 858 + "url": "https://github.com/sponsors/ai" 859 + } 860 + ], 861 + "dependencies": { 862 + "nanoid": "^3.3.7", 863 + "picocolors": "^1.1.1", 864 + "source-map-js": "^1.2.1" 865 + }, 866 + "engines": { 867 + "node": "^10 || ^12 || >=14" 868 + } 869 + }, 870 + "node_modules/rollup": { 871 + "version": "4.27.4", 872 + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.4.tgz", 873 + "integrity": "sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==", 874 + "dev": true, 875 + "dependencies": { 876 + "@types/estree": "1.0.6" 877 + }, 878 + "bin": { 879 + "rollup": "dist/bin/rollup" 880 + }, 881 + "engines": { 882 + "node": ">=18.0.0", 883 + "npm": ">=8.0.0" 884 + }, 885 + "optionalDependencies": { 886 + "@rollup/rollup-android-arm-eabi": "4.27.4", 887 + "@rollup/rollup-android-arm64": "4.27.4", 888 + "@rollup/rollup-darwin-arm64": "4.27.4", 889 + "@rollup/rollup-darwin-x64": "4.27.4", 890 + "@rollup/rollup-freebsd-arm64": "4.27.4", 891 + "@rollup/rollup-freebsd-x64": "4.27.4", 892 + "@rollup/rollup-linux-arm-gnueabihf": "4.27.4", 893 + "@rollup/rollup-linux-arm-musleabihf": "4.27.4", 894 + "@rollup/rollup-linux-arm64-gnu": "4.27.4", 895 + "@rollup/rollup-linux-arm64-musl": "4.27.4", 896 + "@rollup/rollup-linux-powerpc64le-gnu": "4.27.4", 897 + "@rollup/rollup-linux-riscv64-gnu": "4.27.4", 898 + "@rollup/rollup-linux-s390x-gnu": "4.27.4", 899 + "@rollup/rollup-linux-x64-gnu": "4.27.4", 900 + "@rollup/rollup-linux-x64-musl": "4.27.4", 901 + "@rollup/rollup-win32-arm64-msvc": "4.27.4", 902 + "@rollup/rollup-win32-ia32-msvc": "4.27.4", 903 + "@rollup/rollup-win32-x64-msvc": "4.27.4", 904 + "fsevents": "~2.3.2" 905 + } 906 + }, 907 + "node_modules/source-map-js": { 908 + "version": "1.2.1", 909 + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 910 + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 911 + "dev": true, 912 + "engines": { 913 + "node": ">=0.10.0" 914 + } 915 + }, 916 + "node_modules/typescript": { 917 + "version": "5.7.3", 918 + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", 919 + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", 920 + "dev": true, 921 + "license": "Apache-2.0", 922 + "bin": { 923 + "tsc": "bin/tsc", 924 + "tsserver": "bin/tsserver" 925 + }, 926 + "engines": { 927 + "node": ">=14.17" 928 + } 929 + }, 930 + "node_modules/undici-types": { 931 + "version": "6.20.0", 932 + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", 933 + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", 934 + "dev": true 935 + }, 936 + "node_modules/vite": { 937 + "version": "6.0.7", 938 + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.7.tgz", 939 + "integrity": "sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==", 940 + "dev": true, 941 + "license": "MIT", 942 + "dependencies": { 943 + "esbuild": "^0.24.2", 944 + "postcss": "^8.4.49", 945 + "rollup": "^4.23.0" 946 + }, 947 + "bin": { 948 + "vite": "bin/vite.js" 949 + }, 950 + "engines": { 951 + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" 952 + }, 953 + "funding": { 954 + "url": "https://github.com/vitejs/vite?sponsor=1" 955 + }, 956 + "optionalDependencies": { 957 + "fsevents": "~2.3.3" 958 + }, 959 + "peerDependencies": { 960 + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", 961 + "jiti": ">=1.21.0", 962 + "less": "*", 963 + "lightningcss": "^1.21.0", 964 + "sass": "*", 965 + "sass-embedded": "*", 966 + "stylus": "*", 967 + "sugarss": "*", 968 + "terser": "^5.16.0", 969 + "tsx": "^4.8.1", 970 + "yaml": "^2.4.2" 971 + }, 972 + "peerDependenciesMeta": { 973 + "@types/node": { 974 + "optional": true 975 + }, 976 + "jiti": { 977 + "optional": true 978 + }, 979 + "less": { 980 + "optional": true 981 + }, 982 + "lightningcss": { 983 + "optional": true 984 + }, 985 + "sass": { 986 + "optional": true 987 + }, 988 + "sass-embedded": { 989 + "optional": true 990 + }, 991 + "stylus": { 992 + "optional": true 993 + }, 994 + "sugarss": { 995 + "optional": true 996 + }, 997 + "terser": { 998 + "optional": true 999 + }, 1000 + "tsx": { 1001 + "optional": true 1002 + }, 1003 + "yaml": { 1004 + "optional": true 1005 + } 1006 + } 1007 + } 1008 + } 1009 + }
+34
package.json
··· 1 + { 2 + "name": "sample-fireworks", 3 + "version": "0.0.0", 4 + "description": "", 5 + "main": "src/main.ts", 6 + "scripts": { 7 + "dev": "vite", 8 + "start": "vite", 9 + "build": "tsc && vite build", 10 + "serve": "vite preview", 11 + "test": "npm run build && npx playwright test", 12 + "test:integration-update": "npx playwright test --update-snapshots" 13 + }, 14 + "repository": {}, 15 + "keywords": [ 16 + "excalibur", 17 + "excaliburjs", 18 + "vite", 19 + "game-engine" 20 + ], 21 + "author": "", 22 + "license": "", 23 + "bugs": {}, 24 + "homepage": "", 25 + "dependencies": { 26 + "excalibur": "0.30.3" 27 + }, 28 + "devDependencies": { 29 + "@playwright/test": "^1.49.1", 30 + "@types/node": "^22.10.2", 31 + "typescript": "5.7.3", 32 + "vite": "6.0.7" 33 + } 34 + }
+92
playwright.config.ts
··· 1 + import { defineConfig, devices } from '@playwright/test'; 2 + 3 + /** 4 + * Read environment variables from file. 5 + * https://github.com/motdotla/dotenv 6 + */ 7 + // import dotenv from 'dotenv'; 8 + // import path from 'path'; 9 + // dotenv.config({ path: path.resolve(__dirname, '.env') }); 10 + 11 + /** 12 + * See https://playwright.dev/docs/test-configuration. 13 + */ 14 + export default defineConfig({ 15 + testDir: './tests', 16 + webServer: { 17 + command: 'npm run serve', 18 + timeout: 240 * 1000, // linux takes a long time 19 + url: 'http://localhost:4173', 20 + reuseExistingServer: !process.env.CI, 21 + stdout: 'ignore', 22 + stderr: 'pipe', 23 + }, 24 + /* Run tests in files in parallel */ 25 + fullyParallel: true, 26 + /* Fail the build on CI if you accidentally left test.only in the source code. */ 27 + forbidOnly: !!process.env.CI, 28 + /* Retry on CI only */ 29 + retries: process.env.CI ? 2 : 0, 30 + /* Opt out of parallel tests on CI. */ 31 + workers: process.env.CI ? 1 : undefined, 32 + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ 33 + reporter: 'html', 34 + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ 35 + use: { 36 + /* Base URL to use in actions like `await page.goto('/')`. */ 37 + // baseURL: 'http://127.0.0.1:3000', 38 + 39 + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ 40 + trace: 'on-first-retry', 41 + }, 42 + 43 + /* Configure projects for major browsers */ 44 + projects: [ 45 + { 46 + name: 'chromium', 47 + use: { 48 + ...devices['Desktop Chrome'], 49 + launchOptions: { 50 + args: ["--no-sandbox", '--disable-web-security', "--use-angle=gl"] 51 + } 52 + }, 53 + }, 54 + 55 + // { 56 + // name: 'firefox', 57 + // use: { ...devices['Desktop Firefox'] }, 58 + // }, 59 + 60 + // { 61 + // name: 'webkit', 62 + // use: { ...devices['Desktop Safari'] }, 63 + // }, 64 + 65 + /* Test against mobile viewports. */ 66 + // { 67 + // name: 'Mobile Chrome', 68 + // use: { ...devices['Pixel 5'] }, 69 + // }, 70 + // { 71 + // name: 'Mobile Safari', 72 + // use: { ...devices['iPhone 12'] }, 73 + // }, 74 + 75 + /* Test against branded browsers. */ 76 + // { 77 + // name: 'Microsoft Edge', 78 + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, 79 + // }, 80 + // { 81 + // name: 'Google Chrome', 82 + // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, 83 + // }, 84 + ], 85 + 86 + /* Run your local dev server before starting the tests */ 87 + // webServer: { 88 + // command: 'npm run start', 89 + // url: 'http://127.0.0.1:3000', 90 + // reuseExistingServer: !process.env.CI, 91 + // }, 92 + });
+17
readme.md
··· 1 + # Excalibur TypeScript & Vite template 2 + 3 + Check out the full documentation @ https://excaliburjs.com 4 + 5 + You can use the excalibur cli to generate this template 6 + 7 + ```sh 8 + npm create excalibur 9 + ``` 10 + 11 + ## Getting Started 12 + 13 + 1. [Generate a repository](https://github.com/excaliburjs/template-ts-vite/generate) from this template 14 + 2. Modify the `package.json` with your own details 15 + 3. Run `npm install` to install dependencies 16 + 4. Run `npm run dev` to start the Vite server! 17 + 5. Have fun!
+10
renovate.json
··· 1 + { 2 + "extends": [ 3 + "config:base" 4 + ], 5 + "commitMessagePrefix": "chore:", 6 + "automerge": true, 7 + "major": { 8 + "automerge": false 9 + } 10 + }
+19
tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + "target": "ESNext", 4 + "useDefineForClassFields": true, 5 + "module": "ESNext", 6 + "lib": ["ESNext", "DOM"], 7 + "moduleResolution": "Node", 8 + "strict": true, 9 + "skipLibCheck": true, 10 + "sourceMap": true, 11 + "resolveJsonModule": true, 12 + "esModuleInterop": true, 13 + "noEmit": true, 14 + "noUnusedLocals": true, 15 + "noUnusedParameters": false, 16 + "noImplicitReturns": true 17 + }, 18 + "include": ["./src"] 19 + }
+39
vite.config.js
··· 1 + import { defineConfig } from "vite"; 2 + 3 + // if you use tiled maps 4 + // there is a collision between react w/ typescript .tsx 5 + // and tiled tileset files .tsx 6 + // this forces vite to not interpret tsx as react 7 + const tiledPlugin = () => { 8 + return { 9 + name: 'tiled-tileset-plugin', 10 + resolveId: { 11 + order: 'pre', 12 + handler(sourceId, importer, options) { 13 + if (!sourceId.endsWith(".tsx")) return; 14 + return { id: 'tileset:' + sourceId, external: 'relative' } 15 + } 16 + } 17 + }; 18 + } 19 + 20 + export default defineConfig({ 21 + base: './', // optionally give a base path, useful for itch.io to serve relative instead of the default absolut 22 + plugins: [tiledPlugin()], // hint vite that tiled tilesets should be treated as external 23 + // currently excalibur plugins are commonjs 24 + // this forces vite to keep things from bundling ESM together with commonjs 25 + optimizeDeps: { 26 + exclude: ["excalibur"], 27 + }, 28 + build: { 29 + assetsInlineLimit: 0, // excalibur cannot handle inlined xml in prod mode 30 + sourcemap: true, 31 + // Vite uses rollup currently for prod builds so a separate config is needed 32 + // to keep vite from bundling ESM together with commonjs 33 + rollupOptions: { 34 + output: { 35 + format: 'umd' 36 + } 37 + } 38 + } 39 + });
+1
src/files.d.ts
··· 1 + declare module "*.png";
+88
src/firework.ts
··· 1 + import { Actor, BodyComponent, Color, CoordPlane, coroutine, CoroutineGenerator, Entity, GpuParticleEmitter, MotionComponent, ParticleEmitter, Random, Scene, TransformComponent, vec, Vector } from "excalibur"; 2 + 3 + export class Firework extends Actor { 4 + random: Random; 5 + trail: GpuParticleEmitter; 6 + explosion: GpuParticleEmitter; 7 + explosion2: GpuParticleEmitter; 8 + life: number; 9 + body: BodyComponent; 10 + 11 + constructor(pos: Vector, life: number, random: Random) { 12 + super({ name: "Firework" }) 13 + this.random = random; 14 + this.pos = pos; 15 + this.acc = vec(0, 800); 16 + 17 + this.body = new BodyComponent(); 18 + this.life = life; 19 + 20 + this.trail = new GpuParticleEmitter({ 21 + isEmitting: false, 22 + emitRate: 70, 23 + particle: { 24 + life: 1000, 25 + endColor: Color.White, 26 + beginColor: Color.White, 27 + minSpeed: 10, 28 + maxSpeed: 30, 29 + startSize: 3, 30 + endSize: 0, 31 + fade: true, 32 + acc: vec(0, 50), 33 + } 34 + }); 35 + 36 + this.explosion = new GpuParticleEmitter({ 37 + isEmitting: false, 38 + particle: { 39 + life: 2000, 40 + fade: true, 41 + startSize: 5, 42 + endSize: 2, 43 + minSpeed: 10, 44 + maxSpeed: 200, 45 + acc: vec(0, 100), 46 + beginColor: Color.Red, 47 + endColor: Color.Yellow 48 + } 49 + }); 50 + this.explosion2 = new GpuParticleEmitter({ 51 + isEmitting: false, 52 + particle: { 53 + life: 1000, 54 + fade: true, 55 + startSize: 5, 56 + endSize: 2, 57 + minSpeed: 10, 58 + maxSpeed: 200, 59 + acc: vec(0, 100), 60 + beginColor: Color.White, 61 + endColor: Color.Purple 62 + } 63 + }); 64 + 65 + this.addChild(this.trail); 66 + this.addChild(this.explosion); 67 + this.addChild(this.explosion2); 68 + } 69 + 70 + launch() { 71 + coroutine(this.scene!.engine, (function*(this: Firework) { 72 + this.vel = vec(this.random.floating(-200, 200), this.random.floating(-800, -1000)); 73 + this.trail.isEmitting = true; 74 + while (this.life > 0) { 75 + const elapsed = yield; 76 + this.life -= elapsed; 77 + if (this.vel.y >= 0) { 78 + break; 79 + } 80 + } 81 + this.trail.isEmitting = false; 82 + this.explosion.emitParticles(500); 83 + this.explosion2.emitParticles(500); 84 + 85 + } as CoroutineGenerator).bind(this)) 86 + } 87 + 88 + }
+52
src/level.ts
··· 1 + import { DefaultLoader, Engine, ExcaliburGraphicsContext, Random, Scene, SceneActivationContext, vec } from "excalibur"; 2 + import { Player } from "./player"; 3 + import { Firework } from "./firework"; 4 + 5 + export class MyLevel extends Scene { 6 + override onInitialize(engine: Engine): void { 7 + const random = new Random(1337); 8 + // Scene.onInitialize is where we recommend you perform the composition for your game 9 + const player = new Player(); 10 + this.add(player); // Actors need to be added to a scene to be drawn 11 + const firework = new Firework(vec(400, 600), 2000, random); 12 + this.add(firework); 13 + firework.launch(); 14 + 15 + this.input.pointers.on('down', () => { 16 + const firework = new Firework(vec(400, 600), 2000, random); 17 + this.add(firework); 18 + firework.launch(); 19 + }); 20 + } 21 + 22 + override onPreLoad(loader: DefaultLoader): void { 23 + // Add any scene specific resources to load 24 + } 25 + 26 + override onActivate(context: SceneActivationContext<unknown>): void { 27 + // Called when Excalibur transitions to this scene 28 + // Only 1 scene is active at a time 29 + 30 + } 31 + 32 + override onDeactivate(context: SceneActivationContext): void { 33 + // Called when Excalibur transitions away from this scene 34 + // Only 1 scene is active at a time 35 + } 36 + 37 + override onPreUpdate(engine: Engine, elapsedMs: number): void { 38 + // Called before anything updates in the scene 39 + } 40 + 41 + override onPostUpdate(engine: Engine, elapsedMs: number): void { 42 + // Called after everything updates in the scene 43 + } 44 + 45 + override onPreDraw(ctx: ExcaliburGraphicsContext, elapsedMs: number): void { 46 + // Called before Excalibur draws to the screen 47 + } 48 + 49 + override onPostDraw(ctx: ExcaliburGraphicsContext, elapsedMs: number): void { 50 + // Called after Excalibur draws to the screen 51 + } 52 + }
+31
src/main.ts
··· 1 + import { Color, DisplayMode, Engine, FadeInOut } from "excalibur"; 2 + import { loader } from "./resources"; 3 + import { MyLevel } from "./level"; 4 + 5 + // Goal is to keep main.ts small and just enough to configure the engine 6 + 7 + const game = new Engine({ 8 + width: 800, // Logical width and height in game pixels 9 + height: 600, 10 + displayMode: DisplayMode.FitScreenAndFill, // Display mode tells excalibur how to fill the window 11 + pixelArt: true, // pixelArt will turn on the correct settings to render pixel art without jaggies or shimmering artifacts 12 + scenes: { 13 + start: MyLevel 14 + }, 15 + // physics: { 16 + // solver: SolverStrategy.Realistic, 17 + // substep: 5 // Sub step the physics simulation for more robust simulations 18 + // }, 19 + // fixedUpdateTimestep: 16 // Turn on fixed update timestep when consistent physic simulation is important 20 + }); 21 + 22 + game.start('start', { // name of the start scene 'start' 23 + loader, // Optional loader (but needed for loading images/sounds) 24 + inTransition: new FadeInOut({ // Optional in transition 25 + duration: 1000, 26 + direction: 'in', 27 + color: Color.ExcaliburBlue 28 + }) 29 + }).then(() => { 30 + // Do something after the game starts 31 + });
+86
src/player.ts
··· 1 + import { Actor, Collider, CollisionContact, Engine, Side, vec } from "excalibur"; 2 + import { Resources } from "./resources"; 3 + 4 + // Actors are the main unit of composition you'll likely use, anything that you want to draw and move around the screen 5 + // is likely built with an actor 6 + 7 + // They contain a bunch of useful components that you might use 8 + // actor.transform 9 + // actor.motion 10 + // actor.graphics 11 + // actor.body 12 + // actor.collider 13 + // actor.actions 14 + // actor.pointer 15 + 16 + 17 + export class Player extends Actor { 18 + constructor() { 19 + super({ 20 + // Giving your actor a name is optional, but helps in debugging using the dev tools or debug mode 21 + // https://github.com/excaliburjs/excalibur-extension/ 22 + // Chrome: https://chromewebstore.google.com/detail/excalibur-dev-tools/dinddaeielhddflijbbcmpefamfffekc 23 + // Firefox: https://addons.mozilla.org/en-US/firefox/addon/excalibur-dev-tools/ 24 + name: 'Player', 25 + pos: vec(150, 150), 26 + width: 100, 27 + height: 100, 28 + // anchor: vec(0, 0), // Actors default center colliders and graphics with anchor (0.5, 0.5) 29 + // collisionType: CollisionType.Active, // Collision Type Active means this participates in collisions read more https://excaliburjs.com/docs/collisiontypes 30 + }); 31 + 32 + } 33 + 34 + override onInitialize() { 35 + // Generally recommended to stick logic in the "On initialize" 36 + // This runs before the first update 37 + // Useful when 38 + // 1. You need things to be loaded like Images for graphics 39 + // 2. You need excalibur to be initialized & started 40 + // 3. Deferring logic to run time instead of constructor time 41 + // 4. Lazy instantiation 42 + this.graphics.add(Resources.Sword.toSprite()); 43 + 44 + // Actions are useful for scripting common behavior, for example patrolling enemies 45 + this.actions.delay(2000); 46 + this.actions.repeatForever(ctx => { 47 + ctx.moveBy({offset: vec(100, 0), duration: 1000}); 48 + ctx.moveBy({offset: vec(0, 100), duration: 1000}); 49 + ctx.moveBy({offset: vec(-100, 0), duration: 1000}); 50 + ctx.moveBy({offset: vec(0, -100), duration: 1000}); 51 + }); 52 + 53 + // Sometimes you want to click on an actor! 54 + this.on('pointerdown', evt => { 55 + // Pointer events tunnel in z order from the screen down, you can cancel them! 56 + // if (true) { 57 + // evt.cancel(); 58 + // } 59 + console.log('You clicked the actor @', evt.worldPos.toString()); 60 + }); 61 + } 62 + 63 + override onPreUpdate(engine: Engine, elapsedMs: number): void { 64 + // Put any update logic here runs every frame before Actor builtins 65 + } 66 + 67 + override onPostUpdate(engine: Engine, elapsedMs: number): void { 68 + // Put any update logic here runs every frame after Actor builtins 69 + } 70 + 71 + override onPreCollisionResolve(self: Collider, other: Collider, side: Side, contact: CollisionContact): void { 72 + // Called before a collision is resolved, if you want to opt out of this specific collision call contact.cancel() 73 + } 74 + 75 + override onPostCollisionResolve(self: Collider, other: Collider, side: Side, contact: CollisionContact): void { 76 + // Called every time a collision is resolved and overlap is solved 77 + } 78 + 79 + override onCollisionStart(self: Collider, other: Collider, side: Side, contact: CollisionContact): void { 80 + // Called when a pair of objects are in contact 81 + } 82 + 83 + override onCollisionEnd(self: Collider, other: Collider, side: Side, lastContact: CollisionContact): void { 84 + // Called when a pair of objects separates 85 + } 86 + }
+14
src/resources.ts
··· 1 + import { ImageSource, Loader } from "excalibur"; 2 + 3 + // It is convenient to put your resources in one place 4 + export const Resources = { 5 + Sword: new ImageSource("./images/sword.png") // Vite public/ directory serves the root images 6 + } as const; // the 'as const' is a neat typescript trick to get strong typing on your resources. 7 + // So when you type Resources.Sword -> ImageSource 8 + 9 + // We build a loader and add all of our resources to the boot loader 10 + // You can build your own loader by extending DefaultLoader 11 + export const loader = new Loader(); 12 + for (const res of Object.values(Resources)) { 13 + loader.addResource(res); 14 + }
+5
src/style.css
··· 1 + @media (prefers-color-scheme: dark) { 2 + body { 3 + background-color: black; 4 + } 5 + }
+1
src/vite-env.d.ts
··· 1 + /// <reference types="vite/client" />
+7
tests/main.spec.ts
··· 1 + import { test, expect } from '@playwright/test'; 2 + 3 + test('main page looks correct', async ({ page }) => { 4 + await page.goto('http://localhost:4173/'); 5 + await page.click('#excalibur-play'); 6 + await expect(page).toHaveScreenshot(); 7 + });
public/images/sword.png

This is a binary file and will not be displayed.

tests/main.spec.ts-snapshots/main-page-looks-correct-1-chromium-linux.png

This is a binary file and will not be displayed.

tests/main.spec.ts-snapshots/main-page-looks-correct-1-chromium-win32.png

This is a binary file and will not be displayed.