improved road implementation
This commit is contained in:
parent
2edda20571
commit
6b39998232
@ -40,8 +40,8 @@ pub fn main() !void {
|
|||||||
|
|
||||||
rl.clearBackground(.light_gray);
|
rl.clearBackground(.light_gray);
|
||||||
|
|
||||||
area_manager.draw();
|
|
||||||
try road_manager.inputHandler();
|
try road_manager.inputHandler();
|
||||||
|
area_manager.draw();
|
||||||
road_manager.draw();
|
road_manager.draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,13 @@ const globals = @import("../globals.zig");
|
|||||||
pub const Node = struct {
|
pub const Node = struct {
|
||||||
// road_sections: std.ArrayList(road_str.Road),
|
// road_sections: std.ArrayList(road_str.Road),
|
||||||
location: rl.Vector2,
|
location: rl.Vector2,
|
||||||
// todo validation
|
|
||||||
|
|
||||||
pub fn init(location: rl.Vector2) Node {
|
pub fn init(location: rl.Vector2) Node {
|
||||||
return Node{
|
return Node{
|
||||||
.location = location,
|
.location = location,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(self: *const Node) void {
|
pub fn draw(self: *const Node, valid: bool) void {
|
||||||
rl.drawCircleV(self.location, globals.getScale() * road_data.road_thickness / @sqrt(2), .green);
|
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),
|
nodes: std.ArrayList(node_str.Node),
|
||||||
mode: str.InputMode,
|
mode: str.InputMode,
|
||||||
selected_road: ?usize,
|
selected_road: ?usize,
|
||||||
|
min_distance: f32,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator) RoadManager {
|
pub fn init(allocator: std.mem.Allocator) RoadManager {
|
||||||
return RoadManager{
|
return RoadManager{
|
||||||
@ -22,6 +23,7 @@ pub const RoadManager = struct {
|
|||||||
.nodes = std.ArrayList(node_str.Node).init(allocator),
|
.nodes = std.ArrayList(node_str.Node).init(allocator),
|
||||||
.mode = str.InputMode.normal,
|
.mode = str.InputMode.normal,
|
||||||
.selected_road = null,
|
.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 road exists and is not fully built
|
||||||
if (last_id != null and self.roads.items[last_id.?].end_point == null) {
|
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);
|
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));
|
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 {
|
fn removeLastRoad(self: *RoadManager) void {
|
||||||
_ = self.roads.pop();
|
_ = self.roads.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clearRoads(self: *RoadManager) void {
|
fn clearRoads(self: *RoadManager) void {
|
||||||
self.roads.clearAndFree();
|
self.roads.clearAndFree();
|
||||||
|
self.nodes.clearAndFree();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trackRoad(self: *RoadManager, pos: rl.Vector2) void {
|
fn trackRoad(self: *RoadManager, pos: rl.Vector2) void {
|
||||||
@ -58,11 +75,9 @@ pub const RoadManager = struct {
|
|||||||
for (0..self.roads.items.len) |i| {
|
for (0..self.roads.items.len) |i| {
|
||||||
// we skip because that road is not complete
|
// we skip because that road is not complete
|
||||||
if (self.roads.items[i].end_point == null) continue;
|
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.?)) {
|
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(str.RoadState.selected);
|
||||||
self.roads.items[i].setColor(true);
|
|
||||||
self.selected_road = i;
|
self.selected_road = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -109,6 +124,8 @@ pub const RoadManager = struct {
|
|||||||
self.clearRoads();
|
self.clearRoads();
|
||||||
} else if (rl.isKeyReleased(.d)) {
|
} else if (rl.isKeyReleased(.d)) {
|
||||||
self.toggleDeleteMode();
|
self.toggleDeleteMode();
|
||||||
|
} else if (rl.isKeyReleased(.n)) {
|
||||||
|
self.toggleNodeMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,21 +152,62 @@ pub const RoadManager = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn toggleDeleteMode(self: *RoadManager) void {
|
fn toggleDeleteMode(self: *RoadManager) void {
|
||||||
if (self.mode == str.InputMode.delete) {
|
self.togglePrepare();
|
||||||
self.resetTrackedRoad();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cancelRoadbuilding();
|
|
||||||
self.mode = switch (self.mode) {
|
self.mode = switch (self.mode) {
|
||||||
.normal => str.InputMode.delete,
|
.normal => str.InputMode.delete,
|
||||||
.delete => str.InputMode.normal,
|
.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 {
|
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();
|
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 {
|
fn setDefaultColour(self: *RoadManager) void {
|
||||||
for (self.roads.items) |*road| {
|
for (self.roads.items) |*road| {
|
||||||
road.setColor(false);
|
road.setColor(str.RoadState.valid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
const rl = @import("raylib");
|
const rl = @import("raylib");
|
||||||
const globals = @import("../globals.zig");
|
const globals = @import("../globals.zig");
|
||||||
const road_data = @import("road-data.zig");
|
const road_data = @import("road-data.zig");
|
||||||
|
const str = @import("../structures.zig");
|
||||||
|
|
||||||
pub const Road = struct {
|
pub const Road = struct {
|
||||||
color: rl.Color,
|
|
||||||
start_point: rl.Vector2,
|
start_point: rl.Vector2,
|
||||||
end_point: ?rl.Vector2,
|
end_point: ?rl.Vector2,
|
||||||
|
color: rl.Color,
|
||||||
|
|
||||||
pub fn init(pos: rl.Vector2) Road {
|
pub fn init(pos: rl.Vector2) Road {
|
||||||
return Road{
|
return Road{
|
||||||
.color = .black,
|
|
||||||
.start_point = pos,
|
.start_point = pos,
|
||||||
.end_point = null,
|
.end_point = null,
|
||||||
|
.color = .black,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,8 +20,16 @@ pub const Road = struct {
|
|||||||
self.end_point = pos;
|
self.end_point = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setColor(self: *Road, is_selected: bool) void {
|
pub fn setColor(self: *Road, road_state: str.RoadState) void {
|
||||||
self.color = if (is_selected) .green else .black;
|
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 {
|
pub fn draw(self: *const Road) void {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// valid area states
|
||||||
pub const AreaLocation = enum {
|
pub const AreaLocation = enum {
|
||||||
top_left,
|
top_left,
|
||||||
top_right,
|
top_right,
|
||||||
@ -5,8 +6,15 @@ pub const AreaLocation = enum {
|
|||||||
bottom_right,
|
bottom_right,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// road modes
|
||||||
pub const InputMode = enum {
|
pub const InputMode = enum {
|
||||||
normal,
|
normal,
|
||||||
delete,
|
delete,
|
||||||
node,
|
node,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const RoadState = enum {
|
||||||
|
valid,
|
||||||
|
illegal,
|
||||||
|
selected,
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user