add terrain
This commit is contained in:
parent
f94ae22214
commit
892fbb38be
@ -11,11 +11,8 @@ pub fn build(b: *std.Build) !void {
|
|||||||
"Prototype_Character/Default/idle.png",
|
"Prototype_Character/Default/idle.png",
|
||||||
"Prototype_Character/Default/walk.png",
|
"Prototype_Character/Default/walk.png",
|
||||||
"Prototype_Character/Default/death.png",
|
"Prototype_Character/Default/death.png",
|
||||||
"font/pixeloid/PixeloidSans.ttf"
|
"font/pixeloid/PixeloidSans.ttf",
|
||||||
// "sokoban/sokoban_tilesheet.png",
|
"tranquil_tunnels_transparent.png"
|
||||||
// "roboto-font/Roboto-Regular.ttf",
|
|
||||||
// "tiled/map.tmx",
|
|
||||||
// "tiled/tileset.tsx"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const asset_dir_realpath = try b.build_root.join(b.graph.arena, &.{ assets_dir });
|
const asset_dir_realpath = try b.build_root.join(b.graph.arena, &.{ assets_dir });
|
||||||
|
|||||||
103
src/app.zig
103
src/app.zig
@ -44,6 +44,14 @@ idle_animations: AnimationDirections,
|
|||||||
walk_animations: AnimationDirections,
|
walk_animations: AnimationDirections,
|
||||||
death_animations: AnimationDirections,
|
death_animations: AnimationDirections,
|
||||||
|
|
||||||
|
terrain_sheet: Tilesheet,
|
||||||
|
terrain_tiles: []Tile,
|
||||||
|
|
||||||
|
const terrain_origin_x: i32 = -80;
|
||||||
|
const terrain_origin_y: i32 = -60;
|
||||||
|
const terrain_width = 160;
|
||||||
|
const terrain_height = 70;
|
||||||
|
|
||||||
const EntitySlotMap = SlotMapType(u16, u16, Entity);
|
const EntitySlotMap = SlotMapType(u16, u16, Entity);
|
||||||
const EntityId = EntitySlotMap.Id;
|
const EntityId = EntitySlotMap.Id;
|
||||||
|
|
||||||
@ -219,7 +227,7 @@ const Entity = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Upgrades = struct {
|
const Upgrades = struct {
|
||||||
minion_count: u32 = 0,
|
minion_count: u32 = 1,
|
||||||
minion_chop_damage: u32 = 2,
|
minion_chop_damage: u32 = 2,
|
||||||
minion_chop_rate: f32 = 1,
|
minion_chop_rate: f32 = 1,
|
||||||
minion_throw_cooldown: Nanoseconds = std.time.ns_per_s,
|
minion_throw_cooldown: Nanoseconds = std.time.ns_per_s,
|
||||||
@ -227,7 +235,7 @@ const Upgrades = struct {
|
|||||||
minion_carry_capacity: u32 = 1,
|
minion_carry_capacity: u32 = 1,
|
||||||
minion_walk: MinionWalkStats = .{},
|
minion_walk: MinionWalkStats = .{},
|
||||||
|
|
||||||
tree_station_count: u32 = 0,
|
tree_station_count: u32 = 1,
|
||||||
tree_level: u32 = 1,
|
tree_level: u32 = 1,
|
||||||
tree_health: u32 = tree_levels[0].health,
|
tree_health: u32 = tree_levels[0].health,
|
||||||
tree_respawn_duration: Nanoseconds = tree_levels[0].respawn_duration,
|
tree_respawn_duration: Nanoseconds = tree_levels[0].respawn_duration,
|
||||||
@ -390,6 +398,10 @@ const Shop = struct {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Tile = struct {
|
||||||
|
sprite: Gfx.Sprite.Id
|
||||||
|
};
|
||||||
|
|
||||||
fn initImageDataFromSTB(img: STBImage) Gfx.ImageData {
|
fn initImageDataFromSTB(img: STBImage) Gfx.ImageData {
|
||||||
return Gfx.ImageData{
|
return Gfx.ImageData{
|
||||||
.width = img.width,
|
.width = img.width,
|
||||||
@ -429,6 +441,16 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
|||||||
.init(32, 32)
|
.init(32, 32)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const terrain_sheet = try Tilesheet.init(
|
||||||
|
plt.arena,
|
||||||
|
initImageDataFromSTB(try STBImage.load(plt.assets.readFile("tranquil_tunnels_transparent.png"))),
|
||||||
|
128,
|
||||||
|
128,
|
||||||
|
.init(8, 8)
|
||||||
|
);
|
||||||
|
|
||||||
|
const terrain_tiles = try plt.arena.alloc(Tile, terrain_width*terrain_height);
|
||||||
|
|
||||||
const ns_per_s = std.time.ns_per_s;
|
const ns_per_s = std.time.ns_per_s;
|
||||||
const idle_fps = 5;
|
const idle_fps = 5;
|
||||||
const walk_fps = 5;
|
const walk_fps = 5;
|
||||||
@ -449,9 +471,13 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
|||||||
.eternal_flame_id = undefined,
|
.eternal_flame_id = undefined,
|
||||||
.upgrades = .{},
|
.upgrades = .{},
|
||||||
.shop = undefined,
|
.shop = undefined,
|
||||||
|
|
||||||
|
.terrain_sheet = terrain_sheet,
|
||||||
|
.terrain_tiles = terrain_tiles,
|
||||||
};
|
};
|
||||||
|
|
||||||
try self.initShop(plt.arena);
|
try self.initShop(plt.arena);
|
||||||
|
self.initTerrain();
|
||||||
|
|
||||||
self.spawnBurnStation(100);
|
self.spawnBurnStation(100);
|
||||||
self.spawnBurnStation(150);
|
self.spawnBurnStation(150);
|
||||||
@ -553,6 +579,62 @@ fn initShop(self: *App, arena: Allocator) !void {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pickRandom(self: *App, T: type, sprites: []const T) T {
|
||||||
|
const rng = self.prng.random();
|
||||||
|
return sprites[rng.uintLessThan(usize, sprites.len)];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initTerrain(self: *App) void {
|
||||||
|
@memset(self.terrain_tiles, Tile{
|
||||||
|
.sprite = Gfx.getNilSprite()
|
||||||
|
});
|
||||||
|
|
||||||
|
const surface_tiles = &[_]Gfx.Sprite.Id{
|
||||||
|
self.terrain_sheet.get(4, 23),
|
||||||
|
self.terrain_sheet.get(5, 23),
|
||||||
|
self.terrain_sheet.get(3, 23),
|
||||||
|
self.terrain_sheet.get(4, 24)
|
||||||
|
};
|
||||||
|
|
||||||
|
for (0..terrain_width) |x| {
|
||||||
|
const tile = self.getTerrainTile(@as(i32, @intCast(x)) + terrain_origin_x, 0);
|
||||||
|
tile.sprite = self.pickRandom(Gfx.Sprite.Id, surface_tiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
const underground_tiles = &[_]Gfx.Sprite.Id{
|
||||||
|
self.terrain_sheet.get(11, 23),
|
||||||
|
self.terrain_sheet.get(12, 23),
|
||||||
|
self.terrain_sheet.get(11, 24),
|
||||||
|
self.terrain_sheet.get(12, 24),
|
||||||
|
self.terrain_sheet.get(3, 107),
|
||||||
|
self.terrain_sheet.get(3, 107),
|
||||||
|
self.terrain_sheet.get(3, 107),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (0..terrain_width) |x| {
|
||||||
|
for (1..4) |y| {
|
||||||
|
const tile = self.getTerrainTile(@as(i32, @intCast(x)) + terrain_origin_x, @intCast(y));
|
||||||
|
tile.sprite = self.pickRandom(Gfx.Sprite.Id, underground_tiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getTerrainTile(self: *App, x: i32, y: i32) *Tile {
|
||||||
|
const left_edge = terrain_origin_x;
|
||||||
|
const right_edge = terrain_width + terrain_origin_x - 1;
|
||||||
|
|
||||||
|
const top_edge = terrain_origin_y;
|
||||||
|
const bottom_edge = terrain_height + terrain_origin_y - 1;
|
||||||
|
|
||||||
|
assert(left_edge <= x and x <= right_edge);
|
||||||
|
assert(top_edge <= y and y <= bottom_edge);
|
||||||
|
const x_u32: u32 = @intCast(x-terrain_origin_x);
|
||||||
|
const y_u32: u32 = @intCast(y-terrain_origin_y);
|
||||||
|
return &self.terrain_tiles[y_u32 * terrain_width + x_u32];
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn getTerrainEdgeLeft(self: *App)
|
||||||
|
|
||||||
fn spawnEntity(self: *App, e: Entity) ?EntityId {
|
fn spawnEntity(self: *App, e: Entity) ?EntityId {
|
||||||
return self.entities.insert(e) catch {
|
return self.entities.insert(e) catch {
|
||||||
log.warn("Failed to spawn entity {}, entity limit reached", .{e.type});
|
log.warn("Failed to spawn entity {}, entity limit reached", .{e.type});
|
||||||
@ -1153,7 +1235,7 @@ fn showShopPanel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Gfx.drawText(self.font, .{
|
Gfx.drawText(self.font, .{
|
||||||
.text = try std.fmt.allocPrint(plt.arena, "{}H", .{cost}),
|
.text = if (limit_reached) "MAX" else try std.fmt.allocPrint(plt.arena, "{}H", .{cost}),
|
||||||
.pos = .init(panel_size.x - 20, 0),
|
.pos = .init(panel_size.x - 20, 0),
|
||||||
.height = 24,
|
.height = 24,
|
||||||
.color = text_color,
|
.color = text_color,
|
||||||
@ -1605,6 +1687,21 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ // Draw terrain
|
||||||
|
for (0..terrain_height) |y| {
|
||||||
|
for (0..terrain_width) |x| {
|
||||||
|
const tile = self.terrain_tiles[y * terrain_width + x];
|
||||||
|
if (tile.sprite == Gfx.getNilSprite()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tile_size = Vec2.init(32, 32);
|
||||||
|
const tile_pos = Vec2.initFromInt(usize, x, y).add(.initFromInt(i32, terrain_origin_x, terrain_origin_y));
|
||||||
|
Gfx.drawSprite(tile.sprite, tile_pos.multiply(tile_size), tile_size, .white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
var tree_iter = self.initEntityIteratorByType(.tree);
|
var tree_iter = self.initEntityIteratorByType(.tree);
|
||||||
while (tree_iter.next()) |id| {
|
while (tree_iter.next()) |id| {
|
||||||
|
|||||||
@ -47,7 +47,7 @@ pub fn isMousePressed(self: Input, button: MouseButton) bool {
|
|||||||
return self.mouse_buttons.pressed.contains(button);
|
return self.mouse_buttons.pressed.contains(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iMouseReleased(self: Input, button: MouseButton) bool {
|
pub fn isMouseReleased(self: Input, button: MouseButton) bool {
|
||||||
return self.mouse_buttons.released.contains(button);
|
return self.mouse_buttons.released.contains(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user