Use cannonball image for broadside projectiles

This commit is contained in:
Admin 2026-09-19 03:33:13 +00:00
parent cdd5963e0f
commit e85920f4f3
2 changed files with 17 additions and 22 deletions

View File

@ -2,6 +2,7 @@ import Phaser from 'phaser';
import './style.css';
import airshipSheetUrl from './assets/airships.svg?url';
import explosionSheetUrl from './assets/explosions.svg?url';
import cannonballUrl from './assets/cannonball.png?url';
import { airshipLog, registerDebugSnapshot } from './diagnostics.js';
import {
DEFAULT_PIRATE_SHOT_DAMAGE,
@ -80,12 +81,12 @@ class GameScene extends Phaser.Scene {
frameWidth: 64,
frameHeight: 64,
});
this.load.image('cannonball', cannonballUrl);
}
create() {
this.physics.world.setBounds(0, 0, WORLD_SIZE, WORLD_SIZE);
this.drawWorld();
this.createTextures();
this.createAnimations();
this.player = this.physics.add.sprite(1200, 1550, 'airships', 0);
@ -359,24 +360,6 @@ class GameScene extends Phaser.Scene {
island2.fillEllipse(1940, 1830, 210, 112);
}
createTextures() {
const playerShot = this.make.graphics({ x: 0, y: 0, add: false });
playerShot.fillStyle(0xffd36a, 1);
playerShot.fillCircle(5, 5, 5);
playerShot.lineStyle(1, 0xfff0b0, 1);
playerShot.strokeCircle(5, 5, 4);
playerShot.generateTexture('player-shot', 10, 10);
playerShot.destroy();
const pirateShot = this.make.graphics({ x: 0, y: 0, add: false });
pirateShot.fillStyle(0xff6b62, 1);
pirateShot.fillCircle(5, 5, 5);
pirateShot.lineStyle(1, 0xffb0aa, 1);
pirateShot.strokeCircle(5, 5, 4);
pirateShot.generateTexture('pirate-shot', 10, 10);
pirateShot.destroy();
}
update(_time, deltaMs) {
const dt = Math.min(deltaMs / 1000, 0.05);
const hadQueuedPlayerHit = this.pendingPlayerHits.length > 0;
@ -521,7 +504,7 @@ class GameScene extends Phaser.Scene {
if (distance < broadsideRange && broadsideError < broadsideTolerance && this.time.now - lastShot > reloadMs) {
const side = relative >= 0 ? 1 : -1;
this.fireBroadside(pirate, side, this.pirateShots, 'pirate-shot', projectileDamage, 0.9);
this.fireBroadside(pirate, side, this.pirateShots, 'cannonball', projectileDamage, 0.9);
pirate.setData('lastShot', this.time.now);
}
}
@ -530,7 +513,7 @@ class GameScene extends Phaser.Scene {
playerBroadside(side) {
const broadside = side < 0 ? 'port' : 'starboard';
if (this.time.now - this.lastPlayerShot[broadside] < this.playerBroadsideReloadMs) return;
this.fireBroadside(this.player, side, this.playerShots, 'player-shot', 16, 1.0);
this.fireBroadside(this.player, side, this.playerShots, 'cannonball', 16, 1.0);
this.lastPlayerShot[broadside] = this.time.now;
}
@ -554,7 +537,7 @@ class GameScene extends Phaser.Scene {
const x = ship.x + Math.cos(base) * 34;
const y = ship.y + Math.sin(base) * 34;
const shot = group.create(x, y, texture);
shot.setDepth(8);
shot.setDepth(8).setDisplaySize(14, 14);
shot.body.setAllowGravity(false);
shot.setData('bornAt', this.time.now);
shot.setData('damage', projectileDamage);

View File

@ -182,6 +182,18 @@ test('player firing and reload HUD share one reload duration source', async () =
assert.match(source, /Math\.max\(1, this\.playerBroadsideReloadMs\)/);
});
test('player and pirate broadsides use the cannonball image asset', async () => {
const source = await read('src/game-v4.js');
assert.match(source, /import cannonballUrl from '.\/assets\/cannonball\.png\?url'/);
assert.match(source, /this\.load\.image\('cannonball', cannonballUrl\)/);
assert.match(source, /this\.fireBroadside\(this\.player, side, this\.playerShots, 'cannonball'/);
assert.match(source, /this\.fireBroadside\(pirate, side, this\.pirateShots, 'cannonball'/);
assert.match(source, /shot\.setDepth\(8\)\.setDisplaySize\(14, 14\)/);
assert.doesNotMatch(source, /generateTexture\('player-shot'/);
assert.doesNotMatch(source, /generateTexture\('pirate-shot'/);
});
test('mobile HUD skips hidden Phaser rendering and throttles DOM state publishing', async () => {
const source = await read('src/game-v4.js');