render trees
This commit is contained in:
parent
892fbb38be
commit
b356038f1f
177
src/app.zig
177
src/app.zig
@ -51,6 +51,7 @@ const terrain_origin_x: i32 = -80;
|
|||||||
const terrain_origin_y: i32 = -60;
|
const terrain_origin_y: i32 = -60;
|
||||||
const terrain_width = 160;
|
const terrain_width = 160;
|
||||||
const terrain_height = 70;
|
const terrain_height = 70;
|
||||||
|
const terrain_tile_size = Vec2.init(32, 32);
|
||||||
|
|
||||||
const EntitySlotMap = SlotMapType(u16, u16, Entity);
|
const EntitySlotMap = SlotMapType(u16, u16, Entity);
|
||||||
const EntityId = EntitySlotMap.Id;
|
const EntityId = EntitySlotMap.Id;
|
||||||
@ -179,6 +180,7 @@ const Entity = struct {
|
|||||||
|
|
||||||
tree_health: u32 = 0,
|
tree_health: u32 = 0,
|
||||||
tree_max_health: u32 = 0,
|
tree_max_health: u32 = 0,
|
||||||
|
tree_seed: u64 = 0,
|
||||||
|
|
||||||
station_spawn_tree_cooldown: Nanoseconds = 0,
|
station_spawn_tree_cooldown: Nanoseconds = 0,
|
||||||
station_owned_tree: ?EntityId = null,
|
station_owned_tree: ?EntityId = null,
|
||||||
@ -279,9 +281,19 @@ const Upgrades = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Shop = struct {
|
const Shop = struct {
|
||||||
minion_upgrades: []Item,
|
minion_count: Shop.Item,
|
||||||
tree_upgrades: []Item,
|
minion_carry_capacity: Shop.Item,
|
||||||
fire_upgrades: []Item,
|
|
||||||
|
tree_count: Shop.Item,
|
||||||
|
tree_level: Shop.Item,
|
||||||
|
|
||||||
|
fire_speed: Shop.Item,
|
||||||
|
fire_heat_per_wood: Shop.Item,
|
||||||
|
fire_stack_size: Shop.Item,
|
||||||
|
|
||||||
|
minion_upgrades: []*Item,
|
||||||
|
tree_upgrades: []*Item,
|
||||||
|
fire_upgrades: []*Item,
|
||||||
|
|
||||||
const Item = struct {
|
const Item = struct {
|
||||||
label: []const u8,
|
label: []const u8,
|
||||||
@ -491,8 +503,8 @@ pub fn init(self: *App, plt: Platform.Init) !?u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn initShop(self: *App, arena: Allocator) !void {
|
fn initShop(self: *App, arena: Allocator) !void {
|
||||||
const minion_upgrades = try arena.dupe(Shop.Item, &.{
|
self.shop = .{
|
||||||
Shop.Item{
|
.minion_count = Shop.Item{
|
||||||
.label = "Minion count",
|
.label = "Minion count",
|
||||||
.limit = 50,
|
.limit = 50,
|
||||||
.unlocked = true,
|
.unlocked = true,
|
||||||
@ -503,9 +515,8 @@ fn initShop(self: *App, arena: Allocator) !void {
|
|||||||
.cost = 1,
|
.cost = 1,
|
||||||
.cost_scaling = .initFixed(1),
|
.cost_scaling = .initFixed(1),
|
||||||
},
|
},
|
||||||
Shop.Item{
|
.minion_carry_capacity = Shop.Item{
|
||||||
.label = "Carry capacity",
|
.label = "Carry capacity",
|
||||||
.unlocked = true,
|
|
||||||
|
|
||||||
.value_ref = .initU32(&self.upgrades.minion_carry_capacity),
|
.value_ref = .initU32(&self.upgrades.minion_carry_capacity),
|
||||||
.value_scaling = .initFixed(1),
|
.value_scaling = .initFixed(1),
|
||||||
@ -513,12 +524,9 @@ fn initShop(self: *App, arena: Allocator) !void {
|
|||||||
.cost = 1,
|
.cost = 1,
|
||||||
.cost_scaling = .initFixed(1),
|
.cost_scaling = .initFixed(1),
|
||||||
},
|
},
|
||||||
});
|
|
||||||
|
|
||||||
const tree_upgrades = try arena.dupe(Shop.Item, &.{
|
.tree_count = Shop.Item{
|
||||||
Shop.Item{
|
|
||||||
.label = "Tree count",
|
.label = "Tree count",
|
||||||
.unlocked = true,
|
|
||||||
|
|
||||||
.value_ref = .initU32(&self.upgrades.tree_station_count),
|
.value_ref = .initU32(&self.upgrades.tree_station_count),
|
||||||
.value_scaling = .initFixed(1),
|
.value_scaling = .initFixed(1),
|
||||||
@ -526,10 +534,9 @@ fn initShop(self: *App, arena: Allocator) !void {
|
|||||||
.cost = 1,
|
.cost = 1,
|
||||||
.cost_scaling = .initFixed(1),
|
.cost_scaling = .initFixed(1),
|
||||||
},
|
},
|
||||||
Shop.Item{
|
.tree_level = Shop.Item{
|
||||||
.label = "Tree level",
|
.label = "Tree level",
|
||||||
.limit = Upgrades.tree_levels.len,
|
.limit = Upgrades.tree_levels.len,
|
||||||
.unlocked = true,
|
|
||||||
|
|
||||||
.value_ref = .initU32(&self.upgrades.tree_level),
|
.value_ref = .initU32(&self.upgrades.tree_level),
|
||||||
.value_scaling = .initFixed(1),
|
.value_scaling = .initFixed(1),
|
||||||
@ -537,12 +544,9 @@ fn initShop(self: *App, arena: Allocator) !void {
|
|||||||
.cost = 1,
|
.cost = 1,
|
||||||
.cost_scaling = .initFixed(1),
|
.cost_scaling = .initFixed(1),
|
||||||
},
|
},
|
||||||
});
|
|
||||||
|
|
||||||
const fire_upgrades = try arena.dupe(Shop.Item, &.{
|
.fire_speed = Shop.Item{
|
||||||
Shop.Item{
|
|
||||||
.label = "Burn speed",
|
.label = "Burn speed",
|
||||||
.unlocked = true,
|
|
||||||
|
|
||||||
.value_ref = .initF32(&self.upgrades.burn_speed),
|
.value_ref = .initF32(&self.upgrades.burn_speed),
|
||||||
.value_scaling = .initFixed(1),
|
.value_scaling = .initFixed(1),
|
||||||
@ -550,9 +554,8 @@ fn initShop(self: *App, arena: Allocator) !void {
|
|||||||
.cost = 1,
|
.cost = 1,
|
||||||
.cost_scaling = .initFixed(1),
|
.cost_scaling = .initFixed(1),
|
||||||
},
|
},
|
||||||
Shop.Item{
|
.fire_heat_per_wood = Shop.Item{
|
||||||
.label = "Heat per wood",
|
.label = "Heat per wood",
|
||||||
.unlocked = true,
|
|
||||||
|
|
||||||
.value_ref = .initU32(&self.upgrades.burn_heat_per_wood),
|
.value_ref = .initU32(&self.upgrades.burn_heat_per_wood),
|
||||||
.value_scaling = .initFixed(1),
|
.value_scaling = .initFixed(1),
|
||||||
@ -560,9 +563,8 @@ fn initShop(self: *App, arena: Allocator) !void {
|
|||||||
.cost = 1,
|
.cost = 1,
|
||||||
.cost_scaling = .initFixed(1),
|
.cost_scaling = .initFixed(1),
|
||||||
},
|
},
|
||||||
Shop.Item{
|
.fire_stack_size = Shop.Item{
|
||||||
.label = "Max stack size",
|
.label = "Stack size",
|
||||||
.unlocked = true,
|
|
||||||
|
|
||||||
.value_ref = .initU32(&self.upgrades.burn_max_stack_size),
|
.value_ref = .initU32(&self.upgrades.burn_max_stack_size),
|
||||||
.value_scaling = .initFixed(1),
|
.value_scaling = .initFixed(1),
|
||||||
@ -570,12 +572,20 @@ fn initShop(self: *App, arena: Allocator) !void {
|
|||||||
.cost = 1,
|
.cost = 1,
|
||||||
.cost_scaling = .initFixed(1),
|
.cost_scaling = .initFixed(1),
|
||||||
},
|
},
|
||||||
});
|
|
||||||
|
|
||||||
self.shop = .{
|
.minion_upgrades = try arena.dupe(*Shop.Item, &.{
|
||||||
.minion_upgrades = minion_upgrades,
|
&self.shop.minion_count,
|
||||||
.tree_upgrades = tree_upgrades,
|
&self.shop.minion_carry_capacity
|
||||||
.fire_upgrades = fire_upgrades,
|
}),
|
||||||
|
.tree_upgrades = try arena.dupe(*Shop.Item, &.{
|
||||||
|
&self.shop.tree_count,
|
||||||
|
&self.shop.tree_level
|
||||||
|
}),
|
||||||
|
.fire_upgrades = try arena.dupe(*Shop.Item, &.{
|
||||||
|
&self.shop.fire_speed,
|
||||||
|
&self.shop.fire_heat_per_wood,
|
||||||
|
&self.shop.fire_stack_size,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,6 +627,28 @@ fn initTerrain(self: *App) void {
|
|||||||
tile.sprite = self.pickRandom(Gfx.Sprite.Id, underground_tiles);
|
tile.sprite = self.pickRandom(Gfx.Sprite.Id, underground_tiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const grass_tiles = &[_]Gfx.Sprite.Id{
|
||||||
|
self.terrain_sheet.get(113, 45),
|
||||||
|
self.terrain_sheet.get(114, 45),
|
||||||
|
self.terrain_sheet.get(115, 45),
|
||||||
|
self.terrain_sheet.get(116, 45),
|
||||||
|
self.terrain_sheet.get(117, 45),
|
||||||
|
self.terrain_sheet.get(122, 45),
|
||||||
|
self.terrain_sheet.get(123, 45),
|
||||||
|
self.terrain_sheet.get(124, 45),
|
||||||
|
self.terrain_sheet.get(125, 45),
|
||||||
|
Gfx.getNilSprite(),
|
||||||
|
Gfx.getNilSprite(),
|
||||||
|
Gfx.getNilSprite(),
|
||||||
|
Gfx.getNilSprite(),
|
||||||
|
Gfx.getNilSprite(),
|
||||||
|
Gfx.getNilSprite(),
|
||||||
|
};
|
||||||
|
for (0..terrain_width) |x| {
|
||||||
|
const tile = self.getTerrainTile(@as(i32, @intCast(x)) + terrain_origin_x, -1);
|
||||||
|
tile.sprite = self.pickRandom(Gfx.Sprite.Id, grass_tiles);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getTerrainTile(self: *App, x: i32, y: i32) *Tile {
|
fn getTerrainTile(self: *App, x: i32, y: i32) *Tile {
|
||||||
@ -633,8 +665,6 @@ fn getTerrainTile(self: *App, x: i32, y: i32) *Tile {
|
|||||||
return &self.terrain_tiles[y_u32 * terrain_width + x_u32];
|
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});
|
||||||
@ -679,11 +709,14 @@ fn spawnTree(self: *App, station_id: EntityId) void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rng = self.prng.random();
|
||||||
|
|
||||||
const health = self.upgrades.tree_health;
|
const health = self.upgrades.tree_health;
|
||||||
if (self.spawnEntity(Entity{
|
if (self.spawnEntity(Entity{
|
||||||
.type = .tree,
|
.type = .tree,
|
||||||
.tree_health = health,
|
.tree_health = health,
|
||||||
.tree_max_health = health,
|
.tree_max_health = health,
|
||||||
|
.tree_seed = rng.int(u64),
|
||||||
|
|
||||||
.pos = station.pos
|
.pos = station.pos
|
||||||
})) |id| {
|
})) |id| {
|
||||||
@ -1104,10 +1137,10 @@ fn showShopPanel(
|
|||||||
plt: Platform.Frame,
|
plt: Platform.Frame,
|
||||||
panel_label: []const u8,
|
panel_label: []const u8,
|
||||||
panel_pos: Vec2,
|
panel_pos: Vec2,
|
||||||
shop_items: []Shop.Item
|
shop_items: []*Shop.Item
|
||||||
) !void {
|
) !void {
|
||||||
var unlocked_count: f32 = 0;
|
var unlocked_count: f32 = 0;
|
||||||
for (shop_items) |*shop_item| {
|
for (shop_items) |shop_item| {
|
||||||
if (shop_item.unlocked) {
|
if (shop_item.unlocked) {
|
||||||
unlocked_count += 1;
|
unlocked_count += 1;
|
||||||
}
|
}
|
||||||
@ -1154,7 +1187,7 @@ fn showShopPanel(
|
|||||||
Gfx.transformTranslate(.init(10, -5));
|
Gfx.transformTranslate(.init(10, -5));
|
||||||
|
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
for (shop_items) |*shop_item| {
|
for (shop_items) |shop_item| {
|
||||||
if (!shop_item.unlocked) {
|
if (!shop_item.unlocked) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1228,7 +1261,7 @@ fn showShopPanel(
|
|||||||
const new_value = shop_item.value_scaling.apply(shop_item.value_ref.deref());
|
const new_value = shop_item.value_scaling.apply(shop_item.value_ref.deref());
|
||||||
Gfx.drawText(self.font, .{
|
Gfx.drawText(self.font, .{
|
||||||
.text = try allocPrint(plt.arena, "> {f}", .{new_value}),
|
.text = try allocPrint(plt.arena, "> {f}", .{new_value}),
|
||||||
.pos = .init(240, 0),
|
.pos = .init(250, 0),
|
||||||
.height = 24,
|
.height = 24,
|
||||||
.color = text_color
|
.color = text_color
|
||||||
});
|
});
|
||||||
@ -1245,7 +1278,7 @@ fn showShopPanel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn showUI(self: *App, plt: Platform.Frame) !void {
|
fn showUI(self: *App, plt: Platform.Frame) !void {
|
||||||
var heat_pos = Vec2.init(0, -200);
|
var heat_pos = Vec2.init(50, -200);
|
||||||
|
|
||||||
{ // Draw heat counter
|
{ // Draw heat counter
|
||||||
var builder = Gfx.TextBuilder.init(plt.arena);
|
var builder = Gfx.TextBuilder.init(plt.arena);
|
||||||
@ -1285,13 +1318,13 @@ fn showDebugScaling(label: []const u8, scaling: *Shop.Item.Scaling) void {
|
|||||||
_ = ImGUI.inputF32Drag(.{ .label = "quadratic", .value = &scaling.quadratic });
|
_ = ImGUI.inputF32Drag(.{ .label = "quadratic", .value = &scaling.quadratic });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn showDebugShopItems(self: *App, label: []const u8, shop_items: []Shop.Item) void {
|
fn showDebugShopItems(self: *App, label: []const u8, shop_items: []*Shop.Item) void {
|
||||||
_ = self; // autofix
|
_ = self; // autofix
|
||||||
ImGUI.pushID(.{ .string = label });
|
ImGUI.pushID(.{ .string = label });
|
||||||
defer ImGUI.popID();
|
defer ImGUI.popID();
|
||||||
|
|
||||||
_ = ImGUI.text("{s}", .{label});
|
_ = ImGUI.text("{s}", .{label});
|
||||||
for (0.., shop_items) |i, *shop_item| {
|
for (0.., shop_items) |i, shop_item| {
|
||||||
ImGUI.pushID(.{ .int = @intCast(i) });
|
ImGUI.pushID(.{ .int = @intCast(i) });
|
||||||
defer ImGUI.popID();
|
defer ImGUI.popID();
|
||||||
|
|
||||||
@ -1397,6 +1430,66 @@ fn showDebug(self: *App, plt: Platform.Frame) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn drawTree(self: *App, seed: u64, pos: Vec2) void {
|
||||||
|
var prng = Prng.init(seed);
|
||||||
|
const rng = prng.random();
|
||||||
|
|
||||||
|
Gfx.transformPush();
|
||||||
|
defer Gfx.transformPop();
|
||||||
|
|
||||||
|
Gfx.transformTranslate(pos.sub(.init(terrain_tile_size.x/2, terrain_tile_size.y)));
|
||||||
|
Gfx.transformScale(terrain_tile_size);
|
||||||
|
|
||||||
|
Gfx.transformTranslate(.init(rng.float(f32)-0.5, 0));
|
||||||
|
|
||||||
|
const tree_middle = &[_]Gfx.Sprite.Id{
|
||||||
|
self.terrain_sheet.get(125, 41),
|
||||||
|
self.terrain_sheet.get(125, 40),
|
||||||
|
self.terrain_sheet.get(125, 39),
|
||||||
|
};
|
||||||
|
|
||||||
|
const trunk_height = rng.uintAtMost(u32, 4) + 2;
|
||||||
|
|
||||||
|
Gfx.drawSprite(self.terrain_sheet.get(125, 42), .init(0, 0), .init(1, 1), .white);
|
||||||
|
for (0..trunk_height) |i| {
|
||||||
|
const sprite = tree_middle[rng.uintLessThan(u32, tree_middle.len)];
|
||||||
|
var trunk_pos = Vec2.init(0, -@as(f32, @floatFromInt(i)));
|
||||||
|
trunk_pos.x += (rng.float(f32)-0.5)*2 * 0.15;
|
||||||
|
Gfx.drawSprite(sprite, trunk_pos, .init(1, 1), .white);
|
||||||
|
}
|
||||||
|
Gfx.transformTranslate(Vec2.initFromInt(u32, 0, trunk_height).multiplyScalar(-1));
|
||||||
|
Gfx.drawSprite(
|
||||||
|
self.terrain_sheet.get(125, 38),
|
||||||
|
.init(0, 0),
|
||||||
|
.init(1, 1),
|
||||||
|
.white
|
||||||
|
);
|
||||||
|
|
||||||
|
const inner_leaves = self.terrain_sheet.get(123, 42);
|
||||||
|
const bottom_leaves = self.terrain_sheet.get(124, 39);
|
||||||
|
const left_leaves = self.terrain_sheet.get(123, 38);
|
||||||
|
const corner_leaves = self.terrain_sheet.get(123, 39);
|
||||||
|
|
||||||
|
Gfx.drawSprite(bottom_leaves, .init(0, -1), .init(1, 1), .white);
|
||||||
|
Gfx.drawSprite(corner_leaves, .init(-1, -1), .init(1, 1), .white);
|
||||||
|
Gfx.drawSprite(corner_leaves, .init(2, -1), .init(-1, 1), .white);
|
||||||
|
|
||||||
|
const leaves_height = rng.uintAtMost(u32, 3) + 1;
|
||||||
|
|
||||||
|
for (0..leaves_height) |i| {
|
||||||
|
var base = Vec2.initFromInt(usize, 0, i).multiplyScalar(-1);
|
||||||
|
base.x += (rng.float(f32)-0.5)*2 * 0.2;
|
||||||
|
Gfx.drawSprite(inner_leaves, base.add(.init(0, -2)), .init(1, 1), .white);
|
||||||
|
Gfx.drawSprite(left_leaves, base.add(.init(2, -2)), .init(-1, 1), .white);
|
||||||
|
Gfx.drawSprite(left_leaves, base.add(.init(-1, -2)), .init(1, 1), .white);
|
||||||
|
}
|
||||||
|
Gfx.transformTranslate(Vec2.initFromInt(u32, 0, leaves_height).multiplyScalar(-1));
|
||||||
|
|
||||||
|
Gfx.drawSprite(bottom_leaves, .init(0, -1), .init(1, -1), .white);
|
||||||
|
Gfx.drawSprite(corner_leaves, .init(-1, -1), .init(1, -1), .white);
|
||||||
|
Gfx.drawSprite(corner_leaves, .init(2, -1), .init(-1, -1), .white);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn frame(self: *App, plt: Platform.Frame) !void {
|
pub fn frame(self: *App, plt: Platform.Frame) !void {
|
||||||
const input = plt.input;
|
const input = plt.input;
|
||||||
_ = input; // autofix
|
_ = input; // autofix
|
||||||
@ -1456,7 +1549,7 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const wood_station_first_pos = -100;
|
const wood_station_first_pos = -100;
|
||||||
const wood_station_step = -50;
|
const wood_station_step = -70;
|
||||||
|
|
||||||
if (station_count > self.upgrades.tree_station_count) {
|
if (station_count > self.upgrades.tree_station_count) {
|
||||||
for (self.upgrades.tree_station_count..station_count) |i| {
|
for (self.upgrades.tree_station_count..station_count) |i| {
|
||||||
@ -1695,9 +1788,8 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
|||||||
continue;
|
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));
|
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);
|
Gfx.drawSprite(tile.sprite, tile_pos.multiply(terrain_tile_size), terrain_tile_size, .white);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1707,8 +1799,7 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
|||||||
while (tree_iter.next()) |id| {
|
while (tree_iter.next()) |id| {
|
||||||
const e = self.entities.getAssumeExists(id);
|
const e = self.entities.getAssumeExists(id);
|
||||||
|
|
||||||
const tree_size = Vec2.init(40, 100);
|
self.drawTree(e.tree_seed, e.pos);
|
||||||
Gfx.drawRectangle(e.pos.sub(.init(tree_size.x/2, tree_size.y)), tree_size, .rgb(40, 200, 40));
|
|
||||||
|
|
||||||
const progress = @as(f32, @floatFromInt(e.tree_health)) / @as(f32, @floatFromInt(e.tree_max_health));
|
const progress = @as(f32, @floatFromInt(e.tree_health)) / @as(f32, @floatFromInt(e.tree_max_health));
|
||||||
drawProgressBar(progress, e.pos.add(.init(0, 20)), .init(40, 10), .rgb(0, 100, 20));
|
drawProgressBar(progress, e.pos.add(.init(0, 20)), .init(40, 10), .rgb(0, 100, 20));
|
||||||
@ -1788,9 +1879,7 @@ pub fn frame(self: *App, plt: Platform.Frame) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.type == .wood_station) {
|
if (e.type == .burn_station) {
|
||||||
Gfx.drawRectangle(e.pos.sub(.init(5, 5)), .init(10, 10), .rgb(20, 200, 20));
|
|
||||||
} else if (e.type == .burn_station) {
|
|
||||||
Gfx.drawRectangle(e.pos.sub(.init(5, 5)), .init(10, 10), .rgb(200, 20, 20));
|
Gfx.drawRectangle(e.pos.sub(.init(5, 5)), .init(10, 10), .rgb(200, 20, 20));
|
||||||
} else if (e.type == .minion) {
|
} else if (e.type == .minion) {
|
||||||
Gfx.drawText(self.font, .{
|
Gfx.drawText(self.font, .{
|
||||||
|
|||||||
@ -39,8 +39,8 @@ const State = struct {
|
|||||||
nearest_sampler: sg.Sampler,
|
nearest_sampler: sg.Sampler,
|
||||||
default_sampler: Sampler,
|
default_sampler: Sampler,
|
||||||
|
|
||||||
quads_buffer: [2048]Quad,
|
quads_buffer: [2048]VertexQuad,
|
||||||
quads: std.ArrayList(Quad),
|
quads: std.ArrayList(VertexQuad),
|
||||||
|
|
||||||
clear_color: Color,
|
clear_color: Color,
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ pub fn init(gpa: std.mem.Allocator, logger: sg.Logger) !void {
|
|||||||
const max_quads = self.quads_buffer.len;
|
const max_quads = self.quads_buffer.len;
|
||||||
|
|
||||||
bindings.vertex_buffers[0] = sg.makeBuffer(.{
|
bindings.vertex_buffers[0] = sg.makeBuffer(.{
|
||||||
.size = @sizeOf(Quad) * max_quads,
|
.size = @sizeOf(VertexQuad) * max_quads,
|
||||||
.usage = .{ .vertex_buffer = true, .stream_update = true },
|
.usage = .{ .vertex_buffer = true, .stream_update = true },
|
||||||
.label = "quad-vertices"
|
.label = "quad-vertices"
|
||||||
});
|
});
|
||||||
@ -543,42 +543,42 @@ pub fn drawRectangleOutline(pos: Vec2, size: Vec2, color: Color, width: f32, ali
|
|||||||
|
|
||||||
drawSpriteQuad(
|
drawSpriteQuad(
|
||||||
self.default_sprite,
|
self.default_sprite,
|
||||||
.{
|
.init(.{
|
||||||
.init(outer_rect.right(), outer_rect.top()),
|
.init(outer_rect.right(), outer_rect.top()),
|
||||||
.init(outer_rect.left(), outer_rect.top()),
|
.init(outer_rect.left(), outer_rect.top()),
|
||||||
.init(inner_rect.right(), inner_rect.top()),
|
.init(inner_rect.right(), inner_rect.top()),
|
||||||
.init(inner_rect.left(), inner_rect.top()),
|
.init(inner_rect.left(), inner_rect.top()),
|
||||||
},
|
}),
|
||||||
color
|
color
|
||||||
);
|
);
|
||||||
drawSpriteQuad(
|
drawSpriteQuad(
|
||||||
self.default_sprite,
|
self.default_sprite,
|
||||||
.{
|
.init(.{
|
||||||
.init(outer_rect.right(), outer_rect.top()),
|
.init(outer_rect.right(), outer_rect.top()),
|
||||||
.init(inner_rect.right(), inner_rect.top()),
|
.init(inner_rect.right(), inner_rect.top()),
|
||||||
.init(outer_rect.right(), outer_rect.bottom()),
|
.init(outer_rect.right(), outer_rect.bottom()),
|
||||||
.init(inner_rect.right(), inner_rect.bottom()),
|
.init(inner_rect.right(), inner_rect.bottom()),
|
||||||
},
|
}),
|
||||||
color
|
color
|
||||||
);
|
);
|
||||||
drawSpriteQuad(
|
drawSpriteQuad(
|
||||||
self.default_sprite,
|
self.default_sprite,
|
||||||
.{
|
.init(.{
|
||||||
.init(outer_rect.left(), outer_rect.top()),
|
.init(outer_rect.left(), outer_rect.top()),
|
||||||
.init(inner_rect.left(), inner_rect.top()),
|
.init(inner_rect.left(), inner_rect.top()),
|
||||||
.init(outer_rect.left(), outer_rect.bottom()),
|
.init(outer_rect.left(), outer_rect.bottom()),
|
||||||
.init(inner_rect.left(), inner_rect.bottom()),
|
.init(inner_rect.left(), inner_rect.bottom()),
|
||||||
},
|
}),
|
||||||
color
|
color
|
||||||
);
|
);
|
||||||
drawSpriteQuad(
|
drawSpriteQuad(
|
||||||
self.default_sprite,
|
self.default_sprite,
|
||||||
.{
|
.init(.{
|
||||||
.init(outer_rect.right(), outer_rect.bottom()),
|
.init(outer_rect.right(), outer_rect.bottom()),
|
||||||
.init(outer_rect.left(), outer_rect.bottom()),
|
.init(outer_rect.left(), outer_rect.bottom()),
|
||||||
.init(inner_rect.right(), inner_rect.bottom()),
|
.init(inner_rect.right(), inner_rect.bottom()),
|
||||||
.init(inner_rect.left(), inner_rect.bottom()),
|
.init(inner_rect.left(), inner_rect.bottom()),
|
||||||
},
|
}),
|
||||||
color
|
color
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -595,7 +595,7 @@ pub fn drawLine(from: Vec2, to: Vec2, color: Color, width: f32) void {
|
|||||||
|
|
||||||
drawSpriteQuad(
|
drawSpriteQuad(
|
||||||
self.default_sprite,
|
self.default_sprite,
|
||||||
.{ top_right, top_left, bottom_right, bottom_left },
|
.init(.{ top_right, top_left, bottom_right, bottom_left }),
|
||||||
color
|
color
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -755,7 +755,7 @@ pub fn setTexture(id: Texture.Id, texture_data: ImageData) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawTexture(id: Texture.Id, pos: Vec2, size: Vec2, color: Color) void {
|
pub fn drawTexture(id: Texture.Id, pos: Vec2, size: Vec2, color: Color) void {
|
||||||
var quad: Quad = undefined;
|
var quad: VertexQuad = undefined;
|
||||||
quad.setColor(color);
|
quad.setColor(color);
|
||||||
quad.setRect(.{ .pos = pos, .size = size });
|
quad.setRect(.{ .pos = pos, .size = size });
|
||||||
quad.setUVRect(.init(0, 0, 1, 1));
|
quad.setUVRect(.init(0, 0, 1, 1));
|
||||||
@ -795,7 +795,7 @@ pub const Sampler = enum {
|
|||||||
const DrawOptions = struct {
|
const DrawOptions = struct {
|
||||||
sampler: ?Sampler = null,
|
sampler: ?Sampler = null,
|
||||||
texture: Texture.Id,
|
texture: Texture.Id,
|
||||||
quad: Quad
|
quad: VertexQuad
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn draw(opts: DrawOptions) void {
|
pub fn draw(opts: DrawOptions) void {
|
||||||
@ -1180,15 +1180,15 @@ pub fn getSpriteUVRect(id: Sprite.Id) ?Rect {
|
|||||||
return uv_rect;
|
return uv_rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drawSpriteQuad(id: Sprite.Id, points: [4]Vec2, color: Color) void {
|
pub fn drawSpriteQuad(id: Sprite.Id, points: Quad, color: Color) void {
|
||||||
const self = &g_state;
|
const self = &g_state;
|
||||||
|
|
||||||
var quad: Quad = undefined;
|
var quad: VertexQuad = undefined;
|
||||||
quad.setColor(color);
|
quad.setColor(color);
|
||||||
quad.vertices[0].position = points[0];
|
quad.vertices[0].position = points.positions[0];
|
||||||
quad.vertices[1].position = points[1];
|
quad.vertices[1].position = points.positions[1];
|
||||||
quad.vertices[2].position = points[2];
|
quad.vertices[2].position = points.positions[2];
|
||||||
quad.vertices[3].position = points[3];
|
quad.vertices[3].position = points.positions[3];
|
||||||
|
|
||||||
var texture: ?Texture.Id = null;
|
var texture: ?Texture.Id = null;
|
||||||
if (id != self.nil_sprite) {
|
if (id != self.nil_sprite) {
|
||||||
@ -1208,12 +1208,7 @@ fn drawSpriteQuad(id: Sprite.Id, points: [4]Vec2, color: Color) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawSprite(id: Sprite.Id, pos: Vec2, size: Vec2, color: Color) void {
|
pub fn drawSprite(id: Sprite.Id, pos: Vec2, size: Vec2, color: Color) void {
|
||||||
const rect = .{
|
const rect = Quad.initRect(pos, size);
|
||||||
pos,
|
|
||||||
pos.add(.init(size.x, 0)),
|
|
||||||
pos.add(.init(0, size.y)),
|
|
||||||
pos.add(size),
|
|
||||||
};
|
|
||||||
drawSpriteQuad(id, rect, color);
|
drawSpriteQuad(id, rect, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2296,16 +2291,16 @@ pub const Vertex = extern struct {
|
|||||||
color: Vec4,
|
color: Vec4,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Quad = extern struct {
|
pub const VertexQuad = extern struct {
|
||||||
vertices: [4]Vertex,
|
vertices: [4]Vertex,
|
||||||
|
|
||||||
pub fn init(vertices: [4]Vertex) Quad {
|
pub fn init(vertices: [4]Vertex) VertexQuad {
|
||||||
return Quad{
|
return VertexQuad{
|
||||||
.vertices = vertices
|
.vertices = vertices
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setColor(self: *Quad, color: Color) void {
|
pub fn setColor(self: *VertexQuad, color: Color) void {
|
||||||
for (&self.vertices) |*vertex| {
|
for (&self.vertices) |*vertex| {
|
||||||
vertex.color = Vec4{
|
vertex.color = Vec4{
|
||||||
.x = color.r,
|
.x = color.r,
|
||||||
@ -2316,7 +2311,7 @@ pub const Quad = extern struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setUVRect(self: *Quad, rect: Rect) void {
|
pub fn setUVRect(self: *VertexQuad, rect: Rect) void {
|
||||||
const pos = rect.pos;
|
const pos = rect.pos;
|
||||||
const size = rect.size;
|
const size = rect.size;
|
||||||
self.vertices[0].texcoord = pos;
|
self.vertices[0].texcoord = pos;
|
||||||
@ -2325,7 +2320,7 @@ pub const Quad = extern struct {
|
|||||||
self.vertices[3].texcoord = pos.add(size);
|
self.vertices[3].texcoord = pos.add(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setRect(self: *Quad, rect: Rect) void {
|
pub fn setRect(self: *VertexQuad, rect: Rect) void {
|
||||||
const pos = rect.pos;
|
const pos = rect.pos;
|
||||||
const size = rect.size;
|
const size = rect.size;
|
||||||
self.vertices[0].position = pos;
|
self.vertices[0].position = pos;
|
||||||
@ -2335,6 +2330,39 @@ pub const Quad = extern struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const Quad = struct {
|
||||||
|
positions: [4]Vec2,
|
||||||
|
|
||||||
|
pub fn init(positions: [4]Vec2) Quad {
|
||||||
|
return Quad{
|
||||||
|
.positions = positions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn initRect(pos: Vec2, size: Vec2) Quad {
|
||||||
|
return Quad{
|
||||||
|
.positions = .{
|
||||||
|
pos,
|
||||||
|
pos.add(.init(size.x, 0)),
|
||||||
|
pos.add(.init(0, size.y)),
|
||||||
|
pos.add(size),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rotate(self: *Quad, rad: f32, origin: Vec2) void {
|
||||||
|
for (&self.positions) |*pos| {
|
||||||
|
pos.* = pos.sub(origin).rotate(rad).add(origin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn offset(self: *Quad, vec2: Vec2) void {
|
||||||
|
for (&self.positions) |*pos| {
|
||||||
|
pos.* = pos.add(vec2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const TransformFrame = struct {
|
pub const TransformFrame = struct {
|
||||||
offset: Vec2,
|
offset: Vec2,
|
||||||
scale: Vec2,
|
scale: Vec2,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user