Skip to content

Commit

Permalink
Add first draft of minimap with zoom
Browse files Browse the repository at this point in the history
  • Loading branch information
EduardoLR10 committed Nov 3, 2024
1 parent c6e598e commit 0f11039
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 38 deletions.
2 changes: 0 additions & 2 deletions client/src/assets.zig
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -173,6 +172,5 @@ pub fn createMapImage(world: *const GameState.World.Map) !rl.Image {
}
}
}
map.add_borders(&img);
return img;
}
68 changes: 36 additions & 32 deletions client/src/components/hud/map.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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 };
Expand All @@ -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,
Expand All @@ -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 };
}
};
Expand All @@ -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();
Expand All @@ -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);
}
2 changes: 0 additions & 2 deletions client/src/game/camera.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
15 changes: 14 additions & 1 deletion client/src/game/main.zig
Original file line number Diff line number Diff line change
@@ -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");
Expand All @@ -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();
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions client/src/game/state.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
} = .{},
Expand Down
3 changes: 2 additions & 1 deletion client/src/server/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down

0 comments on commit 0f11039

Please sign in to comment.