add fire animation
This commit is contained in:
parent
19e37f507d
commit
3c61d2164d
BIN
assets/fire/1.png
Normal file
BIN
assets/fire/1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
BIN
assets/fire/2.png
Normal file
BIN
assets/fire/2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
BIN
assets/fire/3.png
Normal file
BIN
assets/fire/3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
BIN
assets/fire/4.png
Normal file
BIN
assets/fire/4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/fire/5.png
Normal file
BIN
assets/fire/5.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
@ -12,7 +12,10 @@ pub fn build(b: *std.Build) !void {
|
||||
"Prototype_Character/Default/walk.png",
|
||||
"Prototype_Character/Default/death.png",
|
||||
"font/pixeloid/PixeloidSans.ttf",
|
||||
"tranquil_tunnels_transparent.png"
|
||||
"tranquil_tunnels_transparent.png",
|
||||
"fire/1.png",
|
||||
"fire/2.png",
|
||||
"fire/5.png",
|
||||
};
|
||||
|
||||
const asset_dir_realpath = try b.build_root.join(b.graph.arena, &.{ assets_dir });
|
||||
|
||||
433
src/app.zig
433
src/app.zig
@ -43,11 +43,16 @@ font: Gfx.Font.Id,
|
||||
idle_animations: AnimationDirections,
|
||||
walk_animations: AnimationDirections,
|
||||
death_animations: AnimationDirections,
|
||||
fire1_animation: Animation,
|
||||
fire2_animation: Animation,
|
||||
fire5_animation: Animation,
|
||||
gradient_sprite: Gfx.Sprite.Id,
|
||||
|
||||
terrain_sheet: Tilesheet,
|
||||
terrain_tiles: []Tile,
|
||||
|
||||
show_minion_state: bool = false,
|
||||
|
||||
const terrain_origin_x: i32 = -80;
|
||||
const terrain_origin_y: i32 = -60;
|
||||
const terrain_width = 160;
|
||||
@ -64,7 +69,9 @@ const Tilesheet = struct {
|
||||
width: u32,
|
||||
height: u32,
|
||||
|
||||
pub fn init(gpa: Allocator, image: Gfx.ImageData, width: u32, height: u32, tile_size: Vec2) !Tilesheet {
|
||||
pub fn init(gpa: Allocator, image: Gfx.ImageData, tile_size: Vec2) !Tilesheet {
|
||||
const width = @divFloor(image.width, @as(u32, @intFromFloat(tile_size.x)));
|
||||
const height = @divFloor(image.height, @as(u32, @intFromFloat(tile_size.y)));
|
||||
const sprites = try gpa.alloc(Gfx.Sprite.Id, width * height);
|
||||
errdefer gpa.free(sprites);
|
||||
@memset(sprites, Gfx.getNilSprite());
|
||||
@ -179,6 +186,8 @@ const Entity = struct {
|
||||
minion_carried_wood_len: u32 = 0,
|
||||
minion_wander_target: ?Vec2 = null,
|
||||
minion_wander_cooldown: Nanoseconds = 0,
|
||||
minion_animation: AnimationName = .idle,
|
||||
minion_animation_dir: AnimationDirection = .down,
|
||||
|
||||
tree_health: u32 = 0,
|
||||
tree_visual_health: f32 = 0,
|
||||
@ -195,12 +204,15 @@ const Entity = struct {
|
||||
wood_next_carried: ?EntityId = null,
|
||||
wood_visual_pos: Vec2 = .init(0, 0),
|
||||
|
||||
eternal_flame_size: FlameSize = .small,
|
||||
|
||||
pos: Vec2 = .init(0, 0),
|
||||
vel: Vec2 = .init(0, 0),
|
||||
acc: Vec2 = .init(0, 0),
|
||||
|
||||
animation: AnimationName = .idle,
|
||||
animation_dir: AnimationDirection = .down,
|
||||
animation: ?Animation = null,
|
||||
animation_rect: Rect = .init(0, 0, 0, 0),
|
||||
animation_flip: bool = false,
|
||||
animation_index: u32 = 0,
|
||||
animation_timer: Nanoseconds = 0,
|
||||
|
||||
@ -226,9 +238,14 @@ const Entity = struct {
|
||||
eternal_flame,
|
||||
};
|
||||
|
||||
const FlameSize = enum {
|
||||
small,
|
||||
medium,
|
||||
large,
|
||||
};
|
||||
|
||||
const Flags = packed struct {
|
||||
has_kinematics: bool = false,
|
||||
has_animation: bool = false
|
||||
};
|
||||
};
|
||||
|
||||
@ -436,35 +453,45 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
||||
const idle_sheet = try Tilesheet.init(
|
||||
plt.arena,
|
||||
initImageDataFromSTB(try STBImage.load(plt.assets.readFile("Prototype_Character/Default/idle.png"))),
|
||||
2,
|
||||
3,
|
||||
.init(32, 32)
|
||||
);
|
||||
|
||||
const walk_sheet = try Tilesheet.init(
|
||||
plt.arena,
|
||||
initImageDataFromSTB(try STBImage.load(plt.assets.readFile("Prototype_Character/Default/walk.png"))),
|
||||
4,
|
||||
3,
|
||||
.init(32, 32)
|
||||
);
|
||||
|
||||
const death_sheet = try Tilesheet.init(
|
||||
plt.arena,
|
||||
initImageDataFromSTB(try STBImage.load(plt.assets.readFile("Prototype_Character/Default/death.png"))),
|
||||
3,
|
||||
3,
|
||||
.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 fire1_sheet = try Tilesheet.init(
|
||||
plt.arena,
|
||||
initImageDataFromSTB(try STBImage.load(plt.assets.readFile("fire/1.png"))),
|
||||
.init(16, 32)
|
||||
);
|
||||
|
||||
const fire2_sheet = try Tilesheet.init(
|
||||
plt.arena,
|
||||
initImageDataFromSTB(try STBImage.load(plt.assets.readFile("fire/2.png"))),
|
||||
.init(32, 48)
|
||||
);
|
||||
|
||||
const fire5_sheet = try Tilesheet.init(
|
||||
plt.arena,
|
||||
initImageDataFromSTB(try STBImage.load(plt.assets.readFile("fire/5.png"))),
|
||||
.init(32, 48)
|
||||
);
|
||||
|
||||
const terrain_tiles = try plt.arena.alloc(Tile, terrain_width*terrain_height);
|
||||
|
||||
const ns_per_s = std.time.ns_per_s;
|
||||
@ -496,6 +523,36 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
||||
.idle_animations = try AnimationDirections.init(plt.arena, idle_sheet, ns_per_s / idle_fps, 2),
|
||||
.walk_animations = try AnimationDirections.init(plt.arena, walk_sheet, ns_per_s / walk_fps, 4),
|
||||
.death_animations = try AnimationDirections.init(plt.arena, death_sheet, ns_per_s / death_fps, 3),
|
||||
.fire1_animation = try Animation.init(plt.arena, fire1_sheet, std.time.ns_per_ms * 100, &.{
|
||||
.init(0, 0),
|
||||
.init(1, 0),
|
||||
.init(2, 0),
|
||||
.init(3, 0),
|
||||
.init(4, 0),
|
||||
.init(5, 0),
|
||||
.init(6, 0),
|
||||
.init(7, 0),
|
||||
}),
|
||||
.fire2_animation = try Animation.init(plt.arena, fire2_sheet, std.time.ns_per_ms * 100, &.{
|
||||
.init(0, 0),
|
||||
.init(1, 0),
|
||||
.init(2, 0),
|
||||
.init(3, 0),
|
||||
.init(4, 0),
|
||||
.init(5, 0),
|
||||
.init(6, 0),
|
||||
.init(7, 0),
|
||||
}),
|
||||
.fire5_animation = try Animation.init(plt.arena, fire5_sheet, std.time.ns_per_ms * 100, &.{
|
||||
.init(0, 0),
|
||||
.init(1, 0),
|
||||
.init(2, 0),
|
||||
.init(3, 0),
|
||||
.init(4, 0),
|
||||
.init(5, 0),
|
||||
.init(6, 0),
|
||||
.init(7, 0),
|
||||
}),
|
||||
.entities_buffer = undefined,
|
||||
.entities = .init(&self.entities_buffer),
|
||||
.prng = Prng.init(@truncate(@as(u96, @intCast(now.nanoseconds)))),
|
||||
@ -518,7 +575,8 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
||||
|
||||
self.eternal_flame_id = self.spawnEntity(Entity{
|
||||
.type = .eternal_flame,
|
||||
.pos = .init(200, 0)
|
||||
.pos = .init(250, 0),
|
||||
.eternal_flame_size = .large,
|
||||
}).?;
|
||||
|
||||
return null;
|
||||
@ -695,16 +753,21 @@ fn spawnEntity(self: *App, e: Entity) ?EntityId {
|
||||
}
|
||||
|
||||
pub fn spawnMinion(self: *App, pos: Vec2) void {
|
||||
const character_size = Vec2.init(96, 96);
|
||||
|
||||
_ = self.spawnEntity(Entity{
|
||||
.type = .minion,
|
||||
.flags = .{
|
||||
.has_animation = true,
|
||||
.has_kinematics = true
|
||||
},
|
||||
|
||||
.pos = pos,
|
||||
|
||||
.animation = .idle,
|
||||
.minion_animation = .idle,
|
||||
.animation_rect = .{
|
||||
.pos = .init(-character_size.x/2, -character_size.y*0.7),
|
||||
.size = character_size,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -741,7 +804,7 @@ fn spawnTree(self: *App, station_id: EntityId) void {
|
||||
.tree_max_health = health,
|
||||
.seed = rng.int(u64),
|
||||
|
||||
.pos = station.pos
|
||||
.pos = station.pos.add(.init((rng.float(f32)-0.5) * terrain_tile_size.x, 0))
|
||||
})) |id| {
|
||||
station.station_owned_tree = id;
|
||||
}
|
||||
@ -1085,7 +1148,11 @@ fn minionLogic(self: *App, plt: Platform.Frame, minion_id: EntityId) !void {
|
||||
const wood = self.entities.getAssumeExists(wood_id);
|
||||
const eternal_flame = self.entities.getAssumeExists(self.eternal_flame_id);
|
||||
|
||||
var rng = self.prng.random();
|
||||
|
||||
wood.pos = eternal_flame.pos;
|
||||
wood.pos.x += (rng.float(f32)-0.5) * 2 * 30;
|
||||
wood.pos.y -= rng.float(f32) * 30;
|
||||
wood.wood_burning = true;
|
||||
threw_anything = true;
|
||||
}
|
||||
@ -1391,6 +1458,8 @@ fn showDebug(self: *App, plt: Platform.Frame) !void {
|
||||
self.heat = @intCast(heat);
|
||||
}
|
||||
|
||||
_ = ImGUI.checkbox("Minion state", &self.show_minion_state);
|
||||
|
||||
ImGUI.separator();
|
||||
_ = ImGUI.text("Minion upgrades", .{});
|
||||
_ = ImGUI.inputU32("count", &self.upgrades.minion_count);
|
||||
@ -1469,7 +1538,7 @@ fn showDebug(self: *App, plt: Platform.Frame) !void {
|
||||
var minion_iter = self.initEntityIteratorByType(.minion);
|
||||
while (minion_iter.next()) |minion_id| {
|
||||
const minion = self.entities.getAssumeExists(minion_id);
|
||||
ImGUI.text("{f}, wood_head: {?f}", .{minion_id, minion.minion_carried_wood_head});
|
||||
ImGUI.text("{f}, len: {}, wood_head: {?f}", .{minion_id, minion.minion_carried_wood_len, minion.minion_carried_wood_head});
|
||||
}
|
||||
|
||||
ImGUI.separator();
|
||||
@ -1479,6 +1548,16 @@ fn showDebug(self: *App, plt: Platform.Frame) !void {
|
||||
ImGUI.text("{f}, carried_by: {?f}, next: {?f}", .{wood_id, wood.wood_carried_by, wood.wood_next_carried});
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGUI.beginTabItem("Minions")) {
|
||||
defer ImGUI.endTabItem();
|
||||
|
||||
var minion_iter = self.initEntityIteratorByType(.minion);
|
||||
while (minion_iter.next()) |minion_id| {
|
||||
const minion = self.entities.getAssumeExists(minion_id);
|
||||
ImGUI.text("{f}, animation: {}, acc: {}, vel: {}", .{minion_id, minion.minion_animation, minion.acc.length(), minion.vel.length()});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1490,7 +1569,6 @@ fn drawTree(self: *App, seed: u64, pos: Vec2, health_percent: f32) void {
|
||||
defer Gfx.transformPop();
|
||||
|
||||
Gfx.transformTranslate(pos);
|
||||
Gfx.transformTranslate(.init((rng.float(f32)-0.5) * terrain_tile_size.x, 0));
|
||||
|
||||
{
|
||||
Gfx.transformPush();
|
||||
@ -1553,6 +1631,28 @@ fn drawTree(self: *App, seed: u64, pos: Vec2, health_percent: f32) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn drawEntityAnimation(self: *App, e: *Entity, dt: Nanoseconds) void {
|
||||
_ = self; // autofix
|
||||
if (e.animation) |animation| {
|
||||
e.animation_timer += dt;
|
||||
while (e.animation_timer >= animation.frame_duration) {
|
||||
e.animation_timer -= animation.frame_duration;
|
||||
e.animation_index += 1;
|
||||
}
|
||||
|
||||
e.animation_index = e.animation_index % @as(u32, @intCast(animation.frames.len));
|
||||
const sprite = animation.frames[e.animation_index];
|
||||
|
||||
var rect = e.animation_rect;
|
||||
if (e.animation_flip) {
|
||||
rect.pos.x += rect.size.x;
|
||||
rect.size.x *= -1;
|
||||
}
|
||||
|
||||
Gfx.drawSprite(sprite, e.pos.add(rect.pos), rect.size, .white);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||
const input = plt.input;
|
||||
_ = input; // autofix
|
||||
@ -1655,6 +1755,17 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var minion_iter = self.initEntityIteratorByType(.minion);
|
||||
while (minion_iter.next()) |minion_id| {
|
||||
const minion = self.entities.getAssumeExists(minion_id);
|
||||
|
||||
if (minion.minion_state == .wander and minion.target_entity != null) {
|
||||
self.unsetEntityTarget(minion_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // Ensure that `target_entity` and `targeted_by_entity` don't point to dead entities
|
||||
var entity_iter = self.entities.iterator();
|
||||
while (entity_iter.next()) |entity_id| {
|
||||
@ -1722,6 +1833,27 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||
}
|
||||
}
|
||||
|
||||
{ // Each burn station will assign itself to the nearest minion that has wood
|
||||
var burn_station_iter = self.initEntityIteratorByType(.burn_station);
|
||||
while (burn_station_iter.next()) |burn_station_id| {
|
||||
const burn_station = self.entities.getAssumeExists(burn_station_id);
|
||||
if (burn_station.targeted_by_entity != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var minion_iter = self.initNearestEntityIter(.minion, burn_station.pos, plt.arena);
|
||||
while (try minion_iter.next()) |minion_id| {
|
||||
const minion = self.entities.getAssumeExists(minion_id);
|
||||
const state = minion.minion_state;
|
||||
if (state == .wander and minion.minion_carried_wood_len == self.upgrades.minion_carry_capacity) {
|
||||
self.setEntityTarget(minion_id, burn_station_id);
|
||||
minion.minion_state = .goto_burn_station;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // Each tree entity will assign itself to the nearest minion that isn't busy
|
||||
var tree_iter = self.initEntityIteratorByType(.tree);
|
||||
while (tree_iter.next()) |tree_id| {
|
||||
@ -1786,51 +1918,79 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||
}
|
||||
}
|
||||
|
||||
{ // Each burn station will assign itself to the nearest minion that has wood
|
||||
var burn_station_iter = self.initEntityIteratorByType(.burn_station);
|
||||
while (burn_station_iter.next()) |burn_station_id| {
|
||||
const burn_station = self.entities.getAssumeExists(burn_station_id);
|
||||
if (burn_station.targeted_by_entity != null) {
|
||||
continue;
|
||||
{ // Clear acceleration
|
||||
var entity_iter = self.entities.iterator();
|
||||
while (entity_iter.next()) |id| {
|
||||
const e = self.entities.getAssumeExists(id);
|
||||
|
||||
if (e.flags.has_kinematics) {
|
||||
e.acc = .init(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // Minion logic & animations
|
||||
var minion_iter = self.initEntityIteratorByType(.minion);
|
||||
while (minion_iter.next()) |minion_id| {
|
||||
const minion = self.entities.getAssumeExists(minion_id);
|
||||
|
||||
try self.minionLogic(plt, minion_id);
|
||||
|
||||
if (minion.acc.x > 0) {
|
||||
minion.minion_animation = .walk;
|
||||
minion.minion_animation_dir = .right;
|
||||
} else if (minion.acc.x < 0) {
|
||||
minion.minion_animation = .walk;
|
||||
minion.minion_animation_dir = .left;
|
||||
} else {
|
||||
minion.minion_animation = .idle;
|
||||
minion.minion_animation_dir = .down;
|
||||
}
|
||||
|
||||
var minion_iter = self.initNearestEntityIter(.minion, burn_station.pos, plt.arena);
|
||||
while (try minion_iter.next()) |minion_id| {
|
||||
const minion = self.entities.getAssumeExists(minion_id);
|
||||
const state = minion.minion_state;
|
||||
if (state == .wander and minion.minion_carried_wood_len == self.upgrades.minion_carry_capacity) {
|
||||
self.setEntityTarget(minion_id, burn_station_id);
|
||||
minion.minion_state = .goto_burn_station;
|
||||
break;
|
||||
const animations = switch (minion.minion_animation) {
|
||||
.idle => self.idle_animations,
|
||||
.walk => self.walk_animations,
|
||||
.death => self.death_animations
|
||||
};
|
||||
|
||||
minion.animation_flip = false;
|
||||
minion.animation = switch (minion.minion_animation_dir) {
|
||||
.right => animations.right,
|
||||
.up => animations.up,
|
||||
.down => animations.down,
|
||||
.left => blk: {
|
||||
minion.animation_flip = true;
|
||||
break :blk animations.right;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
{ // Apply kinamatics
|
||||
var entity_iter = self.entities.iterator();
|
||||
while (entity_iter.next()) |id| {
|
||||
const e = self.entities.getAssumeExists(id);
|
||||
|
||||
if (e.flags.has_kinematics) {
|
||||
e.vel = e.vel.add(e.acc.multiplyScalar(dt));
|
||||
e.pos = e.pos.add(e.vel.multiplyScalar(dt));
|
||||
|
||||
e.pos.y = @min(e.pos.y, 0);
|
||||
}
|
||||
|
||||
if (e.type == .minion) {
|
||||
const stats = self.upgrades.minion_walk;
|
||||
e.vel = e.vel.limitLength(stats.max_velocity);
|
||||
|
||||
if (0 <= stats.friction and stats.friction <= 1) {
|
||||
const friction_force = std.math.pow(f32, 1 - stats.friction, dt);
|
||||
e.vel = e.vel.multiplyScalar(friction_force);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var minion_iter = self.entities.iterator();
|
||||
while (minion_iter.next()) |minion_id| {
|
||||
const minion = self.entities.getAssumeExists(minion_id);
|
||||
if (minion.type != .minion) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try self.minionLogic(plt, minion_id);
|
||||
|
||||
if (minion.acc.x > 0) {
|
||||
minion.animation = .walk;
|
||||
minion.animation_dir = .right;
|
||||
} else if (minion.acc.x < 0) {
|
||||
minion.animation = .walk;
|
||||
minion.animation_dir = .left;
|
||||
} else {
|
||||
minion.animation = .idle;
|
||||
minion.animation_dir = .down;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
{ // Wood position follow
|
||||
var wood_iter = self.initEntityIteratorByType(.wood);
|
||||
while (wood_iter.next()) |wood_id| {
|
||||
const wood = self.entities.getAssumeExists(wood_id);
|
||||
@ -1895,86 +2055,97 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||
}
|
||||
}
|
||||
|
||||
const character_size = Vec2.init(96, 96);
|
||||
{
|
||||
var entity_iter = self.entities.iterator();
|
||||
while (entity_iter.next()) |id| {
|
||||
const e = self.entities.getAssumeExists(id);
|
||||
|
||||
if (e.flags.has_kinematics) {
|
||||
e.vel = e.vel.add(e.acc.multiplyScalar(dt));
|
||||
e.pos = e.pos.add(e.vel.multiplyScalar(dt));
|
||||
|
||||
e.pos.y = @min(e.pos.y, 0);
|
||||
|
||||
e.acc = .init(0, 0);
|
||||
}
|
||||
|
||||
if (e.type == .minion) {
|
||||
const stats = self.upgrades.minion_walk;
|
||||
e.vel = e.vel.limitLength(stats.max_velocity);
|
||||
|
||||
if (0 <= stats.friction and stats.friction <= 1) {
|
||||
const friction_force = std.math.pow(f32, 1 - stats.friction, dt);
|
||||
e.vel = e.vel.multiplyScalar(friction_force);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.flags.has_animation) {
|
||||
const animations = switch (e.animation) {
|
||||
.idle => self.idle_animations,
|
||||
.walk => self.walk_animations,
|
||||
.death => self.death_animations
|
||||
};
|
||||
var flip_animation = false;
|
||||
const animation = switch (e.animation_dir) {
|
||||
.right => animations.right,
|
||||
.up => animations.up,
|
||||
.down => animations.down,
|
||||
.left => blk: {
|
||||
flip_animation = true;
|
||||
break :blk animations.right;
|
||||
}
|
||||
};
|
||||
|
||||
e.animation_timer += plt.dt;
|
||||
while (e.animation_timer >= animation.frame_duration) {
|
||||
e.animation_timer -= animation.frame_duration;
|
||||
e.animation_index += 1;
|
||||
}
|
||||
|
||||
e.animation_index = e.animation_index % @as(u32, @intCast(animation.frames.len));
|
||||
const sprite = animation.frames[e.animation_index];
|
||||
|
||||
var size = character_size;
|
||||
var pos = e.pos;
|
||||
pos.y -= character_size.y*0.7;
|
||||
if (flip_animation) {
|
||||
size.x *= -1;
|
||||
pos.x += character_size.x/2;
|
||||
} else {
|
||||
pos.x -= character_size.x/2;
|
||||
}
|
||||
|
||||
Gfx.drawSprite(sprite, pos, size, .white);
|
||||
|
||||
if (e.type == .minion and e.minion_state == .burn_wood and e.minion_throw_cooldown > 0) {
|
||||
Gfx.drawRectangle(e.pos.sub(.init(5, 65)), .init(10, 10), .rgb(200, 20, 20));
|
||||
}
|
||||
}
|
||||
|
||||
if (e.type == .burn_station) {
|
||||
Gfx.drawRectangle(e.pos.sub(.init(5, 5)), .init(10, 10), .rgb(200, 20, 20));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // Draw eternal flame
|
||||
var eternal_flame_iter = self.initEntityIteratorByType(.eternal_flame);
|
||||
while (eternal_flame_iter.next()) |id| {
|
||||
const eternal_flame = self.entities.getAssumeExists(id);
|
||||
|
||||
Gfx.drawRectangle(eternal_flame.pos.sub(.init(10, 50)), .init(30, 50), .rgb(150, 30, 20));
|
||||
{ // Draw holder
|
||||
Gfx.transformPush();
|
||||
defer Gfx.transformPop();
|
||||
Gfx.transformTranslate(eternal_flame.pos);
|
||||
Gfx.transformScale(terrain_tile_size);
|
||||
Gfx.transformTranslate(.init(-1.5, -1));
|
||||
|
||||
Gfx.drawSprite(
|
||||
self.terrain_sheet.get(118, 90),
|
||||
.init(0, 0),
|
||||
.init(1, 1),
|
||||
.white
|
||||
);
|
||||
Gfx.drawSprite(
|
||||
self.terrain_sheet.get(119, 90),
|
||||
.init(1, 0),
|
||||
.init(1, 1),
|
||||
.white
|
||||
);
|
||||
Gfx.drawSprite(
|
||||
self.terrain_sheet.get(120, 90),
|
||||
.init(2, 0),
|
||||
.init(1, 1),
|
||||
.white
|
||||
);
|
||||
}
|
||||
|
||||
switch (eternal_flame.eternal_flame_size) {
|
||||
.small => {
|
||||
const flame_size = Vec2.init(16, 32).multiplyScalar(4);
|
||||
eternal_flame.animation = self.fire1_animation;
|
||||
eternal_flame.animation_rect = .init(-flame_size.x/2, -flame_size.y, flame_size.x, flame_size.y);
|
||||
},
|
||||
.medium => {
|
||||
const flame_size = Vec2.init(32, 48).multiplyScalar(4);
|
||||
eternal_flame.animation = self.fire2_animation;
|
||||
eternal_flame.animation_rect = .init(-flame_size.x/2, -flame_size.y, flame_size.x, flame_size.y);
|
||||
},
|
||||
.large => {
|
||||
const flame_size = Vec2.init(32, 48).multiplyScalar(4);
|
||||
eternal_flame.animation = self.fire5_animation;
|
||||
eternal_flame.animation_rect = .init(-flame_size.x/2, -flame_size.y, flame_size.x, flame_size.y);
|
||||
}
|
||||
}
|
||||
|
||||
self.drawEntityAnimation(eternal_flame, plt.dt);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var entity_iter = self.entities.iterator();
|
||||
while (entity_iter.next()) |id| {
|
||||
const e = self.entities.getAssumeExists(id);
|
||||
|
||||
if (e.type != .eternal_flame) {
|
||||
self.drawEntityAnimation(e, plt.dt);
|
||||
}
|
||||
|
||||
if (e.type == .minion and e.minion_state == .burn_wood and e.minion_throw_cooldown > 0) {
|
||||
Gfx.drawRectangle(e.pos.sub(.init(5, 65)), .init(10, 10), .rgb(200, 20, 20));
|
||||
}
|
||||
|
||||
if (e.type == .burn_station) {
|
||||
Gfx.drawSprite(
|
||||
self.terrain_sheet.get(123, 81),
|
||||
e.pos.sub(.init(terrain_tile_size.x/2, terrain_tile_size.y)),
|
||||
terrain_tile_size,
|
||||
.white
|
||||
);
|
||||
}
|
||||
|
||||
if (e.type == .minion and self.show_minion_state) {
|
||||
Gfx.drawText(self.font, .{
|
||||
.height = 16,
|
||||
.text = try std.fmt.allocPrint(plt.arena, "{}", .{e.minion_state}),
|
||||
.pos = e.pos.add(.init(0, 20)),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // Draw eternal flame stats
|
||||
var eternal_flame_iter = self.initEntityIteratorByType(.eternal_flame);
|
||||
while (eternal_flame_iter.next()) |id| {
|
||||
const eternal_flame = self.entities.getAssumeExists(id);
|
||||
|
||||
Gfx.drawText(self.font, .{
|
||||
.text = try std.fmt.allocPrint(plt.arena, "Stack: {}", .{self.countEternalFlameStackSize()}),
|
||||
.pos = eternal_flame.pos.sub(.init(10, 80)),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user