Compare commits

...

38 Commits
0.1.0 ... main

Author SHA1 Message Date
Ensar Sarajčić de0f97c7e0 Update version to 0.3.0 2022-01-25 14:18:35 +01:00
Ensar Sarajčić bfe2ac2672 Merge branch 'main' of github.com:esensar/bugged-racing 2022-01-25 14:14:02 +01:00
Ensar Sarajčić a0f9d7a65e
Fix readme wind sounds link 2022-01-25 10:30:25 +01:00
Ensar Sarajčić a2b61b0193 Increase resolution of camera sliders 2022-01-25 10:16:27 +01:00
Ensar Sarajčić 7289cf4b09 Add reset to default button for camera settings 2022-01-25 10:16:16 +01:00
Ensar Sarajčić bcb0647926 Fix loading of camera position settings 2022-01-25 10:15:46 +01:00
Ensar Sarajčić d6ec1c407b Reduce number of sliders for camera config 2022-01-25 09:37:11 +01:00
Ensar Sarajčić 4a8c32b2c3 Add camera adjustment settings 2022-01-24 20:55:21 +01:00
Ensar Sarajčić 2df1e29640 Add camera rotation controls 2022-01-24 20:07:15 +01:00
Ensar Sarajčić de0a8111d1
Merge pull request #2 from esensar/handling-improvements
Handling improvements
2022-01-24 10:27:22 -08:00
Ensar Sarajčić 0b0e12d230 Rework bugmobile handling 2022-01-24 19:26:49 +01:00
Ensar Sarajčić 8f8e17d606 Rework beetlecar handling and speed 2022-01-24 19:10:48 +01:00
Ensar Sarajčić 40d49200f4 Change buggy back to 4 wheel drive 2022-01-24 18:50:18 +01:00
Ensar Sarajčić 48db95478c Persist user settings 2022-01-24 17:54:37 +01:00
Ensar Sarajčić 873325fbe4 Add improved engine, tires and wind sounds 2022-01-24 17:40:11 +01:00
Ensar Sarajčić 0a71908bc9 Add basic downforce and drag 2022-01-24 15:33:00 +01:00
Ensar Sarajčić af62cdbafe Prevent cars from producing power with no input in auto mode 2022-01-24 15:19:02 +01:00
Ensar Sarajčić 23152bfbba Adjust weights and engine powers 2022-01-24 15:14:49 +01:00
Ensar Sarajčić 61b7139aa8 Add more control settings 2022-01-21 23:06:33 +01:00
Ensar Sarajčić ef77b64c96 Update version to 0.2.2 2022-01-21 16:56:06 +01:00
Ensar Sarajčić 8a41653dbb Prevent multiple gear switches on single action with manual transmission 2022-01-21 16:55:27 +01:00
Ensar Sarajčić 35da3be64c Fix version info export 2022-01-21 15:00:51 +01:00
Ensar Sarajčić 8cfb9e4883 Add multiplayer version compatibility check 2022-01-21 14:44:57 +01:00
Ensar Sarajčić 4b496071fc Add version info to the game 2022-01-21 14:18:13 +01:00
Ensar Sarajčić cf3685415a Enable workflows on release too 2022-01-21 13:53:56 +01:00
Ensar Sarajčić 5b05771bb3 Add track minimap to GUI 2022-01-21 13:50:50 +01:00
Ensar Sarajčić fbc01a296e Add texture to finish gate 2022-01-20 21:03:38 +01:00
Ensar Sarajčić bbde8b2ae7 Add basic finish gate 2022-01-20 20:52:50 +01:00
Ensar Sarajčić 0c80cab346 Add names in multiplayer 2022-01-20 19:56:06 +01:00
Ensar Sarajčić ad4c8140e2 Add leaderboards to multiplayer games 2022-01-20 19:11:54 +01:00
Ensar Sarajčić 2e2a73e207 Fix issues with reconnecting to server 2022-01-20 18:23:49 +01:00
Ensar Sarajčić c9652ae651 Add very basic multiplayer 2022-01-20 16:50:44 +01:00
Ensar Sarajčić b0981bf20c Delay track and vehicle loading in start menu 2022-01-20 14:18:25 +01:00
Ensar Sarajčić dcea94ac6b Extract out player controls into player_controller 2022-01-20 11:38:35 +01:00
Ensar Sarajčić 82b3feecf4
Merge pull request #1 from esensar/post-jam
Add different cameras and cockpits
2022-01-19 06:54:32 -08:00
Ensar Sarajčić 2417e50544 Add cockpits to bugmobile and beetlecar 2022-01-19 15:37:38 +01:00
Ensar Sarajčić 2e44a97f63 Add cockpit to buggy 2022-01-19 14:35:14 +01:00
Ensar Sarajčić 15d2c83ffc Add different cameras 2022-01-19 11:39:45 +01:00
84 changed files with 2791 additions and 369 deletions

View File

@ -1,6 +1,8 @@
name: "Deploy to Itch.io"
on:
release:
types: [ created ]
workflow_dispatch:
env:

View File

@ -1,6 +1,8 @@
name: "Deploy signed MacOS to Itch.io"
on:
release:
types: [ created ]
workflow_dispatch:
env:

View File

