diff --git a/README.md b/README.md index 8180b84..9ed5140 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ **Attention**: make sure the working directory contains the `src/assets/...` directory otherwise the application will crash (reporting a "FailedToLoadBitmap" error). -If you unzip the binaries package or build from sources this means that the root of the zip/sources is your working directory and you're executing `./zig-out/bin/tins2023` or `.\zig-out\bin\tins2023.exe`. +If you unzip the binaries package or build from sources this means that the root of the zip/sources is your working directory and you're executing `./zig-out/bin/jungle_tale` or `.\zig-out\bin\jungle_tale.exe`. # Rules @@ -56,7 +56,7 @@ Build: `zig build` And run (after building): -`./zig-out/bin/tins2023` +`./zig-out/bin/jungle_tale` Build & run automatically: `zig build run` diff --git a/allegro/allegro.zig b/allegro/allegro.zig index 224bfff..9cc6f6f 100644 --- a/allegro/allegro.zig +++ b/allegro/allegro.zig @@ -65,6 +65,10 @@ pub const Bitmap = struct { return getBitmapHeight(self); } + pub fn heightF(self: Bitmap) f32 { + return @intToFloat(f32, self.height()); + } + pub fn sub(self: Bitmap, x: i32, y: i32, w: i32, h: i32) !Bitmap { return createSubBitmap(self, x, y, w, h); } @@ -72,6 +76,10 @@ pub const Bitmap = struct { pub fn width(self: Bitmap) i32 { return getBitmapWidth(self); } + + pub fn widthF(self: Bitmap) f32 { + return @intToFloat(f32, self.width()); + } }; pub const Color = struct { @@ -119,9 +127,21 @@ pub const Display = struct { return getDisplayHeight(self); } + pub fn heightF(self: Display) f32 { + return @intToFloat(f32, self.height()); + } + + pub fn setTitle(self: Display, title: []const u8) void { + setWindowTitle(self, title); + } + pub fn width(self: Display) i32 { return getDisplayWidth(self); } + + pub fn widthF(self: Display) f32 { + return @intToFloat(f32, self.width()); + } }; pub const DrawFlags = packed struct(c_int) { @@ -708,6 +728,10 @@ pub fn setNewDisplayOption(option: NewDisplayOption, value: i32, importance: Opt c.al_set_new_display_option(@enumToInt(option), value, @enumToInt(importance)); } +pub fn setNewWindowTitle(title: []const u8) void { + c.al_set_new_window_title(&title[0]); +} + pub fn setTargetBitmap(bitmap: Bitmap) void { c.al_set_target_bitmap(bitmap.native); } @@ -716,6 +740,10 @@ pub fn setTargetBackbuffer(display: Display) void { c.al_set_target_bitmap(display.native); } +pub fn setWindowTitle(display: Display, title: []const u8) void { + c.al_set_window_title(display.native, &title[0]); +} + pub fn startTimer(timer: Timer) void { c.al_start_timer(timer.native); } diff --git a/build.zig b/build.zig index 1d79485..57eb45f 100644 --- a/build.zig +++ b/build.zig @@ -19,7 +19,7 @@ pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{}); const exe = b.addExecutable(.{ - .name = "tins2023", + .name = "jungle_tale", // In this case the main source file is merely a path, however, in more // complicated build scripts, this could be a generated file. .root_source_file = .{ .path = "src/main.zig" }, diff --git a/src/assets/images/main_menu.jpg b/src/assets/images/main_menu.jpg new file mode 100644 index 0000000..c45cdbe Binary files /dev/null and b/src/assets/images/main_menu.jpg differ diff --git a/src/assets/images/title_screen.jpg b/src/assets/images/title_screen.jpg new file mode 100644 index 0000000..c41f740 Binary files /dev/null and b/src/assets/images/title_screen.jpg differ diff --git a/src/assets/images/title_untitled.png b/src/assets/images/title_untitled.png deleted file mode 100644 index 46f3419..0000000 Binary files a/src/assets/images/title_untitled.png and /dev/null differ diff --git a/src/context.zig b/src/context.zig index aa6ef86..caaf459 100644 --- a/src/context.zig +++ b/src/context.zig @@ -50,6 +50,7 @@ pub const Context = struct { // allegro.setNewDisplayOption(allegro.NewDisplayOption.SAMPLE_BUFFERS, 1, allegro.OptionImportance.REQUIRE); // allegro.setNewDisplayOption(allegro.NewDisplayOption.SAMPLES, 4, allegro.OptionImportance.REQUIRE); allegro.setNewDisplayFlags(allegro.NewDisplayFlags{ .RESIZABLE = true }); + allegro.setNewWindowTitle("Jungle Tale"); const display = try allegro.createDisplay(DefaultDisplayWidth, DefaultDisplayHeight); events.registerDisplay(display); diff --git a/src/main.zig b/src/main.zig index 8c303ae..7f684e0 100644 --- a/src/main.zig +++ b/src/main.zig @@ -39,7 +39,8 @@ pub fn main() !void { allegro.setNewBitmapFlags(allegro.NewBitmapFlags{ .MIN_LINEAR = true, .MAG_LINEAR = true }); try renderer.textures.addFromFile("opaque", paths.AssetsDir ++ "/images/opaque.png"); - try renderer.textures.addFromFile("title_untitled", paths.AssetsDir ++ "/images/title_untitled.png"); + try renderer.textures.addFromFile("title_screen", paths.AssetsDir ++ "/images/title_screen.jpg"); + try renderer.textures.addFromFile("main_menu", paths.AssetsDir ++ "/images/main_menu.jpg"); try renderer.textures.addFromFile("background_jungle", paths.AssetsDir ++ "/images/background_jungle.png"); allegro.setNewBitmapFlags(allegro.NewBitmapFlags{ .MIN_LINEAR = false, .MAG_LINEAR = false }); @@ -62,7 +63,7 @@ pub fn main() !void { try context.registerFonts(); - try context.switchToScene(GameScene, null); + try context.switchToScene(TitleScene, null); var t = allegro.getTime(); var fpsBuffer = [_]u8{0} ** 32; diff --git a/src/main_menu_scene.zig b/src/main_menu_scene.zig index 6b3e09e..f8707ed 100644 --- a/src/main_menu_scene.zig +++ b/src/main_menu_scene.zig @@ -1,6 +1,7 @@ const allegro = @import("allegro"); const game = @import("game.zig"); const Context = @import("context.zig").Context; +const GameScene = @import("game_scene.zig").GameScene; pub const MainMenuScene = struct { pub fn enter(self: *MainMenuScene, ctx: *Context) void { @@ -14,12 +15,20 @@ pub const MainMenuScene = struct { } pub fn handle(self: *MainMenuScene, ctx: *Context, event: *allegro.Event) !void { - _ = event; - _ = ctx; + switch (event.type) { + allegro.c.ALLEGRO_EVENT_KEY_CHAR => { + switch (event.keyboard.keycode) { + allegro.c.ALLEGRO_KEY_SPACE, allegro.c.ALLEGRO_KEY_ENTER => try ctx.switchToScene(GameScene, null), + else => {}, + } + }, + else => {}, + } _ = self; } - pub fn update(self: *MainMenuScene, ctx: *Context, dt: f32) void { + pub fn tick(self: *MainMenuScene, ctx: *Context, t: f32, dt: f32) void { + _ = t; _ = self; _ = dt; _ = ctx; @@ -29,10 +38,8 @@ pub const MainMenuScene = struct { _ = self; allegro.clearToColor(ctx.palette.background.background); - const center = ctx.viewport.center(); - ctx.textures.get("title_untitled").?.drawTintedCenteredScaled(ctx.palette.background.text, center.x, ctx.viewport.bounds.min.y + ctx.viewport.scale * 100, 0.5 * ctx.viewport.scale); - - ctx.renderer.drawTextV("default", ctx.palette.background.text, 0, 0.3, game.Renderer.TextAlignment.Center, "Play game"); - allegro.drawText(ctx.fonts.get("default").?, ctx.palette.background.text, center.x, ctx.viewport.bounds.min.y + ctx.viewport.scale * 200, allegro.DrawTextFlags.ALIGN_CENTER, "Play game"); + ctx.renderer.drawBackground("main_menu"); + ctx.renderer.drawTextV("default", ctx.palette.background.text, 0.5, 0.5, .Center, "Press [enter] to"); + ctx.renderer.drawTextV("default", ctx.palette.background.text, 0.5, 0.56, .Center, "play the game."); } }; diff --git a/src/renderer.zig b/src/renderer.zig index 8d9fadb..9d9c8ed 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -45,6 +45,12 @@ pub const Renderer = struct { self.display.destroy(); } + pub fn drawBackground(self: Renderer, textureName: []const u8) void { + if (self.textures.get(textureName)) |texture| { + allegro.drawScaledBitmap(texture, 0, 0, texture.widthF(), texture.heightF(), 0, 0, self.display.widthF(), self.display.heightF(), .{}); + } + } + pub fn drawSpriteFrame(self: Renderer, spriteName: []const u8, frame: usize, x: f32, y: f32) void { if (self.sprites.getFrame(spriteName, frame)) |sprite| { sprite.drawScaledUniform(x, y, self.viewport.scale); diff --git a/src/title_scene.zig b/src/title_scene.zig index 8c7a7ff..267aaa6 100644 --- a/src/title_scene.zig +++ b/src/title_scene.zig @@ -19,7 +19,7 @@ pub const TitleScene = struct { switch (event.type) { allegro.c.ALLEGRO_EVENT_KEY_CHAR => { switch (event.keyboard.keycode) { - allegro.c.ALLEGRO_KEY_SPACE => try ctx.switchToScene(MainMenuScene, null), + allegro.c.ALLEGRO_KEY_SPACE, allegro.c.ALLEGRO_KEY_ENTER => try ctx.switchToScene(MainMenuScene, null), else => {}, } }, @@ -38,9 +38,6 @@ pub const TitleScene = struct { pub fn render(self: *TitleScene, ctx: *Context) void { _ = self; allegro.clearToColor(ctx.palette.background.background); - ctx.textures.get("opaque").?.drawTintedScaled(ctx.palette.tertiaryContainer.background, ctx.viewport.bounds.min.x, ctx.viewport.bounds.min.y, ctx.viewport.bounds.width(), ctx.viewport.bounds.height(), allegro.DrawFlags{}); - - const center = ctx.viewport.center(); - ctx.textures.get("title_untitled").?.drawTintedCenteredScaled(ctx.palette.background.text, center.x, center.y, ctx.viewport.scale); + ctx.renderer.drawBackground("title_screen"); } };