logo

Babylon.js Market

SpaceShooterScore

shooter

SpaceShooterScore

1
Unlock

Install with the CLI:

bjs download SpaceShooterScore

SpaceShooterScore

The listener the kill event was missing. SpaceShooterHealth.destroyShip fires wingman.enemy.killed on every hostile death; this is the other end — it turns each kill into points and rebroadcasts the running total for a scoreboard to render.

What it does

SpaceShooterScoreComponent is two numbers: score (the run's accumulated points, starts at 0) and pointsPerKill (the payout, defaults to 100). One lives on the world/director entity — a per-run singleton, not a per-ship counter.

SpaceShooterScoreSystem does no per-frame work. On initialize it subscribes to the one event that matters:

TypeScript
protected onInitialize(): void {
  // The void gets a listener: every enemy death is now worth points.
  this.listen(SpaceShooterHealthEvents.ENEMY_KILLED, () => this.awardKill());
}

Each kill adds the payout to the total and rebroadcasts it as the canonical score.changed:

TypeScript
private awardKill(): void {
  const comp = this.getPrimary();
  if (!comp) return;
  const delta = comp.pointsPerKill;
  comp.score += delta;
  this.eventBus.emit(ScoreEvents.CHANGED, {
    score: comp.score,
    delta,
  });
}

getPrimary returns the first entity carrying the component — the singleton. A scoreboard HUD listening for score.changed updates with no wiring back to this System.

Use it in a scene

Key one SpaceShooterScoreComponent onto the world/director entity, and pull in a scoreboard that renders score.changed. Raise pointsPerKill to make a mission's kills worth more:

JSON
"Director": {
  "components": {
    "SpaceShooterScore": { "pointsPerKill": 250 }
  }
}

The kills come from SpaceShooterHealth — any hostile ship that dies through destroyShip feeds this. Without that death path in the scene there is nothing to count.

Events

  • Emits score.changed (ScoreEvents.CHANGED) after every counted kill — { score, delta }. score is the new total, delta the points that kill was worth.
  • Listens for wingman.enemy.killed (SpaceShooterHealthEvents.ENEMY_KILLED) — the hostile-death signal. Nothing else moves the score.

Dependencies

  • SpaceShooterHealth — owns destroyShip, which emits the wingman.enemy.killed this counts. Its only input.

Notes

  • Kills, not goals. This is the kill-scored variant, named apart from the generic arcade Score (which listens for score.add / goal.scored). Both emit the same score.changed, so a scoreboard swaps between them without rewiring.
  • Only enemy deaths count. It subscribes to ENEMY_KILLED alone — a downed freighter or a lost cargo car (wingman.freighter.killed / wingman.freighter.car.lost) fires its own event and scores nothing here. Add another listener if a mission should pay for those.
  • The event names live in the shared arcade dictionary, not this file — SpaceShooterHealthEvents (in) and ScoreEvents (out) both come from @babylonjsmarket/arcade, so the emitter and this listener never import each other.
  • First match wins. getPrimary returns the first entity with the component; a second SpaceShooterScoreComponent in the same scene is ignored. Keep it a singleton.

More like this

Scoreboard
SpaceShooterHealth
AiPilot
Animation
ArcCamera
Asteroid
Bullet
CameraFollow
CardFan
ChaseCamera6DOF
ChaseCameraTarget
DirectionalLight
Enemy
EnemySpawner
EnvironmentTexture
FlightIntent
FreighterCar
FreighterChain
FreighterHead
GameConfig
Health
HealthBar
HemisphericLight
Jump
KeyboardInput
KeyboardMover
Lifetime
LineOfSight
MachineGun
Mesh
MeshPrimitive
Missile
MissileLauncher
MissionDirector
MoneyField
Movement
Obstacle
ObstacleField
OilBlob
Parts
Physics
PlayerFlightInput
PlayerInput
PlayerWalkAnimator
PokerHUD
PokerTableCards
RespawnTimer
Score
Shadow
ShipFlight
ShipLoadout
ShooterCamera
SkeletonAnimator
SpaceDust
SpaceShooterBullet
TwinStickShooter
WaveDirector
Waypoint
WaypointTrack
WorldOriginAnchor

Was this page helpful?

We read every note — tell us what's working and what isn't.

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search