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/walk.png",
|
||||
"Prototype_Character/Default/death.png",
|
||||
"font/pixeloid/PixeloidSans.ttf"
|
||||
// "sokoban/sokoban_tilesheet.png",
|
||||
// "roboto-font/Roboto-Regular.ttf",
|
||||
// "tiled/map.tmx",
|
||||
// "tiled/tileset.tsx"
|
||||
"font/pixeloid/PixeloidSans.ttf",
|
||||
"tranquil_tunnels_transparent.png"
|
||||
};
|
||||
|
||||
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,
|
||||
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 EntityId = EntitySlotMap.Id;
|
||||
|
||||
@ -219,7 +227,7 @@ const Entity = struct {
|
||||
};
|
||||
|
||||
const Upgrades = struct {
|
||||
minion_count: u32 = 0,
|
||||
minion_count: u32 = 1,
|
||||
minion_chop_damage: u32 = 2,
|
||||
minion_chop_rate: f32 = 1,
|
||||
minion_throw_cooldown: Nanoseconds = std.time.ns_per_s,
|
||||
@ -227,7 +235,7 @@ const Upgrades = struct {
|
||||
minion_carry_capacity: u32 = 1,
|
||||
minion_walk: MinionWalkStats = .{},
|
||||
|
||||
tree_station_count: u32 = 0,
|
||||
tree_station_count: u32 = 1,
|
||||
tree_level: u32 = 1,
|
||||
tree_health: u32 = tree_levels[0].health,
|
||||
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 {
|
||||
return Gfx.ImageData{
|
||||
.width = img.width,
|
||||
@ -429,6 +441,16 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
||||
.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 idle_fps = 5;
|
||||
const walk_fps = 5;
|
||||
@ -449,9 +471,13 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
||||
.eternal_flame_id = undefined,
|
||||
.upgrades = .{},
|
||||
.shop = undefined,
|
||||
|
||||
.terrain_sheet = terrain_sheet,
|
||||
.terrain_tiles = terrain_tiles,
|
||||
};
|
||||
|
||||
try self.initShop(plt.arena);
|
||||
self.initTerrain();
|
||||
|
||||
self.spawnBurnStation(100);
|
||||
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 {
|
||||
return self.entities.insert(e) catch {
|
||||
log.warn("Failed to spawn entity {}, entity limit reached", .{e.type});
|
||||
@ -1153,7 +1235,7 @@ fn showShopPanel(
|
||||
}
|
||||
|
||||
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),
|
||||
.height = 24,
|
||||
.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);
|
||||
while (tree_iter.next()) |id| {
|
||||
|
||||
@ -47,7 +47,7 @@ pub fn isMousePressed(self: Input, button: MouseButton) bool {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user