add doors and keys

This commit is contained in:
Rokas Puzonas 2025-12-15 00:15:45 +02:00
parent 73fbbafbfc
commit df027f34cd
5 changed files with 94 additions and 22 deletions

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.11.2" orientation="orthogonal" renderorder="right-down" width="20" height="15" tilewidth="8" tileheight="8" infinite="0" nextlayerid="3" nextobjectid="1"> <map version="1.10" tiledversion="1.11.2" orientation="orthogonal" renderorder="right-down" width="20" height="15" tilewidth="8" tileheight="8" infinite="0" nextlayerid="4" nextobjectid="1">
<tileset firstgid="1" source="tileset.tsx"/> <tileset firstgid="1" source="tileset.tsx"/>
<layer id="1" name="Actors" width="20" height="15"> <layer id="1" name="Actors" width="20" height="15">
<data encoding="csv"> <data encoding="csv">
@ -7,15 +7,15 @@
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,91,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,5,0,0,0,41,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,40,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,53,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data> </data>
@ -35,10 +35,10 @@
0,0,0,0,17,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0, 0,0,0,0,17,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,
0,0,0,0,17,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0, 0,0,0,0,17,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,
0,0,0,0,17,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0, 0,0,0,0,17,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,
0,0,0,0,83,2,2,68,2,2,2,37,67,36,0,0,0,0,0,0, 0,0,0,0,83,2,2,68,0,2,2,2,67,36,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,17,0,0,0,20,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,17,0,0,0,20,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,33,2,2,2,36,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data> </data>
</layer> </layer>

View File

@ -6,9 +6,19 @@
<property name="type" value="player"/> <property name="type" value="player"/>
</properties> </properties>
</tile> </tile>
<tile id="39">
<properties>
<property name="type" value="locked_door"/>
</properties>
</tile>
<tile id="40"> <tile id="40">
<properties> <properties>
<property name="type" value="pot"/> <property name="type" value="pot"/>
</properties> </properties>
</tile> </tile>
<tile id="90">
<properties>
<property name="type" value="key"/>
</properties>
</tile>
</tileset> </tileset>

View File

