level boundaries
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
6d1e3793ef
commit
a996d03c31
|
@ -0,0 +1,95 @@
|
|||
---
|
||||
title: "Boundaries"
|
||||
date: 2019-05-29T11:05:16-07:00
|
||||
weight: 900
|
||||
---
|
||||
|
||||
Now that we have bouncing capabilities, we can add them easily to other entities. Let's make boundary boxes that make the ball bounce off the sides of the game area.
|
||||
|
||||
**PongFE/Messages/BoundarySpawnMessage.cs**:
|
||||
|
||||
```cs
|
||||
using Encompass;
|
||||
using MoonTools.Structs;
|
||||
|
||||
namespace PongFE.Messages
|
||||
{
|
||||
public struct BoundarySpawnMessage : IMessage
|
||||
{
|
||||
public Position2D Position { get; }
|
||||
public int Width { get; }
|
||||
public int Height { get; }
|
||||
|
||||
public BoundarySpawnMessage(Position2D position, int width, int height)
|
||||
{
|
||||
Position = position;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**PongFE/Engines/BoundarySpawner.cs**:
|
||||
|
||||
```cs
|
||||
using Encompass;
|
||||
using PongFE.Components;
|
||||
using PongFE.Messages;
|
||||
|
||||
namespace PongFE.Spawners
|
||||
{
|
||||
public class BoundarySpawner : Spawner<BoundarySpawnMessage>
|
||||
{
|
||||
protected override void Spawn(BoundarySpawnMessage message)
|
||||
{
|
||||
var entity = CreateEntity();
|
||||
|
||||
AddComponent(entity, new PositionComponent(message.Position));
|
||||
AddComponent(entity, new CollisionComponent(new MoonTools.Bonk.Rectangle(0, 0, message.Width, message.Height)));
|
||||
AddComponent(entity, new CanCauseBounceComponent());
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now we can create the boundary entities by sending messages with WorldBuilder.
|
||||
|
||||
**PongFEGame.cs**
|
||||
|
||||
```cs
|
||||
...
|
||||
|
||||
WorldBuilder.AddEngine(new BoundarySpawner());
|
||||
|
||||
...
|
||||
|
||||
// top boundary
|
||||
WorldBuilder.SendMessage(
|
||||
new BoundarySpawnMessage(
|
||||
new MoonTools.Structs.Position2D(0, -6),
|
||||
1280,
|
||||
6
|
||||
)
|
||||
);
|
||||
|
||||
// right boundary
|
||||
WorldBuilder.SendMessage(
|
||||
new BoundarySpawnMessage(
|
||||
new MoonTools.Structs.Position2D(1280, 0),
|
||||
6,
|
||||
720
|
||||
)
|
||||
);
|
||||
|
||||
// bottom boundary
|
||||
WorldBuilder.SendMessage(
|
||||
new BoundarySpawnMessage(
|
||||
new MoonTools.Structs.Position2D(0, 720),
|
||||
1280,
|
||||
6
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
Notice that we didn't have to write any new game logic to add boundaries to our game. This is the power of modular composition using ECS.
|
|
@ -1,222 +0,0 @@
|
|||
---
|
||||
title: "Spawners"
|
||||
date: 2019-05-29T11:05:16-07:00
|
||||
weight: 900
|
||||
---
|
||||
|
||||
Our Entities are getting a bit more complex now with the addition of BoundingBoxComponents and CollisionTypeComponents.
|
||||
|
||||
I think we should create Spawners for each of our game entities.
|
||||
|
||||
This will be pretty straightforward. Just decide which parameters we need to create our entities, and add the proper components with those parameters.
|
||||
|
||||
### Ball
|
||||
|
||||
In **game/messages/ball_spawn.ts**:
|
||||
|
||||
```ts
|
||||
import { Message } from "encompass-ecs";
|
||||
|
||||
export class BallSpawnMessage extends Message {
|
||||
public x: number;
|
||||
public y: number;
|
||||
public size: number;
|
||||
public x_velocity: number;
|
||||
public y_velocity: number;
|
||||
}
|
||||
```
|
||||
|
||||
In **game/engines/spawners/ball.ts**:
|
||||
|
||||
```ts
|
||||
import { Reads, Spawner } from "encompass-ecs";
|
||||
import { BoundingBoxComponent } from "game/components/bounding_box";
|
||||
import { CanvasComponent } from "game/components/canvas";
|
||||
import { CollisionType, CollisionTypesComponent } from "game/components/collision_types";
|
||||
import { PositionComponent } from "game/components/position";
|
||||
import { VelocityComponent } from "game/components/velocity";
|
||||
import { BallSpawnMessage } from "game/messages/ball_spawn";
|
||||
import { World } from "lua-lib/bump";
|
||||
|
||||
@Reads(BallSpawnMessage)
|
||||
export class BallSpawner extends Spawner {
|
||||
public collision_world: World;
|
||||
|
||||
public initialize(collision_world: World) {
|
||||
this.collision_world = collision_world;
|
||||
}
|
||||
|
||||
public spawn(message: BallSpawnMessage) {
|
||||
const ball_entity = this.create_entity();
|
||||
|
||||
const ball_position_component = ball_entity.add_component(PositionComponent);
|
||||
ball_position_component.x = message.x;
|
||||
ball_position_component.y = message.y;
|
||||
|
||||
const ball_canvas = love.graphics.newCanvas(message.size, message.size);
|
||||
love.graphics.setCanvas(ball_canvas);
|
||||
love.graphics.setBlendMode("alpha");
|
||||
love.graphics.setColor(1, 1, 1, 1);
|
||||
love.graphics.rectangle("fill", 0, 0, message.size, message.size);
|
||||
love.graphics.setCanvas();
|
||||
|
||||
const ball_canvas_component = ball_entity.add_component(CanvasComponent);
|
||||
ball_canvas_component.canvas = ball_canvas;
|
||||
ball_canvas_component.x_scale = 1;
|
||||
ball_canvas_component.y_scale = 1;
|
||||
|
||||
const velocity_component = ball_entity.add_component(VelocityComponent);
|
||||
velocity_component.x = message.x_velocity;
|
||||
velocity_component.y = message.y_velocity;
|
||||
|
||||
const boundaries_component = ball_entity.add_component(BoundingBoxComponent);
|
||||
boundaries_component.width = message.size;
|
||||
boundaries_component.height = message.size;
|
||||
|
||||
const collision_types_component = ball_entity.add_component(CollisionTypesComponent);
|
||||
collision_types_component.collision_types = [ CollisionType.ball ];
|
||||
|
||||
this.collision_world.add(ball_entity, message.x, message.y, message.size, message.size);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Game Boundary
|
||||
|
||||
In **game/messages/game_boundary_spawn.ts**:
|
||||
|
||||
```ts
|
||||
import { Message } from "encompass-ecs";
|
||||
|
||||
export class GameBoundarySpawnMessage extends Message {
|
||||
public x: number;
|
||||
public y: number;
|
||||
public width: number;
|
||||
public height: number;
|
||||
}
|
||||
```
|
||||
|
||||
In **game/spawners/game_boundary.ts**:
|
||||
|
||||
```ts
|
||||
import { Reads, 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 { GameBoundarySpawnMessage } from "game/messages/game_boundary_spawn";
|
||||
import { World } from "lua-lib/bump";
|
||||
|
||||
@Reads(GameBoundarySpawnMessage)
|
||||
export class GameBoundarySpawner extends Spawner {
|
||||
private collision_world: World;
|
||||
|
||||
public initialize(collision_world: World) {
|
||||
this.collision_world = collision_world;
|
||||
}
|
||||
|
||||
public spawn(message: GameBoundarySpawnMessage) {
|
||||
const entity = this.create_entity();
|
||||
|
||||
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.wall ];
|
||||
|
||||
this.collision_world.add(
|
||||
entity,
|
||||
message.x - message.width * 0.5,
|
||||
message.y - message.height * 0.5,
|
||||
message.width,
|
||||
message.height
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Paddle
|
||||
|
||||
In **game/messages/paddle_spawn.ts**:
|
||||
|
||||
```ts
|
||||
import { Message } from "encompass-ecs";
|
||||
|
||||
export class PaddleSpawnMessage extends Message {
|
||||
public x: number;
|
||||
public y: number;
|
||||
public width: number;
|
||||
public height: number;
|
||||
public move_speed: number;
|
||||
}
|
||||
```
|
||||
|
||||
In **game/spawners/paddle.ts**:
|
||||
|
||||
```ts
|
||||
import { Reads, Spawner } from "encompass-ecs";
|
||||
import { BoundingBoxComponent } from "game/components/bounding_box";
|
||||
import { CanvasComponent } from "game/components/canvas";
|
||||
import { CollisionType, CollisionTypesComponent } from "game/components/collision_types";
|
||||
import { PaddleMoveSpeedComponent } from "game/components/paddle_move_speed";
|
||||
import { PlayerOneComponent } from "game/components/player_one";
|
||||
import { PositionComponent } from "game/components/position";
|
||||
import { PaddleSpawnMessage } from "game/messages/paddle_spawn";
|
||||
import { World } from "lua-lib/bump";
|
||||
|
||||
@Reads(PaddleSpawnMessage)
|
||||
export class PaddleSpawner extends Spawner {
|
||||
private collision_world: World;
|
||||
|
||||
public initialize(collision_world: World) {
|
||||
this.collision_world = collision_world;
|
||||
}
|
||||
|
||||
protected spawn(message: PaddleSpawnMessage) {
|
||||
const paddle_entity = this.create_entity();
|
||||
|
||||
paddle_entity.add_component(PlayerOneComponent);
|
||||
|
||||
const width = message.width;
|
||||
const height = message.height;
|
||||
|
||||
const paddle_canvas = love.graphics.newCanvas(width, height);
|
||||
love.graphics.setCanvas(paddle_canvas);
|
||||
love.graphics.setBlendMode("alpha");
|
||||
love.graphics.setColor(1, 1, 1, 1);
|
||||
love.graphics.rectangle("fill", 0, 0, width, height);
|
||||
love.graphics.setCanvas();
|
||||
|
||||
const canvas_component = paddle_entity.add_component(CanvasComponent);
|
||||
canvas_component.canvas = paddle_canvas;
|
||||
canvas_component.x_scale = 1;
|
||||
canvas_component.y_scale = 1;
|
||||
|
||||
const position_component = paddle_entity.add_component(PositionComponent);
|
||||
position_component.x = message.x;
|
||||
position_component.y = message.y;
|
||||
|
||||
const move_speed_component = paddle_entity.add_component(PaddleMoveSpeedComponent);
|
||||
move_speed_component.y = message.move_speed;
|
||||
|
||||
const paddle_boundaries = paddle_entity.add_component(BoundingBoxComponent);
|
||||
paddle_boundaries.width = width;
|
||||
paddle_boundaries.height = height;
|
||||
|
||||
const collision_types_component = paddle_entity.add_component(CollisionTypesComponent);
|
||||
collision_types_component.collision_types = [ CollisionType.paddle ];
|
||||
|
||||
this.collision_world.add(
|
||||
paddle_entity,
|
||||
message.x - width * 0.5,
|
||||
message.y - height * 0.5,
|
||||
width,
|
||||
height
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
Loading…
Reference in New Issue