Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zoom minimap #79

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 64 additions & 27 deletions client/src/components/hud/map.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const std = @import("std");
const GameState = @import("../../game/state.zig");

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 Down Expand Up @@ -58,17 +58,23 @@ 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);
pub fn normalize(
position: rl.Vector2,
map_image: *const rl.Image,
world: *const GameState.World.Map,
) struct { f32, f32 } {
const map_width = map_image.width - 2 * config.map.border_thickness;
const map_height = map_image.height - 2 * config.map.border_thickness;
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_width)) /
(config.assets.tile.size * fWidth));
const normalized_y = character_y *
@as(f32, @as(f32, @floatFromInt(map_height)) /
(config.assets.tile.size * fHeight));
return .{ normalized_x, normalized_y };
}
};
Expand Down Expand Up @@ -103,29 +109,57 @@ fn drawMapName(center: rl.Vector2, name: [:0]const u8, font: *rl.Font) void {
);
}

pub fn at(character: *const GameState.World.Character, world: *const GameState.World.Map, width: f32, height: f32, font: *rl.Font) !void {
pub fn at(
character: *const GameState.World.Character,
world: *const GameState.World.Map,
width: f32,
height: f32,
font: *rl.Font,
) !void {
const position: rl.Vector2 = .{
.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 = config.map.border_thickness +
normalized_x -
@as(f32, @floatFromInt(@divFloor(map_image.width, 2)));
const displacement_y: f32 = config.map.border_thickness +
normalized_y -
@as(f32, @floatFromInt(@divFloor(map_image.height, 2)));

std.debug.print("{}, {}, {}\n", .{ position, normalized_x, normalized_y });

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,
.width = @floatFromInt(@min(outerRadius * 2, map_image.width)),
.height = @floatFromInt(@min(outerRadius * 2, map_image.height)),
.x = displacement_x,
.y = displacement_y,
.width = @floatFromInt(outerRadius * 2),
.height = @floatFromInt(outerRadius * 2),
};

const dest_mask: rl.Rectangle = comptime .{
.x = 0,
.y = 0,
.width = @floatFromInt(outerRadius * 2),
.height = @floatFromInt(outerRadius * 2),
};
var map = rl.imageFromImage(map_image, map_mask);
defer map.unload();

canvas.drawImage(map_image, map_mask, dest_mask, 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 @@ -136,17 +170,20 @@ pub fn at(character: *const GameState.World.Character, world: *const GameState.W
innerRadius,
config.ColorPalette.secondary,
);
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);

texture.draw(@intFromFloat(map_x), @intFromFloat(map_y), config.ColorPalette.secondary);
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, config.ColorPalette.secondary);
rl.drawCircleLinesV(center, innerRadius - 1, config.ColorPalette.secondary);

player(character.stats.face_direction, center);

drawMapName(center, character.stats.map_name, font);
Expand Down
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);
}
31 changes: 30 additions & 1 deletion client/src/game/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const rm = rl.math;
const server = @import("../server/main.zig");
const std = @import("std");
const GameState = @import("state.zig");
const map = @import("../components/hud/map.zig");

fn drawPlayers(gameState: *GameState) void {
const mainPlayer = &gameState.world.character;
Expand Down Expand Up @@ -47,6 +48,27 @@ fn controlInput(gameState: *GameState) !i16 {
try server.character.exitMap(gameState);
rl.enableCursor();
}
const zoom = rl.getMouseWheelMove() * 2;
if (zoom != 0) {
const world = &gameState.world;
world.cameraDistance -= zoom;
world.map.size += zoom;
const initial = entity.inventory.hud.minimap.initial_map.?;
const rect: rl.Rectangle = .{
.x = config.map.border_thickness,
.y = config.map.border_thickness,
.width = @as(f32, @floatFromInt(initial.width)) - config.map.border_thickness * 2,
.height = @as(f32, @floatFromInt(initial.height)) - config.map.border_thickness * 2,
};
var img = initial.copyRec(rect);
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));
map.add_borders(&img);

rl.unloadImage(entity.inventory.hud.minimap.map.?);
entity.inventory.hud.minimap.map = img;
}

return tempAngle;
}
Expand Down Expand Up @@ -93,7 +115,14 @@ fn drawWorld(player: *const GameState.World.Character, world: *const GameState.W
if (object != .empty) {
if (world.objects.get(object)) |objectData| {
const position = assetPosition(fx, fy, config.assets.object.defaultLevel);
rl.drawModelEx(objectData.model.?, position, objectData.axis, objectData.angle, objectData.scale, config.ColorPalette.secondary);
rl.drawModelEx(
objectData.model.?,
position,
objectData.axis,
objectData.angle,
objectData.scale,
config.ColorPalette.secondary,
);
}
}
}
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 @@ -40,6 +40,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 @@ -73,6 +74,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
1 change: 1 addition & 0 deletions client/src/server/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ pub const character = struct {
.ok => |info| {
updateCharacterInfo(&gameState.world.character, info.character);
gameState.world.map.instance = info.map;
gameState.world.character.inventory.hud.minimap.initial_map = try assets.createMapImage(&gameState.world.map);
gameState.world.character.inventory.hud.minimap.map = try assets.createMapImage(&gameState.world.map);
gameState.scene = .spawn;
},
Expand Down
Loading