Skip to content

Commit 8f0da7d

Browse files
shooting bullets
1 parent 9ace994 commit 8f0da7d

File tree

5 files changed

+90
-19
lines changed

5 files changed

+90
-19
lines changed

examples/space-invaders/src/components.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import { Sprite as _Sprite } from "pixi.js";
55
export class Position extends Component("Position")<{
66
x: number;
77
y: number;
8-
}> {}
8+
}> {
9+
static readonly initial = new this({ x: 400, y: 550 });
10+
}
911

1012
export class Collider extends Component("Collider")<{
1113
body: _Body;
@@ -20,9 +22,14 @@ export class Velocity extends Component("Velocity")<{
2022
vy: number;
2123
speed: number;
2224
}> {
23-
static readonly init = new this({ vx: 0, vy: 0, speed: 6 });
25+
static readonly idle = new this({ vx: 0, vy: 0, speed: 6 });
26+
static readonly shootUp = new this({ vx: 0, vy: -10, speed: 6 });
2427
}
2528

26-
export class Bullet extends Component("Bullet")<{}> {}
29+
export class Bullet extends Component("Bullet")<{
30+
damage: number;
31+
}> {
32+
static readonly default = new this({ damage: 10 });
33+
}
2734

2835
export class Player extends Component("Player")<{}> {}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const PLAYER_WIDTH = 40;
2+
export const PLAYER_HEIGHT = 20;

examples/space-invaders/src/input-manager.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ export class InputManager {
1414
this.keyStates.set(event.code, false);
1515
}
1616

17-
public isKeyPressed(
18-
keyCode: "ArrowUp" | "ArrowDown" | "ArrowLeft" | "ArrowRight"
19-
): boolean {
17+
public isKeyPressed(keyCode: "ArrowLeft" | "ArrowRight" | "Space"): boolean {
2018
return this.keyStates.get(keyCode) ?? false;
2119
}
2220
}

examples/space-invaders/src/main.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ import { ECS, update } from "@typeonce/ecs";
22
import Matter from "matter-js";
33
import * as PIXI from "pixi.js";
44
import { Collider, Player, Position, Sprite, Velocity } from "./components";
5+
import { PLAYER_HEIGHT, PLAYER_WIDTH } from "./constants";
56
import { InputManager } from "./input-manager";
67
import {
78
MovementSystem,
89
PhysicsSystem,
910
PlayerInputSystem,
1011
RenderSystem,
12+
ShootingSystem,
1113
} from "./systems";
1214

1315
const app = new PIXI.Application();
@@ -22,27 +24,34 @@ const world = ECS.create(
2224
MovementSystem,
2325
RenderSystem,
2426
PhysicsSystem(engine),
25-
PlayerInputSystem(inputManager)
27+
PlayerInputSystem(inputManager),
28+
ShootingSystem({ app, engine, inputManager })
2629
);
2730

2831
const playerId = createEntity();
2932
const playerSprite = new PIXI.Sprite(PIXI.Texture.WHITE);
30-
playerSprite.width = 40;
31-
playerSprite.height = 20;
33+
playerSprite.width = PLAYER_WIDTH;
34+
playerSprite.height = PLAYER_HEIGHT;
35+
playerSprite.anchor.set(0.5, 0);
3236
app.stage.addChild(playerSprite);
3337

34-
const playerBody = Matter.Bodies.rectangle(400, 550, 40, 20, {
35-
isStatic: true,
36-
});
38+
const initialPosition = Position.initial;
39+
const playerBody = Matter.Bodies.rectangle(
40+
initialPosition.x,
41+
initialPosition.y,
42+
PLAYER_WIDTH,
43+
PLAYER_HEIGHT,
44+
{ isStatic: true }
45+
);
3746
Matter.World.add(engine.world, playerBody);
3847

3948
addComponent(
4049
playerId,
41-
Velocity.init,
42-
new Position({ x: 400, y: 550 }),
50+
Velocity.idle,
51+
initialPosition,
52+
new Player(),
4353
new Sprite({ sprite: playerSprite }),
44-
new Collider({ body: playerBody }),
45-
new Player()
54+
new Collider({ body: playerBody })
4655
);
4756
}
4857
);

examples/space-invaders/src/systems.ts

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
import { query, queryRequired, type SystemUpdate } from "@typeonce/ecs";
22
import * as Matter from "matter-js";
3+
import * as PIXI from "pixi.js";
34

4-
import { Collider, Player, Position, Sprite, Velocity } from "./components";
5+
import {
6+
Bullet,
7+
Collider,
8+
Player,
9+
Position,
10+
Sprite,
11+
Velocity,
12+
} from "./components";
513
import type { InputManager } from "./input-manager";
614

715
const moving = query({ position: Position, velocity: Velocity });
816
const physics = query({ position: Position, collider: Collider });
917
const pixiRender = query({ position: Position, sprite: Sprite });
10-
const player = queryRequired({ player: Player, velocity: Velocity });
18+
const playerVelocity = queryRequired({ player: Player, velocity: Velocity });
19+
const playerPosition = queryRequired({ player: Player, position: Position });
1120

1221
export const MovementSystem: SystemUpdate = ({ world, deltaTime }) => {
1322
moving(world).forEach(({ position, velocity }) => {
@@ -19,7 +28,7 @@ export const MovementSystem: SystemUpdate = ({ world, deltaTime }) => {
1928
export const PlayerInputSystem =
2029
(inputManager: InputManager): SystemUpdate =>
2130
({ world }) => {
22-
const { velocity } = player(world)[0];
31+
const { velocity } = playerVelocity(world)[0];
2332
if (inputManager.isKeyPressed("ArrowLeft")) {
2433
velocity.vx = -velocity.speed;
2534
} else if (inputManager.isKeyPressed("ArrowRight")) {
@@ -45,3 +54,49 @@ export const PhysicsSystem =
4554
collider.body.position.y = position.y;
4655
});
4756
};
57+
58+
export const ShootingSystem =
59+
({
60+
app,
61+
engine,
62+
inputManager,
63+
}: {
64+
inputManager: InputManager;
65+
app: PIXI.Application;
66+
engine: Matter.Engine;
67+
}): SystemUpdate =>
68+
({ world, addComponent, createEntity }) => {
69+
const { position } = playerPosition(world)[0];
70+
if (inputManager.isKeyPressed("Space")) {
71+
const bulletPosition = new Position({
72+
x: position.x,
73+
y: position.y + 10,
74+
});
75+
76+
const bulletSprite = new PIXI.Sprite(PIXI.Texture.WHITE);
77+
bulletSprite.width = 5;
78+
bulletSprite.height = 10;
79+
bulletSprite.tint = 0xf5f5f5;
80+
bulletSprite.anchor.set(0.5, 1);
81+
bulletSprite.position.set(bulletPosition.x, bulletPosition.y);
82+
app.stage.addChild(bulletSprite);
83+
84+
const bulletBody = Matter.Bodies.rectangle(
85+
bulletPosition.x,
86+
bulletPosition.y,
87+
5,
88+
10,
89+
{ isSensor: true }
90+
);
91+
Matter.World.add(engine.world, bulletBody);
92+
93+
addComponent(
94+
createEntity(),
95+
Bullet.default,
96+
bulletPosition,
97+
Velocity.shootUp,
98+
new Sprite({ sprite: bulletSprite }),
99+
new Collider({ body: bulletBody })
100+
);
101+
}
102+
};

0 commit comments

Comments
 (0)