From 7a89b05f8ef67111c3e70eb81e577b697fb14e75 Mon Sep 17 00:00:00 2001 From: Sander Schobers Date: Sun, 4 Jun 2023 17:05:20 +0200 Subject: [PATCH] Progress over >1 day. - Added debug overlay. - Added game scene. * Rendering of background, tiles, items & player. * Added levels (reading from text file). * No collision detection yet. - Automatic resizing of fonts. - Added sprites (animate textures). - Lots of utility methods everywhere.... --- allegro/allegro.zig | 50 ++++++++-- src/assets/fonts/Pixellari-OFL.txt | 91 +++++++++++++++++ src/assets/fonts/Pixellari.ttf | Bin 0 -> 39908 bytes src/assets/images/background_jungle.png | Bin 0 -> 126051 bytes src/assets/images/character_lion_48.png | Bin 0 -> 5063 bytes src/assets/images/item_star_32.png | Bin 0 -> 20331 bytes src/assets/images/text_balloons.png | Bin 0 -> 3527 bytes src/assets/images/tiles_dirt_32.png | Bin 0 -> 3708 bytes src/assets/images/tiles_grass_32.png | Bin 0 -> 2902 bytes src/assets/levels/level1.txt | 21 ++++ src/context.zig | 51 ++++------ src/engine.zig | 3 + src/engine/assets.zig | 80 +++++++++++++++ src/engine/fps.zig | 2 + src/engine/keys.zig | 34 +++++++ src/engine/point.zig | 13 +++ src/engine/point_f.zig | 16 +++ src/engine/rectangle.zig | 5 + src/engine/rectangle_f.zig | 5 + src/engine/scene.zig | 18 ++-- src/engine/viewport.zig | 15 +++ src/game.zig | 3 + src/game/animation.zig | 46 +++++++++ src/game/game.zig | 106 ++++++++++++++++++++ src/game/level.zig | 127 ++++++++++++++++++++++++ src/game_scene.zig | 117 ++++++++++++++++++++++ src/main.zig | 64 +++++++----- src/main_menu_scene.zig | 2 + src/paths.zig | 8 ++ src/renderer.zig | 96 ++++++++++++++++++ src/title_scene.zig | 3 +- 31 files changed, 902 insertions(+), 74 deletions(-) create mode 100644 src/assets/fonts/Pixellari-OFL.txt create mode 100644 src/assets/fonts/Pixellari.ttf create mode 100644 src/assets/images/background_jungle.png create mode 100644 src/assets/images/character_lion_48.png create mode 100644 src/assets/images/item_star_32.png create mode 100644 src/assets/images/text_balloons.png create mode 100644 src/assets/images/tiles_dirt_32.png create mode 100644 src/assets/images/tiles_grass_32.png create mode 100644 src/assets/levels/level1.txt create mode 100644 src/engine/keys.zig create mode 100644 src/game.zig create mode 100644 src/game/animation.zig create mode 100644 src/game/game.zig create mode 100644 src/game/level.zig create mode 100644 src/game_scene.zig create mode 100644 src/paths.zig create mode 100644 src/renderer.zig diff --git a/allegro/allegro.zig b/allegro/allegro.zig index 63cb0f7..5fabd77 100644 --- a/allegro/allegro.zig +++ b/allegro/allegro.zig @@ -9,26 +9,34 @@ pub const Bitmap = struct { destroyBitmap(self); } - pub fn draw(self: Bitmap, x: f32, y: f32, flags: DrawFlags) void { - drawBitmap(self, x, y, flags); + pub fn draw(self: Bitmap, x: f32, y: f32) void { + drawBitmap(self, x, y, DrawFlags{}); } pub fn drawCentered(self: Bitmap, x: f32, y: f32) void { self.draw(x - 0.5 * @intToFloat(f32, self.width()), y - 0.5 * @intToFloat(f32, self.height()), DrawFlags{}); } - pub fn drawCenteredScaled(self: Bitmap, x: f32, y: f32, s: f32) void { + pub fn drawCenteredScaledUniform(self: Bitmap, x: f32, y: f32, s: f32) void { const w = s * @intToFloat(f32, self.width()); const h = s * @intToFloat(f32, self.height()); - self.drawScaled(x - 0.5 * w, y - 0.5 * h, w, h, DrawFlags{}); + self.drawScaled(x - 0.5 * w, y - 0.5 * h, w, h); } - pub fn drawScaled(self: Bitmap, x: f32, y: f32, w: f32, h: f32, flags: DrawFlags) void { - drawScaledBitmap(self, 0, 0, @intToFloat(f32, self.width()), @intToFloat(f32, self.height()), x, y, w, h, flags); + pub fn drawScaled(self: Bitmap, x: f32, y: f32, w: f32, h: f32) void { + drawScaledBitmap(self, 0, 0, @intToFloat(f32, self.width()), @intToFloat(f32, self.height()), x, y, w, h, DrawFlags{}); } - pub fn drawTinted(self: Bitmap, tint: Color, x: f32, y: f32, flags: DrawFlags) void { - drawTintedBitmap(self, tint, x, y, flags); + pub fn drawScaledUniform(self: Bitmap, x: f32, y: f32, s: f32) void { + const sourceW = @intToFloat(f32, self.width()); + const sourceH = @intToFloat(f32, self.height()); + const scaledW = s * sourceW; + const scaledH = s * sourceH; + drawScaledBitmap(self, 0, 0, sourceW, sourceH, x, y, scaledW, scaledH, DrawFlags{}); + } + + pub fn drawTinted(self: Bitmap, tint: Color, x: f32, y: f32) void { + drawTintedBitmap(self, tint, x, y, DrawFlags{}); } pub fn drawTintedCentered(self: Bitmap, tint: Color, x: f32, y: f32) void { @@ -38,17 +46,21 @@ pub const Bitmap = struct { pub fn drawTintedCenteredScaled(self: Bitmap, tint: Color, x: f32, y: f32, s: f32) void { const w = s * @intToFloat(f32, self.width()); const h = s * @intToFloat(f32, self.height()); - self.drawTintedScaled(tint, x - 0.5 * w, y - 0.5 * h, w, h, DrawFlags{}); + self.drawTintedScaled(tint, x - 0.5 * w, y - 0.5 * h, w, h); } - pub fn drawTintedScaled(self: Bitmap, tint: Color, x: f32, y: f32, w: f32, h: f32, flags: DrawFlags) void { - drawTintedScaledBitmap(self, tint, 0, 0, @intToFloat(f32, self.width()), @intToFloat(f32, self.height()), x, y, w, h, flags); + pub fn drawTintedScaled(self: Bitmap, tint: Color, x: f32, y: f32, w: f32, h: f32) void { + drawTintedScaledBitmap(self, tint, 0, 0, @intToFloat(f32, self.width()), @intToFloat(f32, self.height()), x, y, w, h, DrawFlags{}); } pub fn height(self: Bitmap) i32 { return getBitmapHeight(self); } + pub fn sub(self: Bitmap, x: i32, y: i32, w: i32, h: i32) !Bitmap { + return createSubBitmap(self, x, y, w, h); + } + pub fn width(self: Bitmap) i32 { return getBitmapWidth(self); } @@ -396,6 +408,14 @@ pub fn createEventQueue() !EventQueue { return error.FailedToCreateEventQueue; } +pub fn createSubBitmap(bitmap: Bitmap, x: i32, y: i32, width: i32, height: i32) !Bitmap { + const sub = c.al_create_sub_bitmap(bitmap.native, x, y, width, height); + if (sub) |native| { + return Bitmap{ .native = native }; + } + return error.FailedToCreateSubBitmap; +} + pub fn createTimer(interval: f32) !Timer { const timer = c.al_create_timer(interval); if (timer) |native| { @@ -652,6 +672,14 @@ pub fn registerEventSource(queue: EventQueue, source: EventSource) void { c.al_register_event_source(queue.native, source.native); } +pub fn saveBitmap(path: [*:0]const u8, bitmap: Bitmap) bool { + return c.al_save_bitmap(path, bitmap.native); +} + +pub fn saveBitmapF(file: File, ident: []const u8, bitmap: Bitmap) bool { + return c.al_save_bitmap_f(file.native, &ident[0], bitmap.native); +} + pub fn setDisplayFlag(display: Display, flag: NewDisplayFlags, on: bool) bool { return c.al_set_display_flag(display.native, @bitCast(c_int, flag), on); } diff --git a/src/assets/fonts/Pixellari-OFL.txt b/src/assets/fonts/Pixellari-OFL.txt new file mode 100644 index 0000000..2c6ee48 --- /dev/null +++ b/src/assets/fonts/Pixellari-OFL.txt @@ -0,0 +1,91 @@ +SIL OPEN FONT LICENSE + +Version 1.1 - 26 February 2007 + +PREAMBLE + +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS + +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting - in part or in whole - any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION + +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/assets/fonts/Pixellari.ttf b/src/assets/fonts/Pixellari.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5a3a3c2b1104814e62854d43e4f5cffe51216707 GIT binary patch literal 39908 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ή%wR+Qz*L^l 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 iy1-z{sb*(k0Rh2~ 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/text_balloons.png b/src/assets/images/text_balloons.png new file mode 100644 index 0000000000000000000000000000000000000000..83e00b1bb538e948017f9f922fec56a1e61c6a2a GIT binary patch literal 3527 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/tiles_dirt_32.png b/src/assets/images/tiles_dirt_32.png new file mode 100644 index 0000000000000000000000000000000000000000..71b71f438db960bb85715feea5bbdcf9c2de45c8 GIT binary patch literal 3708 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 N*;+YTR+{@9`Ug-`;a~s& literal 0 HcmV?d00001 diff --git a/src/assets/levels/level1.txt b/src/assets/levels/level1.txt new file mode 100644 index 0000000..7d09e4e --- /dev/null +++ b/src/assets/levels/level1.txt @@ -0,0 +1,21 @@ +x x +x x +x x +x S S x +x xxxxxx x +x x +x x +x x +x xxxxxx x +x x +x x +x xxxxxx x +x x +x x +x x +xxxxxxxxxx x +x SSSS x +x SSSSS x +x P S S S S x +xxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + \ No newline at end of file diff --git a/src/context.zig b/src/context.zig index 7d37823..34937e4 100644 --- a/src/context.zig +++ b/src/context.zig @@ -1,26 +1,27 @@ const std = @import("std"); const allegro = @import("allegro"); const engine = @import("engine.zig"); +const paths = @import("paths.zig"); const Palette = @import("palette.zig").Palette; const Scene = @import("scene.zig").Scene; +const Renderer = @import("renderer.zig").Renderer; pub const Context = struct { - const DefaultDisplayWidth = 1280; - const DefaultDisplayHeight = 720; + const DefaultDisplayWidth = 960; + const DefaultDisplayHeight = 540; allocator: std.mem.Allocator, palette: Palette = undefined, shouldQuit: bool = false, - showFPS: bool = false, + showFPS: bool = true, + showDebug: bool = true, scene: ?Scene = null, - display: allegro.Display, events: allegro.EventQueue, + renderer: Renderer, - viewport: engine.Viewport, fps: engine.FPS, - fonts: engine.Fonts, - textures: engine.Textures, + keys: engine.Keys(c_int), pub fn init(allocator: std.mem.Allocator) !Context { if (!allegro.init()) { @@ -41,29 +42,24 @@ pub const Context = struct { if (!allegro.initTtfAddon()) { return error.FailedToInitialize; } + const events = try allegro.createEventQueue(); allegro.setNewDisplayOption(allegro.NewDisplayOption.VSYNC, 1, allegro.OptionImportance.SUGGEST); 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 }); - - const viewport = engine.Viewport.init(DefaultDisplayWidth, DefaultDisplayHeight); const display = try allegro.createDisplay(DefaultDisplayWidth, DefaultDisplayHeight); - const events = try allegro.createEventQueue(); - events.registerDisplay(display); events.registerKeyboard(); events.registerMouse(); return Context{ .allocator = allocator, - .display = display, .events = events, - .viewport = viewport, + .renderer = Renderer.init(allocator, display), .fps = engine.FPS{}, - .fonts = engine.Fonts.init(allocator), - .textures = engine.Textures.init(allocator), + .keys = engine.Keys(c_int).init(allocator), }; } @@ -76,21 +72,24 @@ pub const Context = struct { } pub fn deinit(self: *Context) void { - self.events.destroy(); - self.display.destroy(); self.exitScene(); - self.fonts.deinit(); - self.textures.deinit(); + self.renderer.deinit(); + self.events.destroy(); + } + + pub fn registerFonts(self: *Context) !void { + const viewport = self.renderer.viewport; + const fonts = &self.renderer.fonts; + try fonts.addFromFileTTF("default", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(16)); + try fonts.addFromFileTTF("extra-small", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(12)); + try fonts.addFromFileTTF("large", paths.AssetsDir ++ "/fonts/Pixellari.ttf", viewport.scaledInteger(32)); + try fonts.addFromFileTTF("debug", paths.AssetsDir ++ "/fonts/Cabin-Regular.ttf", viewport.scaledInteger(16)); } pub fn quit(self: *Context) void { self.shouldQuit = true; } - pub fn resized(self: *Context, width: i32, height: i32) void { - self.viewport.update(width, height); - } - pub fn switchToScene(self: *Context, comptime SceneType: type, build: ?*const fn (*SceneType) void) !void { self.exitScene(); @@ -98,10 +97,4 @@ pub const Context = struct { self.scene = scene; scene.enter(self); } - - pub fn toggleFullScreen(self: *Context) void { - var displayFlags = allegro.getDisplayFlags(self.display); - _ = allegro.setDisplayFlag(self.display, allegro.NewDisplayFlags{ .FULLSCREEN_WINDOW = true }, !displayFlags.FULLSCREEN_WINDOW); - self.viewport.update(self.display.width(), self.display.height()); - } }; diff --git a/src/engine.zig b/src/engine.zig index c2b3520..db51883 100644 --- a/src/engine.zig +++ b/src/engine.zig @@ -2,11 +2,14 @@ const assets = @import("engine/assets.zig"); pub const Fonts = assets.Fonts; pub const FPS = @import("engine/fps.zig").FPS; +pub const Keys = @import("engine/keys.zig").Keys; pub const OpaquePtr = @import("engine/opaque_ptr.zig").OpaquePtr; pub const Point = @import("engine/point.zig").Point; pub const PointF = @import("engine/point_f.zig").PointF; pub const Rectangle = @import("engine/rectangle.zig").Rectangle; pub const RectangleF = @import("engine/rectangle_f.zig").RectangleF; pub const Scene = @import("engine/scene.zig").Scene; +pub const Sprite = assets.Sprite; +pub const Sprites = assets.Sprites; pub const Textures = assets.Textures; pub const Viewport = @import("engine/viewport.zig").Viewport; diff --git a/src/engine/assets.zig b/src/engine/assets.zig index a5d31cf..b7863cf 100644 --- a/src/engine/assets.zig +++ b/src/engine/assets.zig @@ -52,6 +52,9 @@ pub const Fonts = struct { pub fn addFromFileTTF(self: *Fonts, name: []const u8, path: [*:0]const u8, size: i32) !void { const font = try allegro.loadTtfFont(path, size, allegro.LoadTtfFontFlags{}); + if (self.assets.get(name)) |f| { + f.destroy(); + } try self.assets.put(name, font); } @@ -95,3 +98,80 @@ pub const Textures = struct { return self.assets.get(name); } }; + +pub const Sprite = struct { + allocator: std.mem.Allocator, + frames: []allegro.Bitmap, + + pub fn init(allocator: std.mem.Allocator, bitmap: allegro.Bitmap, width: i32, height: i32) !Sprite { + const bitmapWidth = bitmap.width(); + const bitmapHeight = bitmap.height(); + + const horizontal = @divTrunc(bitmapWidth, width); + const vertical = @divTrunc(bitmapHeight, height); + const n = @intCast(usize, horizontal * vertical); + const frames = try allocator.alloc(allegro.Bitmap, n); + var i: i32 = 0; + while (i < n) : (i += 1) { + const left = @mod(i, horizontal) * width; + const top = @divTrunc(i, horizontal) * width; + frames[@intCast(usize, i)] = try bitmap.sub(left, top, width, height); + } + + return Sprite{ + .allocator = allocator, + .frames = frames, + }; + } + + pub fn deinit(self: Sprite) void { + for (self.frames) |f| { + f.destroy(); + } + self.allocator.free(self.frames); + } + + pub fn frame(self: Sprite, i: usize) allegro.Bitmap { + return self.frames[i]; + } +}; + +pub const Sprites = struct { + fn deinitAsset(sprite: Sprite) void { + sprite.deinit(); + } + const Map = Assets(Sprite, deinitAsset); + + allocator: std.mem.Allocator, + assets: Map, + + pub fn init(allocator: std.mem.Allocator) Sprites { + return Sprites{ + .allocator = allocator, + .assets = Map.init(allocator), + }; + } + + pub fn deinit(self: *Sprites) void { + self.assets.deinit(); + } + + pub fn add(self: *Sprites, name: []const u8, bitmap: allegro.Bitmap, width: i32, height: i32) !void { + try self.assets.put(name, try Sprite.init(self.allocator, bitmap, width, height)); + } + + pub fn addFromTextures(self: *Sprites, textures: Textures, name: []const u8, width: i32, height: i32) !void { + try self.add(name, textures.get(name).?, width, height); + } + + pub fn get(self: Sprites, name: []const u8) ?Sprite { + return self.assets.get(name); + } + + pub fn getFrame(self: Sprites, name: []const u8, i: usize) ?allegro.Bitmap { + if (self.assets.get(name)) |sprite| { + return sprite.frame(i); + } + return null; + } +}; diff --git a/src/engine/fps.zig b/src/engine/fps.zig index ece6f0e..8e5b5ef 100644 --- a/src/engine/fps.zig +++ b/src/engine/fps.zig @@ -20,6 +20,8 @@ pub const FPS = struct { } pub fn fps(self: FPS) usize { + if (self.framesCounted == 0) return 0; + return @floatToInt(usize, @intToFloat(f32, self.framesCounted) / self.total); } }; diff --git a/src/engine/keys.zig b/src/engine/keys.zig new file mode 100644 index 0000000..069eb3d --- /dev/null +++ b/src/engine/keys.zig @@ -0,0 +1,34 @@ +const std = @import("std"); + +pub fn Keys(comptime KeyType: type) type { + return struct { + const Self = @This(); + + pressed: std.AutoHashMap(KeyType, bool), + + pub fn init(allocator: std.mem.Allocator) Self { + return Self{ + .pressed = std.AutoHashMap(KeyType, bool).init(allocator), + }; + } + + pub fn deinit(self: *Self) void { + self.pressed.deinit(); + } + + pub fn isKeyPressed(self: Self, key: KeyType) bool { + if (self.pressed.get(key)) |pressed| { + return pressed; + } + return false; + } + + pub fn press(self: *Self, key: KeyType) !void { + try self.pressed.put(key, true); + } + + pub fn release(self: *Self, key: KeyType) !void { + try self.pressed.put(key, false); + } + }; +} diff --git a/src/engine/point.zig b/src/engine/point.zig index 11944af..6991f34 100644 --- a/src/engine/point.zig +++ b/src/engine/point.zig @@ -1,9 +1,12 @@ +const std = @import("std"); const PointF = @import("point_f.zig").PointF; pub const Point = struct { x: i64, y: i64, + pub const Zero = Point{ .x = 0, .y = 0 }; + pub fn init(x: i64, y: i64) Point { return Point{ .x = x, .y = y }; } @@ -16,6 +19,16 @@ pub const Point = struct { return Point{ .x = self.x + other.x, .y = self.y + other.y }; } + pub fn distance(self: Point, to: Point) i64 { + return std.math.sqrt(self.distance2(to)); + } + + pub fn distance2(self: Point, to: Point) i64 { + const dx = to.x - self.x; + const dy = to.y - self.y; + return dx * dx + dy * dy; + } + pub fn float(self: Point) PointF { return PointF{ .x = @intToFloat(f32, self.x), .y = @intToFloat(f32, self.y) }; } diff --git a/src/engine/point_f.zig b/src/engine/point_f.zig index 2746fdd..baf23a9 100644 --- a/src/engine/point_f.zig +++ b/src/engine/point_f.zig @@ -6,6 +6,8 @@ pub const PointF = struct { x: f32, y: f32, + pub const Zero = Point{ .x = 0, .y = 0 }; + pub fn init(x: f32, y: f32) PointF { return PointF{ .x = x, .y = y }; } @@ -18,6 +20,16 @@ pub const PointF = struct { return PointF{ .x = std.math.ceil(self.x), .y = std.math.ceil(self.y) }; } + pub fn distance(self: PointF, to: PointF) f32 { + return std.math.sqrt(self.distance2(to)); + } + + pub fn distance2(self: PointF, to: PointF) f32 { + const dx = to.x - self.x; + const dy = to.y - self.y; + return dx * dx + dy * dy; + } + pub fn floor(self: PointF) PointF { return PointF{ .x = std.math.floor(self.x), .y = std.math.floor(self.y) }; } @@ -30,6 +42,10 @@ pub const PointF = struct { return PointF{ .x = self.x * factor, .y = self.y * factor }; } + pub fn round(self: PointF) PointF { + return PointF{ .x = std.math.round(self.x), .y = std.math.round(self.y) }; + } + pub fn subtract(self: PointF, other: PointF) PointF { return PointF{ .x = self.x - other.x, .y = self.y - other.y }; } diff --git a/src/engine/rectangle.zig b/src/engine/rectangle.zig index ef38cee..60e5ae0 100644 --- a/src/engine/rectangle.zig +++ b/src/engine/rectangle.zig @@ -1,4 +1,5 @@ const Point = @import("point.zig").Point; +const RectangleF = @import("rectangle_f.zig").RectangleF; pub const Rectangle = struct { min: Point, @@ -65,6 +66,10 @@ pub const Rectangle = struct { return Point.init(@divTrunc(self.min.x + self.max.x, 2), @divTrunc(self.min.y + self.max.y, 2)); } + pub fn float(self: Rectangle) RectangleF { + return RectangleF{ .min = self.min.float(), .max = self.max.float() }; + } + pub fn height(self: Rectangle) i64 { return self.max.y - self.min.y; } diff --git a/src/engine/rectangle_f.zig b/src/engine/rectangle_f.zig index 6dd3abe..6ae4166 100644 --- a/src/engine/rectangle_f.zig +++ b/src/engine/rectangle_f.zig @@ -1,4 +1,5 @@ const PointF = @import("point_f.zig").PointF; +const Rectangle = @import("rectangle.zig").Rectangle; pub const RectangleF = struct { min: PointF, @@ -69,6 +70,10 @@ pub const RectangleF = struct { return self.max.y - self.min.y; } + pub fn integer(self: RectangleF) Rectangle { + return Rectangle{ .min = self.min.integer(), .max = self.max.integer() }; + } + pub fn width(self: RectangleF) f32 { return self.max.x - self.min.x; } diff --git a/src/engine/scene.zig b/src/engine/scene.zig index ea026e3..7dcb8b8 100644 --- a/src/engine/scene.zig +++ b/src/engine/scene.zig @@ -13,7 +13,7 @@ pub fn Scene(comptime Context: type, comptime Event: type) type { enter: *const fn (Self, *Context) void, exit: *const fn (Self, *Context) void, handle: *const fn (Self, *Context, Event) anyerror!void, - update: *const fn (Self, *Context, f32) void, + tick: *const fn (Self, *Context, f32, f32) void, render: *const fn (Self, *Context) void, }; @@ -29,14 +29,14 @@ pub fn Scene(comptime Context: type, comptime Event: type) type { try self.virtualTable.handle(self, ctx, event); } - pub fn update(self: Self, ctx: *Context, dt: f32) void { - self.virtualTable.update(self, ctx, dt); - } - pub fn render(self: Self, ctx: *Context) void { self.virtualTable.render(self, ctx); } + pub fn tick(self: Self, ctx: *Context, t: f32, dt: f32) void { + self.virtualTable.tick(self, ctx, t, dt); + } + pub fn makeOpaque(comptime SceneType: type, object: *SceneType) Self { return Self{ .object = @ptrToInt(object), .virtualTable = .{ .enter = struct { @@ -57,12 +57,12 @@ pub fn Scene(comptime Context: type, comptime Event: type) type { try scene.handle(ctx, event); } }.handle, - .update = struct { - fn update(self: Self, ctx: *Context, dt: f32) void { + .tick = struct { + fn tick(self: Self, ctx: *Context, t: f32, dt: f32) void { const scene = @intToPtr(*SceneType, self.object); - scene.update(ctx, dt); + scene.tick(ctx, t, dt); } - }.update, + }.tick, .render = struct { fn render(self: Self, ctx: *Context) void { const scene = @intToPtr(*SceneType, self.object); diff --git a/src/engine/viewport.zig b/src/engine/viewport.zig index c53e34d..cafda5a 100644 --- a/src/engine/viewport.zig +++ b/src/engine/viewport.zig @@ -1,3 +1,4 @@ +const std = @import("std"); const PointF = @import("point_f.zig").PointF; const RectangleF = @import("rectangle_f.zig").RectangleF; @@ -30,6 +31,20 @@ pub const Viewport = struct { return self.bounds.center(); } + pub fn scaledInteger(self: Viewport, i: i32) i32 { + return @floatToInt(i32, std.math.round(@intToFloat(f32, i) * self.scale)); + } + + pub fn viewToScreen(self: Viewport, x: f32, y: f32) PointF { + const screenX = self.bounds.min.x + x * self.bounds.width(); + const screenY = self.bounds.min.y + y * self.bounds.height(); + return PointF.init(screenX, screenY); + } + + pub fn viewToScreenP(self: Viewport, position: PointF) PointF { + return self.viewToScreen(position.x, position.y); + } + pub fn update(self: *Viewport, width: i32, height: i32) void { self.actualWidth = width; self.actualHeight = height; diff --git a/src/game.zig b/src/game.zig new file mode 100644 index 0000000..3557b9e --- /dev/null +++ b/src/game.zig @@ -0,0 +1,3 @@ +pub const Animation = @import("game/animation.zig").Animation; +pub const Game = @import("game/game.zig").Game; +pub const Level = @import("game/level.zig").Level; diff --git a/src/game/animation.zig b/src/game/animation.zig new file mode 100644 index 0000000..95f844a --- /dev/null +++ b/src/game/animation.zig @@ -0,0 +1,46 @@ +const allegro = @import("allegro"); +const engine = @import("../engine.zig"); + +pub const Animation = struct { + sprite: engine.Sprite, + current: usize, + begin: usize, + end: usize, + interval: f32, + lastUpdate: f32, + + pub fn init(sprite: engine.Sprite, interval: f32) Animation { + return Animation.initPartialLoop(sprite, interval, 0, sprite.frames.len); + } + + pub fn initPartialLoop(sprite: engine.Sprite, interval: f32, begin: usize, end: usize) Animation { + return Animation{ + .sprite = sprite, + .current = begin, + .begin = begin, + .end = end, + .interval = interval, + .lastUpdate = 0, + }; + } + + pub fn currentFrame(self: *Animation) allegro.Bitmap { + return self.sprite.frames[self.current]; + } + + pub fn reset(self: *Animation) void { + self.current = self.begin; + } + + pub fn tick(self: *Animation, t: f32) void { + const delta = t - self.lastUpdate; + + const skip = @floatToInt(usize, @divFloor(delta, self.interval)); + self.lastUpdate = t - @rem(delta, self.interval); + + self.current = (self.current + skip); + while (self.current >= self.end) { + self.current = self.begin; + } + } +}; diff --git a/src/game/game.zig b/src/game/game.zig new file mode 100644 index 0000000..331d93d --- /dev/null +++ b/src/game/game.zig @@ -0,0 +1,106 @@ +const std = @import("std"); +const engine = @import("../engine.zig"); +const Animation = @import("animation.zig").Animation; +const Renderer = @import("../renderer.zig").Renderer; +const Level = @import("level.zig").Level; + +pub const Game = struct { + pub const Direction = enum { + Left, + Right, + }; + + level: Level, + health: i64 = 4, + playerPosition: engine.PointF, + playerIdleAnimation: Animation, + playerWalkingAnimation: Animation, + playerDirection: Direction, + isPlayerWalking: bool, + + renderer: *Renderer, + // current viewport translated to tiles. + boundsInTiles: engine.RectangleF, + + pub fn init(level: Level, renderer: *Renderer) Game { + const playerPosition = level.character.float(); + return Game{ + .level = level, + .playerPosition = playerPosition, + .playerIdleAnimation = Animation.initPartialLoop(renderer.sprites.get("character_lion_48").?, 0.25, 0, 4), + .playerWalkingAnimation = Animation.initPartialLoop(renderer.sprites.get("character_lion_48").?, 0.125, 4, 8), + .playerDirection = Direction.Right, + .isPlayerWalking = false, + .renderer = renderer, + .boundsInTiles = Game.calculateBoundsInTiles(playerPosition), + }; + } + + fn calculateBoundsInTiles(position: engine.PointF) engine.RectangleF { + return engine.RectangleF.initRelative( + position.x - 15, + @min(position.y - 8.875, 4.125), + 30, + 16.875, + ); + } + + pub fn drawSpriteFrame(self: *Game, spriteName: []const u8, frame: usize, x: i64, y: i64) void { + self.drawSpriteFrameP(spriteName, frame, engine.Point.init(x, y).float()); + } + + pub fn drawSpriteFrameP(self: *Game, spriteName: []const u8, frame: usize, position: engine.PointF) void { + const view = self.tileP(position); + self.renderer.drawSpriteFrameV(spriteName, frame, view.x, view.y); + } + + pub fn moveCharacter(self: *Game, distance: f32) void { + self.playerPosition.x += distance; + self.isPlayerWalking = true; + self.playerDirection = if (distance > 0) Direction.Right else Direction.Left; + + self.boundsInTiles = Game.calculateBoundsInTiles(self.playerPosition); + } + + // return values are in view coordinates + pub fn tile(self: Game, x: f32, y: f32) engine.PointF { + return self.tileP(engine.PointF.init(x, y)); + } + + pub fn tileCenter(self: Game, x: i64, y: i64) engine.PointF { + return self.tileCenterP(engine.Point.init(x, y)); + } + + pub fn tileCenterP(self: Game, position: engine.Point) engine.PointF { + const center = engine.PointF.init(0.5, 0.5); + return self.tileP(position.float().add(center)); + } + + pub fn tileP(self: Game, position: engine.PointF) engine.PointF { + const relative = position.subtract(self.boundsInTiles.min); + return engine.PointF.init(relative.x / self.boundsInTiles.width(), relative.y / self.boundsInTiles.height()); + } + + pub fn tileTopLeft(self: Game, x: i64, y: i64) engine.PointF { + return self.tileTopLeftP(engine.Point.init(x, y)); + } + + pub fn tileTopLeftP(self: Game, p: engine.Point) engine.PointF { + return self.tileP(p.float()); + } + + pub fn tilesInView(self: Game) engine.Rectangle { + // tiles that are partially or completely in view. + return engine.RectangleF.initAbsolute( + std.math.floor(self.boundsInTiles.min.x), + std.math.floor(self.boundsInTiles.min.y), + std.math.floor(self.boundsInTiles.max.x) + 1, + std.math.floor(self.boundsInTiles.max.y) + 1, + ).integer(); + } + + pub fn tick(self: *Game, t: f32, dt: f32) void { + _ = dt; + self.playerAnimation.tick(t); + } +}; diff --git a/src/game/level.zig b/src/game/level.zig new file mode 100644 index 0000000..b6c688f --- /dev/null +++ b/src/game/level.zig @@ -0,0 +1,127 @@ +const std = @import("std"); +const engine = @import("../engine.zig"); + +pub const Level = struct { + pub fn Column(comptime Value: type) type { + return struct { + const Self = @This(); + + values: std.AutoHashMap(i64, Value), + + pub fn init(allocator: std.mem.Allocator) Self { + return Self{ + .values = std.AutoHashMap(i64, Value).init(allocator), + }; + } + + pub fn deinit(self: Self) void { + self.values.deinit(); + } + + pub fn get(self: Self, row: i64) ?Value { + return self.values.get(row); + } + + pub fn set(self: *Self, row: i64, value: Value) !void { + try self.values.put(row, value); + } + }; + } + + pub fn Components(comptime Value: type) type { + return struct { + const Self = @This(); + + allocator: std.mem.Allocator, + columns: std.ArrayList(Column(Value)), + + pub fn init(allocator: std.mem.Allocator) Self { + return Self{ + .allocator = allocator, + .columns = std.ArrayList(Column(Value)).init(allocator), + }; + } + + pub fn deinit(self: Self) void { + for (self.columns.items) |item| { + item.deinit(); + } + self.columns.deinit(); + } + + pub fn column(self: Self, i: i64) *Column(Value) { + return &self.columns.items[@intCast(usize, i)]; + } + + fn ensureColumns(self: *Self, n: usize) !void { + while (self.columns.items.len < n) { + try self.columns.append(Column(Value).init(self.allocator)); + } + } + + pub fn set(self: *Self, c: i64, r: i64, value: Value) !void { + try self.ensureColumns(@intCast(usize, c) + 1); + try self.column(c).set(r, value); + } + }; + } + + pub const Tile = enum { + Grass, + }; + + pub const Collectable = enum { + Star, + }; + + character: engine.Point, + tiles: Components(Tile), + collectables: Components(Collectable), + + pub fn load(allocator: std.mem.Allocator, path: []const u8) !Level { + const path_ = try std.fs.realpathAlloc(allocator, path); + defer allocator.free(path_); + + const file = try std.fs.openFileAbsolute(path_, .{ .mode = .read_only }); + defer file.close(); + + const data = try file.readToEndAlloc(allocator, 1024 * 1024); + defer allocator.free(data); + + return try Level.loadFromMemory(allocator, data); + } + + pub fn loadFromMemory(allocator: std.mem.Allocator, data: []const u8) !Level { + const n = std.mem.count(u8, data, "\n"); + _ = n; + + var character: ?engine.Point = null; + var tiles = Components(Tile).init(allocator); + var collectables = Components(Collectable).init(allocator); + + var lines = std.mem.split(u8, data, "\n"); + var y: i64 = 0; + while (lines.next()) |line| { + defer y += 1; + + try tiles.ensureColumns(line.len); + try collectables.ensureColumns(line.len); + + for (line, 0..) |tile, column| { + var x = @intCast(i64, column); + switch (tile) { + 'P' => character = engine.Point.init(x, y), + 'S' => try collectables.set(x, y, Collectable.Star), + 'x' => try tiles.set(x, y, Tile.Grass), + else => {}, + } + } + } + + return Level{ + .character = character.?, + .tiles = tiles, + .collectables = collectables, + }; + } +}; diff --git a/src/game_scene.zig b/src/game_scene.zig new file mode 100644 index 0000000..73255e0 --- /dev/null +++ b/src/game_scene.zig @@ -0,0 +1,117 @@ +const std = @import("std"); +const allegro = @import("allegro"); +const engine = @import("engine.zig"); +const game = @import("game.zig"); +const paths = @import("paths.zig"); +const Context = @import("context.zig").Context; +const Renderer = @import("renderer.zig").Renderer; + +pub const GameScene = struct { + game: game.Game = undefined, + + pub fn enter(self: *GameScene, ctx: *Context) void { + const level = game.Level.load(ctx.allocator, paths.AssetsDir ++ "/levels/level1.txt") catch unreachable; + self.game = game.Game.init(level, &ctx.renderer); + } + + pub fn exit(self: *GameScene, ctx: *Context) void { + _ = ctx; + _ = self; + } + + pub fn handle(self: *GameScene, ctx: *Context, event: *allegro.Event) !void { + _ = event; + _ = ctx; + _ = self; + } + + pub fn tick(self: *GameScene, ctx: *Context, t: f32, dt: f32) void { + const speed: f32 = 5; // tiles/s + + if (ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_LEFT)) { + self.game.moveCharacter(-speed * dt); + self.game.playerWalkingAnimation.tick(t); + } else if (ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_RIGHT)) { + self.game.moveCharacter(speed * dt); + self.game.playerWalkingAnimation.tick(t); + } else { + if (self.game.isPlayerWalking) { + self.game.playerWalkingAnimation.reset(); + } + self.game.isPlayerWalking = false; + self.game.playerIdleAnimation.tick(t); + } + } + + pub fn render(self: *GameScene, ctx: *Context) void { + allegro.clearToColor(ctx.palette.background.background); + + const renderer = ctx.renderer; + const viewport = renderer.viewport; + + const center = viewport.center(); + _ = center; + const bounds = viewport.bounds; + const scale = viewport.scale; + _ = scale; + const background = renderer.textures.get("background_jungle").?; + const backgroundDisplacementFactor = -0.01; + + const backgroundCenter = self.game.playerPosition.x * backgroundDisplacementFactor; + const backgroundLeft = @mod(backgroundCenter, 1.0) - 1; + + background.drawScaled(bounds.min.x + backgroundLeft * bounds.width(), bounds.min.y, bounds.width(), bounds.height()); + background.drawScaled(bounds.min.x + (backgroundLeft + 1) * bounds.width(), bounds.min.y, bounds.width(), bounds.height()); + + const tileBounds = self.game.tilesInView(); + + var x = tileBounds.min.x; + while (x < tileBounds.max.x) : (x += 1) { + self.game.drawSpriteFrame("tiles_dirt_32", 0, x, 19); + self.game.drawSpriteFrame("tiles_dirt_32", 3, x, 20); + + if (x < 0) continue; + + const tiles = self.game.level.tiles.column(x); + const collectables = self.game.level.collectables.column(x); + var y = tileBounds.min.y; + while (y < tileBounds.max.y) : (y += 1) { + if (tiles.get(y)) |tile| { + switch (tile) { + game.Level.Tile.Grass => { + self.game.drawSpriteFrame("tiles_grass_32", 1, x, y - 1); + self.game.drawSpriteFrame("tiles_grass_32", 5, x, y); + }, + // else => {}, + } + } + + if (collectables.get(y)) |collectable| { + switch (collectable) { + game.Level.Collectable.Star => { + const distanceToPlayer = engine.Point.init(x, y).float().distance(self.game.playerPosition); + self.game.drawSpriteFrame("item_star_32", @floatToInt(usize, @mod(distanceToPlayer * 0.54, 1) * 16), x, y); + }, + } + } + } + } + + const playerDirectionFrameOffset: usize = if (self.game.playerDirection == game.Game.Direction.Left) 0 else 8; + if (self.game.isPlayerWalking) { + self.game.drawSpriteFrameP("character_lion_48", self.game.playerWalkingAnimation.current + playerDirectionFrameOffset, self.game.playerPosition.add(engine.PointF.init(-0.25, -0.25))); + } else { + self.game.drawSpriteFrameP("character_lion_48", self.game.playerIdleAnimation.current + playerDirectionFrameOffset, self.game.playerPosition.add(engine.PointF.init(-0.25, -0.25))); + } + + if (ctx.showDebug) { + ctx.renderer.printTextV("debug", ctx.palette.background.text, 0.01, 0.1, Renderer.TextAlignment.Left, "Character: ({d}, {d})", .{ self.game.playerPosition.x, self.game.playerPosition.y }); + ctx.renderer.printTextV("debug", ctx.palette.background.text, 0.01, 0.15, Renderer.TextAlignment.Left, "Tiles: ({d}, {d}) -> ({d}, {d})", .{ tileBounds.min.x, tileBounds.min.y, tileBounds.max.x, tileBounds.max.y }); + + // const characterTopLeft = self.game.tileP(self.game.playerPosition); + // const characterTopLeftScreen = renderer.viewport.viewToScreenP(characterTopLeft); + // const tileWidthScreen = 32 * viewport.scale; + // renderer.textures.get("opaque").?.drawTintedScaled(allegro.mapRgba(127, 127, 127, 127), characterTopLeftScreen.x, characterTopLeftScreen.y, tileWidthScreen, tileWidthScreen); + } + } +}; diff --git a/src/main.zig b/src/main.zig index 54323f1..384f0ad 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,17 +1,14 @@ const std = @import("std"); const allegro = @import("allegro"); const engine = @import("engine.zig"); +const game = @import("game.zig"); +const paths = @import("paths.zig"); const Context = @import("context.zig").Context; +const GameScene = @import("game_scene.zig").GameScene; const Palette = @import("palette.zig").Palette; +const Renderer = @import("renderer.zig").Renderer; const TitleScene = @import("title_scene.zig").TitleScene; -fn currentFile() []const u8 { - return @src().file; -} - -const sourceDir = std.fs.path.dirname(currentFile()).?; -const assetsDir = sourceDir ++ "/assets"; - fn hexColor(hex: []const u8) allegro.Color { return allegro.Color.initFromHex(hex); } @@ -38,41 +35,69 @@ pub fn main() !void { .background = .{ .background = hexColor("#fffbff"), .text = hexColor("#2b0052") }, .outline = hexColor("#7c757e"), }; + const renderer = &context.renderer; allegro.setNewBitmapFlags(allegro.NewBitmapFlags{ .MIN_LINEAR = true, .MAG_LINEAR = true }); - try context.textures.addFromFile("opaque", assetsDir ++ "/images/opaque.png"); - try context.textures.addFromFile("title_untitled", assetsDir ++ "/images/title_untitled.png"); + 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("background_jungle", paths.AssetsDir ++ "/images/background_jungle.png"); + try renderer.textures.addFromFile("character_lion_48", paths.AssetsDir ++ "/images/character_lion_48.png"); + try renderer.textures.addFromFile("item_star_32", paths.AssetsDir ++ "/images/item_star_32.png"); + try renderer.textures.addFromFile("text_balloons", paths.AssetsDir ++ "/images/text_balloons.png"); + try renderer.textures.addFromFile("tiles_dirt_32", paths.AssetsDir ++ "/images/tiles_dirt_32.png"); + try renderer.textures.addFromFile("tiles_grass_32", paths.AssetsDir ++ "/images/tiles_grass_32.png"); + + try renderer.sprites.addFromTextures(renderer.textures, "character_lion_48", 48, 48); + try renderer.sprites.addFromTextures(renderer.textures, "item_star_32", 32, 32); + try renderer.sprites.addFromTextures(renderer.textures, "tiles_dirt_32", 32, 32); + try renderer.sprites.addFromTextures(renderer.textures, "tiles_grass_32", 32, 32); + allegro.convertMemoryBitmaps(); - try context.fonts.addFromFileTTF("sub", assetsDir ++ "/fonts/Cabin-Regular.ttf", 16); - try context.fonts.addFromFileTTF("default", assetsDir ++ "/fonts/Cabin-Regular.ttf", 32); + try context.registerFonts(); - try context.switchToScene(TitleScene, null); + try context.switchToScene(GameScene, null); var t = allegro.getTime(); var fpsBuffer = [_]u8{0} ** 32; + _ = fpsBuffer; while (!context.shouldQuit) { const scene = if (context.scene) |scene| scene else { break; }; + const newT = allegro.getTime(); + const deltaT = @floatCast(f32, newT - t); + t = newT; + context.fps.update(deltaT); + scene.tick(&context, @floatCast(f32, t), deltaT); + while (!context.events.isEmpty()) { var event: allegro.Event = undefined; _ = context.events.get(&event); switch (event.type) { allegro.c.ALLEGRO_EVENT_DISPLAY_CLOSE => context.quit(), allegro.c.ALLEGRO_EVENT_DISPLAY_RESIZE => { - context.resized(event.display.width, event.display.height); + context.renderer.resized(event.display.width, event.display.height); + try context.registerFonts(); _ = allegro.acknowledgeResize(allegro.Display{ .native = event.display.source.? }); }, allegro.c.ALLEGRO_EVENT_KEY_CHAR => { switch (event.keyboard.keycode) { allegro.c.ALLEGRO_KEY_ESCAPE => context.quit(), allegro.c.ALLEGRO_KEY_F9 => context.showFPS = !context.showFPS, - allegro.c.ALLEGRO_KEY_F11 => context.toggleFullScreen(), + allegro.c.ALLEGRO_KEY_F10 => context.showDebug = !context.showDebug, + allegro.c.ALLEGRO_KEY_F11 => renderer.toggleFullScreen(), + allegro.c.ALLEGRO_KEY_F12 => try renderer.takeScreenshot(), else => {}, } }, + allegro.c.ALLEGRO_EVENT_KEY_DOWN => { + try context.keys.press(event.keyboard.keycode); + }, + allegro.c.ALLEGRO_EVENT_KEY_UP => { + try context.keys.release(event.keyboard.keycode); + }, else => {}, } if (context.shouldQuit) { @@ -81,18 +106,9 @@ pub fn main() !void { try scene.handle(&context, &event); } - const newT = allegro.getTime(); - const deltaT = @floatCast(f32, newT - t); - t = newT; - scene.update(&context, deltaT); - context.fps.update(deltaT); - scene.render(&context); if (context.showFPS) { - if (context.fonts.get("default")) |font| { - const fps = try std.fmt.bufPrintZ(fpsBuffer[0..], "FPS: {}", .{context.fps.fps()}); - allegro.drawText(font, context.palette.background.text, 10, 10, allegro.DrawTextFlags.ALIGN_LEFT, fps); - } + renderer.printTextV("debug", context.palette.background.text, 0.01, 0.01, Renderer.TextAlignment.Left, "FPS: {}", .{context.fps.fps()}); } allegro.flipDisplay(); diff --git a/src/main_menu_scene.zig b/src/main_menu_scene.zig index a126546..6b3e09e 100644 --- a/src/main_menu_scene.zig +++ b/src/main_menu_scene.zig @@ -1,4 +1,5 @@ const allegro = @import("allegro"); +const game = @import("game.zig"); const Context = @import("context.zig").Context; pub const MainMenuScene = struct { @@ -31,6 +32,7 @@ pub const MainMenuScene = struct { 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"); } }; diff --git a/src/paths.zig b/src/paths.zig new file mode 100644 index 0000000..3b75a57 --- /dev/null +++ b/src/paths.zig @@ -0,0 +1,8 @@ +const std = @import("std"); + +fn currentFile() []const u8 { + return @src().file; +} + +pub const SourceDir = std.fs.path.dirname(currentFile()).?; +pub const AssetsDir = SourceDir ++ "/assets"; diff --git a/src/renderer.zig b/src/renderer.zig new file mode 100644 index 0000000..9a1ecfe --- /dev/null +++ b/src/renderer.zig @@ -0,0 +1,96 @@ +const std = @import("std"); +const allegro = @import("allegro"); +const engine = @import("engine.zig"); +const Context = @import("context.zig").Context; + +pub const Renderer = struct { + textFormattingBuffer: [1024]u8 = [_]u8{0} ** 1024, + + display: allegro.Display, + viewport: engine.Viewport, + fonts: engine.Fonts, + textures: engine.Textures, + sprites: engine.Sprites, + + pub const TextAlignment = enum { + Center, + Left, + Right, + + pub fn toDrawTextFlags(self: TextAlignment) allegro.DrawTextFlags { + return switch (self) { + .Center => allegro.DrawTextFlags.ALIGN_CENTER, + .Left => allegro.DrawTextFlags.ALIGN_LEFT, + .Right => allegro.DrawTextFlags.ALIGN_RIGHT, + }; + } + }; + + pub fn init(allocator: std.mem.Allocator, display: allegro.Display) Renderer { + const viewport = engine.Viewport.init(display.width(), display.height()); + + return Renderer{ + .display = display, + .viewport = viewport, + .fonts = engine.Fonts.init(allocator), + .textures = engine.Textures.init(allocator), + .sprites = engine.Sprites.init(allocator), + }; + } + + pub fn deinit(self: *Renderer) void { + self.fonts.deinit(); + self.textures.deinit(); + self.sprites.deinit(); + self.display.destroy(); + } + + pub fn drawText(self: Renderer, fontName: []const u8, color: allegro.Color, x: f32, y: f32, alignment: TextAlignment, text: [*:0]const u8) void { + if (self.fonts.get(fontName)) |font| { + font.draw(color, x, y, alignment.toDrawTextFlags(), text); + } + } + + 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); + } + } + + pub fn drawSpriteFrameV(self: Renderer, spriteName: []const u8, frame: usize, x: f32, y: f32) void { + const screen = self.viewport.viewToScreen(x, y); + self.drawSpriteFrame(spriteName, frame, screen.x, screen.y); + } + + pub fn drawTextV(self: Renderer, fontName: []const u8, color: allegro.Color, x: f32, y: f32, alignment: TextAlignment, text: [*:0]const u8) void { + const screen = self.viewport.viewToScreen(x, y); + self.drawText(fontName, color, screen.x, screen.y, alignment, text); + } + + pub fn printText(self: *Renderer, font: []const u8, color: allegro.Color, x: f32, y: f32, alignment: TextAlignment, comptime fmt: []const u8, args: anytype) void { + const text = std.fmt.bufPrintZ(&self.textFormattingBuffer, fmt, args) catch { + return; + }; + self.drawText(font, color, x, y, alignment, text); + } + + pub fn printTextV(self: *Renderer, font: []const u8, color: allegro.Color, x: f32, y: f32, alignment: TextAlignment, comptime fmt: []const u8, args: anytype) void { + const screen = self.viewport.viewToScreen(x, y).round(); + self.printText(font, color, screen.x, screen.y, alignment, fmt, args); + } + + pub fn resized(self: *Renderer, width: i32, height: i32) void { + self.viewport.update(width, height); + } + + pub fn takeScreenshot(self: Renderer) !void { + const screen = try allegro.getBackbuffer(self.display); + _ = allegro.saveBitmap("screenshot.png", screen); + } + + pub fn toggleFullScreen(self: *Renderer) void { + var displayFlags = allegro.getDisplayFlags(self.display); + _ = allegro.setDisplayFlag(self.display, allegro.NewDisplayFlags{ .FULLSCREEN_WINDOW = true }, !displayFlags.FULLSCREEN_WINDOW); + self.viewport.update(self.display.width(), self.display.height()); + } +}; diff --git a/src/title_scene.zig b/src/title_scene.zig index a1fadda..8c7a7ff 100644 --- a/src/title_scene.zig +++ b/src/title_scene.zig @@ -28,7 +28,8 @@ pub const TitleScene = struct { _ = self; } - pub fn update(self: *TitleScene, ctx: *Context, dt: f32) void { + pub fn tick(self: *TitleScene, ctx: *Context, t: f32, dt: f32) void { + _ = t; _ = self; _ = dt; _ = ctx;