From 582b2c43cb637d882966ce7b743bfc98f4e71821 Mon Sep 17 00:00:00 2001 From: hz Date: Wed, 21 Jan 2026 17:59:14 -0600 Subject: [PATCH] Adding basic car --- game/assets/audio/jump.ogg.import | 38 +++--- .../audio/silly-menu-hover-test.ogg.import | 38 +++--- game/assets/audio/silly-test.ogg.import | 38 +++--- ...ayfairDisplay-VariableFont_wght.ttf.import | 72 +++++------ game/assets/images/pp_start_bg.png.import | 80 ++++++------ game/assets/models/human.blend.import | 118 +++++++++--------- game/icon.svg.import | 86 ++++++------- game/project.godot | 15 ++- game/scenes/Levels/level.tscn | 30 +++-- game/scenes/Levels/menu.gd | 21 ++-- game/scenes/Vehicles/car.gd | 81 ++++++++++++ game/scenes/Vehicles/car.gd.uid | 1 + game/scenes/Vehicles/car.tscn | 43 +++++++ game/scenes/player.gd | 70 ++++++++--- 14 files changed, 452 insertions(+), 279 deletions(-) create mode 100644 game/scenes/Vehicles/car.gd create mode 100644 game/scenes/Vehicles/car.gd.uid create mode 100644 game/scenes/Vehicles/car.tscn diff --git a/game/assets/audio/jump.ogg.import b/game/assets/audio/jump.ogg.import index d0a637d..1e15ee3 100644 --- a/game/assets/audio/jump.ogg.import +++ b/game/assets/audio/jump.ogg.import @@ -1,19 +1,19 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://de2e8sy4x724m" -path="res://.godot/imported/jump.ogg-09aff86a6f79a8fce2febb69902962cf.oggvorbisstr" - -[deps] - -source_file="res://assets/audio/jump.ogg" -dest_files=["res://.godot/imported/jump.ogg-09aff86a6f79a8fce2febb69902962cf.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://de2e8sy4x724m" +path="res://.godot/imported/jump.ogg-09aff86a6f79a8fce2febb69902962cf.oggvorbisstr" + +[deps] + +source_file="res://assets/audio/jump.ogg" +dest_files=["res://.godot/imported/jump.ogg-09aff86a6f79a8fce2febb69902962cf.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/game/assets/audio/silly-menu-hover-test.ogg.import b/game/assets/audio/silly-menu-hover-test.ogg.import index 018ec64..0a47544 100644 --- a/game/assets/audio/silly-menu-hover-test.ogg.import +++ b/game/assets/audio/silly-menu-hover-test.ogg.import @@ -1,19 +1,19 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://64dplcgx2icb" -path="res://.godot/imported/silly-menu-hover-test.ogg-101de051c9810c756b28483653a4c618.oggvorbisstr" - -[deps] - -source_file="res://assets/audio/silly-menu-hover-test.ogg" -dest_files=["res://.godot/imported/silly-menu-hover-test.ogg-101de051c9810c756b28483653a4c618.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://64dplcgx2icb" +path="res://.godot/imported/silly-menu-hover-test.ogg-101de051c9810c756b28483653a4c618.oggvorbisstr" + +[deps] + +source_file="res://assets/audio/silly-menu-hover-test.ogg" +dest_files=["res://.godot/imported/silly-menu-hover-test.ogg-101de051c9810c756b28483653a4c618.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/game/assets/audio/silly-test.ogg.import b/game/assets/audio/silly-test.ogg.import index da1cc68..db3d768 100644 --- a/game/assets/audio/silly-test.ogg.import +++ b/game/assets/audio/silly-test.ogg.import @@ -1,19 +1,19 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://txgki0ijeuud" -path="res://.godot/imported/silly-test.ogg-4a08df8a26b9ee1e5d13235e013c7cfc.oggvorbisstr" - -[deps] - -source_file="res://assets/audio/silly-test.ogg" -dest_files=["res://.godot/imported/silly-test.ogg-4a08df8a26b9ee1e5d13235e013c7cfc.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://txgki0ijeuud" +path="res://.godot/imported/silly-test.ogg-4a08df8a26b9ee1e5d13235e013c7cfc.oggvorbisstr" + +[deps] + +source_file="res://assets/audio/silly-test.ogg" +dest_files=["res://.godot/imported/silly-test.ogg-4a08df8a26b9ee1e5d13235e013c7cfc.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/game/assets/fonts/PlayfairDisplay-VariableFont_wght.ttf.import b/game/assets/fonts/PlayfairDisplay-VariableFont_wght.ttf.import index f1dc51a..ad2f4cf 100644 --- a/game/assets/fonts/PlayfairDisplay-VariableFont_wght.ttf.import +++ b/game/assets/fonts/PlayfairDisplay-VariableFont_wght.ttf.import @@ -1,36 +1,36 @@ -[remap] - -importer="font_data_dynamic" -type="FontFile" -uid="uid://m5ceou0rk6j6" -path="res://.godot/imported/PlayfairDisplay-VariableFont_wght.ttf-fbc765a7962e1c71b0eb2c53d6eb2a10.fontdata" - -[deps] - -source_file="res://assets/fonts/PlayfairDisplay-VariableFont_wght.ttf" -dest_files=["res://.godot/imported/PlayfairDisplay-VariableFont_wght.ttf-fbc765a7962e1c71b0eb2c53d6eb2a10.fontdata"] - -[params] - -Rendering=null -antialiasing=1 -generate_mipmaps=false -disable_embedded_bitmaps=true -multichannel_signed_distance_field=false -msdf_pixel_range=8 -msdf_size=48 -allow_system_fallback=true -force_autohinter=false -modulate_color_glyphs=false -hinting=1 -subpixel_positioning=4 -keep_rounding_remainders=true -oversampling=0.0 -Fallbacks=null -fallbacks=[] -Compress=null -compress=true -preload=[] -language_support={} -script_support={} -opentype_features={} +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://m5ceou0rk6j6" +path="res://.godot/imported/PlayfairDisplay-VariableFont_wght.ttf-fbc765a7962e1c71b0eb2c53d6eb2a10.fontdata" + +[deps] + +source_file="res://assets/fonts/PlayfairDisplay-VariableFont_wght.ttf" +dest_files=["res://.godot/imported/PlayfairDisplay-VariableFont_wght.ttf-fbc765a7962e1c71b0eb2c53d6eb2a10.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/game/assets/images/pp_start_bg.png.import b/game/assets/images/pp_start_bg.png.import index 17419c6..64da61e 100644 --- a/game/assets/images/pp_start_bg.png.import +++ b/game/assets/images/pp_start_bg.png.import @@ -1,40 +1,40 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dhuosr0p605gj" -path="res://.godot/imported/pp_start_bg.png-8fb0f850edd45e79935f992c58fa8ca2.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://assets/images/pp_start_bg.png" -dest_files=["res://.godot/imported/pp_start_bg.png-8fb0f850edd45e79935f992c58fa8ca2.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dhuosr0p605gj" +path="res://.godot/imported/pp_start_bg.png-8fb0f850edd45e79935f992c58fa8ca2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/images/pp_start_bg.png" +dest_files=["res://.godot/imported/pp_start_bg.png-8fb0f850edd45e79935f992c58fa8ca2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/game/assets/models/human.blend.import b/game/assets/models/human.blend.import index 070e247..d05a2b2 100644 --- a/game/assets/models/human.blend.import +++ b/game/assets/models/human.blend.import @@ -1,59 +1,59 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://bb6hj6l23043x" -path="res://.godot/imported/human.blend-738fbf7b85a13f54d00c9db65cf59296.scn" - -[deps] - -source_file="res://assets/models/human.blend" -dest_files=["res://.godot/imported/human.blend-738fbf7b85a13f54d00c9db65cf59296.scn"] - -[params] - -nodes/root_type="" -nodes/root_name="" -nodes/root_script=null -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_name_suffixes=true -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -materials/extract=0 -materials/extract_format=0 -materials/extract_path="" -_subresources={} -blender/nodes/visible=0 -blender/nodes/active_collection_only=false -blender/nodes/punctual_lights=true -blender/nodes/cameras=true -blender/nodes/custom_properties=true -blender/nodes/modifiers=1 -blender/meshes/colors=false -blender/meshes/uvs=true -blender/meshes/normals=true -blender/meshes/export_geometry_nodes_instances=false -blender/meshes/tangents=true -blender/meshes/skins=2 -blender/meshes/export_bones_deforming_mesh_only=false -blender/materials/unpack_enabled=true -blender/materials/export_materials=1 -blender/animation/limit_playback=true -blender/animation/always_sample=true -blender/animation/group_tracks=true -gltf/naming_version=2 +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bb6hj6l23043x" +path="res://.godot/imported/human.blend-738fbf7b85a13f54d00c9db65cf59296.scn" + +[deps] + +source_file="res://assets/models/human.blend" +dest_files=["res://.godot/imported/human.blend-738fbf7b85a13f54d00c9db65cf59296.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +blender/nodes/visible=0 +blender/nodes/active_collection_only=false +blender/nodes/punctual_lights=true +blender/nodes/cameras=true +blender/nodes/custom_properties=true +blender/nodes/modifiers=1 +blender/meshes/colors=false +blender/meshes/uvs=true +blender/meshes/normals=true +blender/meshes/export_geometry_nodes_instances=false +blender/meshes/tangents=true +blender/meshes/skins=2 +blender/meshes/export_bones_deforming_mesh_only=false +blender/materials/unpack_enabled=true +blender/materials/export_materials=1 +blender/animation/limit_playback=true +blender/animation/always_sample=true +blender/animation/group_tracks=true +gltf/naming_version=2 diff --git a/game/icon.svg.import b/game/icon.svg.import index 41c7dda..a53bccb 100644 --- a/game/icon.svg.import +++ b/game/icon.svg.import @@ -1,43 +1,43 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://f2g3tvryiodc" -path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://icon.svg" -dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] - -[params] - -compress/mode=0 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=false -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=1 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://f2g3tvryiodc" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/game/project.godot b/game/project.godot index e2cdff6..90f9bbf 100644 --- a/game/project.godot +++ b/game/project.godot @@ -69,8 +69,13 @@ player_light={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } -player_phone={ -"deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194306,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) -] -} +player_phone={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194306,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +interact={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) +] +} diff --git a/game/scenes/Levels/level.tscn b/game/scenes/Levels/level.tscn index e9f7d93..777f49a 100644 --- a/game/scenes/Levels/level.tscn +++ b/game/scenes/Levels/level.tscn @@ -1,11 +1,12 @@ -[gd_scene load_steps=17 format=3 uid="uid://dchj6g2i8ebph"] +[gd_scene load_steps=18 format=3 uid="uid://dchj6g2i8ebph"] [ext_resource type="Script" uid="uid://brgmxhhhtakja" path="res://scenes/Levels/level.gd" id="1_a4mo8"] [ext_resource type="PackedScene" uid="uid://bb6hj6l23043x" path="res://assets/models/human.blend" id="1_eg4yq"] [ext_resource type="Script" uid="uid://bpxggc8nr6tf6" path="res://scenes/player.gd" id="1_muv8p"] -[ext_resource type="PackedScene" uid="uid://c5of6aaxop1hl" path="res://scenes/block.tscn" id="2_tc7dm"] -[ext_resource type="Script" uid="uid://b7fopt7sx74g8" path="res://scenes/Levels/menu.gd" id="3_tc7dm"] -[ext_resource type="PackedScene" path="res://scenes/Characters/repo_bot.tscn" id="4_repo"] +[ext_resource type="PackedScene" uid="uid://c5of6aaxop1hl" path="res://scenes/block.tscn" id="2_tc7dm"] +[ext_resource type="Script" uid="uid://b7fopt7sx74g8" path="res://scenes/Levels/menu.gd" id="3_tc7dm"] +[ext_resource type="PackedScene" path="res://scenes/Characters/repo_bot.tscn" id="4_repo"] +[ext_resource type="PackedScene" path="res://scenes/Vehicles/car.tscn" id="5_car"] [sub_resource type="PhysicsMaterial" id="PhysicsMaterial_2q6dc"] bounce = 0.5 @@ -58,11 +59,11 @@ debug_color = Color(0.29772994, 0.6216631, 0.28140613, 0.41960785) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) mesh = SubResource("SphereMesh_w7c3h") -[node name="Player" type="RigidBody3D" parent="."] -physics_material_override = SubResource("PhysicsMaterial_w8frs") -script = ExtResource("1_muv8p") -camera_path = NodePath("Camera3D") -phone_path = NodePath("../PhoneUI") +[node name="Player" type="RigidBody3D" parent="."] +physics_material_override = SubResource("PhysicsMaterial_w8frs") +script = ExtResource("1_muv8p") +camera_path = NodePath("Camera3D") +phone_path = NodePath("../PhoneUI") [node name="CollisionShape3D" type="CollisionShape3D" parent="Player"] shape = SubResource("SphereShape3D_mx8sn") @@ -71,10 +72,13 @@ shape = SubResource("SphereShape3D_mx8sn") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.31670225, 0) current = true -[node name="SpotLight3D" type="SpotLight3D" parent="Player"] - -[node name="Ground" type="StaticBody3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) +[node name="SpotLight3D" type="SpotLight3D" parent="Player"] + +[node name="Car" parent="." instance=ExtResource("5_car")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 0, -3) + +[node name="Ground" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) [node name="CollisionShape3D" type="CollisionShape3D" parent="Ground"] shape = SubResource("BoxShape3D_2q6dc") diff --git a/game/scenes/Levels/menu.gd b/game/scenes/Levels/menu.gd index 1d7e852..006e870 100644 --- a/game/scenes/Levels/menu.gd +++ b/game/scenes/Levels/menu.gd @@ -14,13 +14,15 @@ func _input(event): else: pause_game() -func pause_game(): - get_tree().paused = true - visible = true +func pause_game(): + get_tree().paused = true + visible = true + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) -func resume_game(): - get_tree().paused = false - visible = false +func resume_game(): + get_tree().paused = false + visible = false + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) func _on_quit_button_pressed(): get_tree().quit() @@ -28,9 +30,10 @@ func _on_quit_button_pressed(): func _on_continue_button_pressed(): resume_game() -func _on_main_menu_button_pressed(): - resume_game() - get_tree().change_scene_to_file(START_SCREEN_SCENE) +func _on_main_menu_button_pressed(): + resume_game() + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) + get_tree().change_scene_to_file(START_SCREEN_SCENE) func _register_focus_sounds() -> void: if pause_menu == null: diff --git a/game/scenes/Vehicles/car.gd b/game/scenes/Vehicles/car.gd new file mode 100644 index 0000000..9d92881 --- /dev/null +++ b/game/scenes/Vehicles/car.gd @@ -0,0 +1,81 @@ +extends RigidBody3D + +@export var drive_speed := 18.0 +@export var drive_accel := 20.0 +@export var brake_strength := 28.0 +@export var turn_speed := 2.0 +@export var turn_accel := 8.0 +@export var lateral_damp := 10.0 +@export var seat_path: NodePath +@export var exit_path: NodePath +@export var camera_path: NodePath +@export var interact_area_path: NodePath + +@onready var seat: Node3D = get_node(seat_path) if seat_path != NodePath("") else null +@onready var exit_point: Node3D = get_node(exit_path) if exit_path != NodePath("") else null +@onready var car_camera: Camera3D = get_node(camera_path) if camera_path != NodePath("") else null +@onready var interact_area: Area3D = get_node(interact_area_path) if interact_area_path != NodePath("") else null + +var _nearby_driver: Node = null +var _driver: Node = null + +func _ready() -> void: + if interact_area: + interact_area.collision_layer = 2 + interact_area.collision_mask = 1 + interact_area.body_entered.connect(_on_interact_body_entered) + interact_area.body_exited.connect(_on_interact_body_exited) + if car_camera: + car_camera.current = false + +func _process(_delta: float) -> void: + if _driver == null and _nearby_driver != null and Input.is_action_just_pressed("interact"): + _enter_vehicle(_nearby_driver) + elif _driver != null and Input.is_action_just_pressed("interact"): + _exit_vehicle() + +func _integrate_forces(state: PhysicsDirectBodyState3D) -> void: + if _driver == null: + return + + var input2v := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down") + var forward := global_transform.basis.z + forward.y = 0.0 + forward = forward.normalized() + + var current_speed := linear_velocity.dot(forward) + var target_speed := input2v.y * drive_speed + var accel := drive_accel if abs(input2v.y) > 0.01 else brake_strength + var new_forward_speed := move_toward(current_speed, target_speed, accel * state.step) + var forward_vel := forward * new_forward_speed + var lateral_vel := linear_velocity - (forward * current_speed) + lateral_vel = lateral_vel.move_toward(Vector3.ZERO, lateral_damp * state.step) + linear_velocity = forward_vel + lateral_vel + + var speed_factor: float = clamp(abs(new_forward_speed) / drive_speed, 0.0, 1.0) + var target_turn: float = -input2v.x * turn_speed * speed_factor + angular_velocity.y = move_toward(angular_velocity.y, target_turn, turn_accel * state.step) + +func _enter_vehicle(player: Node) -> void: + if seat == null: + return + _driver = player + player.call("enter_vehicle", self, seat, car_camera) + if car_camera: + car_camera.current = true + +func _exit_vehicle() -> void: + if _driver == null: + return + _driver.call("exit_vehicle", exit_point, car_camera) + _driver = null + if car_camera: + car_camera.current = false + +func _on_interact_body_entered(body: Node) -> void: + if body.has_method("enter_vehicle"): + _nearby_driver = body + +func _on_interact_body_exited(body: Node) -> void: + if body == _nearby_driver: + _nearby_driver = null diff --git a/game/scenes/Vehicles/car.gd.uid b/game/scenes/Vehicles/car.gd.uid new file mode 100644 index 0000000..d1fac37 --- /dev/null +++ b/game/scenes/Vehicles/car.gd.uid @@ -0,0 +1 @@ +uid://4qf5yinepytc diff --git a/game/scenes/Vehicles/car.tscn b/game/scenes/Vehicles/car.tscn new file mode 100644 index 0000000..9d1fd51 --- /dev/null +++ b/game/scenes/Vehicles/car.tscn @@ -0,0 +1,43 @@ +[gd_scene load_steps=6 format=3] + +[ext_resource type="Script" path="res://scenes/Vehicles/car.gd" id="1_kbd20"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_7r1j6"] +size = Vector3(1.4, 0.9, 2.6) + +[sub_resource type="BoxShape3D" id="BoxShape3D_jk0m1"] +size = Vector3(2.2, 2.0, 3.8) + +[sub_resource type="BoxMesh" id="BoxMesh_4y8xk"] +size = Vector3(1.4, 0.9, 2.6) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_red"] +albedo_color = Color(0.85, 0.1, 0.1, 1) + +[node name="Car" type="RigidBody3D"] +script = ExtResource("1_kbd20") +seat_path = NodePath("Seat") +exit_path = NodePath("Exit") +camera_path = NodePath("CarCamera") +interact_area_path = NodePath("InteractArea") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("BoxShape3D_7r1j6") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +mesh = SubResource("BoxMesh_4y8xk") +surface_material_override/0 = SubResource("StandardMaterial3D_red") + +[node name="InteractArea" type="Area3D" parent="."] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="InteractArea"] +shape = SubResource("BoxShape3D_jk0m1") + +[node name="Seat" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0, 0.6, 0.0) + +[node name="Exit" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.3, 0.0, 0.0) + +[node name="CarCamera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0, 2.0, 4.2) diff --git a/game/scenes/player.gd b/game/scenes/player.gd index 6036e9f..cc6e206 100644 --- a/game/scenes/player.gd +++ b/game/scenes/player.gd @@ -20,11 +20,14 @@ var current_number_of_jumps := 0 var _pending_mouse_delta := Vector2.ZERO var _last_move_forward := Vector3(0, 0, 1) var _last_move_right := Vector3(1, 0, 0) -var _camera_offset_local := Vector3.ZERO -var _camera_yaw := 0.0 -var _camera_pitch := 0.0 - -@export var camera_follow_speed := 10.0 +var _camera_offset_local := Vector3.ZERO +var _camera_yaw := 0.0 +var _camera_pitch := 0.0 +var _in_vehicle := false +var _vehicle_collision_layer := 0 +var _vehicle_collision_mask := 0 + +@export var camera_follow_speed := 10.0 var jump_sound = preload("res://assets/audio/jump.ogg") var audio_player = AudioStreamPlayer.new() @@ -35,7 +38,7 @@ var audio_player = AudioStreamPlayer.new() @onready var phone: CanvasLayer = get_node(phone_path) if phone_path != NodePath("") else null var phone_visible := false -func _ready() -> void: +func _ready() -> void: axis_lock_angular_x = true axis_lock_angular_z = true angular_damp = 6.0 @@ -44,7 +47,7 @@ func _ready() -> void: add_child(audio_player) audio_player.stream = jump_sound audio_player.volume_db = -20 - if cam: + if cam: _camera_offset_local = cam.transform.origin _camera_pitch = cam.rotation.x _camera_yaw = global_transform.basis.get_euler().y @@ -58,11 +61,16 @@ func _ready() -> void: right.y = 0.0 if forward.length() > 0.0001: _last_move_forward = forward.normalized() - if right.length() > 0.0001: - _last_move_right = right.normalized() - -func _integrate_forces(state): - if cameraMoveMode and _pending_mouse_delta != Vector2.ZERO: + if right.length() > 0.0001: + _last_move_right = right.normalized() + _vehicle_collision_layer = collision_layer + _vehicle_collision_mask = collision_mask + +func _integrate_forces(state): + if _in_vehicle: + linear_velocity = Vector3.ZERO + return + if cameraMoveMode and _pending_mouse_delta != Vector2.ZERO: rotation_x -= _pending_mouse_delta.y * mouse_sensitivity rotation_y -= _pending_mouse_delta.x * mouse_sensitivity rotation_x = clamp(rotation_x, deg_to_rad(-90), deg_to_rad(90)) # Prevent flipping @@ -126,8 +134,10 @@ func _integrate_forces(state): cam.global_position = cam.global_position.lerp(target_pos, camera_follow_speed * state.step) cam.global_rotation = Vector3(_camera_pitch, _camera_yaw, 0.0) -func _input(event): - if event is InputEventMouseButton: +func _input(event): + if _in_vehicle: + return + if event is InputEventMouseButton: if event.button_index == MOUSE_BUTTON_MIDDLE: if event.pressed: cameraMoveMode = true @@ -148,7 +158,33 @@ func _input(event): if event.is_action_pressed("player_light"): $SpotLight3D.visible = !$SpotLight3D.visible -func zoom_camera(factor): - var new_fov = cam.fov * factor - cam.fov = clamp(new_fov, MIN_FOV, MAX_FOV) +func zoom_camera(factor): + var new_fov = cam.fov * factor + cam.fov = clamp(new_fov, MIN_FOV, MAX_FOV) + +func enter_vehicle(_vehicle: Node, seat: Node3D, vehicle_camera: Camera3D) -> void: + _in_vehicle = true + freeze = true + sleeping = true + collision_layer = 0 + collision_mask = 0 + if seat: + global_transform = seat.global_transform + if cam: + cam.current = false + if vehicle_camera: + vehicle_camera.current = true + +func exit_vehicle(exit_point: Node3D, vehicle_camera: Camera3D) -> void: + _in_vehicle = false + freeze = false + sleeping = false + collision_layer = _vehicle_collision_layer + collision_mask = _vehicle_collision_mask + if exit_point: + global_transform = exit_point.global_transform + if vehicle_camera: + vehicle_camera.current = false + if cam: + cam.current = true