diff --git a/client/src/assets.zig b/client/src/assets.zig index 7059273..0724219 100644 --- a/client/src/assets.zig +++ b/client/src/assets.zig @@ -1,5 +1,4 @@ const config = @import("config.zig"); -const map = @import("components/hud/map.zig"); const messages = @import("server/messages.zig"); const rl = @import("raylib"); const rm = rl.math; @@ -173,6 +172,5 @@ pub fn createMapImage(world: *const GameState.World.Map) !rl.Image { } } } - map.add_borders(&img); return img; } diff --git a/client/src/components/hud/map.zig b/client/src/components/hud/map.zig index 6208c35..1c72e08 100644 --- a/client/src/components/hud/map.zig +++ b/client/src/components/hud/map.zig @@ -5,8 +5,11 @@ const rm = rl.math; const std = @import("std"); const GameState = @import("../../game/state.zig"); +const outerRadius = config.map.border_thickness; +pub const innerRadius = outerRadius - 10; + pub fn init_map_texture() rl.Texture { - const side = config.map.border_thickness * 2; + const side = outerRadius * 2; const img = rl.genImageColor(side, side, rl.Color.black); defer img.unload(); return img.toTexture(); @@ -26,13 +29,6 @@ fn rotate_point( }; } -pub fn add_borders(image: *rl.Image) void { - const thickness = config.map.border_thickness; - const width = image.width + 2 * thickness; - const height = image.height + 2 * thickness; - return image.resizeCanvas(width, height, thickness, thickness, rl.Color.black); -} - pub fn player(world_face_direction: i16, center: rl.Vector2) void { const face_direction: f32 = @floatFromInt(@mod(180 - world_face_direction, 360)); const origin = .{ .x = 0, .y = 0 }; @@ -47,9 +43,6 @@ pub fn player(world_face_direction: i16, center: rl.Vector2) void { ); } -const outerRadius = config.map.border_thickness; -pub const innerRadius = outerRadius - 10; - pub fn getCenter(width: f32, height: f32) rl.Vector2 { return .{ .x = width - innerRadius - innerRadius / 2, @@ -58,17 +51,13 @@ pub fn getCenter(width: f32, height: f32) rl.Vector2 { } pub const coordinates = struct { - fn worldToMap(position: rl.Vector2, world: *const GameState.World.Map) struct { f32, f32 } { - const character_x: f32 = rm.clamp(position.x, 0, @floatFromInt(world.instance.width * config.map.mini_map_size)); - const character_y: f32 = rm.clamp(position.y, 0, @floatFromInt(world.instance.height * config.map.mini_map_size)); - return .{ character_x, character_y }; - } pub fn normalize(position: rl.Vector2, map_image: *const rl.Image, world: *const GameState.World.Map) struct { f32, f32 } { - const character_x, const character_y = worldToMap(position, world); + const character_x = position.x; + const character_y = position.y; const fWidth: f32 = @floatFromInt(world.instance.width); const fHeight: f32 = @floatFromInt(world.instance.height); - const normalized_x = character_x * @as(f32, @as(f32, @floatFromInt(map_image.width - 2 * config.map.border_thickness)) / (config.assets.tile.size * fWidth)); - const normalized_y = character_y * @as(f32, @as(f32, @floatFromInt(map_image.height - 2 * config.map.border_thickness)) / (config.assets.tile.size * fHeight)); + const normalized_x = character_x * @as(f32, @as(f32, @floatFromInt(map_image.width)) / (config.assets.tile.size * fWidth)); + const normalized_y = character_y * @as(f32, @as(f32, @floatFromInt(map_image.height)) / (config.assets.tile.size * fHeight)); return .{ normalized_x, normalized_y }; } }; @@ -78,24 +67,36 @@ pub fn at(character: *const GameState.World.Character, world: *const GameState.W .x = character.stats.x_position, .y = character.stats.y_position, }; - const normalized_x, const normalized_y = coordinates.normalize(position, &character.inventory.hud.minimap.map.?, world); + const map_image = character.inventory.hud.minimap.map.?; + + const normalized_x, const normalized_y = coordinates.normalize(position, &map_image, world); + const displacement_x: f32 = normalized_x - @as(f32, @floatFromInt(@divFloor(map_image.width, 2))); + const displacement_y: f32 = normalized_y - @as(f32, @floatFromInt(@divFloor(map_image.height, 2))); const center: rl.Vector2 = getCenter(width, height); - const map_image = character.inventory.hud.minimap.map.?; - const map_x = center.x - outerRadius; - const map_y = center.y - outerRadius; + + var canvas: rl.Image = rl.genImageColor(@intFromFloat(2 * outerRadius), @intFromFloat(2 * outerRadius), rl.Color.black); + defer canvas.unload(); + const map_mask = rl.Rectangle{ - .x = normalized_x, - .y = normalized_y, + .x = @max(0, displacement_x), + .y = @max(0, displacement_y), .width = @floatFromInt(@min(outerRadius * 2, map_image.width)), .height = @floatFromInt(@min(outerRadius * 2, map_image.height)), }; - var map = rl.imageFromImage(map_image, map_mask); - defer map.unload(); + + const target: rl.Rectangle = .{ + .x = -displacement_x, + .y = -displacement_y, + .width = map_mask.width, + .height = map_mask.height, + }; + + canvas.drawImage(map_image, map_mask, target, rl.Color.white); var alpha_mask = rl.genImageColor( - @intFromFloat(map_mask.width), - @intFromFloat(map_mask.height), + @intFromFloat(outerRadius * 2), + @intFromFloat(outerRadius * 2), rl.Color.black, ); defer alpha_mask.unload(); @@ -106,16 +107,19 @@ pub fn at(character: *const GameState.World.Character, world: *const GameState.W innerRadius, rl.Color.white, ); - map.alphaMask(alpha_mask); - const pixels = try rl.loadImageColors(map); + canvas.alphaMask(alpha_mask); + + const pixels = try rl.loadImageColors(canvas); + const texture = character.inventory.hud.minimap.texture.?; rl.updateTexture(texture, pixels.ptr); + const map_x = center.x - outerRadius; + const map_y = center.y - outerRadius; texture.draw(@intFromFloat(map_x), @intFromFloat(map_y), rl.Color.white); rl.drawRing(center, innerRadius, outerRadius, 0, 360, 0, config.ColorPalette.primary); rl.drawCircleLinesV(center, innerRadius, rl.Color.white); rl.drawCircleLinesV(center, innerRadius - 1, rl.Color.white); - // std.debug.print("Main Player", .{}); player(character.stats.face_direction, center); } diff --git a/client/src/game/camera.zig b/client/src/game/camera.zig index 01abb53..65266b6 100644 --- a/client/src/game/camera.zig +++ b/client/src/game/camera.zig @@ -8,8 +8,6 @@ pub fn update(gameState: *GameState) void { const cameraAngle = rm.vector3Normalize(config.angleCameraVector); - gameState.world.cameraDistance -= rl.getMouseWheelMove() * 2; - gameState.world.camera.position = rm.vector3Add(rm.vector3Scale(cameraAngle, gameState.world.cameraDistance), gameState.world.character.position); rl.updateCamera(&gameState.world.camera, rl.CameraMode.camera_custom); } diff --git a/client/src/game/main.zig b/client/src/game/main.zig index cbb668c..50bb3ff 100644 --- a/client/src/game/main.zig +++ b/client/src/game/main.zig @@ -1,6 +1,7 @@ const animate = @import("animation.zig"); const camera = @import("camera.zig"); const config = @import("../config.zig"); +const map = @import("../components/hud/map.zig"); const messages = @import("../server/messages.zig"); const physics = @import("physics.zig"); const rl = @import("raylib"); @@ -18,6 +19,7 @@ fn drawPlayers(gameState: *GameState) void { } fn controlInput(entity: *GameState.World.Character) i16 { + const entity = &world.character; var tempAngle = entity.stats.face_direction; const velocity = &entity.velocity; const deltaTime = rl.getFrameTime(); @@ -39,6 +41,17 @@ fn controlInput(entity: *GameState.World.Character) i16 { tempAngle = 90; } + const zoom = rl.getMouseWheelMove() * 2; + if (zoom != 0) { + world.cameraDistance -= zoom; + world.map.size += zoom; + var img = rl.imageCopy(entity.inventory.hud.minimap.initial_map.?); + const width: f32 = @floatFromInt(world.map.instance.width); + const height: f32 = @floatFromInt(world.map.instance.height); + rl.imageResizeNN(&img, @intFromFloat(width * world.map.size), @intFromFloat(height * world.map.size)); + entity.inventory.hud.minimap.map = img; + } + return tempAngle; } @@ -97,7 +110,7 @@ pub fn spawn(gameState: *GameState) !void { drawPlayers(gameState); - const tempAngle = controlInput(&gameState.world.character); + const tempAngle = controlInput(&gameState.world); physics.character.draw(&gameState.world.character, &gameState.world.map, tempAngle); animate.character.update(&gameState.world.character); camera.update(gameState); diff --git a/client/src/game/state.zig b/client/src/game/state.zig index 0694ba9..00fd9bc 100644 --- a/client/src/game/state.zig +++ b/client/src/game/state.zig @@ -39,6 +39,7 @@ pub const World = struct { instance: messages.Map = .{}, tiles: Tile_Table, objects: Object_Table, + size: f32 = config.map.mini_map_size, }; pub const Character = struct { pub const Animation = struct { @@ -72,6 +73,7 @@ pub const World = struct { spells: []const [:0]const u8 = &.{}, consumables: []const [:0]const u8 = &.{}, minimap: struct { + initial_map: ?rl.Image = null, map: ?rl.Image = null, texture: ?rl.Texture = null, } = .{}, diff --git a/client/src/server/main.zig b/client/src/server/main.zig index 9c548a0..546d87b 100644 --- a/client/src/server/main.zig +++ b/client/src/server/main.zig @@ -131,7 +131,8 @@ pub const character = struct { .ok => |info| { updateCharacterInfo(&gameState.world.character, info.character); gameState.world.map.instance = info.map; - gameState.world.character.inventory.hud.minimap.map = try assets.createMapImage(&gameState.world.map); + gameState.world.character.inventory.hud.minimap.initial_map = try assets.createMapImage(&gameState.world.map); + gameState.world.character.inventory.hud.minimap.map = rl.imageCopy(gameState.world.character.inventory.hud.minimap.initial_map.?); gameState.scene = .spawn; }, .@"error" => |msg| {