const std = @import("std"); const Allocator = std.mem.Allocator; const assert = std.debug.assert; const Engine = @import("engine_lib"); const FontId = Engine.Font.Id; const Vec2 = Engine.Math.Vec2; const rgb = Engine.Math.rgb; const Game = @This(); const FontName = enum { regular, bold, italic, }; const AssetId = enum { font_regular, font_bold, font_italic, sound_wood, texture_icon, }; const State = struct { gpa: Allocator, player: Vec2, }; pub fn init(opts: *const Engine.Init) callconv(.c) *anyopaque { const gpa = opts.gpa; const state = gpa.create(State) catch @panic("OOM"); state.* = State{ .gpa = gpa, .player = .init(50, 50), }; return state; } fn getFont(assets: Engine.Asset.Registry, font_name: FontName) FontId { const asset_id = switch (font_name) { .regular => AssetId.font_regular, .bold => AssetId.font_bold, .italic => AssetId.font_italic, }; return assets.getFont(@intFromEnum(asset_id)); } pub fn loadAssets(assets: *Engine.Asset.Loader) callconv(.c) void { assets.addFont(@intFromEnum(AssetId.font_regular), "roboto-font/Roboto-Regular.ttf"); assets.addFont(@intFromEnum(AssetId.font_bold), "roboto-font/Roboto-Bold.ttf"); assets.addFont(@intFromEnum(AssetId.font_italic), "roboto-font/Roboto-Italic.ttf"); assets.addSound(@intFromEnum(AssetId.sound_wood), "wood01.ogg"); assets.addTexture(@intFromEnum(AssetId.texture_icon), "icon.png"); } pub fn deinit(state_ptr: *anyopaque) callconv(.c) void { const state: *State = @alignCast(@ptrCast(state_ptr)); const gpa = state.gpa; gpa.destroy(state); } pub fn tick(state_ptr: *anyopaque, frame: *Engine.Frame) callconv(.c) void { const state: *State = @alignCast(@ptrCast(state_ptr)); const dt = frame.deltaTime(); const canvas_size = Vec2.init(100, 100); frame.canvas_size = canvas_size; var dir = Vec2.init(0, 0); if (frame.isKeyDown(.W)) { dir.y -= 1; } if (frame.isKeyDown(.S)) { dir.y += 1; } if (frame.isKeyDown(.A)) { dir.x -= 1; } if (frame.isKeyDown(.D)) { dir.x += 1; } dir = dir.normalized(); if (dir.x != 0 or dir.y != 0) { frame.playAudio(.{ .id = frame.assets.getSound(@intFromEnum(AssetId.sound_wood)), .volume = 0.1 }); } state.player = state.player.add(dir.multiplyScalar(50 * dt)); frame.drawRectangle(.{ .rect = .{ .pos = .init(0, 0), .size = canvas_size }, .color = rgb(20, 20, 20) }); const icon = frame.assets.getTexture(@intFromEnum(AssetId.texture_icon)); const size = Vec2.init(20, 20); frame.drawRectangle(.{ .rect = .{ .pos = state.player.sub(size.divideScalar(2)), .size = size }, .color = rgb(200, 2, 200), .sprite = .{ .texture = icon, .uv = .unit } }); if (dir.x != 0 or dir.y != 0) { frame.drawRectanglOutline(state.player.sub(size.divideScalar(2)), size, rgb(20, 20, 20), 3); } if (frame.mouse_position) |mouse_position| { const mouse_size = Vec2.init(10, 10); frame.drawRectangle(.{ .rect = .{ .pos = mouse_position.sub(mouse_size.divideScalar(2)), .size = mouse_size }, .color = rgb(20, 2, 200) }); } frame.drawText(state.player, "Player", .{ .font = getFont(frame.assets, .regular), .size = 10 }); } pub fn debug(state_ptr: *anyopaque, imgui: *Engine.ImGui) callconv(.c) void { const state: *State = @alignCast(@ptrCast(state_ptr)); _ = state; // autofix imgui.text("Hello World!\n", .{}); } comptime { Engine.exportCallbacksIfNeeded(init, tick, deinit, debug, loadAssets); }