package main import "core:math" import "core:fmt" import sc "core:strconv" import rl "vendor:raylib" import "common" // Main drawing function draw :: proc(self: ^Simulator, pos: rl.Vector2) { rl.ClearBackground(rl.LIGHTGRAY) draw_roads(self) draw_nodes(self) draw_cars(self) draw_temp_road(self, pos) if self.display_entity_data do draw_entity_data(self) draw_ui(self) } @(private="file") draw_roads :: proc(self: ^Simulator) { for road, index in self.roads { start := road.nodes[0] end := road.nodes[1] road_colour: rl.Color if road, ok := self.highlighted_road.?; ok && road == uint(index) && self.delete_mode { road_colour = common.ROAD_HIGHLIGHT_COLOUR } else do road_colour = common.ROAD_COLOUR rl.DrawLineEx(self.nodes[start].pos, self.nodes[end].pos, common.ROAD_SIZE, road_colour) } } @(private="file") draw_nodes :: proc(self: ^Simulator) { for node in self.nodes { // draws the snapping radius if key is held down if self.show_details do rl.DrawCircleV(node.pos, common.NODE_SNAP_RADIUS, common.NODE_SNAP_COLOUR) // draws the node rl.DrawCircleV(node.pos, common.NODE_RADIUS, common.NODE_DONE_COLOUR) } } @(private="file") draw_cars :: proc(self: ^Simulator) { for car in self.cars { ref := car.pos.ref // TODO fix in the future // let's fix it by tracking length of the road and pos := car.pos.type == .Node ? self.nodes[ref].pos : self.nodes[self.roads[ref].nodes[0]].pos rect := rl.Rectangle { x = pos.x, y = pos.y, width = common.CAR_WIDTH, height = common.CAR_HEIGHT } rl.DrawRectangleRec(rect, common.CAR_COLOUR) } } @(private="file") draw_temp_road :: proc(self: ^Simulator, pos: rl.Vector2) { // draw temp road if exists val, ok := self.temp_node.? if !ok do return rl.DrawLineEx(self.nodes[val].pos, pos, common.ROAD_SIZE, common.ROAD_COLOUR) rl.DrawCircleV(self.nodes[val].pos, common.NODE_RADIUS, common.NODE_BUILD_COLOUR) rl.DrawCircleV(pos, common.NODE_RADIUS, common.NODE_CURSOR_COLOUR) } // Drawing UI text, mostly for debugging purposes @(private="file") draw_ui :: proc(self: ^Simulator) { entity_count := fmt.ctprintf("Nodes: %d, Roads: %d, Cars: %d", len(self.nodes), len(self.roads), len(self.cars)) rl.DrawText(entity_count, i32(len(entity_count)), common.HEIGHT - common.TEXT_SIZE, common.TEXT_SIZE, common.TEXT_COLOUR) } // Draws ID's on top of all entities (roads, nodes, cars, etc.) @(private="file") draw_entity_data :: proc(self: ^Simulator) { colour := rl.ORANGE for node, index in self.nodes { radius_diff := f32(common.NODE_RADIUS / 2) actual_pos: rl.Vector2 = { node.pos.x - radius_diff, node.pos.y - radius_diff, } id := fmt.caprintf("%d", index) rl.DrawText(id, i32(actual_pos.x), i32(actual_pos.y), common.TEXT_SIZE, colour) } // todo fix in the future for road, index in self.roads { id := fmt.caprintf("%d", index) start := self.nodes[road.nodes[0]] end := self.nodes[road.nodes[1]] // calculate the appropriate coordiante // first get the leftmost node leftmost := start.pos.x <= end.pos.x ? start : end rl.DrawText(id, i32(leftmost.pos.x + road.length / 2), i32((start.pos.y + end.pos.y) / 2), common.TEXT_SIZE, colour) } // todo for cars for car, index in self.cars { id := fmt.caprintf("%d", index) offset := math.sqrt(f32(common.CAR_HEIGHT * len(id))) rl.DrawText(id, i32(car.absolute_pos.x + common.CAR_WIDTH / 2 - offset), i32(car.absolute_pos.y), common.CAR_HEIGHT, colour) } }