diff --git a/project.godot b/project.godot index a5544c9..63032da 100644 --- a/project.godot +++ b/project.godot @@ -14,6 +14,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://scenes/base_track_level.gd" }, { +"base": "VehicleBody", +"class": "BuggedVehicle", +"language": "GDScript", +"path": "res://vehicles/vehicle.gd" +}, { "base": "Particles", "class": "TireSmoke", "language": "GDScript", @@ -26,6 +31,7 @@ _global_script_classes=[ { } ] _global_script_class_icons={ "BaseTrackLevel": "", +"BuggedVehicle": "", "TireSmoke": "", "Track": "" } diff --git a/scenes/base_track_level.gd b/scenes/base_track_level.gd index 457b5fe..1c85b47 100644 --- a/scenes/base_track_level.gd +++ b/scenes/base_track_level.gd @@ -3,19 +3,32 @@ extends Spatial const camera = preload("res://player/camera.tscn") onready var spawn_point = $PlayerSpawnLocation +onready var track = $Track var player_node: Node var gui: Node + func _ready() -> void: player_node.global_transform = spawn_point.global_transform add_child(player_node) add_child(gui) var player_camera = camera.instance() player_camera.global_transform = spawn_point.global_transform - player_camera.global_transform.origin = -spawn_point.global_transform.basis.z * 1000 + player_camera.global_transform.origin -= spawn_point.global_transform.basis.z * 1000 player_camera.follow_target_path = player_node.get_path() add_child(player_camera) + func spawn_player(player_node: Node, gui: Node) -> void: self.player_node = player_node self.gui = gui + + +func reset_player_to(node_to_reset_to: Node, player_node: BuggedVehicle) -> void: + player_node.reset_transform = node_to_reset_to.global_transform + player_node.reset_transform.origin += node_to_reset_to.global_transform.basis.y * 15 + + +func _on_ResetArea_body_entered(body: Node) -> void: + if body.get_groups().has("car"): + reset_player_to(track.get_last_checkpoint(), body) diff --git a/scenes/infinite_loop_track_level.tscn b/scenes/infinite_loop_track_level.tscn index 3814723..e238ea4 100644 --- a/scenes/infinite_loop_track_level.tscn +++ b/scenes/infinite_loop_track_level.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=9 format=2] +[gd_scene load_steps=10 format=2] [ext_resource path="res://scenes/base_track_level.tscn" type="PackedScene" id=1] [ext_resource path="res://assets/dirttrack.png" type="Texture" id=2] @@ -76,6 +76,9 @@ albedo_color = Color( 0.0862745, 0.929412, 0.858824, 1 ) material = SubResource( 2 ) flip_faces = true +[sub_resource type="BoxShape" id=8] +extents = Vector3( 226.72, 25.6138, 197.933 ) + [node name="Spatial" instance=ExtResource( 1 )] [node name="PlayerSpawnLocation" parent="." index="1"] @@ -124,3 +127,11 @@ material = SubResource( 7 ) transform = Transform( 224.434, 0, 0, 0, 224.434, 0, 0, 0, 224.434, 0, 0, 0 ) mesh = SubResource( 3 ) material/0 = null + +[node name="ResetArea" type="Area" parent="." index="5"] + +[node name="CollisionShape" type="CollisionShape" parent="ResetArea" index="0"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -106.576, 0 ) +shape = SubResource( 8 ) + +[connection signal="body_entered" from="ResetArea" to="." method="_on_ResetArea_body_entered"] diff --git a/scenes/tracks/track.gd b/scenes/tracks/track.gd index 3d0ce12..2135fd1 100644 --- a/scenes/tracks/track.gd +++ b/scenes/tracks/track.gd @@ -18,6 +18,9 @@ var last_checkpoint = -1 var start_time = 0 var current_time = 0 +func get_last_checkpoint() -> Node: + return checkpoints.get_child(max(0, last_checkpoint)) + func _ready() -> void: start_time = OS.get_ticks_msec() var length = path.curve.get_baked_length() diff --git a/vehicles/vehicle.gd b/vehicles/vehicle.gd index 060499b..16c4460 100644 --- a/vehicles/vehicle.gd +++ b/vehicles/vehicle.gd @@ -1,34 +1,35 @@ +class_name BuggedVehicle extends VehicleBody signal speed_updated(speed_kph, speed_percent) signal rpm_updated(rpm, rpm_percent) signal gear_updated(gear) -export (float) var MAX_STEER_ANGLE = 25 -export (float) var SPEED_STEER_ANGLE = 10 -export (float) var MAX_STEER_SPEED = 100.0 -export (float) var MAX_STEER_INPUT = 80.0 +export(float) var MAX_STEER_ANGLE = 25 +export(float) var SPEED_STEER_ANGLE = 10 +export(float) var MAX_STEER_SPEED = 100.0 +export(float) var MAX_STEER_INPUT = 80.0 onready var max_steer_angle_rad: float = deg2rad(MAX_STEER_ANGLE) onready var speed_steer_angle_rad: float = deg2rad(SPEED_STEER_ANGLE) onready var max_steer_input_rad: float = deg2rad(MAX_STEER_INPUT) -export (Curve) var steer_curve = null +export(Curve) var steer_curve = null -export (float) var MAX_ENGINE_FORCE = 85.0 -export (float) var MAX_BRAKE_FORCE = 50.0 -export (float) var THROTTLE_POWER = 6000.0 -export (float) var MAX_RPM_LOSS_PS = 3000.0 -export (float) var BASE_ENGINE_PITCH = 0.5 -export (float) var EXPECTED_MAX_SPEED = 200 +export(float) var MAX_ENGINE_FORCE = 85.0 +export(float) var MAX_BRAKE_FORCE = 50.0 +export(float) var THROTTLE_POWER = 6000.0 +export(float) var MAX_RPM_LOSS_PS = 3000.0 +export(float) var BASE_ENGINE_PITCH = 0.5 +export(float) var EXPECTED_MAX_SPEED = 200 -export (Array) var gear_ratios = [ 3.4, 2.5, 2.0, 1.5, 1.25 ] -export (float) var reverse_ratio = -3 -export (float) var final_drive = 3.45 -export (float) var max_rpm = 3500 -export (float) var min_rpm = 900 -export (float) var gear_switch_time = 0.2 -export (Curve) var power_curve = null -export (Curve) var sound_curve = null +export(Array) var gear_ratios = [3.4, 2.5, 2.0, 1.5, 1.25] +export(float) var reverse_ratio = -3 +export(float) var final_drive = 3.45 +export(float) var max_rpm = 3500 +export(float) var min_rpm = 900 +export(float) var gear_switch_time = 0.2 +export(Curve) var power_curve = null +export(Curve) var sound_curve = null var clutch_position: float = 0.0 var rpm = 0 @@ -49,6 +50,8 @@ onready var engine_sound_player: AudioStreamPlayer3D = $engine_sound_player onready var engine_sound_playback: AudioStreamPlayback = $engine_sound_player.get_stream_playback() var traction_wheels: Array +var reset_transform: Transform = Transform.IDENTITY + func _ready(): for wheel in [frwheel, flwheel, rrwheel, rlwheel]: @@ -58,6 +61,11 @@ func _ready(): _generate_engine_sound(0) engine_sound_player.play() +func _integrate_forces(state: PhysicsDirectBodyState) -> void: + if reset_transform != Transform.IDENTITY: + state.set_transform(reset_transform) + reset_transform = Transform.IDENTITY + func _get_gear_ratio(): if gear == 0: return 0 @@ -66,6 +74,7 @@ func _get_gear_ratio(): else: return gear_ratios[gear - 1] + func _handle_gear_switch(delta: float): if gear_timer > 0: gear_timer = max(0, gear_timer - delta) @@ -81,23 +90,31 @@ func _handle_gear_switch(delta: float): gear_timer = gear_switch_time * (2 - clutch_position) emit_signal("gear_updated", gear) + func _has_traction(): for wheel in traction_wheels: if wheel.is_in_contact(): return true return false + func _update_wheels_smoke(): - for wheelnsmoke in [[frwheel, frsmoke], [flwheel, flsmoke], [rrwheel, rrsmoke], [rlwheel, rlsmoke]]: + for wheelnsmoke in [ + [frwheel, frsmoke], [flwheel, flsmoke], [rrwheel, rrsmoke], [rlwheel, rlsmoke] + ]: wheelnsmoke[1].update(wheelnsmoke[0].get_skidinfo()) + func _lerp_rpm(from, to, delta, factor): var new_val = lerp(from, to, factor) if abs(from - new_val) > MAX_RPM_LOSS_PS * delta: - var new_factor = inverse_lerp(from, to, from - sign(from - new_val) * MAX_RPM_LOSS_PS * delta) + var new_factor = inverse_lerp( + from, to, from - sign(from - new_val) * MAX_RPM_LOSS_PS * delta + ) new_val = lerp(from, to, new_factor) return new_val + func _physics_process(delta: float): _update_wheels_smoke() clutch_position = Input.get_action_strength("clutch") @@ -142,7 +159,10 @@ func _physics_process(delta: float): emit_signal("speed_updated", speed, speed / EXPECTED_MAX_SPEED) emit_signal("rpm_updated", rpm, rpm_factor) - var steering_input = Input.get_action_strength("steer_left") - Input.get_action_strength("steer_right") + var steering_input = ( + Input.get_action_strength("steer_left") + - Input.get_action_strength("steer_right") + ) if abs(steering_input) < 0.05: steering_input = 0.0 elif steer_curve: @@ -155,6 +175,7 @@ func _physics_process(delta: float): steering = steering_input * lerp(max_steer_angle_rad, speed_steer_angle_rad, steer_speed_factor) + func _generate_engine_sound(rpm_factor): engine_sound_player.pitch_scale = BASE_ENGINE_PITCH + 2 * rpm_factor var to_fill = engine_sound_playback.get_frames_available() @@ -165,6 +186,11 @@ func _generate_engine_sound(rpm_factor): var fill_percent = 0.0 while to_fill > 0: engine_sound_playback.push_frame(Vector2(1.0, 1.0) * factor) - factor += cos(factor) * sin(factor) * (1 + to_fill % 2) * ((sound_curve.interpolate_baked(fill_percent) - 0.5) * 2) + factor += ( + cos(factor) + * sin(factor) + * (1 + to_fill % 2) + * ((sound_curve.interpolate_baked(fill_percent) - 0.5) * 2) + ) to_fill -= 1 fill_percent += fill_segment