4.2 KiB
4.2 KiB
title | date | weight |
---|---|---|
Scoring | 2019-05-30T16:08:54-07:00 | 1000 |
In Pong, your opponent scores a point by getting the ball behind your paddle.
There's a couple of things we need to sort out here: 1) tracking and displaying each player's score, and 2) reacting appropriately when a ball collides with a goal (side) boundary.
Let's start by creating a ScoreComponent.
import { Component } from "encompass-ecs";
export class ScoreComponent extends Component {
public score: number;
public player_one: boolean;
}
And let's have a new collision type.
export enum CollisionType {
ball,
goal,
paddle,
wall,
}
We'll need a new BallGoalCollisionMessage:
import { Entity, Message } from "encompass-ecs";
export class BallGoalCollisionMessage extends Message {
public ball_entity: Entity;
public goal_entity: Entity;
}
And some dispatch logic in the CollisionDispatchEngine:
...
switch (collision_message.collision_type_one) {
case CollisionType.ball:
switch (collision_message.collision_type_two) {
case CollisionType.goal: {
const message = this.emit_message(BallGoalCollisionMessage);
message.ball_entity = collision_message.entity_one;
message.goal_entity = collision_message.entity_two;
break;
}
...
And a new BallGoalCollisionEngine:
import { Engine, Mutates, Reads } from "encompass-ecs";
import { ScoreComponent } from "game/components/score";
import { BallGoalCollisionMessage } from "game/messages/collisions/ball_goal";
import { World } from "lua-lib/bump";
@Reads(BallGoalCollisionMessage)
@Mutates(ScoreComponent)
export class BallGoalCollisionEngine extends Engine {
private collision_world: World;
public initialize(collision_world: World) {
this.collision_world = collision_world;
}
public update() {
for (const message of this.read_messages(BallGoalCollisionMessage).values()) {
const score_component = this.make_mutable(message.goal_entity.get_component(ScoreComponent));
score_component.score += 1;
message.ball_entity.destroy();
this.collision_world.remove(message.ball_entity);
}
}
}
I've decided we should just attach the ScoreComponent directly to the goal entity for simplicity.
We'll need a way to create our goal entities now.
Let's have a new GoalSpawnMessage:
import { Message } from "encompass-ecs";
export class GoalSpawnMessage extends Message {
public x: number;
public y: number;
public width: number;
public height: number;
public player_one: boolean;
}
And a new GoalSpawner:
import { Spawner } from "encompass-ecs";
import { BoundingBoxComponent } from "game/components/bounding_box";
import { CollisionType, CollisionTypesComponent } from "game/components/collision_types";
import { PositionComponent } from "game/components/position";
import { ScoreComponent } from "game/components/score";
import { GoalSpawnMessage } from "game/messages/goal_spawn";
import { World } from "lua-lib/bump";
export class GoalSpawner extends Spawner {
public spawn_message_type = GoalSpawnMessage;
private collision_world: World;
public initialize(collision_world: World) {
this.collision_world = collision_world;
}
public spawn(message: GoalSpawnMessage) {
const entity = this.create_entity();
const score_component = entity.add_component(ScoreComponent);
score_component.score = 0;
score_component.player_one = message.player_one;
const boundaries = entity.add_component(BoundingBoxComponent);
boundaries.width = message.width;
boundaries.height = message.height;
const position = entity.add_component(PositionComponent);
position.x = message.x;
position.y = message.y;
const collision_types_component = entity.add_component(CollisionTypesComponent);
collision_types_component.collision_types = [ CollisionType.goal ];
this.collision_world.add(
entity,
message.x - message.width * 0.5,
message.y - message.height * 0.5,
message.width,
message.height
);
}
}