Skip to content
This repository was archived by the owner on May 29, 2024. It is now read-only.

Commit c540959

Browse files
committed
Use zig-ecs to manage entities
Had to port the player over to this new paradigm.
1 parent 73bc25f commit c540959

File tree

5 files changed

+110
-35
lines changed

5 files changed

+110
-35
lines changed

build.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub fn build(b: *Builder) void {
2121
native.addPackage(PLATFORM);
2222
native.addPackage(deps.pkgs.zigimg);
2323
native.addPackage(deps.pkgs.math);
24+
native.addPackage(deps.pkgs.ecs);
2425
b.step("native", "Build native binary").dependOn(&native.step);
2526

2627
const native_run = native.run();
@@ -40,6 +41,7 @@ pub fn build(b: *Builder) void {
4041
wasm.addPackage(PLATFORM);
4142
wasm.addPackage(deps.pkgs.zigimg);
4243
wasm.addPackage(deps.pkgs.math);
44+
wasm.addPackage(deps.pkgs.ecs);
4345

4446
const static = b.addInstallDirectory(.{
4547
.source_dir = "static",

src/component.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const math = @import("math");
2+
const Vec2i = math.Vec(2, i64);
3+
const vec2i = Vec2i.init;
4+
5+
pub const Position = struct { pos: Vec2i };
6+
pub const Movement = struct { vel: Vec2i };
7+
pub const Render = struct { tid: u16 };
8+
pub const PlayerControl = struct {};

src/main.zig

Lines changed: 95 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ const tile = @import("./tile.zig");
1414
const generate = @import("./generate.zig");
1515
const Mat4f = math.Mat4(f32);
1616
const Font = @import("./font_render.zig").BitmapFontRenderer;
17+
const ecs = @import("ecs");
18+
const component = @import("./component.zig");
1719

1820
// Setup environment
1921
pub const panic = platform.panic;
@@ -55,8 +57,10 @@ var font: Font = undefined;
5557

5658
var adventureLog = std.ArrayList([]const u8).init(allocator);
5759
var map: Map = undefined;
58-
var playerPos = vec2i(10, 10);
59-
var playerMove = vec2i(0, 0);
60+
var registry: ecs.Registry = undefined;
61+
//var playerPos = vec2i(10, 10);
62+
var camPos = vec2i(0, 0);
63+
//var playerMove = vec2i(0, 0);
6064

6165
pub fn onInit() !void {
6266
std.log.info("app init", .{});
@@ -82,14 +86,21 @@ pub fn onInit() !void {
8286
},
8387
});
8488

85-
playerPos = map.spawn;
89+
registry = ecs.Registry.init(allocator);
90+
91+
var player = registry.create();
92+
registry.add(player, component.Position{ .pos = map.spawn });
93+
registry.add(player, component.Movement{ .vel = vec2i(0, 0) });
94+
registry.add(player, component.Render{ .tid = 25 });
95+
registry.add(player, component.PlayerControl{});
8696
try update_fov();
8797

8898
try adventureLog.append("You descend into the dungeon, hoping to gain experience and treasure.");
8999
}
90100

91101
fn onDeinit() void {
92102
std.log.info("app deinit", .{});
103+
registry.deinit();
93104
map.deinit();
94105
adventureLog.deinit();
95106
font.deinit();
@@ -98,6 +109,7 @@ fn onDeinit() void {
98109
}
99110

100111
pub fn onEvent(event: platform.event.Event) !void {
112+
var playerMove = vec2i(0, 0);
101113
switch (event) {
102114
.KeyDown => |e| switch (e.scancode) {
103115
.KP_8, .W, .UP => playerMove = vec2i(0, -1),
@@ -115,37 +127,80 @@ pub fn onEvent(event: platform.event.Event) !void {
115127
else => {},
116128
}
117129

118-
var moved = false;
119-
if (!map.get(playerPos.addv(playerMove)).solid()) {
120-
playerPos = playerPos.addv(playerMove);
121-
moved = true;
130+
// Set all players movement equal to playerMove
131+
if (!playerMove.eql(vec2i(0, 0))) {
132+
var view = registry.view(.{ component.PlayerControl, component.Movement }, .{});
133+
var iter = view.iterator();
134+
while (iter.next()) |entity| {
135+
const move = view.get(component.Movement, entity);
136+
move.vel = playerMove;
137+
}
122138
}
123-
playerMove = vec2i(0, 0);
124-
125-
if (map.get(playerPos) == .StairsDown) {
126-
map.deinit();
127-
128-
// Create map
129-
map = try generate.generateMap(allocator, .{
130-
.size = vec2i(50, 50),
131-
.max_rooms = 50,
132-
.room_size_range = .{
133-
.min = 3,
134-
.max = 10,
135-
},
136-
});
137-
138-
playerPos = map.spawn;
139+
140+
// Move entities
141+
{
142+
var view = registry.view(.{ component.Position, component.Movement }, .{});
143+
var iter = view.iterator();
144+
while (iter.next()) |entity| {
145+
const pos = view.get(component.Position, entity);
146+
const move = view.get(component.Movement, entity);
147+
148+
const new_pos = pos.pos.addv(move.vel);
149+
if (!map.get(new_pos).solid()) {
150+
pos.pos = new_pos;
151+
}
152+
move.vel = vec2i(0, 0);
153+
}
139154
}
140155

141-
if (moved) {
142-
try update_fov();
156+
// Check if any players are now standing on the stairsdown, and also update the camera pos
157+
{
158+
var any_on_stairs = false;
159+
var view = registry.view(.{ component.PlayerControl, component.Position }, .{});
160+
var iter = view.iterator();
161+
while (iter.next()) |entity| {
162+
const pos = view.getConst(component.Position, entity);
163+
if (map.get(pos.pos) == .StairsDown) {
164+
any_on_stairs = true;
165+
break;
166+
}
167+
camPos = pos.pos;
168+
}
169+
170+
if (any_on_stairs) {
171+
map.deinit();
172+
173+
// Create map
174+
map = try generate.generateMap(allocator, .{
175+
.size = vec2i(50, 50),
176+
.max_rooms = 50,
177+
.room_size_range = .{
178+
.min = 3,
179+
.max = 10,
180+
},
181+
});
182+
183+
iter = view.iterator();
184+
while (iter.next()) |entity| {
185+
const pos = view.get(component.Position, entity);
186+
pos.pos = map.spawn;
187+
camPos = pos.pos;
188+
}
189+
}
143190
}
191+
try update_fov();
144192
}
145193

146194
fn update_fov() !void {
147-
map.visible.deinit();
148-
map.visible = try map.computeFOV(playerPos, 8);
195+
map.visible.clearRetainingCapacity();
196+
197+
var view = registry.view(.{ component.Position, component.PlayerControl }, .{});
198+
var iter = view.iterator();
199+
while (iter.next()) |entity| {
200+
const pos = view.getConst(component.Position, entity);
201+
try map.computeFOV(&map.visible, pos.pos, 8);
202+
}
203+
149204
for (map.visible.items()) |entry| {
150205
try map.explored.put(entry.key, .{});
151206
}
@@ -159,13 +214,24 @@ pub fn render(alpha: f64) !void {
159214
gl.viewport(0, 0, screen_size.x, screen_size.y);
160215

161216
const cam_size = screen_size.intToFloat(f32);
162-
const cam_pos = playerPos.scale(16).intToFloat(f32).subv(cam_size.scaleDiv(2));
217+
const cam_pos = camPos.scale(16).intToFloat(f32).subv(cam_size.scaleDiv(2));
163218

164219
gl.enable(gl.SCISSOR_TEST);
165220
gl.scissor(0, 0, screen_size.x, screen_size.y - 50);
166221
flatRenderer.perspective = Mat4f.orthographic(cam_pos.x, cam_pos.x + cam_size.x, cam_pos.y + cam_size.y, cam_pos.y, -1, 1);
167222
map.render(&flatRenderer);
168-
render_tile(&flatRenderer, .{ .pos = 25 }, playerPos, 1);
223+
224+
// Render entities
225+
{
226+
var view = registry.view(.{ component.Position, component.Render }, .{});
227+
var iter = view.iterator();
228+
while (iter.next()) |entity| {
229+
const pos = view.getConst(component.Position, entity);
230+
const r = view.getConst(component.Render, entity);
231+
render_tile(&flatRenderer, .{ .pos = r.tid }, pos.pos, 1);
232+
}
233+
}
234+
169235
flatRenderer.flush();
170236

171237
gl.disable(gl.SCISSOR_TEST);

src/map.zig

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,11 @@ pub const Map = struct {
129129
}
130130
}
131131

132-
pub fn computeFOV(this: @This(), startingPos: Vec2i, radius: i64) !std.AutoArrayHashMap(Vec2i, void) {
132+
pub fn computeFOV(this: @This(), fov: *std.AutoArrayHashMap(Vec2i, void), startingPos: Vec2i, radius: i64) !void {
133133
var positions_to_check = ArrayDeque(Vec2i).init(this.allocator);
134134
defer positions_to_check.deinit();
135135
try positions_to_check.push_back(startingPos);
136136

137-
var fov = std.AutoArrayHashMap(Vec2i, void).init(this.allocator);
138-
errdefer fov.deinit();
139-
140137
while (positions_to_check.pop_front()) |pos| {
141138
const dist = pos.distance(startingPos);
142139
if (dist > radius) {
@@ -167,7 +164,5 @@ pub const Map = struct {
167164
}
168165
}
169166
}
170-
171-
return fov;
172167
}
173168
};

zig.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@ dependencies:
99
version: branch-wasm
1010
name: zigimg
1111
main: zigimg.zig
12+
- type: git
13+
path: https://github.com/prime31/zig-ecs.git
14+
name: ecs
15+
main: src/ecs.zig
1216

0 commit comments

Comments
 (0)