@ -15,11 +15,15 @@ pub const Type = enum {
player, player,
solid, solid,
pot, pot,
door,
key,
}; };
type: Type, type: Type,
position: Vec2, position: Vec2,
locked: bool = false,
render_tile: ?union(enum) { render_tile: ?union(enum) {
position: Vec2, position: Vec2,
id: Gfx.TileId id: Gfx.TileId

View File

@ -132,6 +132,11 @@ fn loadLevelFromTiled(gpa: Allocator, map: tiled.Map) !Level {
}; };
if (std.mem.eql(u8, tile_type, "player")) { if (std.mem.eql(u8, tile_type, "player")) {
entity.type = .player; entity.type = .player;
} else if (std.mem.eql(u8, tile_type, "key")) {
entity.type = .key;
} else if (std.mem.eql(u8, tile_type, "locked_door")) {
entity.type = .door;
entity.locked = true;
} else if (std.mem.eql(u8, tile_type, "pot")) { } else if (std.mem.eql(u8, tile_type, "pot")) {
entity.type = .pot; entity.type = .pot;
} else if (is_layer_solid) { } else if (is_layer_solid) {
@ -214,7 +219,9 @@ fn canMove(self: *Game, entity: *Entity, dir: Vec2) bool {
return true; return true;
} }
fn moveEntity(self: *Game, entity: *Entity, dir: Vec2) bool { fn moveEntity(self: *Game, entity_id: Entity.Id, dir: Vec2) bool {
const entity = self.level.entities.get(entity_id) orelse return true;
if (entity.type == .solid) { if (entity.type == .solid) {
return false; return false;
} }
@ -226,7 +233,21 @@ fn moveEntity(self: *Game, entity: *Entity, dir: Vec2) bool {
const next_pos = entity.position.add(dir); const next_pos = entity.position.add(dir);
if (self.getEntityAt(next_pos)) |next_entity_id| { if (self.getEntityAt(next_pos)) |next_entity_id| {
const next_entity = self.level.entities.getAssumeExists(next_entity_id); const next_entity = self.level.entities.getAssumeExists(next_entity_id);
if (!self.moveEntity(next_entity, dir)) { if (next_entity.type == .door and next_entity.locked and entity.type == .key) {
_ = self.level.entities.removeAssumeExists(entity_id);
next_entity.locked = false;
return true;
}
if (next_entity.type == .pot or next_entity.type == .key) {
if (!self.moveEntity(next_entity_id, dir)) {
return false;
}
} else if (next_entity.type == .door) {
if (next_entity.locked) {
return false;
}
} else if (next_entity.type == .nil) {
return false; return false;
} }
} }
@ -251,6 +272,26 @@ pub fn getInput(self: *Game, window: *Window) Input {
}; };
} }
fn drawEntity(self: *Game, entity: *Entity) void {
_ = self; // autofix
if (entity.render_tile) |render_tile| {
var tile_coord = switch (render_tile) {
.id => |tile_id| Gfx.getTileCoords(tile_id),
.position => |position| position
};
if (entity.type == .door) {
if (entity.locked) {
tile_coord = Gfx.getTileCoords(.locked_door);
} else {
tile_coord = Gfx.getTileCoords(.open_door);
}
}
Gfx.drawTile(tile_coord, entity.position, .init(1,1), rgb(255, 255, 255));
}
}
pub fn tick(self: *Game, input: Input) !void { pub fn tick(self: *Game, input: Input) !void {
Gfx.drawRectangle(.init(0, 0), .init(self.canvas_size.x, self.canvas_size.y), rgb_hex("#222323").?); Gfx.drawRectangle(.init(0, 0), .init(self.canvas_size.x, self.canvas_size.y), rgb_hex("#222323").?);
if (self.show_grid) { if (self.show_grid) {
@ -284,16 +325,25 @@ pub fn tick(self: *Game, input: Input) !void {
} }
var iter = self.level.entities.iterator(); var iter = self.level.entities.iterator();
while (iter.next()) |tuple| {
const entity = tuple.item;
const entity_id = tuple.id;
if (entity.type == .player) {
_ = self.moveEntity(entity_id, move);
}
}
iter = self.level.entities.iterator();
while (iter.nextItem()) |entity| {
if (entity.type != .player) {
self.drawEntity(entity);
}
}
iter = self.level.entities.iterator();
while (iter.nextItem()) |entity| { while (iter.nextItem()) |entity| {
if (entity.type == .player) { if (entity.type == .player) {
_ = self.moveEntity(entity, move); self.drawEntity(entity);
}
if (entity.render_tile) |render_tile| {
switch (render_tile) {
.id => |tile_id| Gfx.drawTileById(tile_id, entity.position, .init(1,1), rgb(255, 255, 255)),
.position => |position| Gfx.drawTile(position, entity.position, .init(1,1), rgb(255, 255, 255)),
}
} }
} }
} }

View File

@ -455,7 +455,9 @@ pub const ImageId = enum {
}; };
pub const TileId = enum { pub const TileId = enum {
player player,
open_door,
locked_door
}; };
pub const Borders = struct { pub const Borders = struct {
@ -843,7 +845,9 @@ pub fn init(options: Options) !void {
tilemap_size = Vec2.init(@floatFromInt(tilemap.width), @floatFromInt(tilemap.height)); tilemap_size = Vec2.init(@floatFromInt(tilemap.width), @floatFromInt(tilemap.height));
tile_coords = .init(.{ tile_coords = .init(.{
.player = .init(4, 0) .player = .init(4, 0),
.locked_door = .init(7, 2),
.open_door = .init(5, 2)
}); });
var image_iter = image_map.iterator(); var image_iter = image_map.iterator();
@ -983,6 +987,10 @@ pub fn drawTileById(tile_id: TileId, pos: Vec2, size: Vec2, tint: Vec4) void {
drawTile(tile_coord, pos, size, tint); drawTile(tile_coord, pos, size, tint);
} }
pub fn getTileCoords(tile_id: TileId) Vec2 {
return tile_coords.get(tile_id);
}
pub fn drawRectanglOutline(pos: Vec2, size: Vec2, color: Vec4, width: f32) void { pub fn drawRectanglOutline(pos: Vec2, size: Vec2, color: Vec4, width: f32) void {
// TODO: Don't use line segments // TODO: Don't use line segments
drawLine(pos, pos.add(.{ .x = size.x, .y = 0 }), color, width); drawLine(pos, pos.add(.{ .x = size.x, .y = 0 }), color, width);