improved road implementation
This commit is contained in:
parent
2edda20571
commit
6b39998232
@ -40,8 +40,8 @@ pub fn main() !void {
|
||||
|
||||
rl.clearBackground(.light_gray);
|
||||
|
||||
area_manager.draw();
|
||||
try road_manager.inputHandler();
|
||||
area_manager.draw();
|
||||
road_manager.draw();
|
||||
}
|
||||
}
|
||||
|
@ -7,15 +7,13 @@ 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);
|
||||
pub fn draw(self: *const Node, valid: bool) void {
|
||||
rl.drawCircleV(self.location, globals.getScale() * road_data.road_thickness / @sqrt(2.0), if (valid) .green else .red);
|
||||
}
|
||||
};
|
||||
|
@ -13,6 +13,7 @@ pub const RoadManager = struct {
|
||||
nodes: std.ArrayList(node_str.Node),
|
||||
mode: str.InputMode,
|
||||
selected_road: ?usize,
|
||||
min_distance: f32,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) RoadManager {
|
||||
return RoadManager{
|
||||
@ -22,6 +23,7 @@ pub const RoadManager = struct {
|
||||
.nodes = std.ArrayList(node_str.Node).init(allocator),
|
||||
.mode = str.InputMode.normal,
|
||||
.selected_road = null,
|
||||
.min_distance = globals.getScreenWidthF32() / 25.0,
|
||||
};
|
||||
}
|
||||
|
||||
@ -36,18 +38,33 @@ pub const RoadManager = struct {
|
||||
|
||||
// if last road exists and is not fully built
|
||||
if (last_id != null and self.roads.items[last_id.?].end_point == null) {
|
||||
// only confirm if distance is minimal or greater
|
||||
if (rl.Vector2.distance(self.roads.items[last_id.?].start_point, pos) < self.min_distance) return;
|
||||
// if too close to existing nodes, return
|
||||
if (!self.canCreateNode(pos)) return;
|
||||
|
||||
self.roads.items[last_id.?].confirmRoad(pos);
|
||||
try self.nodes.append(node_str.Node.init(pos));
|
||||
}
|
||||
|
||||
try self.roads.append(road_str.Road.init(pos));
|
||||
}
|
||||
|
||||
fn canCreateNode(self: *const RoadManager, pos: rl.Vector2) bool {
|
||||
for (self.nodes.items) |node| {
|
||||
if (rl.Vector2.distance(node.location, pos) < self.min_distance) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn removeLastRoad(self: *RoadManager) void {
|
||||
_ = self.roads.pop();
|
||||
}
|
||||
|
||||
fn clearRoads(self: *RoadManager) void {
|
||||
self.roads.clearAndFree();
|
||||
self.nodes.clearAndFree();
|
||||
}
|
||||
|
||||
fn trackRoad(self: *RoadManager, pos: rl.Vector2) void {
|
||||
@ -58,11 +75,9 @@ pub const RoadManager = struct {
|
||||
for (0..self.roads.items.len) |i| {
|
||||
// we skip because that road is not complete
|
||||
if (self.roads.items[i].end_point == null) continue;
|
||||
std.debug.print("tracking pt1\n", .{});
|
||||
|
||||
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.roads.items[i].setColor(str.RoadState.selected);
|
||||
self.selected_road = i;
|
||||
break;
|
||||
}
|
||||
@ -109,6 +124,8 @@ pub const RoadManager = struct {
|
||||
self.clearRoads();
|
||||
} else if (rl.isKeyReleased(.d)) {
|
||||
self.toggleDeleteMode();
|
||||
} else if (rl.isKeyReleased(.n)) {
|
||||
self.toggleNodeMode();
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,21 +152,62 @@ pub const RoadManager = struct {
|
||||
}
|
||||
|
||||
fn toggleDeleteMode(self: *RoadManager) void {
|
||||
if (self.mode == str.InputMode.delete) {
|
||||
self.resetTrackedRoad();
|
||||
}
|
||||
self.togglePrepare();
|
||||
|
||||
self.cancelRoadbuilding();
|
||||
self.mode = switch (self.mode) {
|
||||
.normal => str.InputMode.delete,
|
||||
.delete => str.InputMode.normal,
|
||||
.node => self.mode,
|
||||
.node => str.InputMode.delete,
|
||||
};
|
||||
}
|
||||
|
||||
fn toggleNodeMode(self: *RoadManager) void {
|
||||
self.togglePrepare();
|
||||
|
||||
self.mode = switch (self.mode) {
|
||||
.normal => str.InputMode.node,
|
||||
.delete => str.InputMode.node,
|
||||
.node => str.InputMode.normal,
|
||||
};
|
||||
}
|
||||
|
||||
fn togglePrepare(self: *RoadManager) void {
|
||||
if (self.mode == str.InputMode.delete) {
|
||||
self.resetTrackedRoad();
|
||||
}
|
||||
self.cancelRoadbuilding();
|
||||
}
|
||||
|
||||
pub fn draw(self: *const RoadManager) void {
|
||||
for (self.roads.items) |road| {
|
||||
// if last road is being drawn display node marker
|
||||
const last = self.roads.getLastOrNull();
|
||||
const pos = rl.getMousePosition();
|
||||
const marker_node = node_str.Node.init(pos);
|
||||
var draw_marker = false;
|
||||
|
||||
if (last != null and last.?.end_point == null) {
|
||||
draw_marker = true;
|
||||
|
||||
// might have to put it in one function because we check this two times
|
||||
// todo canCreateNode and canCreateRoad should be part of node/road struct
|
||||
if (rl.Vector2.distance(last.?.start_point, pos) < self.min_distance) {
|
||||
draw_marker = false;
|
||||
self.roads.items[self.getLastIndex().?].setColor(str.RoadState.illegal);
|
||||
}
|
||||
}
|
||||
|
||||
for (self.roads.items) |*road| {
|
||||
road.draw();
|
||||
if (!road.isValid())
|
||||
road.*.setColor(str.RoadState.valid);
|
||||
}
|
||||
|
||||
if (draw_marker)
|
||||
marker_node.draw(self.canCreateNode(pos));
|
||||
|
||||
if (self.mode != str.InputMode.node) return;
|
||||
for (self.nodes.items) |node| {
|
||||
node.draw(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +218,7 @@ pub const RoadManager = struct {
|
||||
|
||||
fn setDefaultColour(self: *RoadManager) void {
|
||||
for (self.roads.items) |*road| {
|
||||
road.setColor(false);
|
||||
road.setColor(str.RoadState.valid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,18 @@
|
||||
const rl = @import("raylib");
|
||||
const globals = @import("../globals.zig");
|
||||
const road_data = @import("road-data.zig");
|
||||
const str = @import("../structures.zig");
|
||||
|
||||
pub const Road = struct {
|
||||
color: rl.Color,
|
||||
start_point: rl.Vector2,
|
||||
end_point: ?rl.Vector2,
|
||||
color: rl.Color,
|
||||
|
||||
pub fn init(pos: rl.Vector2) Road {
|
||||
return Road{
|
||||
.color = .black,
|
||||
.start_point = pos,
|
||||
.end_point = null,
|
||||
.color = .black,
|
||||
};
|
||||
}
|
||||
|
||||
@ -19,8 +20,16 @@ pub const Road = struct {
|
||||
self.end_point = pos;
|
||||
}
|
||||
|
||||
pub fn setColor(self: *Road, is_selected: bool) void {
|
||||
self.color = if (is_selected) .green else .black;
|
||||
pub fn setColor(self: *Road, road_state: str.RoadState) void {
|
||||
self.color = switch (road_state) {
|
||||
.valid => .black,
|
||||
.illegal => .red,
|
||||
.selected => .green,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isValid(self: *const Road) bool {
|
||||
return rl.colorIsEqual(self.color, rl.Color.black);
|
||||
}
|
||||
|
||||
pub fn draw(self: *const Road) void {
|
||||
|
@ -1,3 +1,4 @@
|
||||
// valid area states
|
||||
pub const AreaLocation = enum {
|
||||
top_left,
|
||||
top_right,
|
||||
@ -5,8 +6,15 @@ pub const AreaLocation = enum {
|
||||
bottom_right,
|
||||
};
|
||||
|
||||
// road modes
|
||||
pub const InputMode = enum {
|
||||
normal,
|
||||
delete,
|
||||
node,
|
||||
};
|
||||
|
||||
pub const RoadState = enum {
|
||||
valid,
|
||||
illegal,
|
||||
selected,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user