road manager fixes, node implementation
This commit is contained in:
parent
3fc0687139
commit
2edda20571
21
src/road/node.zig
Normal file
21
src/road/node.zig
Normal file
@ -0,0 +1,21 @@
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
const road_str = @import("road.zig");
|
||||
const road_data = @import("road-data.zig");
|
||||
const globals = @import("../globals.zig");
|
||||
|
||||
pub const Node = struct {
|
||||
// road_sections: std.ArrayList(road_str.Road),
|
||||
location: rl.Vector2,
|
||||
// todo validation
|
||||
|
||||
pub fn init(location: rl.Vector2) Node {
|
||||
return Node{
|
||||
.location = location,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn draw(self: *const Node) void {
|
||||
rl.drawCircleV(self.location, globals.getScale() * road_data.road_thickness / @sqrt(2), .green);
|
||||
}
|
||||
};
|
@ -1,14 +1,17 @@
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
const road_str = @import("road.zig");
|
||||
const road_data = @import("../road-data.zig");
|
||||
const road_data = @import("road-data.zig");
|
||||
const node_str = @import("node.zig");
|
||||
const globals = @import("../globals.zig");
|
||||
const str = @import("../structures.zig");
|
||||
|
||||
pub const RoadManager = struct {
|
||||
buffer: f32,
|
||||
allocator: std.mem.Allocator,
|
||||
roads: std.ArrayList(road_str.Road),
|
||||
delete_mode: bool,
|
||||
nodes: std.ArrayList(node_str.Node),
|
||||
mode: str.InputMode,
|
||||
selected_road: ?usize,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) RoadManager {
|
||||
@ -16,13 +19,15 @@ pub const RoadManager = struct {
|
||||
.buffer = road_data.road_thickness * globals.getScale() / 2.0,
|
||||
.allocator = allocator,
|
||||
.roads = std.ArrayList(road_str.Road).init(allocator),
|
||||
.delete_mode = false,
|
||||
.nodes = std.ArrayList(node_str.Node).init(allocator),
|
||||
.mode = str.InputMode.normal,
|
||||
.selected_road = null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *RoadManager) void {
|
||||
self.roads.deinit();
|
||||
self.nodes.deinit();
|
||||
}
|
||||
|
||||
fn addRoad(self: *RoadManager, pos: rl.Vector2) !void {
|
||||
@ -46,54 +51,102 @@ pub const RoadManager = struct {
|
||||
}
|
||||
|
||||
fn trackRoad(self: *RoadManager, pos: rl.Vector2) void {
|
||||
if (!self.delete_mode) return;
|
||||
if (self.mode != str.InputMode.delete) return;
|
||||
|
||||
self.setDefaultColour();
|
||||
self.selected_road = null;
|
||||
self.resetTrackedRoad();
|
||||
|
||||
for (self.roads.items) |*road| {
|
||||
for (0..self.roads.items.len) |i| {
|
||||
// we skip because that road is not complete
|
||||
if (road.end_point == null) continue;
|
||||
if (self.roads.items[i].end_point == null) continue;
|
||||
std.debug.print("tracking pt1\n", .{});
|
||||
|
||||
if (cursorOnRoad(road.start_point, pos, road.end_point)) {
|
||||
road.*.setColor(true);
|
||||
// todo pointer or index
|
||||
if (self.cursorOnRoad(self.roads.items[i].start_point, pos, self.roads.items[i].end_point.?)) {
|
||||
std.debug.print("tracking pt2", .{});
|
||||
self.roads.items[i].setColor(true);
|
||||
self.selected_road = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cursorOnRoad(start: rl.Vector2, cursor: rl.Vector2, end: rl.Vector2) bool {}
|
||||
fn cursorOnRoad(self: *const RoadManager, start: rl.Vector2, cursor: rl.Vector2, end: rl.Vector2) bool {
|
||||
const min_x = @min(start.x, end.x) - self.buffer;
|
||||
const max_x = @max(start.x, end.x) + self.buffer;
|
||||
const min_y = @min(start.y, end.y) - self.buffer;
|
||||
const max_y = @max(start.y, end.y) + self.buffer;
|
||||
|
||||
if (!(cursor.x >= min_x and cursor.x <= max_x and cursor.y >= min_y and cursor.y <= max_y)) return false;
|
||||
|
||||
const sc = rl.Vector2{ .x = start.x - cursor.x, .y = start.y - cursor.y };
|
||||
const se = rl.Vector2{ .x = start.x - end.x, .y = start.y - end.y };
|
||||
|
||||
const prod = @abs(sc.x * se.y - sc.y * se.x);
|
||||
const road_length = @sqrt((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y));
|
||||
const threshold = road_length * self.buffer;
|
||||
|
||||
return prod <= threshold;
|
||||
}
|
||||
|
||||
fn cancelRoadbuilding(self: *RoadManager) void {
|
||||
// if we're in process of building a new road cancel it
|
||||
const last_road = self.roads.getLastOrNull();
|
||||
if (last_road != null and last_road.?.end_point == null)
|
||||
self.removeLastRoad();
|
||||
}
|
||||
|
||||
pub fn inputHandler(self: *RoadManager) !void {
|
||||
const pos = rl.getMousePosition();
|
||||
trackRoad(pos);
|
||||
self.trackRoad(pos);
|
||||
|
||||
// mouse inputs
|
||||
if (rl.isMouseButtonReleased(.left)) {
|
||||
if (self.delete_mode) {
|
||||
if (self.selected_road == null) return;
|
||||
// todo might be a problem in the future swapping modes must clear any unfinished roads!
|
||||
self.roads.swapRemove(self.selected_road.?);
|
||||
} else {
|
||||
try self.addRoad(pos);
|
||||
}
|
||||
} else if (rl.isMouseButtonReleased(.right)) {
|
||||
self.removeLastRoad();
|
||||
}
|
||||
try self.handleMouseInput();
|
||||
|
||||
self.handleKeyboardInput();
|
||||
}
|
||||
|
||||
fn handleKeyboardInput(self: *RoadManager) void {
|
||||
// keyboard inputs
|
||||
if (rl.isKeyReleased(.c)) {
|
||||
self.clearRoads();
|
||||
} else if (rl.isKeyReleased(.d)) {
|
||||
self.delete_mode = !self.delete_mode;
|
||||
if (!self.delete_mode) {
|
||||
self.setDefaultColour();
|
||||
self.selected_road = null;
|
||||
}
|
||||
self.toggleDeleteMode();
|
||||
}
|
||||
}
|
||||
|
||||
fn handleMouseInput(self: *RoadManager) !void {
|
||||
// mouse inputs
|
||||
if (rl.isMouseButtonReleased(.left)) {
|
||||
try self.handleLeftClick();
|
||||
} else if (rl.isMouseButtonReleased(.right)) {
|
||||
self.removeLastRoad();
|
||||
}
|
||||
}
|
||||
|
||||
fn handleLeftClick(self: *RoadManager) !void {
|
||||
switch (self.mode) {
|
||||
.normal => try self.addRoad(rl.getMousePosition()),
|
||||
.delete => {
|
||||
if (self.selected_road == null) return;
|
||||
|
||||
_ = self.roads.swapRemove(self.selected_road.?);
|
||||
self.selected_road = null;
|
||||
},
|
||||
.node => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn toggleDeleteMode(self: *RoadManager) void {
|
||||
if (self.mode == str.InputMode.delete) {
|
||||
self.resetTrackedRoad();
|
||||
}
|
||||
|
||||
self.cancelRoadbuilding();
|
||||
self.mode = switch (self.mode) {
|
||||
.normal => str.InputMode.delete,
|
||||
.delete => str.InputMode.normal,
|
||||
.node => self.mode,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn draw(self: *const RoadManager) void {
|
||||
for (self.roads.items) |road| {
|
||||
road.draw();
|
||||
@ -110,4 +163,9 @@ pub const RoadManager = struct {
|
||||
road.setColor(false);
|
||||
}
|
||||
}
|
||||
|
||||
fn resetTrackedRoad(self: *RoadManager) void {
|
||||
self.setDefaultColour();
|
||||
self.selected_road = null;
|
||||
}
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
const rl = @import("raylib");
|
||||
const globals = @import("../globals.zig");
|
||||
const road_data = @import("../road-data.zig");
|
||||
const road_data = @import("road-data.zig");
|
||||
|
||||
pub const Road = struct {
|
||||
color: rl.Color,
|
||||
|
@ -4,3 +4,9 @@ pub const AreaLocation = enum {
|
||||
bottom_left,
|
||||
bottom_right,
|
||||
};
|
||||
|
||||
pub const InputMode = enum {
|
||||
normal,
|
||||
delete,
|
||||
node,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user