Added background image, TTF loading, rgb color struct

This commit is contained in:
2025-01-05 20:03:15 -07:00
parent 8ece62d49a
commit 52097b3861
13 changed files with 386 additions and 13 deletions
+2
View File
@@ -6,6 +6,8 @@ pub const GameState = struct {
r: u8 = 0xff,
g: u8 = 0xff,
b: u8 = 0xff,
SCREEN_WIDTH: u32 = 640,
SCREEN_HEIGHT: u32 = 480,
slime_factory: sf.SlimeFactory = undefined,
renderer: *sdl.struct_SDL_Renderer = undefined,
+17 -9
View File
@@ -6,6 +6,8 @@ const assert = std.debug.assert;
const SCREEN_WIDTH = 640;
const SCREEN_HEIGHT = 480;
const log = sdl.SDL_Log;
const GameText = @import("./text.zig").GameText;
const RGBAColor = @import("./utils/rgb_color.zig").RGBAColor;
var window: *sdl.struct_SDL_Window = undefined;
// var screen_surface: *sdl.struct_SDL_Surface = undefined;
@@ -24,8 +26,11 @@ pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
const texture = try atils.loadTexture(renderer, "assets/png_test.png");
defer sdl.SDL_DestroyTexture(texture);
const bg_texture = try atils.loadTexture(renderer, "assets/background.png");
defer sdl.SDL_DestroyTexture(bg_texture);
try GameText.initFont();
defer GameText.deinitFont();
// var slime_factory = try sf.SlimeFactory.init(allocator, renderer);
// defer slime_factory.deinit();
@@ -86,13 +91,10 @@ pub fn main() !void {
}
_ = sdl.SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 0xff);
_ = sdl.SDL_RenderClear(renderer);
std.debug.print("r:{x} g:{x} b:{x}\n", .{
game_state.r,
game_state.g,
game_state.b,
});
_ = sdl.SDL_RenderCopy(renderer, bg_texture, null, null);
game_state.update_tick();
var text = try GameText.loadFromRenderedText("Test 123", RGBAColor.whiteSmoke().tosdl());
try text.render(&game_state);
// Render red rect
// const fill_rect: sdl.struct_SDL_Rect = sdl.SDL_Rect{ .x = SCREEN_WIDTH / 4, .y = SCREEN_HEIGHT / 4, .w = SCREEN_WIDTH / 2 + img_pos.x, .h = SCREEN_HEIGHT / 2 + img_pos.y };
@@ -105,7 +107,7 @@ pub fn main() !void {
// _ = sdl.SDL_BlitScaled(zig_image, &src_rect, screen_surface, &dest_rect);
// _ = sdl.SDL_UpdateWindowSurface(window);
sdl.SDL_Delay(117);
sdl.SDL_Delay(100);
}
return;
}
@@ -138,11 +140,17 @@ fn init() !void {
log("Unable to initialize SDL Image: %s\n", sdl.IMG_GetError());
return error.SDLInitializationFailed;
}
if (sdl.TTF_Init() < 0) {
log("Unable to initialize SDL TTF: %s\n", sdl.TTF_GetError());
return error.SDLInitializationFailed;
}
}
fn close() void {
sdl.SDL_DestroyRenderer(renderer);
sdl.SDL_DestroyWindow(window);
sdl.IMG_Quit();
sdl.TTF_Quit();
sdl.SDL_Quit();
}
+1
View File
@@ -1,4 +1,5 @@
pub const c = @cImport({
@cInclude("SDL2/SDL.h");
@cInclude("SDL2/SDL_image.h");
@cInclude("SDL2/SDL_ttf.h");
});
+25 -4
View File
@@ -3,12 +3,19 @@ const sdl = @import("sdl.zig").c;
const atils = @import("./asset_utils.zig");
const GameState = @import("./game_state.zig").GameState;
const slime_sprite_sheet_texture_path = "assets/slime_still.png";
const rgba = @import("./utils/rgb_color.zig").RGBAColor;
pub const Slime = struct {
total_frames: u8 = 6,
x: i32 = 64,
y: i32 = 64,
y: i32 = 300,
f: u16 = 0,
color: rgba = .{
.r = 0xd5,
.g = 0x0f,
.b = 0x65,
.a = 110,
},
};
pub const SlimeFactory = struct {
@@ -17,6 +24,11 @@ pub const SlimeFactory = struct {
pub fn init(allocator: std.mem.Allocator, renderer: *sdl.struct_SDL_Renderer) !SlimeFactory {
const texture = try atils.loadTexture(renderer, slime_sprite_sheet_texture_path);
const val = sdl.SDL_SetTextureBlendMode(texture, sdl.SDL_BLENDMODE_BLEND);
if (val != 0) {
sdl.SDL_Log("Failed to set blend mode: %s", sdl.SDL_GetError());
return error.FailedToSetBlendMode;
}
return .{
.slimes = std.ArrayList(Slime).init(allocator),
.slime_sprite_sheet_texture = texture,
@@ -33,12 +45,21 @@ pub const SlimeFactory = struct {
}
pub fn render(sf: *SlimeFactory, game_state: *GameState) void {
_ = sdl.SDL_SetTextureColorMod(sf.slime_sprite_sheet_texture, game_state.r, game_state.g, game_state.b);
if (sf.slimes.items.len == 0) return;
const slime_color = sf.slimes.items[0].color;
_ = sdl.SDL_SetTextureColorMod(
sf.slime_sprite_sheet_texture,
slime_color.r,
slime_color.g,
slime_color.b,
);
_ = sdl.SDL_SetTextureAlphaMod(sf.slime_sprite_sheet_texture, slime_color.a);
for (sf.slimes.items, 0..) |slime, s_idx| {
std.debug.print("Slime {d}:\t{}\n", .{ s_idx + 1, slime });
const sprite_frame_x_dim: u16 = slime.f * 64;
const sprite_frame_rect: sdl.struct_SDL_Rect = .{ .x = sprite_frame_x_dim, .y = 0, .w = 64, .h = 64 };
const dest_rect: sdl.struct_SDL_Rect = .{ .x = slime.x, .y = slime.y, .w = 128, .h = 128 };
const dest_rect: sdl.struct_SDL_Rect = .{ .x = slime.x, .y = slime.y, .w = 64, .h = 64 };
_ = sdl.SDL_RenderCopy(game_state.renderer, sf.slime_sprite_sheet_texture, &sprite_frame_rect, &dest_rect);
sf.slimes.items[s_idx].f = (sf.slimes.items[s_idx].f + 1) % sf.slimes.items[s_idx].total_frames;
}
+84
View File
@@ -0,0 +1,84 @@
const sdl = @import("./sdl.zig").c;
const std = @import("std");
const GameState = @import("./game_state.zig").GameState;
var font: ?*sdl.TTF_Font = null;
var text_texture: ?*sdl.SDL_Texture = null;
var text_init = false;
pub const GameText = struct {
text: []const u8,
color: sdl.SDL_Color,
surface: *sdl.SDL_Surface,
w: u32,
h: u32,
pub fn loadFromRenderedText(text: []const u8, color: sdl.SDL_Color) !GameText {
const c_text: [*c]const u8 = @ptrCast(text);
const text_surface: [*c]sdl.SDL_Surface = sdl.TTF_RenderText_Solid(font.?, c_text, color) orelse {
sdl.SDL_Log("Error loading text surface: %s\n", sdl.SDL_GetError());
return error.FailedToRenderSurface;
};
return .{
.surface = text_surface,
.text = text,
.color = color,
.w = @intCast(text_surface.*.w),
.h = @intCast(text_surface.*.h),
};
}
pub fn deinit(self: *GameText) void {
sdl.SDL_FreeSurface(self.text_surface);
}
pub fn setBlendMode(self: *GameText, blend: sdl.SDL_BlendMode) !void {
_ = self;
_ = blend;
return error.Unimplemented;
}
pub fn setAlpha(self: *GameText, alpha: u8) !void {
_ = self;
_ = alpha;
return error.Unimplemented;
}
pub fn render(self: *GameText, game_state: *GameState) !void {
if (!text_init) {
return error.TextNotInitialized;
}
if (text_texture != null) {
sdl.SDL_DestroyTexture(text_texture);
text_texture = null;
}
// TODO dont create new texture if unchanged
text_texture = sdl.SDL_CreateTextureFromSurface(game_state.renderer, self.surface) orelse {
sdl.SDL_Log("Error loading text texture: %s\n", sdl.SDL_GetError());
return error.FailedToRenderTexture;
};
const srcr = sdl.SDL_Rect{ .x = 0, .y = 0, .w = @intCast(self.w), .h = @intCast(self.h) };
const destr = sdl.SDL_Rect{ .x = @intCast(game_state.SCREEN_WIDTH - self.w), .y = 10, .w = @intCast(self.w), .h = @intCast(self.h) };
_ = sdl.SDL_RenderCopy(game_state.renderer, text_texture, &srcr, &destr);
}
pub fn initFont() !void {
const loaded_font = sdl.TTF_OpenFont("./assets/fonts/DepartureMonoNF-Regular.ttf", 24) orelse {
sdl.SDL_Log("Error loading ttf font: %s\n", sdl.TTF_GetError());
return error.FailedToLoadFont;
};
font = loaded_font;
text_init = true;
}
pub fn deinitFont() void {
sdl.SDL_DestroyTexture(text_texture);
sdl.TTF_CloseFont(font);
text_init = false;
}
};
+116
View File
@@ -0,0 +1,116 @@
const sdl = @import("../sdl.zig").c;
pub const RGBAColor = struct {
r: u8,
g: u8,
b: u8,
a: u8,
pub fn white() RGBAColor {
return .{
.r = 0xff,
.g = 0xff,
.b = 0xff,
.a = 0xff,
};
}
pub fn black() RGBAColor {
return .{
.r = 0x00,
.g = 0x00,
.b = 0x00,
.a = 0xff,
};
}
pub fn red() RGBAColor {
return .{
.r = 0xff,
.g = 0x00,
.b = 0x00,
.a = 0xff,
};
}
pub fn green() RGBAColor {
return .{
.r = 0x00,
.g = 0xff,
.b = 0x00,
.a = 0xff,
};
}
pub fn blue() RGBAColor {
return .{
.r = 0x00,
.g = 0x00,
.b = 0xff,
.a = 0xff,
};
}
pub fn yellow() RGBAColor {
return .{
.r = 0xff,
.g = 0xff,
.b = 0x00,
.a = 0xff,
};
}
pub fn cyan() RGBAColor {
return .{
.r = 0x00,
.g = 0xff,
.b = 0xff,
.a = 0xff,
};
}
pub fn magenta() RGBAColor {
return .{
.r = 0xff,
.g = 0x00,
.b = 0xff,
.a = 0xff,
};
}
pub fn whiteSmoke() RGBAColor {
return .{
.r = 0xf5,
.g = 0xf5,
.b = 0xf5,
.a = 0xff,
};
}
pub fn orange() RGBAColor {
return .{
.r = 0xff,
.g = 0xa5,
.b = 0x00,
.a = 0xff,
};
}
pub fn pink() RGBAColor {
return .{
.r = 0xff,
.g = 0xc0,
.b = 0xcb,
.a = 0xff,
};
}
pub fn tosdl(self: *const RGBAColor) sdl.SDL_Color {
return .{
.r = self.r,
.g = self.g,
.b = self.b,
.a = self.a,
};
}
};