BeeEngine logo BeeEngine JAVASCRIPT 2D ENGINE

Enemy AI in Canvas 2D: Bounds, Timer Sparo e Proiettili (JS)

Documentazione – BeeEngine
v2.8.1

BeeEnemyShooter — Documentazione Tecnica

Nemico che rimbalza e spara: setBounds / shoot, colpi in hazards

📁 Panoramica

BeeEnemyShooter è un BeeEnemy che non pattuglia: spegne speed e si muove con vx/vy via integrate(). Vive in src/gameplay/BeeEnemyShooter.js. Ogni shootInterval (default 1.5 s) un BeeTimer locale chiama shoot: un BeeBullet dal pool engine.bullets (o new se manca), addEntity, poi collisions.add(bulletGroup, bullet) (default gruppo 'hazards').

Quello che non è: un turret fermo, un aiming al player, un diagonal shot. Il colpo è cardinale, nel verso della velocità più forte. Se vx === vy === 0 spara in basso (non più in alto per sbaglio).

const shooter = new BeeEnemyShooter(520, 220, 32, 32); shooter.setBounds(0, 0, 1600, 900); gioco.collisions.setGroup(‘hazards’, [enemy, shooter]); gioco.collisions.overlap(‘player’, ‘hazards’, (p, h) => p.takeDamage(1));

📁 Update: timer, integrate, clamp

Early-return se destroyed o inactive: niente fuoco, niente rimbalzo, niente flip di vx da fermo.

  1. 1. timerfire.duration = shootInterval, poi fire.update(time) (o dt).
  2. 2. parentBeeEnemy.update: x += speed * dt (qui speed è 0), poi integrate su vx/vy.
  3. 3. bordoSegno di vx/vy verso l’interno e worldX/Y clampati. Niente jitter.

setBounds(minX, minY, maxX, maxY) è spazio mondo. Se boundsMaxX/Y restano null, cade su engine.canvas.width/height. Senza canvas (e senza max) l’update esce dopo il parent: si muove, non rimbalza. boundsMin default 0,0.

📁 Sparo e pool

Il timer non sta su gioco.timers: lo ticka l’entity. In pausa updateEntities non gira, quindi non spara. onComplete spara solo se active, non destroyed, e this.engine è settato.

recycle() (release / #sleep) cancella il fuoco. reset() (acquire) fa fire.start(): elapsed e cancelled si azzerano. destroy() cancella e poi super.destroy() (release se pooled). Il secondo giro di vita spara di nuovo.

reset() non rimette posa né vx/vy: solo il timer. Il pool dei proiettili è engine.bullets; lo shooter stesso di solito è un new / prefab 'shooter'.

📁 Dove è facile sbagliare

Senza setBounds il mondo è il canvas. Con camera o mappa più larga dello schermo lo shooter “tocca il bordo” a canvas.width. La demo 800×600 senza camera sta in piedi; un follow-cam no, finché non passi i bound mondo.

Non rimettere speed. Il parent fa ancora this.x += speed * dt (locale) più i bound minX/maxX su worldX. Qui speed = 0 apposta. Se lo alzi hai due moti in X.

I colpi devono stare in un gruppo. Default bulletGroup = 'hazards'. Serve overlap('player', 'hazards') (la demo ce l’ha). Senza pool, add lascia i bullet morti nell’array: run li salta (destroyed), ma la lista cresce.

Niente mira. Il cannone e il colpo seguono l’asse dominante di vx/vy, non il player. Fermare il body (vx = vy = 0) = raffica verso il basso.

📁 Esempio: bound mondo + gruppo

const shooter = new BeeEnemyShooter(520, 220, 32, 32); gioco.addEntity(shooter); shooter.shootInterval = 1; shooter.setBounds(0, 0, mondoW, mondoH); // i nuovi BeeBullet finiscono in ‘hazards’ da soli gioco.collisions.add(‘hazards’, shooter);

📁 Riepilogo API

Estende BeeEnemy. Il timer è un BeeTimer loop, non gioco.after.

Membro Ritorna Scopo
new BeeEnemyShooter(x, y, w?, h?, textureKey?) BeeEnemyShooter speed 0 · vx 80 · vy 60 · interval 1.5 · bulletSpeed 250 · fire già start().
setBounds(minX, minY, maxX, maxY) — Rettangolo mondo del rimbalzo. Max null → canvas.
shootInterval / bulletSpeed / bulletGroup number / number / string Durata copiata sul timer ogni frame. Gruppo default 'hazards'.
shootTimer number Alias di fire.remaining.
update(dt, input, engine) — Early-return se spento. Timer → parent → clamp bordi.
shoot(engine) — Acquire/new bullet, addEntity, collisions.add. Cardinale.
reset() / recycle() — Pool: start / cancel del fuoco. Non tocca la posa.
destroy() — Cancel + super.destroy.
prefabs.type('shooter') classe Factory di stock. Serve una define prima di spawn. Bound e interval li setti tu.