add background
This commit is contained in:
parent
beeacdc701
commit
a4d803fc57
@ -136,6 +136,7 @@ pub const TileVariant = struct {
|
|||||||
const encoded_tiles = try lexer.nextExpectText();
|
const encoded_tiles = try lexer.nextExpectText();
|
||||||
const tiles = try parseEncoding(encoding, scratch.allocator(), encoded_tiles);
|
const tiles = try parseEncoding(encoding, scratch.allocator(), encoded_tiles);
|
||||||
try temp_tiles.appendSlice(scratch.allocator(), tiles.items);
|
try temp_tiles.appendSlice(scratch.allocator(), tiles.items);
|
||||||
|
continue;
|
||||||
|
|
||||||
} else if (node.isTag("chunk")) {
|
} else if (node.isTag("chunk")) {
|
||||||
const chunk = try initChunkDataFromXml(arena, scratch, lexer, encoding);
|
const chunk = try initChunkDataFromXml(arena, scratch, lexer, encoding);
|
||||||
@ -158,7 +159,6 @@ pub const TileVariant = struct {
|
|||||||
.fixed = try arena.dupe(u32, temp_tiles.items)
|
.fixed = try arena.dupe(u32, temp_tiles.items)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseEncoding(
|
fn parseEncoding(
|
||||||
|
|||||||
@ -73,6 +73,9 @@ pub const TilesetReference = struct {
|
|||||||
pub const Tile = struct {
|
pub const Tile = struct {
|
||||||
tileset: *const Tileset,
|
tileset: *const Tileset,
|
||||||
id: u32,
|
id: u32,
|
||||||
|
flip_horizontal: bool,
|
||||||
|
flip_vertical: bool,
|
||||||
|
flip_diagonal: bool,
|
||||||
|
|
||||||
pub fn getProperties(self: Tile) Property.List {
|
pub fn getProperties(self: Tile) Property.List {
|
||||||
return self.tileset.getTileProperties(self.id) orelse .empty;
|
return self.tileset.getTileProperties(self.id) orelse .empty;
|
||||||
@ -216,13 +219,19 @@ fn getTilesetByGid(self: *const Tilemap, gid: u32) ?TilesetReference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getTile(self: *const Tilemap, tilesets: Tileset.List, gid: u32) ?Tile {
|
pub fn getTile(self: *const Tilemap, tilesets: Tileset.List, gid: u32) ?Tile {
|
||||||
const tileset_ref = self.getTilesetByGid(gid & GlobalTileId.Flag.clear) orelse return null;
|
const Flag = GlobalTileId.Flag;
|
||||||
|
|
||||||
|
const gid_without_flags = gid & Flag.clear;
|
||||||
|
const tileset_ref = self.getTilesetByGid(gid_without_flags) orelse return null;
|
||||||
const tileset = tilesets.get(tileset_ref.source) orelse return null;
|
const tileset = tilesets.get(tileset_ref.source) orelse return null;
|
||||||
const id = gid - tileset_ref.first_gid;
|
const id = gid_without_flags - tileset_ref.first_gid;
|
||||||
|
|
||||||
return Tile{
|
return Tile{
|
||||||
.tileset = tileset,
|
.tileset = tileset,
|
||||||
.id = id
|
.id = id,
|
||||||
|
.flip_horizontal = (gid & @intFromEnum(Flag.flipped_horizontally)) > 0,
|
||||||
|
.flip_vertical = (gid & @intFromEnum(Flag.flipped_vertically)) > 0,
|
||||||
|
.flip_diagonal = (gid & @intFromEnum(Flag.flipped_diagonally)) > 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
166
src/assets.zig
166
src/assets.zig
@ -24,7 +24,6 @@ pub const Tilemap = struct {
|
|||||||
texture: Gfx.TextureId,
|
texture: Gfx.TextureId,
|
||||||
tile_size: Engine.Vec2,
|
tile_size: Engine.Vec2,
|
||||||
|
|
||||||
|
|
||||||
pub fn getTileUV(self: Tilemap, tile_x: f32, tile_y: f32) Rect {
|
pub fn getTileUV(self: Tilemap, tile_x: f32, tile_y: f32) Rect {
|
||||||
const texture_info = Engine.Graphics.getTextureInfo(self.texture);
|
const texture_info = Engine.Graphics.getTextureInfo(self.texture);
|
||||||
const tilemap_size = Vec2.initFromInt(u32, texture_info.width, texture_info.height);
|
const tilemap_size = Vec2.initFromInt(u32, texture_info.width, texture_info.height);
|
||||||
@ -39,14 +38,17 @@ pub const Tilemap = struct {
|
|||||||
arena: std.heap.ArenaAllocator,
|
arena: std.heap.ArenaAllocator,
|
||||||
|
|
||||||
font_id: FontName.EnumArray,
|
font_id: FontName.EnumArray,
|
||||||
wood01: Audio.Data.Id,
|
pistol_mask: Gfx.TextureId,
|
||||||
|
bomb_mask: Gfx.TextureId,
|
||||||
|
laser_mask: Gfx.TextureId,
|
||||||
|
dungeon_tilemap: Tilemap,
|
||||||
|
|
||||||
|
skeleton: Gfx.Sprite,
|
||||||
|
snake: Gfx.Sprite,
|
||||||
|
fire_spirit: Gfx.Sprite,
|
||||||
|
|
||||||
map: tiled.Tilemap,
|
map: tiled.Tilemap,
|
||||||
tilesets: tiled.Tileset.List,
|
tilesets: tiled.Tileset.List,
|
||||||
move_sound: []Audio.Data.Id,
|
|
||||||
|
|
||||||
terrain_tilemap: Tilemap,
|
|
||||||
players_tilemap: Tilemap,
|
|
||||||
weapons_tilemap: Tilemap,
|
|
||||||
|
|
||||||
pub fn init(gpa: std.mem.Allocator) !Assets {
|
pub fn init(gpa: std.mem.Allocator) !Assets {
|
||||||
var arena = std.heap.ArenaAllocator.init(gpa);
|
var arena = std.heap.ArenaAllocator.init(gpa);
|
||||||
@ -58,11 +60,83 @@ pub fn init(gpa: std.mem.Allocator) !Assets {
|
|||||||
.italic = try Gfx.addFont("italic", @embedFile("assets/roboto-font/Roboto-Italic.ttf")),
|
.italic = try Gfx.addFont("italic", @embedFile("assets/roboto-font/Roboto-Italic.ttf")),
|
||||||
});
|
});
|
||||||
|
|
||||||
const wood01 = try Audio.load(.{
|
const pistol_mask_image = try STBImage.load(@embedFile("assets/pistol-mask.png"));
|
||||||
.format = .vorbis,
|
defer pistol_mask_image.deinit();
|
||||||
.data = @embedFile("assets/wood01.ogg"),
|
const pistol_mask_texture = try Gfx.addTexture(&.{
|
||||||
|
.{
|
||||||
|
.width = pistol_mask_image.width,
|
||||||
|
.height = pistol_mask_image.height,
|
||||||
|
.rgba = pistol_mask_image.rgba8_pixels
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const bomb_mask_image = try STBImage.load(@embedFile("assets/bomb-mask.png"));
|
||||||
|
defer bomb_mask_image.deinit();
|
||||||
|
const bomb_mask_texture = try Gfx.addTexture(&.{
|
||||||
|
.{
|
||||||
|
.width = bomb_mask_image.width,
|
||||||
|
.height = bomb_mask_image.height,
|
||||||
|
.rgba = bomb_mask_image.rgba8_pixels
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const laser_mask_image = try STBImage.load(@embedFile("assets/laser-mask.png"));
|
||||||
|
defer laser_mask_image.deinit();
|
||||||
|
const laser_mask_texture = try Gfx.addTexture(&.{
|
||||||
|
.{
|
||||||
|
.width = laser_mask_image.width,
|
||||||
|
.height = laser_mask_image.height,
|
||||||
|
.rgba = laser_mask_image.rgba8_pixels
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const creatures_image = try STBImage.load(@embedFile("assets/tiny-creatures/tilemap_packed.png"));
|
||||||
|
defer creatures_image.deinit();
|
||||||
|
const creatures_texture = try Gfx.addTexture(&.{
|
||||||
|
.{
|
||||||
|
.width = creatures_image.width,
|
||||||
|
.height = creatures_image.height,
|
||||||
|
.rgba = creatures_image.rgba8_pixels
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const snake_image = try STBImage.load(@embedFile("assets/snake.png"));
|
||||||
|
defer snake_image.deinit();
|
||||||
|
const snake_texture = try Gfx.addTexture(&.{
|
||||||
|
.{
|
||||||
|
.width = snake_image.width,
|
||||||
|
.height = snake_image.height,
|
||||||
|
.rgba = snake_image.rgba8_pixels
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const fire_spirit_image = try STBImage.load(@embedFile("assets/fire-spirit.png"));
|
||||||
|
defer fire_spirit_image.deinit();
|
||||||
|
const fire_spirit_texture = try Gfx.addTexture(&.{
|
||||||
|
.{
|
||||||
|
.width = fire_spirit_image.width,
|
||||||
|
.height = fire_spirit_image.height,
|
||||||
|
.rgba = fire_spirit_image.rgba8_pixels
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const creatures_tilemap = Tilemap{
|
||||||
|
.texture = creatures_texture,
|
||||||
|
.tile_size = .init(16, 16)
|
||||||
|
};
|
||||||
|
const snake = Gfx.Sprite{
|
||||||
|
.texture = snake_texture,
|
||||||
|
.uv = .unit
|
||||||
|
};
|
||||||
|
const skeleton = Gfx.Sprite{
|
||||||
|
.texture = creatures_texture,
|
||||||
|
.uv = creatures_tilemap.getTileUV(1, 0)
|
||||||
|
};
|
||||||
|
const fire_spirit = Gfx.Sprite{
|
||||||
|
.texture = fire_spirit_texture,
|
||||||
|
.uv = .unit
|
||||||
|
};
|
||||||
|
|
||||||
var scratch = std.heap.ArenaAllocator.init(gpa);
|
var scratch = std.heap.ArenaAllocator.init(gpa);
|
||||||
defer scratch.deinit();
|
defer scratch.deinit();
|
||||||
|
|
||||||
@ -80,76 +154,42 @@ pub fn init(gpa: std.mem.Allocator) !Assets {
|
|||||||
gpa,
|
gpa,
|
||||||
&scratch,
|
&scratch,
|
||||||
&xml_buffers,
|
&xml_buffers,
|
||||||
@embedFile("assets/tileset.tsx")
|
@embedFile("assets/dungeon.tsx")
|
||||||
);
|
);
|
||||||
|
|
||||||
var tilesets: tiled.Tileset.List = .empty;
|
var tilesets: tiled.Tileset.List = .empty;
|
||||||
try tilesets.add(gpa, "tilemap.tsx", tileset);
|
try tilesets.add(gpa, "dungeon.tsx", tileset);
|
||||||
|
|
||||||
const players_image = try STBImage.load(@embedFile("assets/kenney_desert-shooter-pack_1.0/PNG/Players/tilemap_packed.png"));
|
const dungeon_image = try STBImage.load(@embedFile("assets/tiny-dungeon/tilemap_packed.png"));
|
||||||
defer players_image.deinit();
|
defer dungeon_image.deinit();
|
||||||
const players_texture = try Gfx.addTexture(&.{
|
const dungeon_texture = try Gfx.addTexture(&.{
|
||||||
.{
|
.{
|
||||||
.width = players_image.width,
|
.width = dungeon_image.width,
|
||||||
.height = players_image.height,
|
.height = dungeon_image.height,
|
||||||
.rgba = players_image.rgba8_pixels
|
.rgba = dungeon_image.rgba8_pixels
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const tileset_image = try STBImage.load(@embedFile("assets/kenney_desert-shooter-pack_1.0/PNG/Tiles/tilemap_packed.png"));
|
|
||||||
defer tileset_image.deinit();
|
|
||||||
const tileset_texture = try Gfx.addTexture(&.{
|
|
||||||
.{
|
|
||||||
.width = tileset_image.width,
|
|
||||||
.height = tileset_image.height,
|
|
||||||
.rgba = tileset_image.rgba8_pixels
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const weapons_tileset = try STBImage.load(@embedFile("assets/kenney_desert-shooter-pack_1.0/PNG/Weapons/tilemap_packed.png"));
|
|
||||||
defer weapons_tileset.deinit();
|
|
||||||
const weapons_texture = try Gfx.addTexture(&.{
|
|
||||||
.{
|
|
||||||
.width = weapons_tileset.width,
|
|
||||||
.height = weapons_tileset.height,
|
|
||||||
.rgba = weapons_tileset.rgba8_pixels
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const move_c = try Audio.load(.{
|
|
||||||
.data = @embedFile("assets/kenney_desert-shooter-pack_1.0/Sounds/move-c.ogg"),
|
|
||||||
.format = .vorbis,
|
|
||||||
});
|
|
||||||
const move_d = try Audio.load(.{
|
|
||||||
.data = @embedFile("assets/kenney_desert-shooter-pack_1.0/Sounds/move-d.ogg"),
|
|
||||||
.format = .vorbis,
|
|
||||||
});
|
|
||||||
const move_sound = try arena.allocator().dupe(Audio.Data.Id, &.{ move_c, move_d });
|
|
||||||
|
|
||||||
return Assets{
|
return Assets{
|
||||||
.arena = arena,
|
.arena = arena,
|
||||||
.font_id = font_id_array,
|
.font_id = font_id_array,
|
||||||
.wood01 = wood01,
|
.pistol_mask = pistol_mask_texture,
|
||||||
|
.bomb_mask = bomb_mask_texture,
|
||||||
|
.laser_mask = laser_mask_texture,
|
||||||
|
.snake = snake,
|
||||||
|
.skeleton = skeleton,
|
||||||
|
.fire_spirit = fire_spirit,
|
||||||
.map = map,
|
.map = map,
|
||||||
.tilesets = tilesets,
|
.tilesets = tilesets,
|
||||||
.move_sound = move_sound,
|
.dungeon_tilemap = .{
|
||||||
.terrain_tilemap = .{
|
.texture = dungeon_texture,
|
||||||
.texture = tileset_texture,
|
.tile_size = .init(16, 16)
|
||||||
.tile_size = .initFromInt(u32, tileset.tile_width, tileset.tile_height)
|
}
|
||||||
},
|
|
||||||
.players_tilemap = .{
|
|
||||||
.texture = players_texture,
|
|
||||||
.tile_size = .init(24, 24)
|
|
||||||
},
|
|
||||||
.weapons_tilemap = .{
|
|
||||||
.texture = weapons_texture,
|
|
||||||
.tile_size = .init(24, 24)
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Assets, gpa: std.mem.Allocator) void {
|
pub fn deinit(self: *Assets, gpa: std.mem.Allocator) void {
|
||||||
self.map.deinit();
|
|
||||||
self.tilesets.deinit(gpa);
|
self.tilesets.deinit(gpa);
|
||||||
|
self.map.deinit();
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
}
|
}
|
||||||
|
|||||||
4
src/assets/dungeon.tsx
Normal file
4
src/assets/dungeon.tsx
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<tileset version="1.10" tiledversion="1.11.2" name="dungeon" tilewidth="16" tileheight="16" tilecount="132" columns="12">
|
||||||
|
<image source="tiny-dungeon/tilemap_packed.png" width="192" height="176"/>
|
||||||
|
</tileset>
|
||||||
BIN
src/assets/fire-spirit.png
Normal file
BIN
src/assets/fire-spirit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 320 B |
14
src/assets/game.tiled-project
Normal file
14
src/assets/game.tiled-project
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"automappingRulesFile": "",
|
||||||
|
"commands": [
|
||||||
|
],
|
||||||
|
"compatibilityVersion": 1100,
|
||||||
|
"extensionsPath": "extensions",
|
||||||
|
"folders": [
|
||||||
|
"."
|
||||||
|
],
|
||||||
|
"properties": [
|
||||||
|
],
|
||||||
|
"propertyTypes": [
|
||||||
|
]
|
||||||
|
}
|
||||||
23
src/assets/map.tmx
Normal file
23
src/assets/map.tmx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?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="16" tileheight="16" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||||
|
<tileset firstgid="1" source="dungeon.tsx"/>
|
||||||
|
<layer id="1" name="Tile Layer 1" width="20" height="15">
|
||||||
|
<data encoding="csv">
|
||||||
|
2147483701,51,51,51,52,52,51,51,51,51,51,52,52,52,51,51,51,51,51,53,
|
||||||
|
536870963,49,49,49,49,49,49,49,49,50,50,50,50,50,49,49,49,49,49,2684354611,
|
||||||
|
1610612788,49,43,43,49,49,49,49,49,50,50,50,50,50,49,49,43,43,49,2684354611,
|
||||||
|
1610612788,49,43,43,49,49,50,49,49,49,50,50,50,50,49,49,43,43,50,2684354611,
|
||||||
|
1610612788,50,50,49,49,49,50,50,49,49,49,49,49,49,49,49,49,50,50,3758096436,
|
||||||
|
1610612788,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,50,3758096436,
|
||||||
|
1610612788,49,49,49,49,49,49,50,50,50,50,49,49,50,49,49,49,49,49,3758096436,
|
||||||
|
536870963,49,49,49,49,49,49,49,50,50,50,50,50,50,49,49,49,49,49,2684354611,
|
||||||
|
536870963,49,50,50,49,49,49,49,49,49,50,50,50,50,49,49,49,50,50,3758096436,
|
||||||
|
536870963,49,50,50,49,49,49,49,49,49,49,49,49,49,49,49,50,50,50,3758096436,
|
||||||
|
1610612788,50,50,49,49,49,49,50,50,49,49,49,49,49,49,50,50,50,49,2684354611,
|
||||||
|
1610612788,49,43,43,49,49,50,50,50,50,50,49,49,49,49,50,43,43,49,2684354611,
|
||||||
|
536870963,49,43,43,49,50,50,50,49,49,49,49,49,49,49,50,43,43,49,3758096436,
|
||||||
|
536870963,49,49,49,49,50,50,49,49,49,49,49,49,49,49,49,49,49,49,2684354611,
|
||||||
|
3221225525,1073741875,1073741875,1073741875,1073741875,1073741876,1073741876,1073741875,1073741875,1073741875,1073741875,1073741875,1073741875,1073741876,1073741876,1073741875,1073741875,1073741875,1073741876,1073741877
|
||||||
|
</data>
|
||||||
|
</layer>
|
||||||
|
</map>
|
||||||
BIN
src/assets/snake.png
Normal file
BIN
src/assets/snake.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 406 B |
22
src/assets/tiny-dungeon/License.txt
Normal file
22
src/assets/tiny-dungeon/License.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Tiny Dungeon (1.0)
|
||||||
|
|
||||||
|
Created/distributed by Kenney (www.kenney.nl)
|
||||||
|
Creation date: 05-07-2022
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
License: (Creative Commons Zero, CC0)
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
|
This content is free to use in personal, educational and commercial projects.
|
||||||
|
Support us by crediting Kenney or www.kenney.nl (this is not mandatory)
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Donate: http://support.kenney.nl
|
||||||
|
Patreon: http://patreon.com/kenney/
|
||||||
|
|
||||||
|
Follow on Twitter for updates:
|
||||||
|
http://twitter.com/KenneyNL
|
||||||
9
src/assets/tiny-dungeon/Tilesheet.txt
Normal file
9
src/assets/tiny-dungeon/Tilesheet.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Tilesheet information:
|
||||||
|
|
||||||
|
Tile size • 16px × 16px
|
||||||
|
Space between tiles • 1px × 1px
|
||||||
|
---
|
||||||
|
Total tiles (horizontal) • 12 tiles
|
||||||
|
Total tiles (vertical) • 11 tiles
|
||||||
|
---
|
||||||
|
Total tiles in sheet • 132 tiles
|
||||||
BIN
src/assets/tiny-dungeon/tilemap_packed.png
Normal file
BIN
src/assets/tiny-dungeon/tilemap_packed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
@ -10,6 +10,7 @@ const GenerationalArrayList = @import("./generational_array_list.zig").Generatio
|
|||||||
const Engine = @import("./engine/root.zig");
|
const Engine = @import("./engine/root.zig");
|
||||||
const Nanoseconds = Engine.Nanoseconds;
|
const Nanoseconds = Engine.Nanoseconds;
|
||||||
const Vec2 = Engine.Vec2;
|
const Vec2 = Engine.Vec2;
|
||||||
|
const Sprite = Engine.Graphics.Sprite;
|
||||||
const Line = Engine.Math.Line;
|
const Line = Engine.Math.Line;
|
||||||
const Rect = Engine.Math.Rect;
|
const Rect = Engine.Math.Rect;
|
||||||
const Range = Engine.Math.Range;
|
const Range = Engine.Math.Range;
|
||||||
@ -55,10 +56,11 @@ const Player = struct {
|
|||||||
max_health: u32 = 0,
|
max_health: u32 = 0,
|
||||||
last_shot_at: ?Nanoseconds = null,
|
last_shot_at: ?Nanoseconds = null,
|
||||||
invincible_until: ?Nanoseconds = null,
|
invincible_until: ?Nanoseconds = null,
|
||||||
gun: ?Gun = null,
|
gun: Gun = .pistol,
|
||||||
|
|
||||||
pub fn getRect(self: Player) Rect {
|
pub fn getRect(self: Player) Rect {
|
||||||
return getCenteredRect(self.kinetic.pos, 16);
|
const pos = self.kinetic.pos;
|
||||||
|
return Rect.initCentered(pos.x, pos.y, 16, 24);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,6 +92,8 @@ const Enemy = struct {
|
|||||||
kinetic: Kinetic,
|
kinetic: Kinetic,
|
||||||
speed: f32,
|
speed: f32,
|
||||||
size: f32,
|
size: f32,
|
||||||
|
sprite: Sprite,
|
||||||
|
|
||||||
target: ?Vec2 = null,
|
target: ?Vec2 = null,
|
||||||
distance_to_target: ?f32 = null,
|
distance_to_target: ?f32 = null,
|
||||||
|
|
||||||
@ -147,18 +151,8 @@ const Wave = struct {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const Pickup = struct {
|
|
||||||
const Kind = enum {
|
|
||||||
money
|
|
||||||
};
|
|
||||||
|
|
||||||
pos: Vec2,
|
|
||||||
kind: Kind,
|
|
||||||
};
|
|
||||||
|
|
||||||
const world_size = Vec2.init(20 * 16, 15 * 16);
|
const world_size = Vec2.init(20 * 16, 15 * 16);
|
||||||
const invincibility_duration_s = 0.5;
|
const invincibility_duration_s = 0.5;
|
||||||
const pickup_spawn_duration_s = Range.init(1, 5);
|
|
||||||
const wave_infos = [_]Wave.Info{
|
const wave_infos = [_]Wave.Info{
|
||||||
.{
|
.{
|
||||||
.kind = .regular,
|
.kind = .regular,
|
||||||
@ -196,24 +190,15 @@ bullets: std.ArrayList(Bullet) = .empty,
|
|||||||
lasers: std.ArrayList(Laser) = .empty,
|
lasers: std.ArrayList(Laser) = .empty,
|
||||||
bombs: std.ArrayList(Bomb) = .empty,
|
bombs: std.ArrayList(Bomb) = .empty,
|
||||||
|
|
||||||
pickups: std.ArrayList(Pickup) = .empty,
|
|
||||||
next_pickup_spawn_at: Nanoseconds,
|
|
||||||
|
|
||||||
wave_timer: Nanoseconds = 0,
|
wave_timer: Nanoseconds = 0,
|
||||||
|
|
||||||
waves: std.ArrayList(Wave) = .empty,
|
waves: std.ArrayList(Wave) = .empty,
|
||||||
spawned_waves: std.ArrayList(usize) = .empty,
|
spawned_waves: std.ArrayList(usize) = .empty,
|
||||||
|
|
||||||
pub fn init(gpa: Allocator, seed: u64, assets: *Assets, state: State) CombatScreen {
|
pub fn init(gpa: Allocator, seed: u64, assets: *Assets, state: State) CombatScreen {
|
||||||
var rng = RNGState.init(seed);
|
|
||||||
|
|
||||||
const next_pickup_spawn_at_s = pickup_spawn_duration_s.random(rng.random());
|
|
||||||
const next_pickup_spawn_at: Nanoseconds = @intFromFloat(next_pickup_spawn_at_s * std.time.ns_per_s);
|
|
||||||
|
|
||||||
return CombatScreen{
|
return CombatScreen{
|
||||||
.gpa = gpa,
|
.gpa = gpa,
|
||||||
.assets = assets,
|
.assets = assets,
|
||||||
.next_pickup_spawn_at = next_pickup_spawn_at,
|
|
||||||
.player = .{
|
.player = .{
|
||||||
.kinetic = .{
|
.kinetic = .{
|
||||||
.pos = world_size.divideScalar(2)
|
.pos = world_size.divideScalar(2)
|
||||||
@ -222,7 +207,7 @@ pub fn init(gpa: Allocator, seed: u64, assets: *Assets, state: State) CombatScre
|
|||||||
.health = state.max_health,
|
.health = state.max_health,
|
||||||
.max_health = state.max_health,
|
.max_health = state.max_health,
|
||||||
},
|
},
|
||||||
.rng = rng
|
.rng = RNGState.init(seed)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +220,6 @@ pub fn deinit(self: *CombatScreen) void {
|
|||||||
self.bullets.deinit(self.gpa);
|
self.bullets.deinit(self.gpa);
|
||||||
self.enemies.deinit(self.gpa);
|
self.enemies.deinit(self.gpa);
|
||||||
self.waves.deinit(self.gpa);
|
self.waves.deinit(self.gpa);
|
||||||
self.pickups.deinit(self.gpa);
|
|
||||||
self.spawned_waves.deinit(self.gpa);
|
self.spawned_waves.deinit(self.gpa);
|
||||||
self.lasers.deinit(self.gpa);
|
self.lasers.deinit(self.gpa);
|
||||||
self.bombs.deinit(self.gpa);
|
self.bombs.deinit(self.gpa);
|
||||||
@ -244,6 +228,7 @@ pub fn deinit(self: *CombatScreen) void {
|
|||||||
|
|
||||||
const EnemyOptions = struct {
|
const EnemyOptions = struct {
|
||||||
pos: ?Vec2 = null,
|
pos: ?Vec2 = null,
|
||||||
|
sprite: Sprite,
|
||||||
size: f32 = 20
|
size: f32 = 20
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -290,18 +275,8 @@ pub fn spawnEnemy(self: *CombatScreen, opts: EnemyOptions) !Enemy.Id {
|
|||||||
return try self.enemies.insert(self.gpa, Enemy{
|
return try self.enemies.insert(self.gpa, Enemy{
|
||||||
.kinetic = .{ .pos = pos },
|
.kinetic = .{ .pos = pos },
|
||||||
.speed = 50,
|
.speed = 50,
|
||||||
.size = opts.size
|
.size = opts.size,
|
||||||
});
|
.sprite = opts.sprite
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawnPickup(self: *CombatScreen) !void {
|
|
||||||
const margin = 10;
|
|
||||||
const spawn_area = (Rect{ .pos = .zero, .size = world_size }).grow(-margin);
|
|
||||||
const pos = Vec2.initRandomRect(self.rng.random(), spawn_area);
|
|
||||||
|
|
||||||
try self.pickups.append(self.gpa, Pickup{
|
|
||||||
.pos = pos,
|
|
||||||
.kind = .money
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +285,49 @@ const TickResult = struct {
|
|||||||
player_finished: bool
|
player_finished: bool
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn drawMap(self: *CombatScreen, frame: *Engine.Frame) void {
|
||||||
|
const tilemap = self.assets.dungeon_tilemap;
|
||||||
|
const texture_info = Engine.Graphics.getTextureInfo(tilemap.texture);
|
||||||
|
const tilemap_size = Vec2.initFromInt(u32, texture_info.width, texture_info.height);
|
||||||
|
|
||||||
|
for (self.assets.map.layers) |layer| {
|
||||||
|
if (layer.variant != .tile) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tile_layer = layer.variant.tile;
|
||||||
|
for (0..tile_layer.height) |y| {
|
||||||
|
for (0..tile_layer.width) |x| {
|
||||||
|
const tile_gid = tile_layer.get(@intCast(x), @intCast(y)) orelse continue;
|
||||||
|
if (tile_gid == 0) continue;
|
||||||
|
|
||||||
|
const tile = self.assets.map.getTile(self.assets.tilesets, tile_gid) orelse continue;
|
||||||
|
const tile_id_f32: f32 = @floatFromInt(tile.id);
|
||||||
|
const width_in_tiles = tilemap_size.x / tilemap.tile_size.x;
|
||||||
|
const tile_x = @rem(tile_id_f32, width_in_tiles);
|
||||||
|
const tile_y = @divFloor(tile_id_f32, width_in_tiles);
|
||||||
|
|
||||||
|
frame.drawRectangle(.{
|
||||||
|
.rect = .{
|
||||||
|
.pos = Vec2.initFromInt(usize, x, y).multiply(tilemap.tile_size),
|
||||||
|
.size = tilemap.tile_size
|
||||||
|
},
|
||||||
|
.color = rgb(255, 255, 255),
|
||||||
|
.sprite = .{
|
||||||
|
.texture = tilemap.texture,
|
||||||
|
.uv = tilemap.getTileUV(tile_x, tile_y)
|
||||||
|
},
|
||||||
|
.uv_flip_diagonal = tile.flip_diagonal,
|
||||||
|
.uv_flip_vertical = tile.flip_vertical,
|
||||||
|
.uv_flip_horizontal = tile.flip_horizontal,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResult {
|
pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResult {
|
||||||
|
|
||||||
const dt = frame.deltaTime();
|
const dt = frame.deltaTime();
|
||||||
|
|
||||||
var result = TickResult{
|
var result = TickResult{
|
||||||
@ -357,7 +374,9 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
|
|||||||
while (wave.enemies_spawned < expected_enemies) {
|
while (wave.enemies_spawned < expected_enemies) {
|
||||||
switch (wave.kind) {
|
switch (wave.kind) {
|
||||||
.regular => {
|
.regular => {
|
||||||
_ = try self.spawnEnemy(.{});
|
_ = try self.spawnEnemy(.{
|
||||||
|
.sprite = self.assets.skeleton
|
||||||
|
});
|
||||||
},
|
},
|
||||||
.snake => {
|
.snake => {
|
||||||
var arena = std.heap.ArenaAllocator.init(self.gpa);
|
var arena = std.heap.ArenaAllocator.init(self.gpa);
|
||||||
@ -367,7 +386,9 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
|
|||||||
const rand = self.rng.random();
|
const rand = self.rng.random();
|
||||||
const snake_length = rand.intRangeAtMost(u32, wave.min_group_size, wave.max_group_size);
|
const snake_length = rand.intRangeAtMost(u32, wave.min_group_size, wave.max_group_size);
|
||||||
|
|
||||||
const head_id = try self.spawnEnemy(.{ });
|
const head_id = try self.spawnEnemy(.{
|
||||||
|
.sprite = self.assets.snake
|
||||||
|
});
|
||||||
try enemies.append(arena.allocator(), head_id);
|
try enemies.append(arena.allocator(), head_id);
|
||||||
|
|
||||||
const head = self.enemies.getAssumeExists(head_id);
|
const head = self.enemies.getAssumeExists(head_id);
|
||||||
@ -379,6 +400,7 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
|
|||||||
for (0..snake_length) |i| {
|
for (0..snake_length) |i| {
|
||||||
const tail_pos = head_pos.sub(dir_to_center.multiplyScalar(@floatFromInt(i * gap)));
|
const tail_pos = head_pos.sub(dir_to_center.multiplyScalar(@floatFromInt(i * gap)));
|
||||||
const tail_id = try self.spawnEnemy(.{
|
const tail_id = try self.spawnEnemy(.{
|
||||||
|
.sprite = self.assets.snake,
|
||||||
.pos = tail_pos
|
.pos = tail_pos
|
||||||
});
|
});
|
||||||
try enemies.append(arena.allocator(), tail_id);
|
try enemies.append(arena.allocator(), tail_id);
|
||||||
@ -407,6 +429,7 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
|
|||||||
|
|
||||||
const enemy_id = try self.spawnEnemy(.{
|
const enemy_id = try self.spawnEnemy(.{
|
||||||
.pos = center.add(Vec2.initAngle(angle).multiplyScalar(distance)),
|
.pos = center.add(Vec2.initAngle(angle).multiplyScalar(distance)),
|
||||||
|
.sprite = self.assets.fire_spirit,
|
||||||
.size = 10
|
.size = 10
|
||||||
});
|
});
|
||||||
try enemies.append(arena.allocator(), enemy_id);
|
try enemies.append(arena.allocator(), enemy_id);
|
||||||
@ -434,19 +457,9 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.wave_timer >= self.next_pickup_spawn_at) {
|
|
||||||
const next_pickup_spawn_at_s = pickup_spawn_duration_s.random(self.rng.random());
|
|
||||||
const next_pickup_spawn_at: Nanoseconds = @intFromFloat(next_pickup_spawn_at_s * std.time.ns_per_s);
|
|
||||||
self.next_pickup_spawn_at = self.wave_timer + next_pickup_spawn_at;
|
|
||||||
try self.spawnPickup();
|
|
||||||
}
|
|
||||||
|
|
||||||
frame.graphics.canvas_size = world_size;
|
frame.graphics.canvas_size = world_size;
|
||||||
|
|
||||||
frame.drawRectangle(.{
|
self.drawMap(frame);
|
||||||
.rect = .init(0, 0, world_size.x, world_size.y),
|
|
||||||
.color = rgb(20, 20, 20)
|
|
||||||
});
|
|
||||||
|
|
||||||
var dir = Vec2.init(0, 0);
|
var dir = Vec2.init(0, 0);
|
||||||
if (frame.isKeyDown(.W)) {
|
if (frame.isKeyDown(.W)) {
|
||||||
@ -500,45 +513,52 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
|
|||||||
if (frame.isMouseDown(.left) and cooldown_complete) {
|
if (frame.isMouseDown(.left) and cooldown_complete) {
|
||||||
self.player.last_shot_at = frame.time_ns;
|
self.player.last_shot_at = frame.time_ns;
|
||||||
|
|
||||||
if (self.player.gun) |gun| {
|
switch (self.player.gun) {
|
||||||
switch (gun) {
|
.pistol => {
|
||||||
.pistol => {
|
try self.bullets.append(self.gpa, .{
|
||||||
try self.bullets.append(self.gpa, .{
|
.kinetic = .{
|
||||||
.kinetic = .{
|
.pos = self.player.kinetic.pos,
|
||||||
.pos = self.player.kinetic.pos,
|
},
|
||||||
},
|
.dir = bullet_dir,
|
||||||
.dir = bullet_dir,
|
.speed = 50
|
||||||
.speed = 50
|
});
|
||||||
});
|
},
|
||||||
},
|
.bomb => {
|
||||||
.bomb => {
|
try self.bombs.append(self.gpa, .{
|
||||||
try self.bombs.append(self.gpa, .{
|
.kinetic = .{
|
||||||
.kinetic = .{
|
.pos = self.player.kinetic.pos,
|
||||||
.pos = self.player.kinetic.pos,
|
.vel = bullet_dir.multiplyScalar(800)
|
||||||
.vel = bullet_dir.multiplyScalar(800)
|
},
|
||||||
},
|
.size = 10,
|
||||||
.size = 10,
|
.explode_at = frame.time_ns + std.time.ns_per_s,
|
||||||
.explode_at = frame.time_ns + std.time.ns_per_s,
|
.explosion_radius = 50
|
||||||
.explosion_radius = 50
|
});
|
||||||
});
|
},
|
||||||
},
|
.laser => {
|
||||||
.laser => {
|
try self.lasers.append(self.gpa, .{
|
||||||
try self.lasers.append(self.gpa, .{
|
.origin = self.player.kinetic.pos,
|
||||||
.origin = self.player.kinetic.pos,
|
.dir = bullet_dir,
|
||||||
.dir = bullet_dir,
|
.size = 10,
|
||||||
.size = 10,
|
.created_at = frame.time_ns,
|
||||||
.created_at = frame.time_ns,
|
.duration = std.time.ns_per_s
|
||||||
.duration = std.time.ns_per_s
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
frame.drawRectangle(.{
|
frame.drawRectangle(.{
|
||||||
.rect = self.player.getRect(),
|
.rect = self.player.getRect(),
|
||||||
.color = rgb(255, 255, 255)
|
.color = rgb(255, 255, 255),
|
||||||
|
.sprite = .{
|
||||||
|
.texture = switch (self.player.gun) {
|
||||||
|
.pistol => self.assets.pistol_mask,
|
||||||
|
.bomb => self.assets.bomb_mask,
|
||||||
|
.laser => self.assets.laser_mask,
|
||||||
|
},
|
||||||
|
.uv = .unit
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (self.bullets.items) |*bullet| {
|
for (self.bullets.items) |*bullet| {
|
||||||
@ -775,40 +795,19 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
|
|||||||
}
|
}
|
||||||
|
|
||||||
enemy.kinetic.update(dt, .{});
|
enemy.kinetic.update(dt, .{});
|
||||||
|
|
||||||
frame.drawRectangle(.{
|
frame.drawRectangle(.{
|
||||||
.rect = enemy_rect,
|
.rect = enemy_rect,
|
||||||
.color = rgb(20, 200, 20)
|
.color = rgba(20, 20, 200, 0.2),
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
var index: usize = 0;
|
|
||||||
while (index < self.pickups.items.len) {
|
|
||||||
var destroy: bool = false;
|
|
||||||
const pickup = self.pickups.items[index];
|
|
||||||
|
|
||||||
const pickup_rect = Rect.initCentered(pickup.pos.x, pickup.pos.y, 10, 10);
|
|
||||||
|
|
||||||
if (pickup_rect.hasOverlap(self.player.getRect())) {
|
|
||||||
switch (pickup.kind) {
|
|
||||||
.money => {
|
|
||||||
state.money += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
destroy = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const pos = enemy.kinetic.pos;
|
||||||
|
const sprite_size = enemy.sprite.getSize();
|
||||||
frame.drawRectangle(.{
|
frame.drawRectangle(.{
|
||||||
.rect = pickup_rect,
|
.rect = Rect.initCentered(pos.x, pos.y, sprite_size.x, sprite_size.y),
|
||||||
.color = rgb(20, 20, 200)
|
.color = rgb(255, 255, 255),
|
||||||
|
.sprite = enemy.sprite
|
||||||
});
|
});
|
||||||
|
|
||||||
if (destroy) {
|
|
||||||
_ = self.pickups.swapRemove(index);
|
|
||||||
} else {
|
|
||||||
index += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -842,7 +841,7 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
|
|||||||
|
|
||||||
frame.drawTextFormat(.init(10, 30), text_opts, "{d}", .{ state.money });
|
frame.drawTextFormat(.init(10, 30), text_opts, "{d}", .{ state.money });
|
||||||
frame.drawTextFormat(.init(10, 50), text_opts, "{d}/{d}", .{ self.player.health, self.player.max_health });
|
frame.drawTextFormat(.init(10, 50), text_opts, "{d}/{d}", .{ self.player.health, self.player.max_health });
|
||||||
frame.drawTextFormat(.init(10, 70), text_opts, "{?}", .{ self.player.gun });
|
frame.drawTextFormat(.init(10, 70), text_opts, "{}", .{ self.player.gun });
|
||||||
|
|
||||||
result.player_died = (self.player.health == 0);
|
result.player_died = (self.player.health == 0);
|
||||||
if (self.enemies.count == 0 and self.waves.items.len == 0 and self.spawned_waves.items.len == wave_infos.len) {
|
if (self.enemies.count == 0 and self.waves.items.len == 0 and self.spawned_waves.items.len == wave_infos.len) {
|
||||||
|
|||||||
@ -46,6 +46,9 @@ pub const Command = union(enum) {
|
|||||||
sprite: ?Sprite = null,
|
sprite: ?Sprite = null,
|
||||||
rotation: f32 = 0,
|
rotation: f32 = 0,
|
||||||
origin: Vec2 = .init(0, 0),
|
origin: Vec2 = .init(0, 0),
|
||||||
|
uv_flip_diagonal: bool = false,
|
||||||
|
uv_flip_horizontal: bool = false,
|
||||||
|
uv_flip_vertical: bool = false
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const DrawCircle = struct {
|
pub const DrawCircle = struct {
|
||||||
@ -88,6 +91,12 @@ pub const TextureInfo = Texture.Info;
|
|||||||
pub const Sprite = struct {
|
pub const Sprite = struct {
|
||||||
texture: TextureId,
|
texture: TextureId,
|
||||||
uv: Rect,
|
uv: Rect,
|
||||||
|
|
||||||
|
pub fn getSize(self: Sprite) Vec2 {
|
||||||
|
const texture_info = getTextureInfo(self.texture);
|
||||||
|
const texture_size = Vec2.initFromInt(u32, texture_info.width, texture_info.height);
|
||||||
|
return self.uv.size.multiply(texture_size);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var gpa: std.mem.Allocator = undefined;
|
var gpa: std.mem.Allocator = undefined;
|
||||||
@ -333,7 +342,41 @@ fn drawRectangle(opts: Command.DrawRectangle) void {
|
|||||||
|
|
||||||
if (opts.sprite) |sprite| {
|
if (opts.sprite) |sprite| {
|
||||||
const uv = sprite.uv;
|
const uv = sprite.uv;
|
||||||
const quad = [4]Vertex{ .{ .pos = pos.add(top_left), .uv = .init(uv.left(), uv.top()) }, .{ .pos = pos.add(top_right), .uv = .init(uv.right(), uv.top()) }, .{ .pos = pos.add(bottom_right), .uv = .init(uv.right(), uv.bottom()) }, .{ .pos = pos.add(bottom_left), .uv = .init(uv.left(), uv.bottom()) } };
|
var uv_top_left = Vec2.init(uv.left(), uv.top());
|
||||||
|
var uv_top_right = Vec2.init(uv.right(), uv.top());
|
||||||
|
var uv_bottom_right = Vec2.init(uv.right(), uv.bottom());
|
||||||
|
var uv_bottom_left = Vec2.init(uv.left(), uv.bottom());
|
||||||
|
|
||||||
|
if (opts.uv_flip_diagonal) {
|
||||||
|
std.mem.swap(Vec2, &uv_bottom_left, &uv_top_right);
|
||||||
|
}
|
||||||
|
if (opts.uv_flip_horizontal) {
|
||||||
|
std.mem.swap(Vec2, &uv_top_left, &uv_top_right);
|
||||||
|
std.mem.swap(Vec2, &uv_bottom_left, &uv_bottom_right);
|
||||||
|
}
|
||||||
|
if (opts.uv_flip_vertical) {
|
||||||
|
std.mem.swap(Vec2, &uv_top_left, &uv_bottom_left);
|
||||||
|
std.mem.swap(Vec2, &uv_top_right, &uv_bottom_right);
|
||||||
|
}
|
||||||
|
|
||||||
|
const quad = [4]Vertex{
|
||||||
|
.{
|
||||||
|
.pos = pos.add(top_left),
|
||||||
|
.uv = uv_top_left
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.pos = pos.add(top_right),
|
||||||
|
.uv = uv_top_right,
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.pos = pos.add(bottom_right),
|
||||||
|
.uv = uv_bottom_right
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.pos = pos.add(bottom_left),
|
||||||
|
.uv = uv_bottom_left
|
||||||
|
}
|
||||||
|
};
|
||||||
drawQuad(quad, opts.color, sprite.texture);
|
drawQuad(quad, opts.color, sprite.texture);
|
||||||
} else {
|
} else {
|
||||||
const quad = .{ pos.add(top_left), pos.add(top_right), pos.add(bottom_right), pos.add(bottom_left) };
|
const quad = .{ pos.add(top_left), pos.add(top_right), pos.add(bottom_right), pos.add(bottom_left) };
|
||||||
|
|||||||
@ -368,6 +368,11 @@ pub const Rect = struct {
|
|||||||
pos: Vec2,
|
pos: Vec2,
|
||||||
size: Vec2,
|
size: Vec2,
|
||||||
|
|
||||||
|
pub const unit = Rect{
|
||||||
|
.pos = .zero,
|
||||||
|
.size = .init(1, 1),
|
||||||
|
};
|
||||||
|
|
||||||
pub const zero = Rect{
|
pub const zero = Rect{
|
||||||
.pos = Vec2.zero,
|
.pos = Vec2.zero,
|
||||||
.size = Vec2.zero
|
.size = Vec2.zero
|
||||||
|
|||||||
@ -124,10 +124,6 @@ pub fn debug(self: *Game) !void {
|
|||||||
}
|
}
|
||||||
defer imgui.endWindow();
|
defer imgui.endWindow();
|
||||||
|
|
||||||
if (imgui.button("Spawn enemy")) {
|
|
||||||
_ = try self.combat_screen.spawnEnemy(.{});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (imgui.button("Restart")) {
|
if (imgui.button("Restart")) {
|
||||||
try self.restartAndShowCombatScreen();
|
try self.restartAndShowCombatScreen();
|
||||||
}
|
}
|
||||||
@ -144,10 +140,7 @@ pub fn debug(self: *Game) !void {
|
|||||||
|
|
||||||
const screen = &self.combat_screen;
|
const screen = &self.combat_screen;
|
||||||
|
|
||||||
const time_left_til_pickup = screen.next_pickup_spawn_at - screen.wave_timer;
|
|
||||||
|
|
||||||
imgui.textFmt("Waves: {}\n", .{screen.waves.items.len});
|
imgui.textFmt("Waves: {}\n", .{screen.waves.items.len});
|
||||||
imgui.textFmt("Bullets: {}\n", .{screen.bullets.items.len});
|
imgui.textFmt("Bullets: {}\n", .{screen.bullets.items.len});
|
||||||
imgui.textFmt("Enemies: {}\n", .{screen.enemies.count});
|
imgui.textFmt("Enemies: {}\n", .{screen.enemies.count});
|
||||||
imgui.textFmt("Time until next pickup: {d:.2}s\n", .{@as(f32, @floatFromInt(time_left_til_pickup)) / std.time.ns_per_s});
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user