flip sprites

This commit is contained in:
Rokas Puzonas 2026-02-01 04:16:02 +02:00
parent a4d803fc57
commit a249dc3cf9
5 changed files with 84 additions and 26 deletions

View File

@ -41,6 +41,7 @@ font_id: FontName.EnumArray,
pistol_mask: Gfx.TextureId,
bomb_mask: Gfx.TextureId,
laser_mask: Gfx.TextureId,
bullet: Gfx.TextureId,
dungeon_tilemap: Tilemap,
skeleton: Gfx.Sprite,
@ -89,14 +90,13 @@ pub fn init(gpa: std.mem.Allocator) !Assets {
.rgba = laser_mask_image.rgba8_pixels
}
});
const creatures_image = try STBImage.load(@embedFile("assets/tiny-creatures/tilemap_packed.png"));
defer creatures_image.deinit();
const creatures_texture = try Gfx.addTexture(&.{
const skeleton_image = try STBImage.load(@embedFile("assets/skeleton.png"));
defer skeleton_image.deinit();
const skeleton_texture = try Gfx.addTexture(&.{
.{
.width = creatures_image.width,
.height = creatures_image.height,
.rgba = creatures_image.rgba8_pixels
.width = skeleton_image.width,
.height = skeleton_image.height,
.rgba = skeleton_image.rgba8_pixels
}
});
@ -120,17 +120,23 @@ pub fn init(gpa: std.mem.Allocator) !Assets {
}
});
const creatures_tilemap = Tilemap{
.texture = creatures_texture,
.tile_size = .init(16, 16)
};
const bullet_image = try STBImage.load(@embedFile("assets/bullet.png"));
defer bullet_image.deinit();
const bullet_texture = try Gfx.addTexture(&.{
.{
.width = bullet_image.width,
.height = bullet_image.height,
.rgba = bullet_image.rgba8_pixels
}
});
const snake = Gfx.Sprite{
.texture = snake_texture,
.uv = .unit
};
const skeleton = Gfx.Sprite{
.texture = creatures_texture,
.uv = creatures_tilemap.getTileUV(1, 0)
.texture = skeleton_texture,
.uv = .unit
};
const fire_spirit = Gfx.Sprite{
.texture = fire_spirit_texture,
@ -181,6 +187,7 @@ pub fn init(gpa: std.mem.Allocator) !Assets {
.fire_spirit = fire_spirit,
.map = map,
.tilesets = tilesets,
.bullet = bullet_texture,
.dungeon_tilemap = .{
.texture = dungeon_texture,
.tile_size = .init(16, 16)

BIN
src/assets/bullet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

BIN
src/assets/skeleton.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

View File

@ -57,6 +57,7 @@ const Player = struct {
last_shot_at: ?Nanoseconds = null,
invincible_until: ?Nanoseconds = null,
gun: Gun = .pistol,
facing_left: bool = false,
pub fn getRect(self: Player) Rect {
const pos = self.kinetic.pos;
@ -93,6 +94,7 @@ const Enemy = struct {
speed: f32,
size: f32,
sprite: Sprite,
facing_left: bool = false,
target: ?Vec2 = null,
distance_to_target: ?f32 = null,
@ -327,7 +329,6 @@ fn drawMap(self: *CombatScreen, frame: *Engine.Frame) void {
}
pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResult {
const dt = frame.deltaTime();
var result = TickResult{
@ -476,6 +477,10 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
}
dir = dir.normalized();
if (dir.x != 0) {
self.player.facing_left = dir.x < 0;
}
if (frame.isKeyPressed(._1)) {
self.player.gun = .pistol;
} else if (frame.isKeyPressed(._2)) {
@ -548,18 +553,32 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
}
frame.drawRectangle(.{
.rect = self.player.getRect(),
.color = rgb(255, 255, 255),
.sprite = .{
{
var sprite = Engine.Graphics.Sprite{
.texture = switch (self.player.gun) {
.pistol => self.assets.pistol_mask,
.bomb => self.assets.bomb_mask,
.laser => self.assets.laser_mask,
},
.uv = .unit
};
const sprite_size = sprite.getSize();
if (self.player.facing_left) {
sprite = sprite.flipHorizontal();
}
});
const pos = self.player.kinetic.pos;
frame.drawRectangle(.{
.rect = Rect.initCentered(pos.x, pos.y, sprite_size.x, sprite_size.y),
.color = rgb(255, 255, 255),
.sprite = sprite
});
frame.drawRectangle(.{
.rect = self.player.getRect(),
.color = rgba(255, 255, 255, 0.5),
});
}
for (self.bullets.items) |*bullet| {
bullet.kinetic.vel = bullet.dir.multiplyScalar(bullet.speed);
@ -576,9 +595,20 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
}
}
const pos = bullet.kinetic.pos;
const sprite_size = Engine.Graphics.getTextureSize(self.assets.bullet);
frame.drawRectangle(.{
.rect = Rect.initCentered(pos.x, pos.y, sprite_size.x, sprite_size.y),
.color = rgb(255, 255, 255),
.sprite = .{
.texture = self.assets.bullet,
.uv = .unit
}
});
frame.drawRectangle(.{
.rect = bullet_rect,
.color = rgb(200, 20, 255)
.color = rgba(200, 20, 255, 0.5)
});
}
@ -772,6 +802,7 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
if (to_target.length() > 1) {
const dir_to_target = to_target.normalized();
enemy.kinetic.vel = dir_to_target.multiplyScalar(enemy.speed);
enemy.facing_left = enemy.kinetic.vel.x < 0;
} else {
enemy.kinetic.vel = .zero;
}
@ -796,17 +827,21 @@ pub fn tick(self: *CombatScreen, state: *State, frame: *Engine.Frame) !TickResul
enemy.kinetic.update(dt, .{});
frame.drawRectangle(.{
.rect = enemy_rect,
.color = rgba(20, 20, 200, 0.2),
});
const pos = enemy.kinetic.pos;
const sprite_size = enemy.sprite.getSize();
var sprite = enemy.sprite;
if (enemy.facing_left) {
sprite = sprite.flipHorizontal();
}
frame.drawRectangle(.{
.rect = Rect.initCentered(pos.x, pos.y, sprite_size.x, sprite_size.y),
.color = rgb(255, 255, 255),
.sprite = enemy.sprite
.sprite = sprite
});
frame.drawRectangle(.{
.rect = enemy_rect,
.color = rgba(20, 20, 200, 0.2),
});
}
}

View File

@ -92,6 +92,17 @@ pub const Sprite = struct {
texture: TextureId,
uv: Rect,
pub fn flipHorizontal(self: Sprite) Sprite {
var uv = self.uv;
uv.pos.x += uv.size.x;
uv.size.x *= -1;
return Sprite{
.texture = self.texture,
.uv = uv
};
}
pub fn getSize(self: Sprite) Vec2 {
const texture_info = getTextureInfo(self.texture);
const texture_size = Vec2.initFromInt(u32, texture_info.width, texture_info.height);
@ -456,3 +467,8 @@ pub fn getTextureInfo(id: TextureId) TextureInfo {
const texture = textures.items[@intFromEnum(id)];
return texture.info;
}
pub fn getTextureSize(id: TextureId) Vec2 {
const texture_info = getTextureInfo(id);
return Vec2.initFromInt(u32, texture_info.width, texture_info.height);
}