level boundaries
continuous-integration/drone/push Build is passing Details

main
Evan Hemsley 2020-07-14 18:50:26 -07:00
parent 6d1e3793ef
commit a996d03c31
2 changed files with 95 additions and 222 deletions

View File

@ -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.

View File

@ -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
);
}
}
```