diff options
Diffstat (limited to '')
-rw-r--r-- | Scripts/car_behaviour.gd | 78 | ||||
-rw-r--r-- | Scripts/scene_control.gd | 13 |
2 files changed, 91 insertions, 0 deletions
diff --git a/Scripts/car_behaviour.gd b/Scripts/car_behaviour.gd new file mode 100644 index 0000000..b71ebb6 --- /dev/null +++ b/Scripts/car_behaviour.gd @@ -0,0 +1,78 @@ +extends StaticBody2D + +# editor variables +@export var max_speed = 300 +@export var steer_force = 0.1 +@export var look_ahead = 75 +@export var num_rays = 32 + +# context array +var ray_directions = [] +var interest = [] +var danger = [] + +var chosen_dir = Vector2.ZERO +var velocity = Vector2.ZERO +var acceleration = Vector2.ZERO + + +# Called when the node enters the scene tree for the first time. +func _ready(): + interest.resize(num_rays) + danger.resize(num_rays) + ray_directions.resize(num_rays) + for i in num_rays: + var angle = i * 2 * PI / num_rays + ray_directions[i] = Vector2.RIGHT.rotated(angle) + print(ray_directions) + + +func _physics_process(delta): + set_interest() + set_danger() + choose_direction() + var desired_velocity = chosen_dir.rotated(rotation) * max_speed + velocity = velocity.lerp(desired_velocity, steer_force) + rotation = velocity.angle() + move_and_collide(velocity * delta) + +func set_interest(): + # Set interest in each slot based on world direction + if owner and owner.has_method("get_path_direction"): + var path_direction = owner.get_path_direction(position) + for i in num_rays: + var d = ray_directions[i].rotated(rotation).dot(path_direction) + interest[i] = max(0, d) + # If no world path, use default interest + else: + set_default_interest() + +func set_default_interest(): + # Default to moving forward + for i in num_rays: + var d = ray_directions[i].rotated(rotation).dot(transform.x) + interest[i] = max(0, d) + +func set_danger(): + # Cast rays to find danger directions + var space_state = get_world_2d().direct_space_state + + var params = PhysicsRayQueryParameters2D.new() + params.from = position + params.exclude = [self] + + for i in num_rays: + params.to = position + ray_directions[i].rotated(rotation) * look_ahead + var result = space_state.intersect_ray(params) + danger[i] = 1.0 if result else 0.0 + +func choose_direction(): + # Eliminate interest in slots with danger + for i in num_rays: + if danger[i] > 0.0: + interest[i] = 0.0 + # Choose direction based on remaining interest + chosen_dir = Vector2.ZERO + for i in num_rays: + chosen_dir += ray_directions[i] * interest[i] + chosen_dir = chosen_dir.normalized() diff --git a/Scripts/scene_control.gd b/Scripts/scene_control.gd new file mode 100644 index 0000000..9f231e0 --- /dev/null +++ b/Scripts/scene_control.gd @@ -0,0 +1,13 @@ +extends Node + +class_name SceneControl + +@onready var path : Path2D = $Path2D + +@on#ready var path_follow : PathFollow2D = $Path2D/PathFollow2D + + +func get_path_direction(pos): + var offset = path.curve.get_closest_offset(pos) + path_follow.h_offset = offset + return path_follow.transform.x |