diff --git a/.gitignore b/.gitignore index e901168..499ec12 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /.zig-cache /zig-out +/.idea \ No newline at end of file diff --git a/src/areas.zig b/src/areas.zig index 7f0c625..adda826 100644 --- a/src/areas.zig +++ b/src/areas.zig @@ -3,27 +3,41 @@ const rl = @import("raylib"); const spawn_area = @import("spawn-area.zig"); const structures = @import("structures.zig"); -const Areas = struct { - areas: []spawn_area.SpawnArea, +pub const Areas = struct { allocator: std.mem.Allocator, + areas: []spawn_area.SpawnArea, pub fn init(allocator: std.mem.Allocator, size: usize) !Areas { const values = std.enums.values(structures.AreaLocation); - if (size > values.len) size = values.len; + var max_areas = size; + if (size > values.len) max_areas = values.len; var used_areas = std.ArrayList(structures.AreaLocation).init(allocator); defer used_areas.deinit(); - // here we generate size random AreaLocation enums that aren't in used_areas - // the random generator will only generate AreaLocation enums that are not in - // - // todo implement function which will subtract values from used_areas (after RANDOM) - // based on this we will fill data with 0..size data and return the final value + var prng = std.Random.DefaultPrng.init(blk: { + var seed: u64 = undefined; + try std.posix.getrandom(std.mem.asBytes(&seed)); + break :blk seed; + }); + + const rand = prng.random(); + const area_data = try allocator.alloc(spawn_area.SpawnArea, size); + + for (area_data) |*area| { + // give us all valid values we can use for AreaLocation + const valid_values = try getEnumValuesMinusUsed(allocator, used_areas, values); + defer allocator.free(valid_values); + + const num = rand.intRangeAtMost(usize, 0, valid_values.len - 1); // random number + // here we create new spawnarea + area.* = spawn_area.SpawnArea.init(valid_values[num]); + try used_areas.append(valid_values[num]); + } - const data = try allocator.alloc(structures.AreaLocation, size); - // todo data must be set before returned return Areas{ - .areas = data, + .allocator = allocator, + .areas = area_data, }; } @@ -31,8 +45,28 @@ const Areas = struct { self.allocator.free(self.areas); } - pub fn draw(areas: *Areas) void { - // todo implement draw - _ = areas; + pub fn draw(self: *Areas) void { + for (self.areas) |area| { + area.draw(); + } + } + + fn getEnumValuesMinusUsed(allocator: std.mem.Allocator, used_values: std.ArrayList(structures.AreaLocation), values: []const structures.AreaLocation) ![]structures.AreaLocation { + var valuesToRandomise = try allocator.alloc(structures.AreaLocation, values.len - used_values.items.len); + + var i: usize = 0; + + outer: for (values) |value| { + for (used_values.items) |used_val| { + if (value == used_val) { + continue :outer; + } + } + // this value is clean and can get put into values good for randomisation + valuesToRandomise[i] = value; + i += 1; + } + + return valuesToRandomise; } }; diff --git a/src/globals.zig b/src/globals.zig index 10da674..1c4ec03 100644 --- a/src/globals.zig +++ b/src/globals.zig @@ -2,12 +2,17 @@ const rl = @import("raylib"); var screen_width: i32 = 1920; var screen_height: i32 = 1080; +const scale: i32 = 5; + +pub fn getScale() i32 { + return scale; +} pub fn getScreenWidth() i32 { return screen_width; } -pub fn getScreenHeihgt() i32 { +pub fn getScreenHeight() i32 { return screen_height; } diff --git a/src/main.zig b/src/main.zig index 509f549..f7eb32c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -13,7 +13,7 @@ pub fn main() !void { .window_resizable = true, }); - rl.initWindow(globals.getScreenWidth, globals.getScreenHeihgt, "Promet SIM"); + rl.initWindow(globals.getScreenWidth(), globals.getScreenHeight(), "Promet SIM"); defer rl.closeWindow(); rl.maximizeWindow(); diff --git a/src/spawn-area.zig b/src/spawn-area.zig index 4064a94..1dde63a 100644 --- a/src/spawn-area.zig +++ b/src/spawn-area.zig @@ -1,12 +1,46 @@ const rl = @import("raylib"); const structures = @import("structures.zig"); +const globals = @import("globals.zig"); pub const SpawnArea = struct { + area: structures.AreaLocation, location: rl.Vector2, // cars - size: .{ i32, i32 }, + width: i32, + height: i32, - pub fn init(loc: structures.AreaLocation) SpawnArea { - return SpawnArea{ .location = loc, .size = .{ undefined, undefined } }; + pub fn init(area_loc: structures.AreaLocation) SpawnArea { + var new_spawn = SpawnArea{ + .area = area_loc, + .location = undefined, + .width = 100, + .height = 50, + }; + + // need to do this outside the "constructor", as the function needs reference to self + new_spawn.setLocation(); + + return new_spawn; + } + + // todo if window size changes this needs to be recalculated + fn setLocation(self: *SpawnArea) void { + self.location = switch (self.area) { + .top_left => rl.Vector2{ .x = 0, .y = 0 }, + .top_right => rl.Vector2{ .x = globals.getScreenWidth() - self.width * globals.getScale(), .y = 0 }, + .bottom_left => rl.Vector2{ .x = 0, .y = globals.getScreenHeight() - self.height * globals.getScale() }, + .bottom_right => rl.Vector2{ .x = globals.getScreenWidth() - self.width * globals.getScale(), .y = globals.getScreenHeight() - self.height * globals.getScale() }, + }; + } + + pub fn draw(self: *SpawnArea) void { + const rect = rl.Rectangle{ + .x = self.location.x, + .y = self.location.y, + .width = self.width * globals.getScale(), + .height = self.height * globals.getScale(), + }; + rl.drawRectangleRec(rect, .dark_gray); + // todo draw cars } }; diff --git a/src/structures.zig b/src/structures.zig index d6fcee1..f169ed2 100644 --- a/src/structures.zig +++ b/src/structures.zig @@ -1,6 +1,6 @@ -const AreaLocation = enum { - TopLeft, - TopRight, - BottomLeft, - BottomRihgt, +pub const AreaLocation = enum { + top_left, + top_right, + bottom_left, + bottom_right, };