@ -12,3 +12,21 @@ Game is available on [Itch.io](https://esensar.itch.io/bugged-racing).
Game source code is licensed under [MIT license](/LICENSE).
Assets are licensed under [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/).
## Credits
This game includes assets from [opengameart.org](opengameart.org), [freesound.org](freesound.org) and other sources.
### Sounds
#### Wind sounds
[Wind sounds](/assets/wind%20woosh%20loop.ogg) used in the game is available on [opengameart.org](https://opengameart.org/content/wind-whoosh-loop) under CC0 license (public domain).
#### Engine sounds
[Engine sounds](/assets/engine.wav) used in the game is available on [freesound.org](https://freesound.org/people/MarlonHJ/sounds/242740/) under CC0 license (public domain).
#### Tire sounds
[Tire sounds](/assets/tires_squal_loop.wav) used in the game is available on [opengameart.org](https://opengameart.org/content/car-tire-squeal-skid-loop) under [CC-BY 3.0 license](https://creativecommons.org/licenses/by/3.0/). Sound is provided by [audible-edge (Tom Haigh)](http://www.freesound.org/people/audible-edge/) and submitted by [qubodup](https://opengameart.org/users/qubodup)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/checkered.png-668a157f2d2ca6daad4a9e7d6de114d0.s3tc.stex"
path.etc2="res://.import/checkered.png-668a157f2d2ca6daad4a9e7d6de114d0.etc2.stex"
metadata={
"imported_formats": [ "s3tc", "etc2" ],
"vram_texture": true
}
[deps]
source_file="res://assets/checkered.png"
dest_files=[ "res://.import/checkered.png-668a157f2d2ca6daad4a9e7d6de114d0.s3tc.stex", "res://.import/checkered.png-668a157f2d2ca6daad4a9e7d6de114d0.etc2.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=1
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0

BIN
assets/engine.wav 100644

Binary file not shown.

View File

@ -0,0 +1,21 @@
[remap]
importer="wav"
type="AudioStreamSample"
path="res://.import/engine.wav-cc4df8df683a7f5419ef7019228b045a.sample"
[deps]
source_file="res://assets/engine.wav"
dest_files=[ "res://.import/engine.wav-cc4df8df683a7f5419ef7019228b045a.sample" ]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop=true
compress/mode=0

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/player_icon.png-97b071f9d92f0abba7d34c4aae551713.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/player_icon.png"
dest_files=[ "res://.import/player_icon.png-97b071f9d92f0abba7d34c4aae551713.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,21 @@
[remap]
importer="wav"
type="AudioStreamSample"
path="res://.import/tires_squal_loop.wav-6f4aaa09ee4bdf0eca94aed4cc79779d.sample"
[deps]
source_file="res://assets/tires_squal_loop.wav"
dest_files=[ "res://.import/tires_squal_loop.wav-6f4aaa09ee4bdf0eca94aed4cc79779d.sample" ]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop=true
compress/mode=0

Binary file not shown.

View File

@ -0,0 +1,15 @@
[remap]
importer="ogg_vorbis"
type="AudioStreamOGGVorbis"
path="res://.import/wind woosh loop.ogg-843e7b8cdfc6f4a378e2da0a4cb7290b.oggstr"
[deps]
source_file="res://assets/wind woosh loop.ogg"
dest_files=[ "res://.import/wind woosh loop.ogg-843e7b8cdfc6f4a378e2da0a4cb7290b.oggstr" ]
[params]
loop=true
loop_offset=0

View File

@ -5,7 +5,7 @@ platform="HTML5"
runnable=true
custom_features=""
export_filter="all_resources"
include_filter=""
include_filter="info.json"
exclude_filter=""
export_path="build/html/index.html"
script_export_mode=1
@ -40,7 +40,7 @@ platform="Mac OSX"
runnable=true
custom_features=""
export_filter="all_resources"
include_filter=""
include_filter="info.json"
exclude_filter=""
export_path="build/mac/bugged-racing.zip"
script_export_mode=1
@ -73,7 +73,7 @@ platform="Windows Desktop"
runnable=true
custom_features=""
export_filter="all_resources"
include_filter=""
include_filter="info.json"
exclude_filter=""
export_path="build/windows/bugged-racing.exe"
script_export_mode=1
@ -114,7 +114,7 @@ platform="Linux/X11"
runnable=true
custom_features=""
export_filter="all_resources"
include_filter=""
include_filter="info.json"
exclude_filter=""
export_path="build/linux/bugged-racing.x86_64"
script_export_mode=1

7
info.json 100644
View File

@ -0,0 +1,7 @@
{
"version": {
"major": 0,
"minor": 3,
"patch": 0
}
}

View File

@ -1,7 +1,8 @@
[gd_scene load_steps=5 format=2]
[gd_scene load_steps=6 format=2]
[ext_resource path="res://menu/about.gd" type="Script" id=1]
[ext_resource path="res://assets/fonts/kenney-future-narrow.ttf" type="DynamicFontData" id=2]
[ext_resource path="res://menu/default_theme.tres" type="Theme" id=3]
[sub_resource type="DynamicFont" id=1]
size = 48
@ -13,6 +14,7 @@ font_data = ExtResource( 2 )
[node name="About" type="Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
theme = ExtResource( 3 )
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
@ -44,7 +46,7 @@ scroll_horizontal_enabled = false
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/ScrollContainer"]
margin_right = 800.0
margin_bottom = 1974.0
margin_bottom = 2300.0
size_flags_horizontal = 3
[node name="Title" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
@ -137,20 +139,78 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="Label7" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
[node name="Label17" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 490.0
margin_right = 800.0
margin_bottom = 508.0
custom_fonts/font = SubResource( 2 )
text = "Credits:"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label20" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 516.0
margin_right = 800.0
margin_bottom = 534.0
custom_fonts/font = SubResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label23" type="RichTextLabel" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 542.0
margin_right = 800.0
margin_bottom = 782.0
size_flags_vertical = 0
custom_fonts/normal_font = SubResource( 2 )
bbcode_enabled = true
bbcode_text = "This game includes assets from [url=https://opengameart.org]opengameart.org[/url], [url=https://freesound.org]freesound.org[/url] and other sources.
- Sounds:
Wind sound used in the game is available on [url=https://opengameart.org/content/wind-whoosh-loop]opengameart.org[/url] under CC0 license (public domain).
Engine sound used in the game is available on [url=https://freesound.org/people/MarlonHJ/sounds/242740/]freesound.org[/url] under CC0 license (public domain).
Tire sound used in the game is available on [url=https://opengameart.org/content/car-tire-squeal-skid-loop]opengameart.org[/url] under [url=https://creativecommons.org/licenses/by/3.0/]CC-BY 3.0 license[/url]. Sound is provided by [url=http://www.freesound.org/people/audible-edge/]audible-edge (Tom Haigh)[/url] and submitted by [url=https://opengameart.org/users/qubodup]qubodup[/url]"
text = "This game includes assets from opengameart.org, freesound.org and other sources.
- Sounds:
Wind sound used in the game is available on opengameart.org under CC0 license (public domain).
Engine sound used in the game is available on freesound.org under CC0 license (public domain).
Tire sound used in the game is available on opengameart.org under CC-BY 3.0 license. Sound is provided by audible-edge (Tom Haigh) and submitted by qubodup"
fit_content_height = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label21" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 790.0
margin_right = 800.0
margin_bottom = 808.0
custom_fonts/font = SubResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label7" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 816.0
margin_right = 800.0
margin_bottom = 834.0
custom_fonts/font = SubResource( 2 )
text = "Open source licences:"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label8" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 516.0
margin_top = 842.0
margin_right = 800.0
margin_bottom = 534.0
margin_bottom = 860.0
custom_fonts/font = SubResource( 2 )
align = 1
__meta__ = {
@ -158,9 +218,9 @@ __meta__ = {
}
[node name="Label11" type="RichTextLabel" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 542.0
margin_top = 868.0
margin_right = 800.0
margin_bottom = 562.0
margin_bottom = 888.0
custom_fonts/normal_font = SubResource( 2 )
bbcode_enabled = true
bbcode_text = "Godot Engine (also available in [url=https://godotengine.org/license]web version[/url]):"
@ -168,9 +228,9 @@ text = "Godot Engine (also available in web version):"
fit_content_height = true
[node name="Label9" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 570.0
margin_top = 896.0
margin_right = 800.0
margin_bottom = 1092.0
margin_bottom = 1418.0
custom_fonts/font = SubResource( 2 )
text = "
This game uses Godot Engine, available under the following license:
@ -188,9 +248,9 @@ __meta__ = {
}
[node name="Label12" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 1100.0
margin_top = 1426.0
margin_right = 800.0
margin_bottom = 1118.0
margin_bottom = 1444.0
custom_fonts/font = SubResource( 2 )
align = 1
__meta__ = {
@ -198,9 +258,9 @@ __meta__ = {
}
[node name="Label10" type="RichTextLabel" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 1126.0
margin_top = 1452.0
margin_right = 800.0
margin_bottom = 1206.0
margin_bottom = 1532.0
custom_fonts/normal_font = SubResource( 2 )
bbcode_enabled = true
bbcode_text = "[url=https://www.freetype.org/]FreeType[/url]:
@ -212,9 +272,9 @@ text = "FreeType:
fit_content_height = true
[node name="Label13" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 1214.0
margin_top = 1540.0
margin_right = 800.0
margin_bottom = 1232.0
margin_bottom = 1558.0
custom_fonts/font = SubResource( 2 )
align = 1
__meta__ = {
@ -222,9 +282,9 @@ __meta__ = {
}
[node name="Label14" type="RichTextLabel" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 1240.0
margin_top = 1566.0
margin_right = 800.0
margin_bottom = 1660.0
margin_bottom = 1986.0
custom_fonts/normal_font = SubResource( 2 )
bbcode_enabled = true
bbcode_text = "[url=http://enet.bespin.org/]ENet[/url]:
@ -250,9 +310,9 @@ text = "ENet:
fit_content_height = true
[node name="Label15" type="Label" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 1668.0
margin_top = 1994.0
margin_right = 800.0
margin_bottom = 1686.0
margin_bottom = 2012.0
custom_fonts/font = SubResource( 2 )
align = 1
__meta__ = {
@ -260,9 +320,9 @@ __meta__ = {
}
[node name="Label16" type="RichTextLabel" parent="MarginContainer/ScrollContainer/VBoxContainer"]
margin_top = 1694.0
margin_top = 2020.0
margin_right = 800.0
margin_bottom = 1974.0
margin_bottom = 2300.0
custom_fonts/normal_font = SubResource( 2 )
bbcode_enabled = true
bbcode_text = "[url=https://tls.mbed.org/]MBedTLS[/url]:
@ -291,6 +351,7 @@ fit_content_height = true
[connection signal="meta_clicked" from="MarginContainer/ScrollContainer/VBoxContainer/Label3" to="." method="_on_link_meta_clicked"]
[connection signal="meta_clicked" from="MarginContainer/ScrollContainer/VBoxContainer/Label19" to="." method="_on_link_meta_clicked"]
[connection signal="meta_clicked" from="MarginContainer/ScrollContainer/VBoxContainer/Label18" to="." method="_on_link_meta_clicked"]
[connection signal="meta_clicked" from="MarginContainer/ScrollContainer/VBoxContainer/Label23" to="." method="_on_link_meta_clicked"]
[connection signal="meta_clicked" from="MarginContainer/ScrollContainer/VBoxContainer/Label11" to="." method="_on_link_meta_clicked"]
[connection signal="meta_clicked" from="MarginContainer/ScrollContainer/VBoxContainer/Label10" to="." method="_on_link_meta_clicked"]
[connection signal="meta_clicked" from="MarginContainer/ScrollContainer/VBoxContainer/Label14" to="." method="_on_link_meta_clicked"]

View File

@ -0,0 +1,41 @@
extends Spatial
const CAMERA_CONTROLLER = preload("res://player/cameras/camera_controller.gd")
var vehicle_path = "res://vehicles/buggy.tscn"
var camera_controller: CameraController
var vehicle: Node = null
func _ready() -> void:
reset()
func _process(_delta: float) -> void:
if Input.is_action_just_released("next_camera"):
camera_controller.next_camera()
camera_controller.update_camera(
(
Input.get_action_strength("turn_camera_right")
- Input.get_action_strength("turn_camera_left")
),
Input.get_action_strength("turn_camera_up") - Input.get_action_strength("turn_camera_down"),
Input.is_action_pressed("look_backwards")
)
func change_vehicle_to(new_vehicle_path: String) -> void:
vehicle_path = new_vehicle_path
reset()
func reset() -> void:
if vehicle != null:
vehicle.queue_free()
camera_controller.clear()
vehicle = load(vehicle_path).instance()
add_child(vehicle)
camera_controller = CAMERA_CONTROLLER.new()
camera_controller.attach_cameras_to(vehicle)

View File

@ -0,0 +1,237 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://icon.png" type="Texture" id=1]
[ext_resource path="res://menu/camera_config_scene.gd" type="Script" id=2]
[sub_resource type="PlaneMesh" id=1]
[sub_resource type="SpatialMaterial" id=2]
albedo_texture = ExtResource( 1 )
[sub_resource type="ConcavePolygonShape" id=3]
data = PoolVector3Array( 1, 0, 1, -1, 0, 1, 1, 0, -1, -1, 0, 1, -1, 0, -1, 1, 0, -1 )
[sub_resource type="CylinderMesh" id=4]
height = 15.0
[sub_resource type="ConvexPolygonShape" id=5]
points = PoolVector3Array( -1, -7.5, 0, -0.995301, -7.5, -0.0980814, -0.995301, -7.5, 0.0978857, -1, 7.5, 0, -0.980814, -7.5, -0.195184, -0.995301, 7.5, -0.0980814, -0.980814, -7.5, 0.194988, -0.995301, 7.5, 0.0978857, -0.957126, -7.5, -0.290329, -0.980814, 7.5, -0.195184, -0.957126, -7.5, 0.290133, -0.980814, 7.5, 0.194988, -0.924041, -7.5, -0.382733, -0.957126, 7.5, -0.290329, -0.924041, -7.5, 0.382537, -0.957126, 7.5, 0.290133, -0.88195, -7.5, -0.471417, -0.924041, 7.5, -0.382733, -0.88195, -7.5, 0.471222, -0.924041, 7.5, 0.382537, -0.831637, -7.5, -0.555599, -0.88195, 7.5, -0.471417, -0.831637, -7.5, 0.555403, -0.88195, 7.5, 0.471222, -0.773101, -7.5, -0.634495, -0.831637, 7.5, -0.555599, -0.773101, -7.5, 0.634299, -0.831637, 7.5, 0.555403, -0.707126, -7.5, -0.707126, -0.773101, 7.5, -0.634495, -0.707126, -7.5, 0.70693, -0.773101, 7.5, 0.634299, -0.634495, -7.5, -0.773101, -0.707126, 7.5, -0.707126, -0.634495, -7.5, 0.772905, -0.707126, 7.5, 0.70693, -0.555599, -7.5, -0.831637, -0.634495, 7.5, -0.773101, -0.555599, -7.5, 0.831441, -0.634495, 7.5, 0.772905, -0.471417, -7.5, -0.88195, -0.555599, 7.5, -0.831637, -0.471417, -7.5, 0.881754, -0.555599, 7.5, 0.831441, -0.382733, -7.5, -0.924041, -0.471417, 7.5, -0.88195, -0.382733, -7.5, 0.923845, -0.471417, 7.5, 0.881754, -0.290329, -7.5, -0.957126, -0.382733, 7.5, -0.924041, -0.290329, -7.5, 0.95693, -0.382733, 7.5, 0.923845, -0.195184, -7.5, -0.980814, -0.290329, 7.5, -0.957126, -0.195184, -7.5, 0.980619, -0.290329, 7.5, 0.95693, -0.0980814, -7.5, -0.995301, -0.195184, 7.5, -0.980814, -0.0980814, -7.5, 0.995106, -0.195184, 7.5, 0.980619, 0, -7.5, -1, -0.0980814, 7.5, -0.995301, 0, -7.5, 1, -0.0980814, 7.5, 0.995106, 0.0978857, -7.5, -0.995301, 0, 7.5, -1, 0.0978857, -7.5, 0.995106, 0, 7.5, 1, 0.194988, -7.5, -0.980814, 0.0978857, 7.5, -0.995301, 0.194988, -7.5, 0.980619, 0.0978857, 7.5, 0.995106, 0.290133, -7.5, -0.957126, 0.194988, 7.5, -0.980814, 0.290133, -7.5, 0.95693, 0.194988, 7.5, 0.980619, 0.382537, -7.5, -0.924041, 0.290133, 7.5, -0.957126, 0.382537, -7.5, 0.923845, 0.290133, 7.5, 0.95693, 0.471222, -7.5, -0.88195, 0.382537, 7.5, -0.924041, 0.471222, -7.5, 0.881754, 0.382537, 7.5, 0.923845, 0.555403, -7.5, -0.831637, 0.471222, 7.5, -0.88195, 0.555403, -7.5, 0.831441, 0.471222, 7.5, 0.881754, 0.634299, -7.5, -0.773101, 0.555403, 7.5, -0.831637, 0.634299, -7.5, 0.772905, 0.555403, 7.5, 0.831441, 0.70693, -7.5, -0.707126, 0.634299, 7.5, -0.773101, 0.70693, -7.5, 0.70693, 0.634299, 7.5, 0.772905, 0.772905, -7.5, -0.634495, 0.70693, 7.5, -0.707126, 0.772905, -7.5, 0.634299, 0.70693, 7.5, 0.70693, 0.831441, -7.5, -0.555599, 0.772905, 7.5, -0.634495, 0.831441, -7.5, 0.555403, 0.772905, 7.5, 0.634299, 0.881754, -7.5, -0.471417, 0.831441, 7.5, -0.555599, 0.881754, -7.5, 0.471222, 0.831441, 7.5, 0.555403, 0.923845, -7.5, -0.382733, 0.881754, 7.5, -0.471417, 0.923845, -7.5, 0.382537, 0.881754, 7.5, 0.471222, 0.95693, -7.5, -0.290329, 0.923845, 7.5, -0.382733, 0.95693, -7.5, 0.290133, 0.923845, 7.5, 0.382537, 0.980619, -7.5, -0.195184, 0.95693, 7.5, -0.290329, 0.980619, -7.5, 0.194988, 0.95693, 7.5, 0.290133, 0.995106, -7.5, -0.0980814, 0.980619, 7.5, -0.195184, 0.995106, -7.5, 0.0978857, 0.980619, 7.5, 0.194988, 1, -7.5, 0, 0.995106, 7.5, -0.0980814, 0.995106, 7.5, 0.0978857, 1, 7.5, 0 )
[node name="Spatial" type="Spatial"]
script = ExtResource( 2 )
[node name="StaticBody" type="StaticBody" parent="."]
transform = Transform( 99.9785, 0, 0, 0, 99.9785, 0, 0, 0, 99.9785, 0, 0, 0 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody"]
transform = Transform( 6.13726, 0, 0, 0, 6.13726, 0, 0, 0, 6.13726, 0, 0, 0 )
mesh = SubResource( 1 )
material/0 = SubResource( 2 )
[node name="CollisionShape" type="CollisionShape" parent="StaticBody"]
transform = Transform( 6.13726, 0, 0, 0, 6.13726, 0, 0, 0, 6.13726, 0, 0, 0 )
shape = SubResource( 3 )
[node name="StaticBody48" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, -31.0595, 4.33657, 9.2691 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody48"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody48"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody49" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, -22.0595, 4.33657, 9.2691 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody49"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody49"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody50" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, -13.0595, 4.33657, 9.2691 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody50"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody50"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody51" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, -5.05947, 4.33657, 9.2691 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody51"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody51"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody52" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, 2.94053, 4.33657, 9.2691 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody52"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody52"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody53" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, 13.9405, 4.33657, 9.2691 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody53"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody53"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody54" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, 24.9405, 4.33657, 9.2691 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody54"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody54"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody55" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, 34.9405, 4.33657, 9.2691 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody55"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody55"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody56" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, 34.9405, 4.33657, -8.7309 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody56"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody56"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody57" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, 30.9405, 4.33657, -8.7309 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody57"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody57"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody58" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, 25.9405, 4.33657, -8.7309 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody58"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody58"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody59" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, 20.9405, 4.33657, -8.7309 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody59"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody59"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody60" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, 13.9405, 4.33657, -8.7309 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody60"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody60"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody61" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, 6.94053, 4.33657, -8.7309 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody61"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody61"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody62" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, -4.05947, 4.33657, -8.7309 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody62"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody62"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody63" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, -20.0595, 4.33657, -8.7309 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody63"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody63"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )
[node name="StaticBody64" type="StaticBody" parent="."]
transform = Transform( 0.375559, 0, 0, 0, -1.64162e-08, 1, 0, -0.375559, -4.37114e-08, -20.0595, 4.33657, -8.7309 )
[node name="MeshInstance" type="MeshInstance" parent="StaticBody64"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
mesh = SubResource( 4 )
material/0 = null
[node name="CollisionShape" type="CollisionShape" parent="StaticBody64"]
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, -0.417043, 0 )
shape = SubResource( 5 )

View File

@ -0,0 +1,19 @@
extends Node
func show_simple_alert(text: String, title: String = "Alert") -> void:
var dialog = AcceptDialog.new()
dialog.dialog_text = text
dialog.window_title = title
dialog.connect("modal_closed", dialog, "queue_free")
var scene_tree = Engine.get_main_loop()
scene_tree.current_scene.add_child(dialog)
dialog.popup_centered()
func create_simple_alert(text: String, title: String = "Alert") -> AcceptDialog:
var dialog = AcceptDialog.new()
dialog.dialog_text = text
dialog.window_title = title
dialog.connect("modal_closed", dialog, "queue_free")
return dialog

View File

@ -0,0 +1,10 @@
[gd_resource type="Theme" load_steps=3 format=2]
[ext_resource path="res://assets/fonts/kenney-future-narrow.ttf" type="DynamicFontData" id=1]
[sub_resource type="DynamicFont" id=1]
size = 32
font_data = ExtResource( 1 )
[resource]
default_font = SubResource( 1 )

View File

@ -3,15 +3,23 @@ extends Panel
func _ready() -> void:
# gdlint: ignore=max-line-length
$MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer/StartButton.grab_focus()
$MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer/SingleplayerButton.grab_focus()
$MarginContainer/VSplitContainer/VBoxContainer/VersionLabel.text = (
"Version: %s"
% GlobalSettings.get_version_string()
)
func _on_StartButton_pressed() -> void:
func _on_SingleplayerButton_pressed() -> void:
get_tree().change_scene("res://menu/start_menu.tscn")
func _on_MultiplayerButton_pressed() -> void:
get_tree().change_scene("res://menu/multiplayer_menu.tscn")
func _on_ExitButton_pressed() -> void:
get_tree().quit()
get_tree().notification(MainLoop.NOTIFICATION_WM_QUIT_REQUEST)
func _on_SettingsButton_pressed() -> void:

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=9 format=2]
[gd_scene load_steps=11 format=2]
[ext_resource path="res://assets/fonts/kenney-future-narrow.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://menu/main_menu.gd" type="Script" id=2]
@ -6,11 +6,15 @@
[ext_resource path="res://assets/kenneylogo.png" type="Texture" id=4]
[ext_resource path="res://assets/kritaicon.png" type="Texture" id=5]
[ext_resource path="res://assets/blendericon.png" type="Texture" id=6]
[ext_resource path="res://menu/default_theme.tres" type="Theme" id=7]
[sub_resource type="DynamicFont" id=1]
size = 64
font_data = ExtResource( 1 )
[sub_resource type="DynamicFont" id=3]
font_data = ExtResource( 1 )
[sub_resource type="DynamicFont" id=2]
size = 32
font_data = ExtResource( 1 )
@ -18,6 +22,7 @@ font_data = ExtResource( 1 )
[node name="MainMenu" type="Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
theme = ExtResource( 7 )
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
@ -39,7 +44,11 @@ margin_right = 984.0
margin_bottom = 560.0
dragger_visibility = 1
[node name="Title" type="Label" parent="MarginContainer/VSplitContainer"]
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VSplitContainer"]
margin_right = 984.0
margin_bottom = 98.0
[node name="Title" type="Label" parent="MarginContainer/VSplitContainer/VBoxContainer"]
margin_right = 984.0
margin_bottom = 72.0
custom_colors/font_color = Color( 0.419608, 0.0117647, 0.0117647, 1 )
@ -48,8 +57,19 @@ text = "Bugged Racing"
align = 1
valign = 1
[node name="VersionLabel" type="Label" parent="MarginContainer/VSplitContainer/VBoxContainer"]
margin_top = 80.0
margin_right = 984.0
margin_bottom = 98.0
custom_fonts/font = SubResource( 3 )
text = "Version:"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VSplitContainer" type="VSplitContainer" parent="MarginContainer/VSplitContainer"]
margin_top = 96.0
margin_top = 122.0
margin_right = 984.0
margin_bottom = 560.0
split_offset = 973
@ -57,51 +77,53 @@ dragger_visibility = 1
[node name="CenterContainer" type="CenterContainer" parent="MarginContainer/VSplitContainer/VSplitContainer"]
margin_right = 984.0
margin_bottom = 376.0
margin_bottom = 350.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer"]
margin_left = 398.0
margin_top = 80.0
margin_right = 586.0
margin_bottom = 296.0
margin_left = 348.0
margin_top = 39.0
margin_right = 636.0
margin_bottom = 311.0
[node name="StartButton" type="Button" parent="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_right = 188.0
[node name="SingleplayerButton" type="Button" parent="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_right = 288.0
margin_bottom = 48.0
custom_fonts/font = SubResource( 2 )
text = "Start"
text = "Singleplayer"
[node name="MultiplayerButton" type="Button" parent="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 56.0
margin_right = 288.0
margin_bottom = 104.0
text = "Multiplayer"
[node name="SettingsButton" type="Button" parent="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 56.0
margin_right = 188.0
margin_bottom = 104.0
custom_fonts/font = SubResource( 2 )
margin_top = 112.0
margin_right = 288.0
margin_bottom = 160.0
text = "Settings"
[node name="AboutButton" type="Button" parent="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 112.0
margin_right = 188.0
margin_bottom = 160.0
custom_fonts/font = SubResource( 2 )
margin_top = 168.0
margin_right = 288.0
margin_bottom = 216.0
text = "About"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ExitButton" type="Button" parent="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 168.0
margin_right = 188.0
margin_bottom = 216.0
custom_fonts/font = SubResource( 2 )
margin_top = 224.0
margin_right = 288.0
margin_bottom = 272.0
text = "Exit"
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VSplitContainer/VSplitContainer"]
margin_top = 400.0
margin_top = 374.0
margin_right = 984.0
margin_bottom = 464.0
margin_bottom = 438.0
__meta__ = {
"_edit_use_anchors_": false
}
@ -146,7 +168,8 @@ __meta__ = {
"_edit_use_anchors_": false
}
[connection signal="pressed" from="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer/StartButton" to="." method="_on_StartButton_pressed"]
[connection signal="pressed" from="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer/SingleplayerButton" to="." method="_on_SingleplayerButton_pressed"]
[connection signal="pressed" from="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer/MultiplayerButton" to="." method="_on_MultiplayerButton_pressed"]
[connection signal="pressed" from="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer/SettingsButton" to="." method="_on_SettingsButton_pressed"]
[connection signal="pressed" from="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer/AboutButton" to="." method="_on_AboutButton_pressed"]
[connection signal="pressed" from="MarginContainer/VSplitContainer/VSplitContainer/CenterContainer/VBoxContainer/ExitButton" to="." method="_on_ExitButton_pressed"]

View File

@ -0,0 +1,59 @@
extends Panel
const BUGGY = "res://vehicles/buggy.tscn"
const BEETLE = "res://vehicles/beetlecar.tscn"
const BUGMOBILE = "res://vehicles/bugmobile.tscn"
const TEST_SCENE = "res://scenes/test_level.tscn"
const INFINITE_LOOP_SCENE = "res://scenes/infinite_loop_track_level.tscn"
const ROUNDING_ERROR = "res://scenes/rounding_error_track_level.tscn"
const SCARAB = "res://scenes/scarab_track_level.tscn"
const RACE_CONDITION = "res://scenes/race_condition_track_level.tscn"
const GUI_SCENE = "res://player/gui.tscn"
var vehicles = [BEETLE, BUGGY, BUGMOBILE]
var tracks = [INFINITE_LOOP_SCENE, ROUNDING_ERROR, RACE_CONDITION, SCARAB, TEST_SCENE]
# gdlint: ignore=max-line-length
onready var vehicle_selector = $MarginContainer/VSplitContainer/CenterContainer/GridContainer/VehicleSelector
# gdlint: ignore=max-line-length
onready var track_selector = $MarginContainer/VSplitContainer/CenterContainer/GridContainer/TrackSelector
onready var ip = $MarginContainer/VSplitContainer/CenterContainer/GridContainer/IpBox
onready var port = $MarginContainer/VSplitContainer/CenterContainer/GridContainer/PortBox
func _ready() -> void:
vehicle_selector.grab_focus()
vehicle_selector.add_item("Beetlecar")
vehicle_selector.add_item("Buggy")
vehicle_selector.add_item("Bugmobile")
track_selector.add_item("Infinite Loop")
track_selector.add_item("Rounding Error")
track_selector.add_item("Race Condition")
track_selector.add_item("Scarab")
track_selector.add_item("Testing grounds")
func _on_JoinButton_pressed() -> void:
if vehicle_selector.get_selected_id() < 0:
return
if track_selector.get_selected_id() < 0:
return
var vehicle = vehicles[vehicle_selector.get_selected_id()]
MultiplayerController.create_client(ip.text, int(float(port.text)), vehicle)
queue_free()
func _on_HostButton_pressed() -> void:
if vehicle_selector.get_selected_id() < 0:
return
if track_selector.get_selected_id() < 0:
return
var vehicle = vehicles[vehicle_selector.get_selected_id()]
var track = tracks[track_selector.get_selected_id()]
MultiplayerController.create_server(int(float(port.text)), track, vehicle)
queue_free()
func _on_BackButton_pressed() -> void:
get_tree().change_scene("res://menu/main_menu.tscn")

View File

@ -0,0 +1,151 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://assets/fonts/kenney-future-narrow.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://menu/multiplayer_menu.gd" type="Script" id=2]
[ext_resource path="res://menu/default_theme.tres" type="Theme" id=3]
[sub_resource type="DynamicFont" id=3]
size = 64
font_data = ExtResource( 1 )
[node name="StartMenu" type="Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
theme = ExtResource( 3 )
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MarginContainer" type="MarginContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 20.0
margin_top = 20.0
margin_right = -20.0
margin_bottom = -20.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VSplitContainer" type="VSplitContainer" parent="MarginContainer"]
margin_right = 984.0
margin_bottom = 560.0
dragger_visibility = 1
[node name="HSplitContainer" type="HSplitContainer" parent="MarginContainer/VSplitContainer"]
margin_right = 984.0
margin_bottom = 72.0
dragger_visibility = 1
[node name="BackButton" type="Button" parent="MarginContainer/VSplitContainer/HSplitContainer"]
margin_right = 116.0
margin_bottom = 72.0
text = "Back"
[node name="Title" type="Label" parent="MarginContainer/VSplitContainer/HSplitContainer"]
margin_left = 140.0
margin_right = 984.0
margin_bottom = 72.0
custom_fonts/font = SubResource( 3 )
text = "Multiplayer"
align = 1
valign = 1
[node name="CenterContainer" type="CenterContainer" parent="MarginContainer/VSplitContainer"]
margin_top = 96.0
margin_right = 984.0
margin_bottom = 560.0
[node name="GridContainer" type="GridContainer" parent="MarginContainer/VSplitContainer/CenterContainer"]
margin_left = 199.0
margin_top = 72.0
margin_right = 785.0
margin_bottom = 392.0
custom_constants/vseparation = 16
custom_constants/hseparation = 32
columns = 2
[node name="Ip" type="Label" parent="MarginContainer/VSplitContainer/CenterContainer/GridContainer"]
margin_top = 10.0
margin_right = 204.0
margin_bottom = 46.0
text = "IP: "
align = 2
[node name="IpBox" type="LineEdit" parent="MarginContainer/VSplitContainer/CenterContainer/GridContainer"]
margin_left = 236.0
margin_right = 586.0
margin_bottom = 56.0
rect_min_size = Vector2( 350, 0 )
text = "127.0.0.1"
align = 1
[node name="Port" type="Label" parent="MarginContainer/VSplitContainer/CenterContainer/GridContainer"]
margin_top = 82.0
margin_right = 204.0
margin_bottom = 118.0
text = "Port: "
align = 2
[node name="PortBox" type="LineEdit" parent="MarginContainer/VSplitContainer/CenterContainer/GridContainer"]
margin_left = 236.0
margin_top = 72.0
margin_right = 586.0
margin_bottom = 128.0
rect_min_size = Vector2( 350, 0 )
text = "30661"
align = 1
[node name="Vehicle" type="Label" parent="MarginContainer/VSplitContainer/CenterContainer/GridContainer"]
margin_top = 150.0
margin_right = 204.0
margin_bottom = 186.0
text = "Vehicle: "
align = 2
[node name="VehicleSelector" type="OptionButton" parent="MarginContainer/VSplitContainer/CenterContainer/GridContainer"]
margin_left = 236.0
margin_top = 144.0
margin_right = 586.0
margin_bottom = 192.0
text = "Select vehicle"
align = 1
[node name="Track" type="Label" parent="MarginContainer/VSplitContainer/CenterContainer/GridContainer"]
margin_top = 214.0
margin_right = 204.0
margin_bottom = 250.0
text = "Track: "
align = 2
[node name="TrackSelector" type="OptionButton" parent="MarginContainer/VSplitContainer/CenterContainer/GridContainer"]
margin_left = 236.0
margin_top = 208.0
margin_right = 586.0
margin_bottom = 256.0
text = "Select track"
align = 1
[node name="JoinButton" type="Button" parent="MarginContainer/VSplitContainer/CenterContainer/GridContainer"]
margin_top = 272.0
margin_right = 204.0
margin_bottom = 320.0
text = "Join Game"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="HostButton" type="Button" parent="MarginContainer/VSplitContainer/CenterContainer/GridContainer"]
margin_left = 236.0
margin_top = 272.0
margin_right = 586.0
margin_bottom = 320.0
text = "Host Game"
__meta__ = {
"_edit_use_anchors_": false
}
[connection signal="pressed" from="MarginContainer/VSplitContainer/HSplitContainer/BackButton" to="." method="_on_BackButton_pressed"]
[connection signal="pressed" from="MarginContainer/VSplitContainer/CenterContainer/GridContainer/JoinButton" to="." method="_on_JoinButton_pressed"]
[connection signal="pressed" from="MarginContainer/VSplitContainer/CenterContainer/GridContainer/HostButton" to="." method="_on_HostButton_pressed"]

View File

@ -18,5 +18,7 @@ func _on_ContinueButton_pressed():
func _on_ExitButton_pressed():
get_tree().paused = false
if MultiplayerController.is_online():
MultiplayerController.quit()
get_tree().change_scene("res://menu/main_menu.tscn")
get_tree().root.get_child(get_tree().root.get_child_count() - 1).queue_free()

View File

@ -1,20 +1,15 @@
[gd_scene load_steps=5 format=2]
[gd_scene load_steps=3 format=2]
[ext_resource path="res://assets/fonts/kenney-future-narrow.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://menu/default_theme.tres" type="Theme" id=1]
[ext_resource path="res://menu/pause_menu.gd" type="Script" id=2]
[sub_resource type="DynamicFont" id=1]
font_data = ExtResource( 1 )
[sub_resource type="DynamicFont" id=2]
font_data = ExtResource( 1 )
[node name="PauseMenu" type="PopupDialog"]
pause_mode = 2
anchor_left = 0.25
anchor_top = 0.25
anchor_right = 0.75
anchor_bottom = 0.75
theme = ExtResource( 1 )
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
@ -35,8 +30,7 @@ dragger_visibility = 1
[node name="Title" type="Label" parent="MarginContainer/VSplitContainer"]
margin_right = 472.0
margin_bottom = 18.0
custom_fonts/font = SubResource( 1 )
margin_bottom = 36.0
text = "Game Paused"
align = 1
valign = 1
@ -45,23 +39,21 @@ __meta__ = {
}
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VSplitContainer"]
margin_top = 42.0
margin_top = 60.0
margin_right = 472.0
margin_bottom = 260.0
alignment = 1
[node name="ContinueButton" type="Button" parent="MarginContainer/VSplitContainer/VBoxContainer"]
margin_top = 89.0
margin_top = 48.0
margin_right = 472.0
margin_bottom = 113.0
custom_fonts/font = SubResource( 2 )
margin_bottom = 96.0
text = "Continue"
[node name="ExitButton" type="Button" parent="MarginContainer/VSplitContainer/VBoxContainer"]
margin_top = 117.0
margin_top = 104.0
margin_right = 472.0
margin_bottom = 141.0
custom_fonts/font = SubResource( 2 )
margin_bottom = 152.0
text = "Exit to main menu"
[connection signal="pressed" from="MarginContainer/VSplitContainer/VBoxContainer/ContinueButton" to="." method="_on_ContinueButton_pressed"]

View File

@ -1,23 +1,71 @@
extends Panel
const PLAYER_CONTROLLER = preload("res://player/vehicle_controller.gd")
const CAMERA_TEST_SCENE = preload("res://menu/camera_config_scene.tscn")
const BUGGY = "res://vehicles/buggy.tscn"
const BEETLE = "res://vehicles/beetlecar.tscn"
const BUGMOBILE = "res://vehicles/bugmobile.tscn"
var vehicles = [BEETLE, BUGGY, BUGMOBILE]
var inputs = BuggedVehicle.VehicleInputs.new()
onready var master_bus := AudioServer.get_bus_index("Master")
onready var sound_bus := AudioServer.get_bus_index("Sound")
onready var music_bus := AudioServer.get_bus_index("Music")
# gdlint: ignore=max-line-length
onready var master_slider: HSlider = $MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/MasterSlider
onready var master_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Audio/Audio/MasterSlider
# gdlint: ignore=max-line-length
onready var sound_slider: HSlider = $MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/SoundEffectsSlider
onready var sound_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Audio/Audio/SoundEffectsSlider
# gdlint: ignore=max-line-length
onready var music_slider: HSlider = $MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/MusicSlider
onready var music_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Audio/Audio/MusicSlider
# gdlint: ignore=max-line-length
onready var auto_clutch_cb: CheckBox = $MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/AutoClutchCheckBox
onready var auto_clutch_cb: CheckBox = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/AutoClutchCheckBox
# gdlint: ignore=max-line-length
onready var automatic_transmission_cb: CheckBox = $MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/AutomaticTransmissionCheckBox
onready var automatic_transmission_cb: CheckBox = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/AutomaticTransmissionCheckBox
# gdlint: ignore=max-line-length
onready var fullscreen_cb: CheckBox = $MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/FullscreenCheckBox
onready var fullscreen_cb: CheckBox = $MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/System/FullscreenCheckBox
# gdlint: ignore=max-line-length
onready var borderless_cb: CheckBox = $MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/BorderlessCheckBox
onready var borderless_cb: CheckBox = $MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/System/BorderlessCheckBox
# gdlint: ignore=max-line-length
onready var multiplayer_name_box: LineEdit = $MarginContainer/VSplitContainer/TabContainer/Gameplay/Gameplay/MultiplayerNameBox
# gdlint: ignore=max-line-length
onready var steering_sensitivity_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/SteeringSensitivitySlider
# gdlint: ignore=max-line-length
onready var steering_return_speed_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/SteeringReturnSpeedSlider
# gdlint: ignore=max-line-length
onready var steering_deadzone_inner_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/SteeringInnerDeadzoneSlider
# gdlint: ignore=max-line-length
onready var steering_deadzone_outer_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/SteeringOuterDeadzoneSlider
# gdlint: ignore=max-line-length
onready var throttle_sensitivity_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/ThrottleSensitivitySlider
# gdlint: ignore=max-line-length
onready var brakes_sensitivity_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/BrakesSensitivitySlider
# gdlint: ignore=max-line-length
onready var steering_value_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Steering/HSlider
# gdlint: ignore=max-line-length
onready var throttle_value_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Throttle/HSlider
# gdlint: ignore=max-line-length
onready var brakes_value_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Brakes/HSlider
# gdlint: ignore=max-line-length
onready var gear_value_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Gear/HSlider
# gdlint: ignore=max-line-length
onready var fov_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera/FovSlider
# gdlint: ignore=max-line-length
onready var move_depth_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera/MoveDepthSlider
# gdlint: ignore=max-line-length
onready var move_horizontal_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera/MoveHorizontalSlider
# gdlint: ignore=max-line-length
onready var move_vertical_slider: HSlider = $MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera/MoveVerticalSlider
# gdlint: ignore=max-line-length
onready var vehicle_selector: OptionButton = $MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/VBoxContainer/VehicleSelector
# gdlint: ignore=max-line-length
onready var viewport: Viewport = $MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/VBoxContainer/ViewportContainer/Viewport
onready var camera_scene = CAMERA_TEST_SCENE.instance()
func _ready() -> void:
@ -27,13 +75,45 @@ func _ready() -> void:
music_slider.value = db2linear(AudioServer.get_bus_volume_db(music_bus))
auto_clutch_cb.pressed = GlobalSettings.auto_clutch
automatic_transmission_cb.pressed = GlobalSettings.automatic_transmission
multiplayer_name_box.text = GlobalSettings.multiplayer_name
steering_sensitivity_slider.value = GlobalSettings.steering_sensitivity
steering_return_speed_slider.value = GlobalSettings.return_speed
steering_deadzone_inner_slider.value = GlobalSettings.steering_deadzone_inner
steering_deadzone_outer_slider.value = GlobalSettings.steering_deadzone_outer
throttle_sensitivity_slider.value = GlobalSettings.throttle_sensitivity
brakes_sensitivity_slider.value = GlobalSettings.brake_sensitivity
fov_slider.value = GlobalSettings.camera_fov
move_depth_slider.value = GlobalSettings.camera_move_depth
move_horizontal_slider.value = GlobalSettings.camera_move_horizontal
move_vertical_slider.value = GlobalSettings.camera_move_vertical
fullscreen_cb.pressed = false
borderless_cb.pressed = false
var controller = PLAYER_CONTROLLER.new()
controller.input_sink_path = get_path()
add_child(controller)
if OS.is_window_fullscreen():
_set_fullscreen(true)
if OS.get_borderless_window():
_set_borderless(true)
vehicle_selector.add_item("Beetlecar")
vehicle_selector.add_item("Buggy")
vehicle_selector.add_item("Bugmobile")
vehicle_selector.selected = 1
viewport.add_child(camera_scene)
func _physics_process(_delta: float) -> void:
steering_value_slider.value = -inputs.steering
throttle_value_slider.value = inputs.throttle
brakes_value_slider.value = inputs.brake
match inputs.gear_request:
BuggedVehicle.GearRequest.UP:
gear_value_slider.value += 1
BuggedVehicle.GearRequest.DOWN:
gear_value_slider.value -= 1
func _on_autoclutch_toggled(new_state: bool) -> void:
GlobalSettings.auto_clutch = new_state
@ -55,6 +135,7 @@ func _on_automatictransmission_toggled(new_state: bool) -> void:
func _on_BackButton_pressed() -> void:
GlobalSettings.multiplayer_name = multiplayer_name_box.text
get_tree().change_scene("res://menu/main_menu.tscn")
@ -70,6 +151,57 @@ func _on_MusicSlider_value_changed(new_value: float) -> void:
AudioServer.set_bus_volume_db(music_bus, linear2db(new_value))
func _on_SteeringSensitivitySlider_value_changed(new_value: float) -> void:
GlobalSettings.steering_sensitivity = new_value
func _on_SteeringReturnSpeedSlider_value_changed(new_value: float) -> void:
GlobalSettings.return_speed = new_value
func _on_SteeringInnerDeadzoneSlider_value_changed(new_value: float) -> void:
GlobalSettings.steering_deadzone_inner = new_value
func _on_SteeringOuterDeadzoneSlider_value_changed(new_value: float) -> void:
GlobalSettings.steering_deadzone_outer = new_value
func _on_ThrottleSensitivitySlider_value_changed(new_value: float) -> void:
GlobalSettings.throttle_sensitivity = new_value
func _on_BrakesSensitivitySlider_value_changed(new_value: float) -> void:
GlobalSettings.brake_sensitivity = new_value
func _on_FovSlider_value_changed(new_value: float) -> void:
GlobalSettings.camera_fov = new_value
func _on_MoveDepthSlider_value_changed(new_value: float) -> void:
GlobalSettings.camera_move_depth = new_value
func _on_MoveHorizontalSlider_value_changed(new_value: float) -> void:
GlobalSettings.camera_move_horizontal = new_value
func _on_MoveVerticalSlider_value_changed(new_value: float) -> void:
GlobalSettings.camera_move_vertical = new_value
func _on_VehicleSelector_item_selected(item_index: int) -> void:
camera_scene.change_vehicle_to(vehicles[item_index])
func _on_ResetToDefaultButton_pressed() -> void:
fov_slider.value = 70
move_depth_slider.value = 0
move_horizontal_slider.value = 0
move_vertical_slider.value = 0
func _set_fullscreen(new_state: bool) -> void:
OS.set_window_fullscreen(new_state)
OS.set_window_maximized(new_state)

View File

@ -2,24 +2,22 @@
[ext_resource path="res://assets/fonts/kenney-future-narrow.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://menu/settings_menu.gd" type="Script" id=2]
[ext_resource path="res://menu/default_theme.tres" type="Theme" id=3]
[sub_resource type="DynamicFont" id=1]
size = 64
font_data = ExtResource( 1 )
[sub_resource type="DynamicFont" id=4]
size = 24
[sub_resource type="DynamicFont" id=5]
font_data = ExtResource( 1 )
[sub_resource type="DynamicFont" id=3]
font_data = ExtResource( 1 )
[sub_resource type="DynamicFont" id=5]
font_data = ExtResource( 1 )
[node name="SettingsMenu" type="Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
theme = ExtResource( 3 )
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
@ -32,10 +30,13 @@ margin_left = 20.0
margin_top = 20.0
margin_right = -20.0
margin_bottom = -20.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VSplitContainer" type="VSplitContainer" parent="MarginContainer"]
margin_right = 984.0
margin_bottom = 615.0
margin_bottom = 560.0
dragger_visibility = 1
[node name="HSplitContainer" type="HSplitContainer" parent="MarginContainer/VSplitContainer"]
@ -44,12 +45,12 @@ margin_bottom = 72.0
dragger_visibility = 1
[node name="BackButton" type="Button" parent="MarginContainer/VSplitContainer/HSplitContainer"]
margin_right = 75.0
margin_right = 116.0
margin_bottom = 72.0
text = "Back"
[node name="Title" type="Label" parent="MarginContainer/VSplitContainer/HSplitContainer"]
margin_left = 99.0
margin_left = 140.0
margin_right = 984.0
margin_bottom = 72.0
custom_fonts/font = SubResource( 1 )
@ -57,60 +58,59 @@ text = "Settings"
align = 1
valign = 1
[node name="CenterContainer" type="CenterContainer" parent="MarginContainer/VSplitContainer"]
[node name="TabContainer" type="TabContainer" parent="MarginContainer/VSplitContainer"]
margin_top = 96.0
margin_right = 984.0
margin_bottom = 615.0
margin_bottom = 560.0
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VSplitContainer/CenterContainer"]
margin_left = 356.0
margin_right = 627.0
margin_bottom = 519.0
[node name="Gameplay" type="ScrollContainer" parent="MarginContainer/VSplitContainer/TabContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 8.0
margin_top = 72.0
margin_right = -8.0
margin_bottom = -8.0
[node name="Gameplay" type="Label" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_right = 271.0
margin_bottom = 27.0
custom_fonts/font = SubResource( 4 )
text = "Gameplay"
[node name="Gameplay" type="VBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Gameplay"]
margin_right = 968.0
margin_bottom = 82.0
size_flags_horizontal = 3
[node name="MultiplayerNameLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Gameplay/Gameplay"]
margin_right = 968.0
margin_bottom = 18.0
custom_fonts/font = SubResource( 5 )
text = "Multiplayer name"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="AutoClutchCheckBox" type="CheckBox" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 35.0
margin_right = 271.0
margin_bottom = 83.0
custom_fonts/font = SubResource( 3 )
text = "Automatic Clutch"
align = 1
[node name="MultiplayerNameBox" type="LineEdit" parent="MarginContainer/VSplitContainer/TabContainer/Gameplay/Gameplay"]
margin_top = 26.0
margin_right = 968.0
margin_bottom = 82.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="AutomaticTransmissionCheckBox" type="CheckBox" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 91.0
margin_right = 271.0
margin_bottom = 139.0
custom_fonts/font = SubResource( 3 )
text = "Automatic Transmission"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Audio" type="ScrollContainer" parent="MarginContainer/VSplitContainer/TabContainer"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 8.0
margin_top = 72.0
margin_right = -8.0
margin_bottom = -8.0
[node name="AudioLabel" type="Label" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 147.0
margin_right = 271.0
margin_bottom = 174.0
custom_fonts/font = SubResource( 4 )
text = "Audio"
align = 1
[node name="Audio" type="VBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Audio"]
margin_right = 968.0
margin_bottom = 190.0
size_flags_horizontal = 3
[node name="MasterLabel" type="Label" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 182.0
margin_right = 271.0
margin_bottom = 200.0
[node name="MasterLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Audio/Audio"]
margin_right = 968.0
margin_bottom = 18.0
custom_fonts/font = SubResource( 5 )
text = "Master"
align = 1
@ -118,10 +118,10 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="MasterSlider" type="HSlider" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 208.0
margin_right = 271.0
margin_bottom = 240.0
[node name="MasterSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Audio/Audio"]
margin_top = 26.0
margin_right = 968.0
margin_bottom = 58.0
max_value = 1.0
step = 0.05
value = 1.0
@ -129,10 +129,10 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="SoundEffectsLabel" type="Label" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 248.0
margin_right = 271.0
margin_bottom = 266.0
[node name="SoundEffectsLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Audio/Audio"]
margin_top = 66.0
margin_right = 968.0
margin_bottom = 84.0
custom_fonts/font = SubResource( 5 )
text = "Sound Effects"
align = 1
@ -140,10 +140,10 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="SoundEffectsSlider" type="HSlider" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 274.0
margin_right = 271.0
margin_bottom = 306.0
[node name="SoundEffectsSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Audio/Audio"]
margin_top = 92.0
margin_right = 968.0
margin_bottom = 124.0
max_value = 1.0
step = 0.05
value = 1.0
@ -151,10 +151,10 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="MusicLabel" type="Label" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 314.0
margin_right = 271.0
margin_bottom = 332.0
[node name="MusicLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Audio/Audio"]
margin_top = 132.0
margin_right = 968.0
margin_bottom = 150.0
custom_fonts/font = SubResource( 5 )
text = "Music"
align = 1
@ -162,10 +162,10 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="MusicSlider" type="HSlider" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 340.0
margin_right = 271.0
margin_bottom = 372.0
[node name="MusicSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Audio/Audio"]
margin_top = 158.0
margin_right = 968.0
margin_bottom = 190.0
max_value = 1.0
step = 0.05
value = 1.0
@ -173,18 +173,34 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="VideoLabel" type="Label" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 380.0
margin_right = 271.0
margin_bottom = 407.0
custom_fonts/font = SubResource( 4 )
text = "Video"
align = 1
[node name="Video" type="ScrollContainer" parent="MarginContainer/VSplitContainer/TabContainer"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 8.0
margin_top = 72.0
margin_right = -8.0
margin_bottom = -8.0
[node name="FullscreenCheckBox" type="CheckBox" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 415.0
margin_right = 271.0
margin_bottom = 463.0
[node name="TabContainer" type="TabContainer" parent="MarginContainer/VSplitContainer/TabContainer/Video"]
margin_right = 968.0
margin_bottom = 384.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="System" type="VBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 8.0
margin_top = 72.0
margin_right = -8.0
margin_bottom = -8.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="FullscreenCheckBox" type="CheckBox" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/System"]
margin_right = 952.0
margin_bottom = 48.0
custom_fonts/font = SubResource( 3 )
text = "Fullscreen"
align = 1
@ -192,10 +208,10 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="BorderlessCheckBox" type="CheckBox" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_top = 471.0
margin_right = 271.0
margin_bottom = 519.0
[node name="BorderlessCheckBox" type="CheckBox" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/System"]
margin_top = 56.0
margin_right = 952.0
margin_bottom = 104.0
custom_fonts/font = SubResource( 3 )
text = "Borderless"
align = 1
@ -203,11 +219,410 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="Camera" type="HSplitContainer" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 8.0
margin_top = 72.0
margin_right = -8.0
margin_bottom = -8.0
size_flags_horizontal = 3
split_offset = -500
[node name="Camera" type="VBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera"]
margin_right = 226.0
margin_bottom = 556.0
rect_pivot_offset = Vector2( -793.71, -168 )
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="FovLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera"]
margin_right = 404.0
margin_bottom = 18.0
custom_fonts/font = SubResource( 5 )
text = "FOV"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="FovSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera"]
margin_top = 26.0
margin_right = 404.0
margin_bottom = 58.0
min_value = 1.0
max_value = 180.0
step = 0.01
value = 70.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MoveDepthLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera"]
margin_top = 66.0
margin_right = 404.0
margin_bottom = 84.0
custom_fonts/font = SubResource( 5 )
text = "Move forward/backward"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MoveDepthSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera"]
margin_top = 92.0
margin_right = 404.0
margin_bottom = 124.0
min_value = -1.0
max_value = 1.0
step = 0.001
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MoveHorizontalLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera"]
margin_top = 198.0
margin_right = 404.0
margin_bottom = 216.0
custom_fonts/font = SubResource( 5 )
text = "Move left/right"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MoveHorizontalSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera"]
margin_top = 224.0
margin_right = 404.0
margin_bottom = 256.0
min_value = -1.0
max_value = 1.0
step = 0.001
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MoveVerticalLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera"]
margin_top = 330.0
margin_right = 404.0
margin_bottom = 348.0
custom_fonts/font = SubResource( 5 )
text = "Move down/up"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MoveVerticalSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera"]
margin_top = 356.0
margin_right = 404.0
margin_bottom = 388.0
min_value = -1.0
max_value = 1.0
step = 0.001
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ResetToDefaultButton" type="Button" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera"]
margin_right = 24.0
margin_bottom = 48.0
text = "Reset to default"
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera"]
margin_left = 250.0
margin_right = 952.0
margin_bottom = 556.0
[node name="ViewportContainer" type="ViewportContainer" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/VBoxContainer"]
margin_left = 153.0
margin_right = 952.0
margin_bottom = 500.0
[node name="Viewport" type="Viewport" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/VBoxContainer/ViewportContainer"]
size = Vector2( 500, 500 )
handle_input_locally = false
render_target_update_mode = 0
gui_disable_input = true
[node name="VehicleSelector" type="OptionButton" parent="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/VBoxContainer"]
margin_right = 349.0
margin_bottom = 48.0
align = 1
[node name="Controls" type="ScrollContainer" parent="MarginContainer/VSplitContainer/TabContainer"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 8.0
margin_top = 72.0
margin_right = -8.0
margin_bottom = -8.0
[node name="Controls" type="VBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Controls"]
margin_right = 968.0
margin_bottom = 566.0
size_flags_horizontal = 3
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_right = 944.0
margin_bottom = 58.0
[node name="Steering" type="VBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer"]
margin_right = 230.0
margin_bottom = 58.0
size_flags_horizontal = 3
[node name="Label" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Steering"]
margin_right = 230.0
margin_bottom = 18.0
custom_fonts/font = SubResource( 3 )
text = "Steering"
[node name="HSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Steering"]
margin_top = 26.0
margin_right = 230.0
margin_bottom = 58.0
min_value = -1.0
max_value = 1.0
step = 0.01
editable = false
[node name="Throttle" type="VBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer"]
margin_left = 238.0
margin_right = 468.0
margin_bottom = 58.0
size_flags_horizontal = 3
[node name="Label" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Throttle"]
margin_right = 230.0
margin_bottom = 18.0
custom_fonts/font = SubResource( 3 )
text = "Throttle"
[node name="HSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Throttle"]
margin_top = 26.0
margin_right = 230.0
margin_bottom = 58.0
max_value = 1.0
step = 0.01
editable = false
[node name="Brakes" type="VBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer"]
margin_left = 476.0
margin_right = 706.0
margin_bottom = 58.0
size_flags_horizontal = 3
[node name="Label" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Brakes"]
margin_right = 230.0
margin_bottom = 18.0
custom_fonts/font = SubResource( 3 )
text = "Brakes"
[node name="HSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Brakes"]
margin_top = 26.0
margin_right = 230.0
margin_bottom = 58.0
max_value = 1.0
step = 0.01
editable = false
[node name="Gear" type="VBoxContainer" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer"]
margin_left = 714.0
margin_right = 944.0
margin_bottom = 58.0
size_flags_horizontal = 3
[node name="Label" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Gear"]
margin_right = 230.0
margin_bottom = 18.0
custom_fonts/font = SubResource( 3 )
text = "Gear"
[node name="HSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/HBoxContainer/Gear"]
margin_top = 26.0
margin_right = 230.0
margin_bottom = 58.0
min_value = -1.0
max_value = 6.0
editable = false
[node name="AutoClutchCheckBox" type="CheckBox" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 66.0
margin_right = 944.0
margin_bottom = 114.0
custom_fonts/font = SubResource( 3 )
text = "Automatic Clutch"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="AutomaticTransmissionCheckBox" type="CheckBox" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 122.0
margin_right = 944.0
margin_bottom = 170.0
custom_fonts/font = SubResource( 3 )
text = "Automatic Transmission"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="SteeringSensitivityLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 178.0
margin_right = 944.0
margin_bottom = 196.0
custom_fonts/font = SubResource( 5 )
text = "Steering Sensitivity"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="SteeringSensitivitySlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 204.0
margin_right = 944.0
margin_bottom = 236.0
min_value = 0.01
max_value = 1.0
step = 0.01
value = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="SteeringInnerDeadzoneLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 244.0
margin_right = 944.0
margin_bottom = 262.0
custom_fonts/font = SubResource( 5 )
text = "Steering Inner Deadzone"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="SteeringInnerDeadzoneSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 270.0
margin_right = 944.0
margin_bottom = 302.0
max_value = 0.4
step = 0.01
value = 0.4
__meta__ = {
"_edit_use_anchors_": false
}
[node name="SteeringOuterDeadzoneLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 310.0
margin_right = 944.0
margin_bottom = 328.0
custom_fonts/font = SubResource( 5 )
text = "Steering Outer Deadzone"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="SteeringOuterDeadzoneSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 336.0
margin_right = 944.0
margin_bottom = 368.0
max_value = 0.4
step = 0.01
value = 0.4
__meta__ = {
"_edit_use_anchors_": false
}
[node name="SteeringReturnSpeedLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 376.0
margin_right = 944.0
margin_bottom = 394.0
custom_fonts/font = SubResource( 5 )
text = "Steering Return Speed"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="SteeringReturnSpeedSlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 402.0
margin_right = 944.0
margin_bottom = 434.0
max_value = 60.0
step = 0.01
value = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ThrottleSensitivityLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 442.0
margin_right = 944.0
margin_bottom = 460.0
custom_fonts/font = SubResource( 5 )
text = "Throttle Sensitivity"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ThrottleSensitivitySlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 468.0
margin_right = 944.0
margin_bottom = 500.0
min_value = 0.01
max_value = 1.0
step = 0.01
value = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="BrakesSensitivityLabel" type="Label" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 508.0
margin_right = 944.0
margin_bottom = 526.0
custom_fonts/font = SubResource( 5 )
text = "Brakes Sensitivity"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="BrakesSensitivitySlider" type="HSlider" parent="MarginContainer/VSplitContainer/TabContainer/Controls/Controls"]
margin_top = 534.0
margin_right = 944.0
margin_bottom = 566.0
min_value = 0.01
max_value = 1.0
step = 0.01
value = 1.0
__meta__ = {
"_edit_use_anchors_": false
}
[connection signal="pressed" from="MarginContainer/VSplitContainer/HSplitContainer/BackButton" to="." method="_on_BackButton_pressed"]
[connection signal="toggled" from="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/AutoClutchCheckBox" to="." method="_on_autoclutch_toggled"]
[connection signal="toggled" from="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/AutomaticTransmissionCheckBox" to="." method="_on_automatictransmission_toggled"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/MasterSlider" to="." method="_on_MasterSlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/SoundEffectsSlider" to="." method="_on_SoundEffectsSlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/MusicSlider" to="." method="_on_MusicSlider_value_changed"]
[connection signal="toggled" from="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/FullscreenCheckBox" to="." method="_on_fullscreen_toggled"]
[connection signal="toggled" from="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer/BorderlessCheckBox" to="." method="_on_borderless_toggled"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Audio/Audio/MasterSlider" to="." method="_on_MasterSlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Audio/Audio/SoundEffectsSlider" to="." method="_on_SoundEffectsSlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Audio/Audio/MusicSlider" to="." method="_on_MusicSlider_value_changed"]
[connection signal="toggled" from="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/System/FullscreenCheckBox" to="." method="_on_fullscreen_toggled"]
[connection signal="toggled" from="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/System/BorderlessCheckBox" to="." method="_on_borderless_toggled"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera/FovSlider" to="." method="_on_FovSlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera/MoveDepthSlider" to="." method="_on_MoveDepthSlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera/MoveHorizontalSlider" to="." method="_on_MoveHorizontalSlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera/MoveVerticalSlider" to="." method="_on_MoveVerticalSlider_value_changed"]
[connection signal="pressed" from="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/Camera/ResetToDefaultButton" to="." method="_on_ResetToDefaultButton_pressed"]
[connection signal="item_selected" from="MarginContainer/VSplitContainer/TabContainer/Video/TabContainer/Camera/VBoxContainer/VehicleSelector" to="." method="_on_VehicleSelector_item_selected"]
[connection signal="toggled" from="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/AutoClutchCheckBox" to="." method="_on_autoclutch_toggled"]
[connection signal="toggled" from="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/AutomaticTransmissionCheckBox" to="." method="_on_automatictransmission_toggled"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/SteeringSensitivitySlider" to="." method="_on_SteeringSensitivitySlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/SteeringInnerDeadzoneSlider" to="." method="_on_SteeringInnerDeadzoneSlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/SteeringOuterDeadzoneSlider" to="." method="_on_SteeringOuterDeadzoneSlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/SteeringReturnSpeedSlider" to="." method="_on_SteeringReturnSpeedSlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/ThrottleSensitivitySlider" to="." method="_on_ThrottleSensitivitySlider_value_changed"]
[connection signal="value_changed" from="MarginContainer/VSplitContainer/TabContainer/Controls/Controls/BrakesSensitivitySlider" to="." method="_on_BrakesSensitivitySlider_value_changed"]

View File

@ -1,14 +1,14 @@
extends Panel
const BUGGY = preload("res://vehicles/buggy.tscn")
const BEETLE = preload("res://vehicles/beetlecar.tscn")
const BUGMOBILE = preload("res://vehicles/bugmobile.tscn")
const TEST_SCENE = preload("res://scenes/test_level.tscn")
const INFINITE_LOOP_SCENE = preload("res://scenes/infinite_loop_track_level.tscn")
const ROUNDING_ERROR = preload("res://scenes/rounding_error_track_level.tscn")
const SCARAB = preload("res://scenes/scarab_track_level.tscn")
const RACE_CONDITION = preload("res://scenes/race_condition_track_level.tscn")
const GUI_SCENE = preload("res://player/gui.tscn")
const BUGGY = "res://vehicles/buggy.tscn"
const BEETLE = "res://vehicles/beetlecar.tscn"
const BUGMOBILE = "res://vehicles/bugmobile.tscn"
const TEST_SCENE = "res://scenes/test_level.tscn"
const INFINITE_LOOP_SCENE = "res://scenes/infinite_loop_track_level.tscn"
const ROUNDING_ERROR = "res://scenes/rounding_error_track_level.tscn"
const SCARAB = "res://scenes/scarab_track_level.tscn"
const RACE_CONDITION = "res://scenes/race_condition_track_level.tscn"
const GUI_SCENE = "res://player/gui.tscn"
var vehicles = [BEETLE, BUGGY, BUGMOBILE]
var tracks = [INFINITE_LOOP_SCENE, ROUNDING_ERROR, RACE_CONDITION, SCARAB, TEST_SCENE]
@ -39,11 +39,11 @@ func _on_StartButton_pressed() -> void:
return
var vehicle = vehicles[vehicle_selector.get_selected_id()]
var track = tracks[track_selector.get_selected_id()]
_start_track_with_vehicle(track.instance(), vehicle.instance())
_start_track_with_vehicle(load(track).instance(), load(vehicle).instance())
func _start_track_with_vehicle(track: Node, vehicle: Node) -> void:
var gui = GUI_SCENE.instance()
var gui = load(GUI_SCENE).instance()
vehicle.connect("speed_updated", gui, "update_speed")
vehicle.connect("rpm_updated", gui, "update_rpm")
vehicle.connect("gear_updated", gui, "update_gear")

View File

@ -2,18 +2,16 @@
[ext_resource path="res://assets/fonts/kenney-future-narrow.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://menu/start_menu.gd" type="Script" id=2]
[ext_resource path="res://menu/default_theme.tres" type="Theme" id=3]
[sub_resource type="DynamicFont" id=1]
size = 64
font_data = ExtResource( 1 )
[sub_resource type="DynamicFont" id=2]
size = 32
font_data = ExtResource( 1 )
[node name="StartMenu" type="Panel"]
anchor_right = 1.0
anchor_bottom = 1.0
theme = ExtResource( 3 )
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
@ -41,12 +39,12 @@ margin_bottom = 72.0
dragger_visibility = 1
[node name="BackButton" type="Button" parent="MarginContainer/VSplitContainer/HSplitContainer"]
margin_right = 75.0
margin_right = 116.0
margin_bottom = 72.0
text = "Back"
[node name="Title" type="Label" parent="MarginContainer/VSplitContainer/HSplitContainer"]
margin_left = 99.0
margin_left = 140.0
margin_right = 984.0
margin_bottom = 72.0
custom_fonts/font = SubResource( 1 )
@ -68,7 +66,6 @@ margin_bottom = 312.0
[node name="VehicleSelector" type="OptionButton" parent="MarginContainer/VSplitContainer/CenterContainer/VBoxContainer"]
margin_right = 349.0
margin_bottom = 48.0
custom_fonts/font = SubResource( 2 )
text = "Select vehicle"
align = 1
@ -76,7 +73,6 @@ align = 1
margin_top = 56.0
margin_right = 349.0
margin_bottom = 104.0
custom_fonts/font = SubResource( 2 )
text = "Select Track"
align = 1
__meta__ = {
@ -87,7 +83,6 @@ __meta__ = {
margin_top = 112.0
margin_right = 349.0
margin_bottom = 160.0
custom_fonts/font = SubResource( 2 )
text = "Start"
__meta__ = {
"_edit_use_anchors_": false

View File

@ -0,0 +1,232 @@
extends Node
signal peers_updated
const GUI_SCENE = "res://player/gui.tscn"
var enet_peer = NetworkedMultiplayerENet.new()
var peers = {}
var version_checked = []
var current_track: Node = null
var current_track_path: String
var current_vehicle: String
var colors = [
Color.blue, Color.yellow, Color.green, Color.violet, Color.brown, Color.cyan, Color.orange
]
class PeerInfo:
var id: int
var vehicle: String
var name: String
var spawned: bool
var color: Color
static func new_peer(
new_id: int,
new_vehicle: String = "",
new_name: String = "",
new_spawned: bool = false,
new_color: Color = Color(1, 1, 1)
) -> PeerInfo:
var new_instance = PeerInfo.new()
new_instance.id = new_id
new_instance.vehicle = new_vehicle
new_instance.name = new_name
new_instance.spawned = new_spawned
new_instance.color = new_color
return new_instance
func to_array() -> Array:
return [id, vehicle, name, spawned, color]
func from_array(data: Array) -> void:
self.id = data[0]
self.vehicle = data[1]
self.name = data[2]
self.spawned = data[3]
self.color = data[4]
func _ready():
enet_peer.connect("peer_connected", self, "_peer_connected")
enet_peer.connect("peer_disconnected", self, "_peer_disconnected")
get_tree().connect("connected_to_server", self, "_connected_to_server")
enet_peer.connect("server_disconnected", self, "_server_disconnected")
get_tree().connect("connection_failed", self, "_connection_failed")
func is_online():
var network_peer = get_tree().get_network_peer()
if network_peer == null:
return false
return network_peer.get_connection_status() == NetworkedMultiplayerPeer.CONNECTION_CONNECTED
func create_server(port, track, vehicle):
current_track_path = track
current_track = load(track).instance()
current_vehicle = vehicle
enet_peer.create_server(port, 2)
get_tree().network_peer = enet_peer
peers[1] = PeerInfo.new_peer(
1, vehicle, GlobalSettings.multiplayer_name, true, get_next_color(1)
)
create_player(1, vehicle)
get_tree().root.call_deferred("add_child", current_track)
emit_signal("peers_updated")
func create_client(address, port, vehicle):
current_vehicle = vehicle
enet_peer.create_client(address, port)
get_tree().network_peer = enet_peer
peers[get_tree().get_network_unique_id()] = PeerInfo.new_peer(
get_tree().get_network_unique_id(),
vehicle,
GlobalSettings.multiplayer_name,
true,
get_next_color(1)
)
emit_signal("peers_updated")
func _peer_connected(peer_id):
peers[peer_id] = PeerInfo.new_peer(peer_id, "", "", false, get_next_color(peer_id))
rpc_id(
peer_id,
"add_player",
get_tree().get_network_unique_id(),
peers[get_tree().get_network_unique_id()].to_array()
)
emit_signal("peers_updated")
if get_tree().get_network_unique_id() == 1:
if version_checked.has(peer_id):
rpc_id(peer_id, "select_track", current_track_path)
func _peer_disconnected(peer_id):
peers.erase(peer_id)
destroy_player(peer_id)
func _connected_to_server():
rpc_id(
1, "check_version", get_tree().get_network_unique_id(), GlobalSettings.get_version_string()
)
func _connection_failed():
current_track = null
get_tree().network_peer = null
_server_disconnected()
func _server_disconnected():
current_track = null
peers.clear()
get_tree().network_peer = null
get_tree().root.get_child(get_tree().root.get_child_count() - 1).queue_free()
var alert = Alerter.create_simple_alert("Connection to the host has been lost.")
get_tree().root.add_child(alert)
alert.connect("popup_hide", self, "_on_disconnect_confirmed")
alert.popup_centered()
func _on_disconnect_confirmed():
get_tree().change_scene("res://menu/main_menu.tscn")
func create_player(peer_id, vehicle_path):
var vehicle = load(vehicle_path).instance()
var gui
if peer_id == get_tree().get_network_unique_id():
gui = load(GUI_SCENE).instance()
vehicle.connect("speed_updated", gui, "update_speed")
vehicle.connect("rpm_updated", gui, "update_rpm")
vehicle.connect("gear_updated", gui, "update_gear")
vehicle.set_network_master(peer_id)
vehicle.name = String(peer_id)
if peer_id == get_tree().get_network_unique_id():
current_track.call_deferred("spawn_player", vehicle, gui)
else:
current_track.call_deferred("spawn_vehicle", vehicle)
func destroy_player(peer_id):
current_track.remove_player(String(peer_id))
func quit():
enet_peer.close_connection()
current_track = null
get_tree().network_peer = null
peers.clear()
remote func add_player(peer_id, peer_info: Array):
if peers[peer_id] == null:
peers[peer_id] = PeerInfo.new_peer(peer_id, "", "", false, get_next_color(peer_id))
if peers[peer_id].spawned == false:
peers[peer_id].from_array(peer_info)
# Check for duplicate names on server side and update colors
if get_tree().get_network_unique_id() == 1:
var names = []
for peer in peers:
if peer != peer_id:
names.append(peers[peer].name)
if names.has(peers[peer_id].name):
peers[peer_id].name = peers[peer_id].name + ("(%s)" % peer_id)
rpc("update_name", peer_id, peers[peer_id].name)
peers[peer_id].color = get_next_color(peer_id)
rpc("update_color", peer_id, peers[peer_id].color)
if current_track != null:
peers[peer_id].spawned = true
create_player(peer_id, peers[peer_id].vehicle)
else:
peers[peer_id].spawned = false
emit_signal("peers_updated")
remote func check_version(peer_id: int, version: String) -> void:
if version != GlobalSettings.get_version_string():
enet_peer.disconnect_peer(peer_id)
return
version_checked.append(peer_id)
rpc_id(peer_id, "select_track", current_track_path)
remote func select_track(track_path):
current_track = load(track_path).instance()
get_tree().root.call_deferred("add_child", current_track)
create_player(get_tree().get_network_unique_id(), current_vehicle)
for peer in peers:
if peers[peer].spawned == false:
peers[peer].spawned = true
create_player(peer, peers[peer].vehicle)
emit_signal("peers_updated")
remote func update_name(peer_id, name: String):
peers[peer_id].name = name
emit_signal("peers_updated")
remote func update_color(peer_id, color: Color):
peers[peer_id].color = color
emit_signal("peers_updated")
func get_next_color(peer_id: int) -> Color:
if peers.size() >= colors.size():
return Color(peer_id)
else:
return colors[peers.size()]

View File

@ -0,0 +1,63 @@
class_name CameraController
extends Reference
const FOLLOW_CAMERA = preload("res://player/cameras/follow_camera.tscn")
const STATIC_CAMERA = preload("res://player/cameras/static_camera.tscn")
var _cameras = []
func attach_cameras_to(player_node: BuggedVehicle) -> void:
var cockpit_camera = STATIC_CAMERA.instance()
player_node.get_cockpit_position().add_child(cockpit_camera)
cockpit_camera.reset()
var follow_camera = FOLLOW_CAMERA.instance()
follow_camera.global_transform = player_node.global_transform.translated(
-player_node.global_transform.basis.z * 100
)
follow_camera.follow_target_path = player_node.get_path()
player_node.get_parent().add_child(follow_camera)
var bumpera_camera = STATIC_CAMERA.instance()
player_node.get_bumper_position().add_child(bumpera_camera)
var hood_camera = STATIC_CAMERA.instance()
player_node.get_hood_position().add_child(hood_camera)
var static_follow_camera = STATIC_CAMERA.instance()
player_node.get_static_follow_position().add_child(static_follow_camera)
_cameras = [follow_camera, cockpit_camera, hood_camera, bumpera_camera, static_follow_camera]
for cam in _cameras:
cam.reset()
select_camera(GlobalSettings.selected_camera)
func select_camera(camera_index: int) -> void:
if _cameras.size() == 0:
return
var select_index = camera_index
if camera_index < 0 or camera_index >= _cameras.size():
select_index = 0
GlobalSettings.selected_camera = select_index
_cameras[select_index].current = true
func clear():
for cam in _cameras:
cam.queue_free()
_cameras = []
func next_camera() -> void:
select_camera(GlobalSettings.selected_camera + 1)
func update_camera(horizontal: float, vertical: float, look_back: bool) -> void:
horizontal = clamp(horizontal, -1.0, 1.0)
vertical = clamp(vertical, -1.0, 1.0)
if look_back:
horizontal = 2.0
for cam in _cameras:
cam.reset()
cam.update_rotation(horizontal, vertical)

View File

@ -6,6 +6,8 @@ export var target_height: float = 2.0
var follow_target: Node = null
var last_lookat: Vector3
var target_angle_horizontal = 0
var target_angle_vertical = 0
# Called when the node enters the scene tree for the first time.
@ -27,10 +29,28 @@ func _physics_process(delta):
else:
target_pos.y = follow_target.global_transform.origin.y + target_height
global_transform.origin = global_transform.origin.linear_interpolate(target_pos, delta * 20.0)
last_lookat = last_lookat.linear_interpolate(
follow_target.global_transform.origin, delta * 20.0
)
var original_diff = target_pos - follow_target.global_transform.origin
var rotation_adjustment = (
original_diff.rotated(Vector3.DOWN, target_angle_horizontal).rotated(
Vector3.LEFT, target_angle_vertical
)
- original_diff
)
target_pos += rotation_adjustment
global_transform.origin = global_transform.origin.linear_interpolate(target_pos, delta * 20.0)
look_at(last_lookat, Vector3(0.0, 1.0, 0.0))
func reset() -> void:
pass
func update_rotation(horizontal: float, vertical: float) -> void:
target_angle_horizontal = horizontal * deg2rad(90)
target_angle_vertical = vertical * deg2rad(90)

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://player/camera.gd" type="Script" id=1]
[ext_resource path="res://player/cameras/follow_camera.gd" type="Script" id=1]
[node name="camera" type="Camera"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 5.88022, 23.0639 )

View File

@ -0,0 +1,20 @@
extends Camera
func reset() -> void:
rotation = Vector3.ZERO
rotate(Vector3.UP, deg2rad(180))
fov = GlobalSettings.camera_fov
translation = Vector3.ZERO
translate(
Vector3(
GlobalSettings.camera_move_horizontal,
GlobalSettings.camera_move_vertical,
GlobalSettings.camera_move_depth
)
)
func update_rotation(horizontal: float, vertical: float) -> void:
rotate(Vector3.DOWN, horizontal * deg2rad(90))
rotate(Vector3.LEFT, vertical * deg2rad(90))

View File

@ -0,0 +1,7 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://player/cameras/static_camera.gd" type="Script" id=1]
[node name="camera" type="Camera"]
far = 1000.0
script = ExtResource( 1 )

View File

@ -0,0 +1,63 @@
class_name PlayerVehicleController
extends Node
export(NodePath) var input_sink_path = null
onready var _input_sink = get_node(input_sink_path)
func _physics_process(delta: float) -> void:
var steering_sensitivity = GlobalSettings.steering_sensitivity
var return_speed = GlobalSettings.return_speed
var throttle_sensitivity = GlobalSettings.throttle_sensitivity
var brake_sensitivity = GlobalSettings.brake_sensitivity
var steering_deadzone_inner = GlobalSettings.steering_deadzone_inner
var steering_deadzone_outer = GlobalSettings.steering_deadzone_outer
_input_sink.inputs.throttle = move_toward(
_input_sink.inputs.throttle,
Input.get_action_strength("throttle"),
lerp(delta, 1, throttle_sensitivity)
)
_input_sink.inputs.clutch = Input.get_action_strength("clutch")
_input_sink.inputs.brake = move_toward(
_input_sink.inputs.brake,
Input.get_action_strength("brake"),
lerp(delta, 1, brake_sensitivity)
)
_input_sink.inputs.handbrake = Input.get_action_strength("handbrake")
var steering_input = (
Input.get_action_strength("steer_left")
- Input.get_action_strength("steer_right")
)
if abs(steering_input) <= steering_deadzone_inner:
steering_input = 0.0
if abs(steering_input) >= (1 - steering_deadzone_outer):
steering_input = 1.0 * sign(steering_input)
if (
abs(steering_input) > steering_deadzone_inner
and abs(steering_input) < (1 - steering_deadzone_outer)
):
steering_input = (
sign(steering_input)
* inverse_lerp(
steering_deadzone_inner, 1 - steering_deadzone_outer, abs(steering_input)
)
)
var steering_factor = steering_sensitivity
if abs(_input_sink.inputs.steering) > abs(steering_input):
steering_factor *= return_speed
_input_sink.inputs.steering = move_toward(
_input_sink.inputs.steering, steering_input, lerp(delta, 1, steering_factor)
)
if Input.is_action_just_pressed("gear_up"):
_input_sink.inputs.gear_request = BuggedVehicle.GearRequest.UP
elif Input.is_action_just_pressed("gear_down"):
_input_sink.inputs.gear_request = BuggedVehicle.GearRequest.DOWN
else:
_input_sink.inputs.gear_request = BuggedVehicle.GearRequest.NONE

View File

@ -19,6 +19,16 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://vehicles/vehicle.gd"
}, {
"base": "Reference",
"class": "CameraController",
"language": "GDScript",
"path": "res://player/cameras/camera_controller.gd"
}, {
"base": "Node",
"class": "PlayerVehicleController",
"language": "GDScript",
"path": "res://player/vehicle_controller.gd"
}, {
"base": "Particles",
"class": "TireSmoke",
"language": "GDScript",
@ -32,6 +42,8 @@ _global_script_classes=[ {
_global_script_class_icons={
"BaseTrackLevel": "",
"BuggedVehicle": "",
"CameraController": "",
"PlayerVehicleController": "",
"TireSmoke": "",
"Track": ""
}
@ -45,7 +57,9 @@ config/icon="res://icon.png"
[autoload]
GlobalSettings="*res://settings/GlobalSettings.gd"
GlobalSettings="*res://settings/global_settings.gd"
MultiplayerController="*res://network/multiplayer_controller.gd"
Alerter="*res://menu/components/alerter.gd"
[editor_plugins]
@ -124,6 +138,42 @@ reset_vehicle={
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null)
]
}
next_camera={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":70,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
]
}
turn_camera_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":76,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":2,"axis_value":1.0,"script":null)
]
}
turn_camera_left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":74,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":2,"axis_value":-1.0,"script":null)
]
}
turn_camera_up={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":73,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":3,"axis_value":-1.0,"script":null)
]
}
turn_camera_down={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":75,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":3,"axis_value":1.0,"script":null)
]
}
look_backwards={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":66,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":10,"pressure":0.0,"pressed":false,"script":null)
]
}
[physics]

View File

@ -1,29 +1,39 @@
class_name BaseTrackLevel
extends Spatial
const CAMERA = preload("res://player/camera.tscn")
const CAMERA_CONTROLLER = preload("res://player/cameras/camera_controller.gd")
const PLAYER_CONTROLLER = preload("res://player/vehicle_controller.gd")
var player_node: Node
var player_node: BuggedVehicle
var gui: Node
var camera_controller: CameraController
var player_controller: PlayerVehicleController
var ready = false
onready var track = $Track
func _ready() -> void:
reset_player_to(track.get_furthest_checkpoint(), player_node)
add_child(player_node)
add_child(gui)
var player_camera = CAMERA.instance()
player_camera.global_transform = player_node.global_transform.translated(
-player_node.global_transform.basis.z * 100
)
player_camera.follow_target_path = player_node.get_path()
add_child(player_camera)
if player_node != null:
_spawn_in_player()
ready = true
func spawn_player(player_node: Node, gui: Node) -> void:
func spawn_player(player_node: BuggedVehicle, gui: Node) -> void:
self.player_node = player_node
self.gui = gui
if ready:
_spawn_in_player()
func spawn_vehicle(vehicle: BuggedVehicle) -> void:
vehicle.connect("position_updated", track, "_on_player_position_updated")
reset_player_to(track.get_furthest_checkpoint(), vehicle)
add_child(vehicle)
func remove_player(peer_id: String) -> void:
get_node(peer_id).queue_free()
func reset_player_to(node_to_reset_to: Node, player_node: BuggedVehicle) -> void:
@ -33,13 +43,37 @@ func reset_player_to(node_to_reset_to: Node, player_node: BuggedVehicle) -> void
).origin,
node_to_reset_to.global_transform.basis.y
)
player_node.reset_transform.origin += node_to_reset_to.global_transform.basis.y * 3
player_node.reset_transform.origin += node_to_reset_to.global_transform.basis.y * 2
func _spawn_in_player():
reset_player_to(track.get_furthest_checkpoint(), player_node)
player_node.connect("position_updated", track, "_on_player_position_updated")
add_child(player_node)
add_child(gui)
player_controller = PLAYER_CONTROLLER.new()
player_controller.input_sink_path = player_node.get_path()
player_node.add_child(player_controller)
camera_controller = CAMERA_CONTROLLER.new()
camera_controller.attach_cameras_to(player_node)
func _process(_delta: float) -> void:
if Input.is_action_just_released("reset_vehicle"):
reset_player_to(track.get_furthest_checkpoint(), player_node)
if Input.is_action_just_released("next_camera"):
camera_controller.next_camera()
camera_controller.update_camera(
(
Input.get_action_strength("turn_camera_right")
- Input.get_action_strength("turn_camera_left")
),
Input.get_action_strength("turn_camera_up") - Input.get_action_strength("turn_camera_down"),
Input.is_action_pressed("look_backwards")
)
func _on_ResetArea_body_entered(body: Node) -> void:
if body.get_groups().has("car"):

View File

@ -0,0 +1,12 @@
extends Node2D
export(Curve2D) var curve
export(Color) var color = Color.red
export(float) var width = 2.0
func _draw() -> void:
if curve == null:
return
draw_polyline(curve.get_baked_points(), color, width)

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://scenes/components/curved_line_2d.gd" type="Script" id=1]
[node name="CurvedLine2d" type="Node2D"]
script = ExtResource( 1 )

View File

@ -0,0 +1,43 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://assets/checkered.png" type="Texture" id=1]
[sub_resource type="CubeMesh" id=1]
size = Vector3( 0.1, 0.75, 1 )
[sub_resource type="SpatialMaterial" id=2]
albedo_color = Color( 0.333333, 0.333333, 0.333333, 1 )
[sub_resource type="CubeMesh" id=3]
size = Vector3( 0.3, 1, 1 )
[sub_resource type="SpatialMaterial" id=4]
albedo_texture = ExtResource( 1 )
uv1_scale = Vector3( 2.07, 2.592, 1 )
uv1_triplanar = true
[node name="Spatial" type="Spatial"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.15, 0 )
[node name="StaticBody" type="StaticBody" parent="."]
[node name="MeshInstance" type="MeshInstance" parent="StaticBody"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.444051, 0.366505, 0 )
mesh = SubResource( 1 )
skeleton = NodePath("../..")
material/0 = SubResource( 2 )
[node name="MeshInstance2" type="MeshInstance" parent="StaticBody"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.448985, 0.365196, 0 )
mesh = SubResource( 1 )
skeleton = NodePath("../..")
material/0 = SubResource( 2 )
[node name="MeshInstance3" type="MeshInstance" parent="StaticBody"]
transform = Transform( -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0, 1, 0, 0.894511, 0 )
mesh = SubResource( 3 )
skeleton = NodePath("../..")
material/0 = SubResource( 4 )
[node name="CollisionPolygon" type="CollisionPolygon" parent="StaticBody"]
polygon = PoolVector2Array( -0.5, 0, -0.5, 1.05, 0.5, 1.05, 0.5, 0, 0.4, 0, 0.4, 0.75, -0.4, 0.75, -0.4, 0 )

View File

@ -72,6 +72,7 @@ albedo_color = Color( 0.203922, 0.203922, 0.203922, 1 )
[node name="Track" parent="." index="1"]
track_path = NodePath("../Path")
checkpoint_polygon = PoolVector2Array( -20, -4, -20, 10, 20, 10, 20, -4 )
gate_size = Vector3( 42, 20, 5 )
[node name="Grass" type="StaticBody" parent="." index="2"]
transform = Transform( 0.8, 0, 0, 0, 1, 0, 0, 0, 0.4, 0, 5, 0 )

View File

@ -0,0 +1,90 @@
extends Node2D
export(Vector2) var size = Vector2(200, 200)
export(Texture) var player_icon
onready var scaling_helper = $ScalingHelper
onready var track_path = $ScalingHelper/TrackPath
onready var track_line = $ScalingHelper/TrackLine
onready var start_line = $ScalingHelper/TrackPath/StartLine
onready var players_container = $ScalingHelper/Players
func _ready() -> void:
scaling_helper.position.x = size.x / 2
scaling_helper.position.y = size.y / 2
MultiplayerController.connect("peers_updated", self, "_on_peers_updated")
func set_curve(curve: Curve3D) -> void:
var curve2d = Curve2D.new()
var point_count = curve.get_point_count()
for point in range(point_count):
var point3d = curve.get_point_position(point)
var point_in = curve.get_point_in(point)
var point_out = curve.get_point_out(point)
curve2d.add_point(
Vector2(point3d.x, point3d.z),
Vector2(point_in.x, point_in.z),
Vector2(point_out.x, point_out.z)
)
var max_x = curve2d.get_baked_points()[0].x
var max_y = curve2d.get_baked_points()[0].y
var min_x = curve2d.get_baked_points()[0].x
var min_y = curve2d.get_baked_points()[0].y
for point in curve2d.get_baked_points():
if point.x > max_x:
max_x = point.x
if point.x < min_x:
min_x = point.x
if point.y > max_y:
max_y = point.y
if point.y < min_y:
min_y = point.y
var center_x = (max_x + min_x) / 2
var center_y = (max_y + min_y) / 2
var width = max_x - min_x
var height = max_y - min_y
var max_dim = max(width, height)
var scale_factor = size.x / (max_dim + track_line.width)
var new_center_x = scaling_helper.position.x - (center_x * scale_factor)
var new_center_y = scaling_helper.position.y - (center_y * scale_factor)
scaling_helper.scale.x = scale_factor
scaling_helper.scale.y = scale_factor
scaling_helper.position.x = new_center_x
scaling_helper.position.y = new_center_y
track_path.curve = curve2d
track_line.curve = curve2d
start_line.offset = 0.01
func on_player_position_updated(player_id: int, position: Transform) -> void:
var existing_node: Sprite = players_container.get_node_or_null(String(player_id))
if existing_node == null:
var player_color
if MultiplayerController.is_online():
player_color = MultiplayerController.peers[player_id].color
else:
player_color = Color(1, 1, 1)
existing_node = Sprite.new()
existing_node.name = String(player_id)
existing_node.texture = player_icon
existing_node.modulate = player_color
players_container.add_child(existing_node)
existing_node.position.x = position.origin.x
existing_node.position.y = position.origin.z
existing_node.rotation = position.basis.x.signed_angle_to(Vector3.LEFT, Vector3.UP)
func _on_peers_updated() -> void:
for peer in MultiplayerController.peers:
var existing_node: Sprite = players_container.get_node_or_null(String(peer))
if existing_node != null:
var player_color = MultiplayerController.peers[peer].color
existing_node.modulate = player_color
for child in players_container.get_children():
if not MultiplayerController.peers.has(int(float(child.name))):
child.queue_free()

View File

@ -0,0 +1,37 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://assets/player_icon.png" type="Texture" id=1]
[ext_resource path="res://scenes/track_minimap.gd" type="Script" id=2]
[ext_resource path="res://scenes/components/curved_line_2d.tscn" type="PackedScene" id=3]
[sub_resource type="Gradient" id=1]
offsets = PoolRealArray( 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 )
colors = PoolColorArray( 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1 )
[sub_resource type="GradientTexture" id=2]
gradient = SubResource( 1 )
width = 50
[node name="TrackMinimap" type="Node2D"]
script = ExtResource( 2 )
player_icon = ExtResource( 1 )
[node name="ScalingHelper" type="Node2D" parent="."]
[node name="TrackPath" type="Path2D" parent="ScalingHelper"]
curve = null
[node name="StartLine" type="PathFollow2D" parent="ScalingHelper/TrackPath"]
position = Vector2( -99.1171, -154.856 )
rotation = -0.742965
[node name="Sprite" type="Sprite" parent="ScalingHelper/TrackPath/StartLine"]
rotation = 1.5708
scale = Vector2( 1, 5 )
texture = SubResource( 2 )
[node name="TrackLine" parent="ScalingHelper" instance=ExtResource( 3 )]
color = Color( 0.482353, 0, 0, 1 )
width = 10.0
[node name="Players" type="Node2D" parent="ScalingHelper"]

View File

@ -1,15 +1,24 @@
extends MarginContainer
var best_time = -1
var leaderboards_data = {}
onready var time_value = $VBoxContainer/HBoxContainer/TimeValue
onready var best_time_value = $VBoxContainer/HBoxContainer/BestTimeValue
onready var wrong_way_label = $VBoxContainer/WrongWayLabel
onready var wrong_way_label = $CenterContainer/WrongWayLabel
onready var leaderboards = $VBoxContainer/LeaderboardsLine
onready var leaderboards_list = $VBoxContainer/LeaderboardsLine/VBoxContainer/Leaderboards
onready var track_minimap = $VBoxContainer2/HBoxContainer/ViewportContainer/TrackRadar/TrackMinimap
func _ready() -> void:
time_value.text = "NaN"
best_time_value.text = "NaN"
if MultiplayerController.is_online():
leaderboards.visible = true
MultiplayerController.connect("peers_updated", self, "_on_peers_updated")
else:
leaderboards.visible = false
func _on_time_updated(new_time: float) -> void:
@ -20,6 +29,9 @@ func _on_lap_complete(lap_time: float) -> void:
if lap_time < best_time or best_time < 0:
best_time = lap_time
best_time_value.text = _format_time(best_time)
if MultiplayerController.is_online():
update_leaderboard_time(String(get_tree().get_network_unique_id()), lap_time)
rpc("update_leaderboard_time", String(get_tree().get_network_unique_id()), lap_time)
func _on_wrong_way_detected() -> void:
@ -33,3 +45,46 @@ func _format_time(time: float) -> String:
var second = floor((time / 1000.0) - minute * 60)
var millisecond = time - minute * 60 * 1000 - second * 1000
return "%02d:%02d.%03d" % [minute, second, millisecond]
remote func update_leaderboard_time(peer_id: String, lap_time: float):
leaderboards_data[peer_id] = lap_time
_refresh_leaderboard()
func _refresh_leaderboard():
var leaderboards_sorted = []
for peer in leaderboards_data:
leaderboards_sorted.append([peer, leaderboards_data[peer]])
leaderboards_sorted.sort_custom(self, "_leaderbords_comparison")
for child in leaderboards_list.get_children():
child.queue_free()
for entry in leaderboards_sorted:
var label = Label.new()
var player_name = MultiplayerController.peers[int(float(entry[0]))].name
label.text = "%s - %s" % [player_name, _format_time(entry[1])]
leaderboards_list.add_child(label)
func _leaderbords_comparison(left: Array, right: Array) -> bool:
return left[1] < right[1]
func set_curve(curve: Curve3D) -> void:
track_minimap.set_curve(curve)
func on_player_position_updated(player_id: int, position: Transform) -> void:
track_minimap.on_player_position_updated(player_id, position)
func _on_peers_updated() -> void:
for peer in leaderboards_data.keys():
if not MultiplayerController.peers.has(peer):
leaderboards_data.erase(peer)
_refresh_leaderboard()

View File

@ -1,7 +1,8 @@
[gd_scene load_steps=4 format=2]
[gd_scene load_steps=6 format=2]
[ext_resource path="res://assets/fonts/kenney-future-narrow.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://scenes/trackgui.gd" type="Script" id=2]
[ext_resource path="res://scenes/track_minimap.tscn" type="PackedScene" id=3]
[sub_resource type="DynamicFont" id=1]
size = 36
@ -9,6 +10,10 @@ outline_size = 2
outline_color = Color( 1, 1, 1, 0.317647 )
font_data = ExtResource( 1 )
[sub_resource type="Theme" id=2]
default_font = SubResource( 1 )
Label/colors/font_color = Color( 0.482353, 0, 0, 1 )
[node name="TrackGUI" type="MarginContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
@ -16,6 +21,7 @@ margin_left = 20.0
margin_top = 20.0
margin_right = -20.0
margin_bottom = -20.0
theme = SubResource( 2 )
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
@ -34,8 +40,6 @@ margin_right = 289.0
margin_bottom = 41.0
size_flags_horizontal = 3
size_flags_vertical = 0
custom_colors/font_color = Color( 0.482353, 0, 0, 1 )
custom_fonts/font = SubResource( 1 )
text = "Current lap -"
align = 1
valign = 1
@ -46,8 +50,6 @@ margin_right = 489.0
margin_bottom = 41.0
size_flags_horizontal = 3
size_flags_vertical = 0
custom_colors/font_color = Color( 0.482353, 0, 0, 1 )
custom_fonts/font = SubResource( 1 )
text = "12:23.245"
__meta__ = {
"_edit_use_anchors_": false
@ -59,8 +61,6 @@ margin_right = 562.0
margin_bottom = 41.0
size_flags_horizontal = 3
size_flags_vertical = 0
custom_colors/font_color = Color( 0.482353, 0, 0, 1 )
custom_fonts/font = SubResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
@ -71,8 +71,6 @@ margin_right = 784.0
margin_bottom = 41.0
size_flags_horizontal = 3
size_flags_vertical = 0
custom_colors/font_color = Color( 0.482353, 0, 0, 1 )
custom_fonts/font = SubResource( 1 )
text = "Best Lap -"
[node name="BestTimeValue" type="Label" parent="VBoxContainer/HBoxContainer"]
@ -81,24 +79,77 @@ margin_right = 984.0
margin_bottom = 41.0
size_flags_horizontal = 3
size_flags_vertical = 0
custom_colors/font_color = Color( 0.482353, 0, 0, 1 )
custom_fonts/font = SubResource( 1 )
text = "01:23.256"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="WrongWayLabel" type="Label" parent="VBoxContainer"]
visible = false
[node name="LeaderboardsLine" type="HBoxContainer" parent="VBoxContainer"]
margin_top = 49.0
margin_right = 984.0
margin_bottom = 90.0
margin_bottom = 98.0
alignment = 2
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/LeaderboardsLine"]
margin_left = 684.0
margin_right = 984.0
margin_bottom = 49.0
[node name="LeaderboardsLabel" type="Label" parent="VBoxContainer/LeaderboardsLine/VBoxContainer"]
margin_right = 300.0
margin_bottom = 41.0
text = "Leaderboards"
[node name="Leaderboards" type="VBoxContainer" parent="VBoxContainer/LeaderboardsLine/VBoxContainer"]
margin_top = 49.0
margin_right = 300.0
margin_bottom = 49.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="CenterContainer" type="CenterContainer" parent="."]
margin_right = 984.0
margin_bottom = 560.0
[node name="WrongWayLabel" type="Label" parent="CenterContainer"]
visible = false
margin_left = 238.0
margin_top = 259.0
margin_right = 745.0
margin_bottom = 300.0
size_flags_horizontal = 3
size_flags_vertical = 0
custom_colors/font_color = Color( 0.482353, 0, 0, 1 )
custom_fonts/font = SubResource( 1 )
text = "Wrong Way! Turn Around!"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer2" type="VBoxContainer" parent="."]
margin_right = 984.0
margin_bottom = 560.0
alignment = 2
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer2"]
margin_top = 360.0
margin_right = 984.0
margin_bottom = 560.0
alignment = 2
[node name="ViewportContainer" type="ViewportContainer" parent="VBoxContainer2/HBoxContainer"]
margin_left = 784.0
margin_right = 984.0
margin_bottom = 200.0
[node name="TrackRadar" type="Viewport" parent="VBoxContainer2/HBoxContainer/ViewportContainer"]
size = Vector2( 200, 200 )
transparent_bg = true
handle_input_locally = false
disable_3d = true
usage = 0
render_target_update_mode = 3
gui_disable_input = true
[node name="TrackMinimap" parent="VBoxContainer2/HBoxContainer/ViewportContainer/TrackRadar" instance=ExtResource( 3 )]

View File

@ -5,12 +5,15 @@ signal time_updated(new_time)
signal lap_complete(lap_time)
signal wrong_way
const FINISH_GATE = preload("res://scenes/finish_gate.tscn")
export(NodePath) var track_path = null
export(int, 10, 50) var checkpoint_count = 20
export(float) var checkpoint_depth = 5.0
export(PoolVector2Array) var checkpoint_polygon = PoolVector2Array(
[Vector2(-10, -10), Vector2(-10, 10), Vector2(10, 10), Vector2(10, -10)]
)
export(Vector3) var gate_size = Vector3(20, 10, 5)
var furthest_checkpoint = -1
var last_checkpoint = -1
@ -21,6 +24,7 @@ var current_time = 0
var lap_done = false
onready var checkpoints = $Checkpoints
onready var track_gui = $TrackGUI
onready var path: Path = get_node(track_path)
@ -44,7 +48,11 @@ func _ready() -> void:
section += section_size
checkpoints.add_child(new_checkpoint)
new_checkpoint.connect("body_entered", self, "_on_body_entered_area", [new_checkpoint])
var gate = FINISH_GATE.instance()
gate.scale = gate_size
checkpoints.get_child(0).add_child(gate)
checkpoints.global_transform.origin = path.global_transform.origin
track_gui.set_curve(path.curve)
func _process(_delta: float) -> void:
@ -52,6 +60,12 @@ func _process(_delta: float) -> void:
func _on_body_entered_area(body: Node, area: Area) -> void:
if (
MultiplayerController.is_online()
and body.get_network_master() != get_tree().get_network_unique_id()
):
return
if body.get_groups().has("car"):
if area.get_index() < last_checkpoint || abs(area.get_index() - last_checkpoint) > 1:
emit_signal("wrong_way")
@ -84,3 +98,7 @@ func _build_checkpoint_collision():
func _update_time():
current_time = OS.get_ticks_msec() - start_time
emit_signal("time_updated", current_time)
func _on_player_position_updated(player_id: int, position: Transform) -> void:
track_gui.on_player_position_updated(player_id, position)

View File

@ -1,15 +1,10 @@
[gd_scene load_steps=4 format=2]
[gd_scene load_steps=3 format=2]
[ext_resource path="res://scenes/tracks/track.gd" type="Script" id=1]
[ext_resource path="res://scenes/trackgui.tscn" type="PackedScene" id=2]
[sub_resource type="SpatialMaterial" id=7]
flags_transparent = true
albedo_color = Color( 0.0470588, 0.956863, 0.921569, 0.439216 )
[node name="Track" type="Spatial"]
script = ExtResource( 1 )
debug_material = SubResource( 7 )
[node name="Checkpoints" type="Spatial" parent="."]

View File

@ -1,4 +0,0 @@
extends Node
var auto_clutch: bool = false
var automatic_transmission: bool = true

View File

@ -0,0 +1,109 @@
extends Node
var auto_clutch: bool = true
var automatic_transmission: bool = true
var steering_sensitivity = 1.0
var return_speed = 2.0
var throttle_sensitivity = 1.0
var brake_sensitivity = 1.0
var steering_deadzone_inner = 0.0
var steering_deadzone_outer = 0.0
var selected_camera: int = 0
var multiplayer_name: String = "Player"
var camera_fov = 70
var camera_move_depth = 0
var camera_move_horizontal = 0
var camera_move_vertical = 0
var _config: Dictionary
func _ready() -> void:
_config = read_json_file("res://info.json")
get_tree().set_auto_accept_quit(false)
var stored_config = read_json_file("user://settings.json")
if stored_config.has("hidden"):
selected_camera = stored_config["hidden"].get("selected_camera", 0)
if stored_config.has("gameplay"):
multiplayer_name = stored_config["gameplay"].get("multiplayer_name", "Player")
if stored_config.has("controls"):
auto_clutch = stored_config["controls"].get("auto_clutch", true)
automatic_transmission = stored_config["controls"].get("automatic_transmission", true)
steering_sensitivity = stored_config["controls"].get("steering_sensitivity", 1.0)
return_speed = stored_config["controls"].get("return_speed", 2.0)
throttle_sensitivity = stored_config["controls"].get("throttle_sensitivity", 1.0)
brake_sensitivity = stored_config["controls"].get("brake_sensitivity", 1.0)
steering_deadzone_inner = stored_config["controls"].get("steering_deadzone_inner", 1.0)
steering_deadzone_outer = stored_config["controls"].get("steering_deadzone_outer", 1.0)
if stored_config.has("camera"):
camera_fov = stored_config["camera"].get("fov", 70)
camera_move_depth = stored_config["camera"].get("move_depth", 0)
camera_move_horizontal = stored_config["camera"].get("move_horizontal", 0)
camera_move_vertical = stored_config["camera"].get("move_vertical", 0)
func read_json_file(file_path: String) -> Dictionary:
var file = File.new()
if not file.file_exists(file_path):
print("File not found: %s" % file_path)
return Dictionary()
file.open(file_path, File.READ)
var content_as_text = file.get_as_text()
var content_as_dictionary = parse_json(content_as_text)
return content_as_dictionary
func save_json_file(file_path: String, contents: Dictionary) -> void:
var file = File.new()
file.open(file_path, File.WRITE)
file.store_line(to_json(contents))
file.close()
func get_version_string() -> String:
var version = _config["version"]
var major = version["major"]
var minor = version["minor"]
var patch = version["patch"]
return "%d.%d.%d" % [major, minor, patch]
func save_settings() -> void:
save_json_file("user://settings.json", to_dictionary())
func to_dictionary() -> Dictionary:
return {
"hidden": {"selected_camera": selected_camera},
"gameplay": {"multiplayer_name": multiplayer_name},
"controls":
{
"auto_clutch": auto_clutch,
"automatic_transmission": automatic_transmission,
"steering_sensitivity": steering_sensitivity,
"return_speed": return_speed,
"throttle_sensitivity": throttle_sensitivity,
"brake_sensitivity": brake_sensitivity,
"steering_deadzone_inner": steering_deadzone_inner,
"steering_deadzone_outer": steering_deadzone_outer,
},
"camera":
{
"fov": camera_fov,
"move_depth": camera_move_depth,
"move_horizontal": camera_move_horizontal,
"move_vertical": camera_move_vertical
}
}
# Handle quit
func _notification(what):
if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST:
save_settings()
get_tree().quit() # default behavior

View File

@ -1,23 +1,21 @@
[gd_scene load_steps=13 format=2]
[gd_scene load_steps=16 format=2]
[ext_resource path="res://vehicles/vehicle.gd" type="Script" id=1]
[ext_resource path="res://assets/beetlecar.glb" type="PackedScene" id=2]
[ext_resource path="res://vehicles/tire_smoke.tscn" type="PackedScene" id=3]
[ext_resource path="res://vehicles/pedal.gd" type="Script" id=4]
[ext_resource path="res://vehicles/meter.gd" type="Script" id=5]
[ext_resource path="res://vehicles/steering_controller.gd" type="Script" id=6]
[ext_resource path="res://assets/engine.wav" type="AudioStream" id=7]
[ext_resource path="res://assets/wind woosh loop.ogg" type="AudioStream" id=8]
[sub_resource type="Curve" id=3]
_data = [ Vector2( 0, 0 ), 0.0, 3.60634, 0, 1, Vector2( 0.15566, 0.561364 ), 1.56017, 1.56017, 0, 0, Vector2( 0.830189, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 0 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="Curve" id=4]
_data = [ Vector2( 0, 0.492045 ), 0.0, 0.0, 0, 0, Vector2( 0.15566, 1 ), 0.0, 0.0, 0, 0, Vector2( 0.212264, 0 ), 0.0, 0.0, 0, 0, Vector2( 0.29717, 1 ), 0.0, 0.0, 0, 0, Vector2( 0.410377, 0 ), 0.0, 0.0, 0, 0, Vector2( 0.481132, 0.701136 ), 0.0, 0.0, 0, 0, Vector2( 0.566038, 0.282955 ), 0.0, 0.0, 0, 0, Vector2( 0.589623, 0.6375 ), 0.0, 0.0, 0, 0, Vector2( 0.660377, 0.373864 ), 0.0, 0.0, 0, 0, Vector2( 0.669811, 0.5375 ), 0.0, 0.0, 0, 0, Vector2( 0.764151, 0.0284091 ), 0.0, 0.0, 0, 0, Vector2( 0.811321, 1 ), 0.0, 0.0, 0, 0, Vector2( 0.938679, 0 ), 0.0, 0.0, 0, 0, Vector2( 1, 1 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CapsuleShape" id=11]
radius = 0.394377
height = 2.03536
[sub_resource type="AudioStreamGenerator" id=2]
mix_rate = 5500.0
buffer_length = 1.0
[sub_resource type="Curve" id=9]
_data = [ Vector2( 0, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 0.493182 ), 0.0, 0.0, 0, 0 ]
@ -43,42 +41,65 @@ radial_segments = 4
rings = 3
[node name="beetlecar" groups=["car"] instance=ExtResource( 2 )]
mass = 340.0
mass = 750.0
script = ExtResource( 1 )
max_steer_angle = 18.0
speed_steer_angle = 8.0
max_steer_speed = 60.0
max_steer_input = 60.0
max_engine_force = 100.0
max_brake_force = 60.0
max_steer_input = 35.0
max_engine_force = 650.0
max_brake_force = 90.0
base_engine_pitch = 0.38
gear_ratios = [ 2.99, 2.5, 1.98, 1.56, 1.32, 1.12 ]
final_drive = 4.0
max_rpm = 8000.0
gear_switch_time = 0.5
expected_max_speed = 170.0
drag_factor = 1.55
downforce_factor = 0.2
gear_ratios = [ 6.67, 4.95, 3.65, 2.78, 2.25 ]
final_drive = 2.5
max_rpm = 8500.0
gear_switch_time = 0.3
power_curve = SubResource( 3 )
sound_curve = SubResource( 4 )
automatic_gear_up_threshold = 0.85
[node name="rear_right" parent="." index="0"]
use_as_traction = true
wheel_roll_influence = 0.01
wheel_radius = 0.38
wheel_rest_length = 0.3
wheel_friction_slip = 12.0
wheel_friction_slip = 2.0
suspension_travel = 0.3
suspension_stiffness = 12.0
suspension_max_force = 4000.0
damping_compression = 0.75
damping_relaxation = 0.8
[node name="brake_pedal" parent="chassis/cockpit" index="0"]
script = ExtResource( 4 )
[node name="clutch_pedal" parent="chassis/cockpit" index="1"]
script = ExtResource( 4 )
[node name="gas_pedal" parent="chassis/cockpit" index="2"]
script = ExtResource( 4 )
[node name="rpm_meter" parent="chassis/cockpit" index="3"]
script = ExtResource( 5 )
needle_path = NodePath("rpm_needle")
[node name="speed_meter" parent="chassis/cockpit" index="4"]
script = ExtResource( 5 )
needle_path = NodePath("speed_needle")
[node name="steering_controller" parent="chassis/cockpit" index="5"]
transform = Transform( -5.15093, 0, -4.50309e-07, 0, 5.15093, 0, 4.50309e-07, 0, -5.15093, 0.591791, 0.882535, 1.0757 )
script = ExtResource( 6 )
[node name="rear_left" parent="." index="3"]
transform = Transform( 1, 0, 0, 0, 1, -1.50996e-07, 0, 1.50996e-07, 1, 0.621506, 0.375, -0.83483 )
use_as_traction = true
wheel_roll_influence = 0.01
wheel_radius = 0.38
wheel_rest_length = 0.3
wheel_friction_slip = 12.0
wheel_friction_slip = 2.0
suspension_travel = 0.3
suspension_stiffness = 12.0
suspension_max_force = 4000.0
damping_compression = 0.75
damping_relaxation = 0.8
@ -90,9 +111,10 @@ use_as_steering = true
wheel_roll_influence = 0.01
wheel_radius = 0.38
wheel_rest_length = 0.3
wheel_friction_slip = 10.0
wheel_friction_slip = 1.95
suspension_travel = 0.3
suspension_stiffness = 12.0
suspension_max_force = 4000.0
damping_compression = 0.75
damping_relaxation = 0.8
@ -102,9 +124,10 @@ use_as_steering = true
wheel_roll_influence = 0.01
wheel_radius = 0.38
wheel_rest_length = 0.3
wheel_friction_slip = 10.0
wheel_friction_slip = 1.95
suspension_travel = 0.3
suspension_stiffness = 12.0
suspension_max_force = 4000.0
damping_compression = 0.75
damping_relaxation = 0.8
@ -117,8 +140,8 @@ shape = SubResource( 11 )
[node name="engine_sound_player" type="AudioStreamPlayer3D" parent="." index="7"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.14201, 0.968668 )
stream = SubResource( 2 )
unit_db = 14.0
stream = ExtResource( 7 )
pitch_scale = 0.1
bus = "Sound"
[node name="Smoke" type="Particles" parent="." index="8"]
@ -139,3 +162,26 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.621508, 0.0502438, 1.19336
[node name="fl_tire_smoke" parent="." index="12" instance=ExtResource( 3 )]
transform = Transform( 1, 0, 0, 0, 1, -1.50996e-07, 0, 1.50996e-07, 1, 0.621506, 0.0502438, 1.19336 )
[node name="cockpit" type="Position3D" parent="." index="13"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.122976, 1.13133, 0.315432 )
[node name="hood" type="Position3D" parent="." index="14"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.01256, 0.87905 )
[node name="bumper" type="Position3D" parent="." index="15"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.535274, 1.89154 )
[node name="static_follow" type="Position3D" parent="." index="16"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.59115, -3.01375 )
[node name="wind_sound_player" type="AudioStreamPlayer3D" parent="." index="17"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.08447, 1.12391 )
stream = ExtResource( 8 )
[connection signal="brake_updated" from="." to="chassis/cockpit/brake_pedal" method="_on_value_updated"]
[connection signal="clutch_updated" from="." to="chassis/cockpit/clutch_pedal" method="_on_value_updated"]
[connection signal="rpm_updated" from="." to="chassis/cockpit/rpm_meter" method="_on_value_updated"]
[connection signal="speed_updated" from="." to="chassis/cockpit/speed_meter" method="_on_value_updated"]
[connection signal="steering_updated" from="." to="chassis/cockpit/steering_controller" method="_on_steering_updated"]
[connection signal="throttle_updated" from="." to="chassis/cockpit/gas_pedal" method="_on_value_updated"]

View File

@ -1,22 +1,21 @@
[gd_scene load_steps=13 format=2]
[gd_scene load_steps=16 format=2]
[ext_resource path="res://assets/basic_buggy.glb" type="PackedScene" id=1]
[ext_resource path="res://vehicles/tire_smoke.tscn" type="PackedScene" id=2]
[ext_resource path="res://vehicles/vehicle.gd" type="Script" id=3]
[ext_resource path="res://vehicles/steering_controller.gd" type="Script" id=4]
[ext_resource path="res://vehicles/meter.gd" type="Script" id=5]
[ext_resource path="res://assets/engine.wav" type="AudioStream" id=6]
[ext_resource path="res://vehicles/pedal.gd" type="Script" id=7]
[ext_resource path="res://assets/wind woosh loop.ogg" type="AudioStream" id=8]
[sub_resource type="Curve" id=2]
_data = [ Vector2( 0, 0 ), 0.0, 0.0, 0, 0, Vector2( 0.0660377, 0.243255 ), 0.0, 0.0, 0, 0, Vector2( 0.25, 0.563636 ), 4.02975, 4.02975, 0, 0, Vector2( 0.518868, 0.761364 ), 3.22818, 3.22818, 0, 0, Vector2( 0.849057, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 0 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="Curve" id=4]
_data = [ Vector2( 0, 0 ), 0.0, 0.0, 0, 0, Vector2( 0.0849057, 1 ), 0.0, 0.0, 0, 0, Vector2( 0.15566, 0.746591 ), 0.0, 0.0, 0, 0, Vector2( 0.349057, 1 ), 0.0, 0.0, 0, 0, Vector2( 0.382075, 0 ), 0.0, 0.0, 0, 0, Vector2( 0.400943, 1 ), 0.0, 0.0, 0, 0, Vector2( 0.438679, 0 ), 0.0, 0.0, 0, 0, Vector2( 1, 1 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CapsuleShape" id=11]
radius = 0.452181
height = 2.78888
[sub_resource type="AudioStreamGenerator" id=3]
mix_rate = 5500.0
[sub_resource type="Curve" id=8]
_data = [ Vector2( 0, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 0.205682 ), 0.0, 0.0, 0, 0 ]
@ -42,28 +41,54 @@ radial_segments = 4
rings = 3
[node name="buggy" groups=["car"] instance=ExtResource( 1 )]
mass = 400.0
mass = 1400.0
script = ExtResource( 3 )
max_steer_angle = 30.0
speed_steer_angle = 14.0
max_steer_speed = 120.0
max_engine_force = 160.0
max_brake_force = 80.0
max_engine_force = 550.0
max_brake_force = 220.0
throttle_power = 10000.0
max_rpm_loss_ps = 4000.0
base_engine_pitch = 0.45
drag_factor = 1.65
downforce_factor = 1.1
gear_ratios = [ 3.8, 2.7, 2.2, 1.75, 1.4, 1.2 ]
max_rpm = 5000.0
power_curve = SubResource( 2 )
sound_curve = SubResource( 4 )
automatic_gear_up_threshold = 0.85
automatic_gear_down_threshold = 0.4
[node name="brake_pedal" parent="chassis/cockpit" index="0"]
script = ExtResource( 7 )
[node name="clutch_pedal" parent="chassis/cockpit" index="1"]
script = ExtResource( 7 )
[node name="gas_pedal" parent="chassis/cockpit" index="2"]
script = ExtResource( 7 )
[node name="rpm_meter" parent="chassis/cockpit" index="3"]
transform = Transform( 1, 0, 0, 0, 0.351842, 0.93606, 0, -0.93606, 0.351842, 0.036114, 0.360487, 0.695986 )
script = ExtResource( 5 )
needle_path = NodePath("rpm_needle")
[node name="rpm_needle" parent="chassis/cockpit/rpm_meter" index="0"]
transform = Transform( 1, 0, 0, 0, 0.351842, -0.93606, 0, 0.93606, 0.351842, -0.000453245, 0.000504017, -0.00276601 )
[node name="speed_meter" parent="chassis/cockpit" index="4"]
script = ExtResource( 5 )
needle_path = NodePath("speed_needle")
[node name="speed_needle" parent="chassis/cockpit/speed_meter" index="0"]
transform = Transform( 1, 0, 0, 0, 0.351841, -0.93606, 0, 0.93606, 0.351841, -0.00056617, 0.000744879, -0.00399888 )
[node name="steering_controller" parent="chassis/cockpit" index="5"]
script = ExtResource( 4 )
[node name="front_left" parent="." index="1"]
use_as_traction = true
use_as_steering = true
wheel_radius = 0.6
wheel_rest_length = 0.68
wheel_friction_slip = 2.0
wheel_friction_slip = 2.25
suspension_travel = 1.2
suspension_stiffness = 4.5
suspension_max_force = 14000.0
@ -80,7 +105,7 @@ use_as_traction = true
use_as_steering = true
wheel_radius = 0.6
wheel_rest_length = 0.68
wheel_friction_slip = 2.0
wheel_friction_slip = 2.25
suspension_travel = 1.2
suspension_stiffness = 4.5
suspension_max_force = 14000.0
@ -94,7 +119,7 @@ transform = Transform( -1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )
use_as_traction = true
wheel_radius = 0.6
wheel_rest_length = 0.68
wheel_friction_slip = 1.9
wheel_friction_slip = 2.05
suspension_travel = 1.2
suspension_stiffness = 4.5
suspension_max_force = 14000.0
@ -106,7 +131,7 @@ transform = Transform( 1, 0, 0, 0, 1, -1.50996e-07, 0, 1.50996e-07, 1, -0.950755
use_as_traction = true
wheel_radius = 0.6
wheel_rest_length = 0.68
wheel_friction_slip = 1.9
wheel_friction_slip = 2.05
suspension_travel = 1.2
suspension_stiffness = 4.5
suspension_max_force = 14000.0
@ -117,9 +142,9 @@ damping_relaxation = 0.94
transform = Transform( -1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )
[node name="engine_sound_player" type="AudioStreamPlayer3D" parent="." index="7"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.14201, 0.968668 )
stream = SubResource( 3 )
unit_db = 14.0
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.14201, -1.46122 )
stream = ExtResource( 6 )
pitch_scale = 0.1
bus = "Sound"
[node name="Smoke" type="Particles" parent="." index="8"]
@ -139,3 +164,26 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.950753, -0.0380455, -1.41438
[node name="rr_tire_smoke" parent="." index="12" instance=ExtResource( 2 )]
transform = Transform( 1, 0, 0, 0, 1, -1.50996e-07, 0, 1.50996e-07, 1, -0.950755, -0.038045, -1.41438 )
[node name="cockpit" type="Position3D" parent="." index="13"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.44962, 0.200323 )
[node name="hood" type="Position3D" parent="." index="14"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.31056, 0.894584 )
[node name="bumper" type="Position3D" parent="." index="15"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.811448, 1.79879 )
[node name="static_follow" type="Position3D" parent="." index="16"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.15146, -4.84184 )
[node name="wind_sound_player" type="AudioStreamPlayer3D" parent="." index="17"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.39214, 1.12139 )
stream = ExtResource( 8 )
[connection signal="brake_updated" from="." to="chassis/cockpit/brake_pedal" method="_on_value_updated"]
[connection signal="clutch_updated" from="." to="chassis/cockpit/clutch_pedal" method="_on_value_updated"]
[connection signal="rpm_updated" from="." to="chassis/cockpit/rpm_meter" method="_on_value_updated"]
[connection signal="speed_updated" from="." to="chassis/cockpit/speed_meter" method="_on_value_updated"]
[connection signal="steering_updated" from="." to="chassis/cockpit/steering_controller" method="_on_steering_updated"]
[connection signal="throttle_updated" from="." to="chassis/cockpit/gas_pedal" method="_on_value_updated"]

View File

@ -1,22 +1,21 @@
[gd_scene load_steps=15 format=2]
[gd_scene load_steps=18 format=2]
[ext_resource path="res://vehicles/tire_smoke.tscn" type="PackedScene" id=1]
[ext_resource path="res://assets/bugmobile.glb" type="PackedScene" id=2]
[ext_resource path="res://vehicles/vehicle.gd" type="Script" id=3]
[ext_resource path="res://vehicles/steering_controller.gd" type="Script" id=4]
[ext_resource path="res://vehicles/pedal.gd" type="Script" id=5]
[ext_resource path="res://vehicles/meter.gd" type="Script" id=6]
[ext_resource path="res://assets/engine.wav" type="AudioStream" id=7]
[ext_resource path="res://assets/wind woosh loop.ogg" type="AudioStream" id=8]
[sub_resource type="Curve" id=18]
_data = [ Vector2( 0, 0 ), 0.0, 0.0, 0, 0, Vector2( 0.179245, 0.584091 ), 4.91185, 4.91185, 0, 0, Vector2( 0.603774, 0.954545 ), 6.05975, 6.05975, 0, 0, Vector2( 0.806604, 0.989773 ), 0.0, 0.0, 0, 0, Vector2( 1, 0 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="Curve" id=19]
_data = [ Vector2( 0, 0 ), 0.0, 0.0, 0, 0, Vector2( 0.127358, 1 ), 0.0, 0.0, 0, 0, Vector2( 0.174528, 0.65 ), 0.0, 0.0, 0, 0, Vector2( 0.212264, 1 ), 0.0, 0.0, 0, 0, Vector2( 0.353774, 0.35 ), 0.0, 0.0, 0, 0, Vector2( 0.363208, 0.968182 ), 0.0, 0.0, 0, 0, Vector2( 0.485849, 0.313636 ), 0.0, 0.0, 0, 0, Vector2( 0.627358, 0.140909 ), 0.0, 0.0, 0, 0, Vector2( 0.721698, 0.259091 ), 0.0, 0.0, 0, 0, Vector2( 0.745283, 0.623864 ), 0.0, 0.0, 0, 0, Vector2( 0.872642, 0.794318 ), 0.0, 0.0, 0, 0, Vector2( 0.915094, 0.248864 ), 0.0, 0.0, 0, 0, Vector2( 0.933962, 0.5125 ), 0.0, 0.0, 0, 0, Vector2( 1, 0 ), 0.0, 0.0, 0, 0 ]
[sub_resource type="CapsuleShape" id=20]
radius = 0.274866
height = 2.75974
[sub_resource type="AudioStreamGenerator" id=12]
mix_rate = 5500.0
[sub_resource type="Gradient" id=13]
offsets = PoolRealArray( 0, 0.5, 1 )
colors = PoolColorArray( 0, 0.278431, 0.270588, 1, 0.356863, 0.764706, 0.670588, 1, 1, 1, 1, 1 )
@ -50,53 +49,70 @@ radial_segments = 4
rings = 3
[node name="bugmobile" groups=["car"] instance=ExtResource( 2 )]
mass = 600.0
mass = 1900.0
script = ExtResource( 3 )
max_steer_angle = 16.0
speed_steer_angle = 8.0
max_steer_speed = 60.0
max_steer_input = 50.0
max_engine_force = 320.0
max_brake_force = 95.0
max_engine_force = 1400.0
max_brake_force = 230.0
throttle_power = 8000.0
max_rpm_loss_ps = 2200.0
base_engine_pitch = 0.65
drag_factor = 0.85
downforce_factor = 1.8
gear_ratios = [ 3.5, 2.95, 2.64, 2.0, 1.67, 1.42 ]
final_drive = 4.36
max_rpm = 9000.0
power_curve = SubResource( 18 )
sound_curve = SubResource( 19 )
[node name="rear_left" parent="." index="0"]
use_as_traction = true
wheel_radius = 0.52
wheel_rest_length = 0.47
wheel_friction_slip = 8.0
suspension_travel = 0.4
suspension_stiffness = 9.0
suspension_max_force = 7000.0
wheel_friction_slip = 5.54
suspension_travel = 0.35
suspension_stiffness = 12.0
suspension_max_force = 10000.0
damping_compression = 0.87
damping_relaxation = 0.9
[node name="front_left" parent="." index="2"]
use_as_steering = true
wheel_radius = 0.35
wheel_rest_length = 0.45
wheel_friction_slip = 7.0
suspension_travel = 0.45
suspension_stiffness = 12.0
suspension_max_force = 7000.0
wheel_rest_length = 0.47
wheel_friction_slip = 4.45
suspension_travel = 0.55
suspension_stiffness = 15.0
suspension_max_force = 15000.0
damping_compression = 0.9
damping_relaxation = 0.92
[node name="brake_pedal" parent="chassis/cockpit" index="0"]
script = ExtResource( 5 )
[node name="clutch_pedal" parent="chassis/cockpit" index="1"]
script = ExtResource( 5 )
[node name="gas_pedal" parent="chassis/cockpit" index="2"]
script = ExtResource( 5 )
[node name="steering_controller" parent="chassis/cockpit" index="3"]
script = ExtResource( 4 )
[node name="rpm_meter" parent="chassis/cockpit/steering_controller" index="0"]
script = ExtResource( 6 )
needle_path = NodePath("rpm_needle")
[node name="speed_meter" parent="chassis/cockpit/steering_controller" index="1"]
script = ExtResource( 6 )
needle_path = NodePath("speed_needle")
[node name="front_right" parent="." index="4"]
use_as_steering = true
wheel_radius = 0.35
wheel_rest_length = 0.45
wheel_friction_slip = 7.0
suspension_travel = 0.45
suspension_stiffness = 12.0
suspension_max_force = 7000.0
wheel_rest_length = 0.47
wheel_friction_slip = 4.45
suspension_travel = 0.55
suspension_stiffness = 15.0
suspension_max_force = 15000.0
damping_compression = 0.9
damping_relaxation = 0.92
@ -104,10 +120,10 @@ damping_relaxation = 0.92
use_as_traction = true
wheel_radius = 0.52
wheel_rest_length = 0.47
wheel_friction_slip = 8.0
suspension_travel = 0.4
suspension_stiffness = 9.0
suspension_max_force = 7000.0
wheel_friction_slip = 5.54
suspension_travel = 0.35
suspension_stiffness = 12.0
suspension_max_force = 10000.0
damping_compression = 0.87
damping_relaxation = 0.9
@ -117,8 +133,8 @@ shape = SubResource( 20 )
[node name="engine_sound_player" type="AudioStreamPlayer3D" parent="." index="7"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.791119, -2.27857 )
stream = SubResource( 12 )
unit_db = 14.0
stream = ExtResource( 7 )
pitch_scale = 0.1
bus = "Sound"
[node name="Smoke" type="Particles" parent="." index="8"]
@ -138,3 +154,26 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 1.18159, 0.117865, -1.93644 )
[node name="rr_tire_smoke" parent="." index="12" instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, -1.50996e-07, 0, 1.50996e-07, 1, -1.02536, 0.101852, -1.93766 )
[node name="cockpit" type="Position3D" parent="." index="13"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.03657, 0 )
[node name="hood" type="Position3D" parent="." index="14"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.00873, 0.756477 )
[node name="bumper" type="Position3D" parent="." index="15"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.605405, 1.5324 )
[node name="static_follow" type="Position3D" parent="." index="16"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.88984, -4.78212 )
[node name="wind_sound_player" type="AudioStreamPlayer3D" parent="." index="17"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.18462, 0.791153 )
stream = ExtResource( 8 )
[connection signal="brake_updated" from="." to="chassis/cockpit/brake_pedal" method="_on_value_updated"]
[connection signal="clutch_updated" from="." to="chassis/cockpit/clutch_pedal" method="_on_value_updated"]
[connection signal="rpm_updated" from="." to="chassis/cockpit/steering_controller/rpm_meter" method="_on_value_updated"]
[connection signal="speed_updated" from="." to="chassis/cockpit/steering_controller/speed_meter" method="_on_value_updated"]
[connection signal="steering_updated" from="." to="chassis/cockpit/steering_controller" method="_on_steering_updated"]
[connection signal="throttle_updated" from="." to="chassis/cockpit/gas_pedal" method="_on_value_updated"]

12
vehicles/meter.gd 100644
View File

@ -0,0 +1,12 @@
extends MeshInstance
export(float) var min_angle = -90
export(float) var max_angle = 90
export(NodePath) var needle_path = null
func _on_value_updated(_value: int, value_percent: float) -> void:
get_node(needle_path).rotation.y = -(
deg2rad(min_angle)
+ value_percent * deg2rad(max_angle - min_angle)
)

View File

@ -0,0 +1,8 @@
extends MeshInstance
export(float) var min_angle = 0
export(float) var max_angle = 45
func _on_value_updated(value_percent: float) -> void:
rotation.x = -(deg2rad(min_angle) + value_percent * deg2rad(max_angle - min_angle))

View File

@ -0,0 +1,11 @@
extends MeshInstance
export(float) var max_steer_angle = 90
func update_angle(steering_angle_percent: float) -> void:
rotation.z = deg2rad(max_steer_angle) * steering_angle_percent
func _on_steering_updated(_steering_angle: float, steering_angle_percent: float) -> void:
update_angle(steering_angle_percent)

View File

@ -7,24 +7,19 @@ onready var sound_playback: AudioStreamPlayback = $tire_sound_player.get_stream_
func _ready() -> void:
_update_sound(1)
# sound_player.play()
sound_player.playing = true
sound_player.stream_paused = true
func update(skidinfo: float) -> void:
_update_sound(skidinfo)
if skidinfo < 0.5:
if skidinfo < 0.25:
emitting = true
sound_player.stream_paused = false
else:
emitting = false
sound_player.stream_paused = true
func _update_sound(skidinfo: float) -> void:
sound_player.pitch_scale = 1 + (1 - skidinfo)
var to_fill = sound_playback.get_frames_available()
var factor = (1 - skidinfo) * 2
if to_fill <= 0:
return
while to_fill > 0:
sound_playback.push_frame(Vector2(1.0, 1.0) * factor)
factor += 1
to_fill -= 1
sound_player.pitch_scale = 1 + pow(skidinfo, 2) - skidinfo / 3

View File

@ -1,6 +1,7 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://vehicles/tire_smoke.gd" type="Script" id=1]
[ext_resource path="res://assets/tires_squal_loop.wav" type="AudioStream" id=2]
[sub_resource type="Curve" id=1]
_data = [ Vector2( 0, 1 ), 0.0, 0.0, 0, 0, Vector2( 1, 0.0170454 ), 0.0, 0.0, 0, 0 ]
@ -25,9 +26,6 @@ material = SubResource( 4 )
radial_segments = 4
rings = 4
[sub_resource type="AudioStreamGenerator" id=6]
mix_rate = 5500.0
[node name="tire_smoke" type="Particles"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.541801, 0 )
emitting = false
@ -39,8 +37,7 @@ draw_pass_1 = SubResource( 5 )
script = ExtResource( 1 )
[node name="tire_sound_player" type="AudioStreamPlayer3D" parent="."]
stream = SubResource( 6 )
unit_db = 25.0
unit_size = 2.0
stream = ExtResource( 2 )
max_db = 1.0
bus = "Sound"
area_mask = 2

View File

@ -3,12 +3,16 @@ extends VehicleBody
signal speed_updated(speed_kph, speed_percent)
signal rpm_updated(rpm, rpm_percent)
signal throttle_updated(throttle_percent)
signal brake_updated(brake_percent)
signal clutch_updated(clutch_percent)
signal gear_updated(gear)
signal steering_updated(steering_angle, steering_percent)
signal position_updated(player_id, position)
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
enum GearRequest { NONE, UP, DOWN }
export(float) var max_steer_input = 30
export(float) var max_engine_force = 85.0
export(float) var max_brake_force = 50.0
@ -17,6 +21,9 @@ 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 drag_factor = 1.0
export(float) var downforce_factor = 1.0
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
@ -38,6 +45,8 @@ var gear_timer = 0
var traction_wheels: Array
var reset_transform: Transform = Transform.IDENTITY
var inputs: VehicleInputs = VehicleInputs.new()
onready var frwheel: VehicleWheel = $front_right
onready var flwheel: VehicleWheel = $front_left
onready var rrwheel: VehicleWheel = $rear_right
@ -48,15 +57,34 @@ onready var rrsmoke: TireSmoke = $rr_tire_smoke
onready var rlsmoke: TireSmoke = $rl_tire_smoke
onready var engine_sound_player: AudioStreamPlayer3D = $engine_sound_player
onready var engine_sound_playback: AudioStreamPlayback = $engine_sound_player.get_stream_playback()
onready var wind_sound_player: AudioStreamPlayer3D = $wind_sound_player
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)
onready var auto_clutch_rpm_limit = max_rpm * automatic_gear_down_threshold
class VehicleInputs:
var gear_request = GearRequest.NONE
var clutch = 0.0
var throttle = 0.0
var brake = 0.0
var handbrake = 0.0
# Left is positive, right is negative
var steering = 0.0
func to_array() -> Array:
return [gear_request, clutch, throttle, brake, handbrake, steering]
func from_array(array: Array) -> void:
gear_request = array[0]
clutch = array[1]
throttle = array[2]
brake = array[3]
handbrake = array[4]
steering = array[5]
func _ready():
for wheel in [frwheel, flwheel, rrwheel, rlwheel]:
if wheel.use_as_traction:
@ -64,6 +92,23 @@ func _ready():
_generate_engine_sound(0)
engine_sound_player.play()
wind_sound_player.play()
func get_cockpit_position() -> Node:
return $cockpit
func get_hood_position() -> Node:
return $hood
func get_bumper_position() -> Node:
return $bumper
func get_static_follow_position() -> Node:
return $static_follow
func _integrate_forces(state: PhysicsDirectBodyState) -> void:
@ -87,10 +132,11 @@ func _handle_gear_switch(delta: float):
if gear_timer > 0:
gear_timer = max(0, gear_timer - delta)
if clutch_position > 0.8 or GlobalSettings.auto_clutch or GlobalSettings.automatic_transmission:
if Input.is_action_just_pressed("gear_up"):
_gear_up()
if Input.is_action_just_pressed("gear_down"):
_gear_down()
match inputs.gear_request:
GearRequest.UP:
_gear_up()
GearRequest.DOWN:
_gear_down()
func _gear_up():
@ -133,10 +179,10 @@ func _lerp_rpm(from, to, delta, factor):
func _physics_process(delta: float):
_update_wheels_smoke()
clutch_position = Input.get_action_strength("clutch")
clutch_position = inputs.clutch
_handle_gear_switch(delta)
var throttle = Input.get_action_strength("throttle")
var brake_input = Input.get_action_strength("brake")
var throttle = inputs.throttle
var brake_input = inputs.brake
var wheel_rpm = traction_wheels[0].get_rpm()
var speed = wheel_rpm * 2.0 * PI * rrwheel.wheel_radius / 60.0 * 3600.0 / 1000.0
@ -156,6 +202,13 @@ func _physics_process(delta: float):
if GlobalSettings.auto_clutch or GlobalSettings.automatic_transmission:
clutch_position = 1 - min(rpm, auto_clutch_rpm_limit) / auto_clutch_rpm_limit
if throttle == 0.0 and linear_velocity.length() < 1:
clutch_position = 1
apply_central_impulse(linear_velocity * -1 * drag_factor)
apply_central_impulse(
linear_velocity.length() * -1 * global_transform.basis.y * downforce_factor
)
if gear_timer > 0:
clutch_position = 1
@ -178,16 +231,20 @@ func _physics_process(delta: float):
var power_factor = power_curve.interpolate_baked(rpm_factor)
_generate_engine_sound(rpm_factor)
_generate_wind_sound(speed)
# Transfer to transmission
var transmission_input = power_factor * (1 - clutch_position) * _get_gear_ratio()
var final_input = transmission_input * final_drive
emit_signal("throttle_updated", throttle)
emit_signal("brake_updated", brake_input)
emit_signal("clutch_updated", clutch_position)
brake = brake_input * max_brake_force
engine_force = throttle * final_input * max_engine_force
var handbrake = Input.get_action_strength("handbrake")
var handbrake = inputs.handbrake
rrwheel.brake = handbrake * max_brake_force
rlwheel.brake = handbrake * max_brake_force
@ -200,33 +257,37 @@ 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")
)
if abs(steering_input) < 0.05:
steering_input = 0.0
var steering_input = inputs.steering * max_steer_input_rad
var steer_speed_factor = clamp(speed / max_steer_speed, 0.0, 1.0)
steering = clamp(steering_input, -max_steer_input_rad, max_steer_input_rad)
emit_signal("steering_updated", steering, steering / max_steer_input_rad)
steering = steering_input * lerp(max_steer_angle_rad, speed_steer_angle_rad, steer_speed_factor)
emit_signal("position_updated", get_network_master(), global_transform)
if MultiplayerController.is_online():
if get_network_master() == get_tree().get_network_unique_id():
_synchronize()
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()
var factor = rpm_factor
if to_fill <= 0:
return
var fill_segment = 1.0 / to_fill
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)
)
to_fill -= 1
fill_percent += fill_segment
engine_sound_player.unit_db = 1 + 2 * rpm_factor
func _generate_wind_sound(speed):
wind_sound_player.pitch_scale = 1 + speed / 150
wind_sound_player.unit_db = pow(speed, 2) / 1500 * (0.5 + drag_factor) - 20
func _synchronize():
rpc("sync_position", transform)
rpc("sync_inputs", inputs.to_array())
remote func sync_position(position: Transform):
reset_transform = position
emit_signal("position_updated", get_network_master(), global_transform)
remote func sync_inputs(remote_inputs):
inputs.from_array(remote_inputs)