improved roadbuilding
This commit is contained in:
parent
147202d053
commit
2e8ebaa737
@ -37,8 +37,8 @@
|
||||
// internet connectivity.
|
||||
.dependencies = .{
|
||||
.raylib_zig = .{
|
||||
.url = "git+https://github.com/Not-Nik/raylib-zig?ref=devel#5013830647196ba938a3a25a36b8245606e9a9cd",
|
||||
.hash = "raylib_zig-5.6.0-dev-KE8REM0tBQAHVn9Xjqlgu9l1qgfTmP8aJa1kLhD584bV",
|
||||
.url = "git+https://github.com/Not-Nik/raylib-zig?ref=devel#e8167c2e560402510220fdf419afbc7c2fc51e5d",
|
||||
.hash = "raylib_zig-5.6.0-dev-KE8REIouBQDbt-DSHmhUc9YFjJ_pFUS5tvRDPnBzsMdU",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
|
@ -7,15 +7,19 @@ const car = @import("../car/car.zig");
|
||||
pub const SpawnArea = struct {
|
||||
area: structures.AreaLocation,
|
||||
location: rl.Vector2,
|
||||
calculated: rl.Vector2, // x/y + width/height * scale
|
||||
width: i32,
|
||||
height: i32,
|
||||
red_line_th: f32,
|
||||
|
||||
pub fn init(area_loc: structures.AreaLocation) SpawnArea {
|
||||
var new_spawn = SpawnArea{
|
||||
.area = area_loc,
|
||||
.location = undefined,
|
||||
.calculated = undefined,
|
||||
.width = 100,
|
||||
.height = 50,
|
||||
.red_line_th = 5.0,
|
||||
};
|
||||
|
||||
// need to do this outside the "constructor", as the function needs reference to self
|
||||
@ -31,6 +35,9 @@ pub const SpawnArea = struct {
|
||||
.bottom_left => rl.Vector2{ .x = 0, .y = globals.getScreenHeightF32() - @as(f32, @floatFromInt(self.height)) * globals.getScale() },
|
||||
.bottom_right => rl.Vector2{ .x = globals.getScreenWidthF32() - @as(f32, @floatFromInt(self.width)) * globals.getScale(), .y = globals.getScreenHeightF32() - @as(f32, @floatFromInt(self.height)) * globals.getScale() },
|
||||
};
|
||||
|
||||
self.calculated.x = self.location.x + intToFloat(self.width) * globals.getScale();
|
||||
self.calculated.y = self.location.y + intToFloat(self.height) * globals.getScale();
|
||||
}
|
||||
|
||||
pub fn getNodeLocation(self: *const SpawnArea) rl.Vector2 {
|
||||
@ -49,53 +56,9 @@ pub const SpawnArea = struct {
|
||||
};
|
||||
rl.drawRectangleRec(rect, .dark_gray);
|
||||
|
||||
// red line for hover
|
||||
if (self.checkHover()) {
|
||||
var start_pos: rl.Vector2 = undefined;
|
||||
var end_pos: rl.Vector2 = undefined;
|
||||
|
||||
// this should be precalculated shouldn't need do calculate this each time just for the sake of drawing it
|
||||
switch (self.area) {
|
||||
.top_left => {
|
||||
start_pos = rl.Vector2 {
|
||||
.x = self.location.x + intToFloat(self.width) * globals.getScale(),
|
||||
.y = self.location.y,
|
||||
};
|
||||
|
||||
end_pos = rl.Vector2 {
|
||||
.x = start_pos.x,
|
||||
.y = self.location.y + intToFloat(self.height) * globals.getScale(),
|
||||
};
|
||||
},
|
||||
.top_right => {
|
||||
start_pos = self.location;
|
||||
end_pos = rl.Vector2 {
|
||||
.x = start_pos.x,
|
||||
.y = self.location.y + intToFloat(self.height) * globals.getScale(),
|
||||
};
|
||||
},
|
||||
.bottom_left => {
|
||||
start_pos = rl.Vector2 {
|
||||
.x = self.location.x + intToFloat(self.width) * globals.getScale(),
|
||||
.y = self.location.y,
|
||||
};
|
||||
|
||||
end_pos = rl.Vector2 {
|
||||
.x = start_pos.x,
|
||||
.y = self.location.y + intToFloat(self.height) * globals.getScale(),
|
||||
};
|
||||
},
|
||||
.bottom_right => {
|
||||
start_pos = self.location;
|
||||
end_pos = rl.Vector2 {
|
||||
.x = start_pos.x,
|
||||
.y = self.location.y + intToFloat(self.height) * globals.getScale(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
rl.drawLineEx(start_pos, end_pos, 5, .red);
|
||||
}
|
||||
// TODO implement a functionality which will prevent user from drawing near corner
|
||||
// when the corner is touched road will not follow through it will be forbiden
|
||||
// and the corner rectangle will start shining
|
||||
}
|
||||
|
||||
fn checkHover(self: *const SpawnArea) bool {
|
||||
|
@ -16,7 +16,7 @@ pub const Car = struct {
|
||||
.parent_location = parent_location,
|
||||
.cell = cells,
|
||||
.slot = slots,
|
||||
|
||||
// destination (will be described as an area the car will try to reach)
|
||||
.location = undefined,
|
||||
.color = .dark_blue,
|
||||
.fuel = 100.0,
|
||||
|
@ -19,16 +19,14 @@ pub fn main() !void {
|
||||
|
||||
rl.setExitKey(.null);
|
||||
rl.maximizeWindow();
|
||||
rl.setTargetFPS(60);
|
||||
rl.setTargetFPS(144);
|
||||
|
||||
var area_manager = try areas.Areas.init(allocator, 4);
|
||||
defer area_manager.deinit();
|
||||
|
||||
var road_manager = roadman_str.RoadManager.init(allocator);
|
||||
var road_manager = try roadman_str.RoadManager.init(allocator, area_manager);
|
||||
defer road_manager.deinit();
|
||||
|
||||
try road_manager.addAreaNodes(area_manager);
|
||||
|
||||
while (!rl.windowShouldClose()) {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
@ -40,8 +38,7 @@ pub fn main() !void {
|
||||
globals.setWindowSize(new_width, new_height);
|
||||
area_manager.recalculate();
|
||||
try road_manager.updateAreaNodes(area_manager);
|
||||
// todo this will bring some trouble because what if other nodes/roads, when resized, will be placed upon existing spawn area
|
||||
|
||||
// this will bring some trouble because what if other nodes/roads, when resized, will be placed upon existing spawn area
|
||||
}
|
||||
|
||||
rl.clearBackground(.light_gray);
|
||||
|
@ -16,9 +16,14 @@ pub const RoadManager = struct {
|
||||
mode: str.InputMode,
|
||||
selected_road: ?usize,
|
||||
min_distance: f32,
|
||||
area_num: usize,
|
||||
temp_nodes: bool,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator) RoadManager {
|
||||
return RoadManager{
|
||||
pub fn init(allocator: std.mem.Allocator, areas: area_str.Areas) !RoadManager {
|
||||
const nodes = try areas.getNodes();
|
||||
defer allocator.free(nodes);
|
||||
|
||||
var road_man = RoadManager{
|
||||
.buffer = road_data.road_thickness * globals.getScale() / 2.0,
|
||||
.allocator = allocator,
|
||||
.roads = std.ArrayList(road_str.Road).init(allocator),
|
||||
@ -26,7 +31,12 @@ pub const RoadManager = struct {
|
||||
.mode = str.InputMode.normal,
|
||||
.selected_road = null,
|
||||
.min_distance = globals.getScreenWidthF32() / 25.0,
|
||||
.area_num = nodes.len,
|
||||
.temp_nodes = false,
|
||||
};
|
||||
|
||||
try road_man.nodes.appendSlice(nodes);
|
||||
return road_man;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *RoadManager) void {
|
||||
@ -40,13 +50,16 @@ 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) {
|
||||
// TODO RETURN IF MOUSE IS IN AREA!!! (we can only draw roads from there)
|
||||
|
||||
// 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;
|
||||
// only if close enough to node AND TODO THEN FORCE THE FUCKER TO SNAP ON IT
|
||||
|
||||
self.roads.items[last_id.?].confirmRoad(pos);
|
||||
try self.nodes.append(node_str.Node.init(pos));
|
||||
} else if (self.canCreateNode(pos)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try self.roads.append(road_str.Road.init(pos));
|
||||
@ -66,9 +79,7 @@ pub const RoadManager = struct {
|
||||
|
||||
fn clearRoads(self: *RoadManager) void {
|
||||
self.roads.clearAndFree();
|
||||
// todo this will delete spawn nodes which MUST NOT be deleted
|
||||
// fix at earliest convinience
|
||||
self.nodes.clearAndFree();
|
||||
self.nodes.shrinkAndFree(self.area_num);
|
||||
}
|
||||
|
||||
fn trackRoad(self: *RoadManager, pos: rl.Vector2) void {
|
||||
@ -124,13 +135,19 @@ pub const RoadManager = struct {
|
||||
|
||||
fn handleKeyboardInput(self: *RoadManager) void {
|
||||
// keyboard inputs
|
||||
if (rl.isKeyReleased(.c)) {
|
||||
if (rl.isKeyReleased(.b)) {
|
||||
self.toggleMode(str.InputMode.build);
|
||||
} else if (rl.isKeyReleased(.c)) {
|
||||
self.clearRoads();
|
||||
} else if (rl.isKeyReleased(.d)) {
|
||||
self.toggleDeleteMode();
|
||||
self.toggleMode(str.InputMode.delete);
|
||||
} else if (rl.isKeyReleased(.n)) {
|
||||
self.toggleNodeMode();
|
||||
self.toggleMode(str.InputMode.node);
|
||||
} else if (rl.isKeyReleased(.escape)) {
|
||||
self.toggleMode(str.InputMode.normal);
|
||||
}
|
||||
|
||||
self.temp_nodes = rl.isKeyDown(.left_control);
|
||||
}
|
||||
|
||||
fn handleMouseInput(self: *RoadManager) !void {
|
||||
@ -144,7 +161,7 @@ pub const RoadManager = struct {
|
||||
|
||||
fn handleLeftClick(self: *RoadManager) !void {
|
||||
switch (self.mode) {
|
||||
.normal => try self.addRoad(rl.getMousePosition()),
|
||||
.normal => {},
|
||||
.delete => {
|
||||
if (self.selected_road == null) return;
|
||||
|
||||
@ -152,27 +169,15 @@ pub const RoadManager = struct {
|
||||
self.selected_road = null;
|
||||
},
|
||||
.node => {},
|
||||
.build => try self.addRoad(rl.getMousePosition()),
|
||||
}
|
||||
}
|
||||
|
||||
fn toggleDeleteMode(self: *RoadManager) void {
|
||||
fn toggleMode(self: *RoadManager, mode: str.InputMode) void {
|
||||
self.togglePrepare();
|
||||
|
||||
self.mode = switch (self.mode) {
|
||||
.normal => str.InputMode.delete,
|
||||
.delete => str.InputMode.normal,
|
||||
.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,
|
||||
};
|
||||
if (self.mode != mode)
|
||||
self.mode = mode;
|
||||
}
|
||||
|
||||
fn togglePrepare(self: *RoadManager) void {
|
||||
@ -207,19 +212,17 @@ pub const RoadManager = struct {
|
||||
}
|
||||
}
|
||||
|
||||
if (self.mode != str.InputMode.node) return;
|
||||
if (self.mode != str.InputMode.node and !self.temp_nodes) return;
|
||||
for (self.nodes.items) |node| {
|
||||
node.draw(true);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn drawMode(self: *const RoadManager) !void {
|
||||
const prefix = "Mode: ";
|
||||
const text = @tagName(self.mode); // this turns an enum into string like "normal"
|
||||
const full_text = try std.fmt.allocPrintZ(self.allocator, "{s}{s}", .{ prefix, text });
|
||||
const full_text = try std.fmt.allocPrintZ(self.allocator, "Mode: {s}", .{text});
|
||||
defer self.allocator.free(full_text);
|
||||
|
||||
// draw funct
|
||||
rl.drawText(full_text, @divTrunc(globals.getScreenWidth(), 3), 50, 100, .dark_blue);
|
||||
}
|
||||
|
||||
@ -239,13 +242,6 @@ pub const RoadManager = struct {
|
||||
self.selected_road = null;
|
||||
}
|
||||
|
||||
pub fn addAreaNodes(self: *RoadManager, areas: area_str.Areas) !void {
|
||||
const nodes = try areas.getNodes();
|
||||
defer self.allocator.free(nodes);
|
||||
|
||||
try self.nodes.appendSlice(nodes);
|
||||
}
|
||||
|
||||
pub fn updateAreaNodes(self: *RoadManager, areas: area_str.Areas) !void {
|
||||
const nodes = try areas.getNodes();
|
||||
defer self.allocator.free(nodes);
|
||||
|
@ -11,6 +11,7 @@ pub const InputMode = enum {
|
||||
normal,
|
||||
delete,
|
||||
node,
|
||||
build,
|
||||
};
|
||||
|
||||
pub const RoadState = enum {
|
||||
|
Loading…
x
Reference in New Issue
Block a user