commit f8ffcbb6be9feb3d0ca3fff78c5b859c6811265a Author: ObeseTermite Date: Sat Mar 14 12:08:16 2026 -0700 Initial commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f28239b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +charset = utf-8 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0af181c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Godot 4+ specific ignores +.godot/ +/android/ diff --git a/Cart/cart.gd b/Cart/cart.gd new file mode 100644 index 0000000..51e9398 --- /dev/null +++ b/Cart/cart.gd @@ -0,0 +1,25 @@ +extends Node2D +class_name Cart + +@export var spline : Spline + + +var going = false +var progress = 0 + +func _ready(): + hide() + +func _process(delta: float) -> void: + if len(spline.curve_points) > 1: + position = spline.curve_points[progress] + rotation = (spline.curve_points[progress+1] - position).angle() + + if not going: + return + + progress += 1 + if progress >= len(spline.curve_points)-1: + going = false + hide() + progress = 0 diff --git a/Cart/cart.gd.uid b/Cart/cart.gd.uid new file mode 100644 index 0000000..5334350 --- /dev/null +++ b/Cart/cart.gd.uid @@ -0,0 +1 @@ +uid://jrmwg6neheh5 diff --git a/Cart/cart.tscn b/Cart/cart.tscn new file mode 100644 index 0000000..6a9b2c4 --- /dev/null +++ b/Cart/cart.tscn @@ -0,0 +1,12 @@ +[gd_scene format=3 uid="uid://pdmq2mjt8uxg"] + +[ext_resource type="Script" uid="uid://jrmwg6neheh5" path="res://Cart/cart.gd" id="1_amo0v"] +[ext_resource type="Texture2D" uid="uid://xcgu5k1v41tq" path="res://cart.png" id="2_f3qtc"] + +[node name="Cart" type="Node2D" unique_id=800624852] +script = ExtResource("1_amo0v") + +[node name="Cart Sprite" type="Sprite2D" parent="." unique_id=1281407851] +scale = Vector2(0.1, 0.1) +texture = ExtResource("2_f3qtc") +offset = Vector2(0, -165) diff --git a/Splines/spline.gd b/Splines/spline.gd new file mode 100644 index 0000000..8ac29eb --- /dev/null +++ b/Splines/spline.gd @@ -0,0 +1,7 @@ +extends Node2D + +class_name Spline + +var points : PackedVector2Array + +var curve_points : PackedVector2Array diff --git a/Splines/spline.gd.uid b/Splines/spline.gd.uid new file mode 100644 index 0000000..16be4cc --- /dev/null +++ b/Splines/spline.gd.uid @@ -0,0 +1 @@ +uid://k0tl2g83mr6s diff --git a/Splines/spline.tscn b/Splines/spline.tscn new file mode 100644 index 0000000..bc5a963 --- /dev/null +++ b/Splines/spline.tscn @@ -0,0 +1,6 @@ +[gd_scene format=3 uid="uid://cbh3fab2u11vg"] + +[ext_resource type="Script" uid="uid://k0tl2g83mr6s" path="res://Splines/spline.gd" id="1_2cbjp"] + +[node name="Spline" type="Node2D" unique_id=1036543531] +script = ExtResource("1_2cbjp") diff --git a/UI/Spline Editor/control_point.gd b/UI/Spline Editor/control_point.gd new file mode 100644 index 0000000..505fa84 --- /dev/null +++ b/UI/Spline Editor/control_point.gd @@ -0,0 +1,24 @@ +extends Button + +class_name ControlPoint + +var locked : bool = false + +func _draw(): + draw_circle(size/2, 5, Color.DIM_GRAY, true, -1, true) + draw_circle(size/2, 5, Color.WHITE, false, 1, true) + +func get_represented_position() -> Vector2: + return position + size/2 + +func set_represented_position(new_position : Vector2): + position = new_position - size/2 + + var parent = get_parent() + if parent != null: + parent.update() + + +func _process(delta: float) -> void: + if button_pressed: + set_represented_position(get_global_mouse_position()) diff --git a/UI/Spline Editor/control_point.gd.uid b/UI/Spline Editor/control_point.gd.uid new file mode 100644 index 0000000..fa6650a --- /dev/null +++ b/UI/Spline Editor/control_point.gd.uid @@ -0,0 +1 @@ +uid://bpx1v5s2m4ept diff --git a/UI/Spline Editor/control_point.tscn b/UI/Spline Editor/control_point.tscn new file mode 100644 index 0000000..754c79a --- /dev/null +++ b/UI/Spline Editor/control_point.tscn @@ -0,0 +1,11 @@ +[gd_scene format=3 uid="uid://di4jvhvyqtusq"] + +[ext_resource type="Script" uid="uid://bpx1v5s2m4ept" path="res://UI/Spline Editor/control_point.gd" id="1_ottbd"] + +[node name="Control Point" type="Button" unique_id=1542646560] +custom_minimum_size = Vector2(10, 10) +offset_right = 50.0 +offset_bottom = 50.0 +focus_mode = 0 +flat = true +script = ExtResource("1_ottbd") diff --git a/UI/Spline Editor/spline_editor.gd b/UI/Spline Editor/spline_editor.gd new file mode 100644 index 0000000..0bb2896 --- /dev/null +++ b/UI/Spline Editor/spline_editor.gd @@ -0,0 +1,71 @@ +extends Control + +@export var spline : Spline +@export var cart : Cart +@export var control_point_scene : PackedScene + +@export var steps : int = 10 + +var editing = true + +func _ready() -> void: + pass + + +func _draw(): + if editing: + for i in range(len(spline.points)-1): + draw_line(spline.points[i], spline.points[i+1], Color.DIM_GRAY, 1, true) + + if len(spline.curve_points) > 2: + draw_polyline(spline.curve_points, Color.WHITE, 3, true) + +func _process(delta: float) -> void: + if not editing: + return + + if Input.is_action_just_pressed("add_new_point"): + var new_control_point : ControlPoint = control_point_scene.instantiate() + new_control_point.set_represented_position(get_global_mouse_position()) + add_child(new_control_point) + update() + +func update(): + spline.points = [] + for child in get_children(): + if not child is ControlPoint: + continue + spline.points.append(child.get_represented_position()) + + spline.curve_points = [] + for i in range(len(spline.points)-3): + var b0 : Vector2 = spline.points[i] + var b1 : Vector2 = spline.points[i+1] + var b2 : Vector2 = spline.points[i+2] + var b3 : Vector2 = spline.points[i+3] + + var t : float = 0 + while t < 0.99: + # B-spline calculations + var calculated_position =\ + ((-b0+3*b1-3*b2+b3)*(t**3) +\ + (3*b0-6*b1+3*b2)*(t**2) +\ + (-3*b0+3*b2)*t +\ + (b0+4*b1+b2))/6 + spline.curve_points.append(calculated_position) + t += 0.1 + queue_redraw() + + +func _on_check_button_toggled(toggled_on: bool) -> void: + editing = toggled_on + for child in get_children(): + if not child is ControlPoint: + continue + child.visible = editing + update() + + +func _on_start_pressed() -> void: + cart.going = true + cart.show() diff --git a/UI/Spline Editor/spline_editor.gd.uid b/UI/Spline Editor/spline_editor.gd.uid new file mode 100644 index 0000000..e1e95cc --- /dev/null +++ b/UI/Spline Editor/spline_editor.gd.uid @@ -0,0 +1 @@ +uid://dttjp7o66ghn4 diff --git a/UI/Spline Editor/spline_editor.tscn b/UI/Spline Editor/spline_editor.tscn new file mode 100644 index 0000000..8582ec8 --- /dev/null +++ b/UI/Spline Editor/spline_editor.tscn @@ -0,0 +1,40 @@ +[gd_scene format=3 uid="uid://curwvxlv5wr2s"] + +[ext_resource type="Script" uid="uid://dttjp7o66ghn4" path="res://UI/Spline Editor/spline_editor.gd" id="1_ahlr6"] +[ext_resource type="PackedScene" uid="uid://di4jvhvyqtusq" path="res://UI/Spline Editor/control_point.tscn" id="2_td7mw"] + +[sub_resource type="InputEventKey" id="InputEventKey_td7mw"] +device = -1 +keycode = 69 +unicode = 101 + +[sub_resource type="Shortcut" id="Shortcut_j0rrm"] +events = [SubResource("InputEventKey_td7mw")] + +[node name="Spline Editor" type="Control" unique_id=1591101939] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_ahlr6") +control_point_scene = ExtResource("2_td7mw") + +[node name="HBoxContainer" type="HBoxContainer" parent="." unique_id=836867708] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 + +[node name="Start" type="Button" parent="HBoxContainer" unique_id=767033586] +layout_mode = 2 +text = "Start Roller Coaster" + +[node name="CheckButton" type="CheckButton" parent="HBoxContainer" unique_id=1422024819] +layout_mode = 2 +button_pressed = true +shortcut = SubResource("Shortcut_j0rrm") +text = "Editing" + +[connection signal="pressed" from="HBoxContainer/Start" to="." method="_on_start_pressed"] +[connection signal="toggled" from="HBoxContainer/CheckButton" to="." method="_on_check_button_toggled"] diff --git a/cart.png b/cart.png new file mode 100644 index 0000000..e9bda16 Binary files /dev/null and b/cart.png differ diff --git a/cart.png.import b/cart.png.import new file mode 100644 index 0000000..c9dd1f8 --- /dev/null +++ b/cart.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://xcgu5k1v41tq" +path="res://.godot/imported/cart.png-c0d5895155eac46d26ac9947ca1d6fe3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://cart.png" +dest_files=["res://.godot/imported/cart.png-c0d5895155eac46d26ac9947ca1d6fe3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..c6bbb7d --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + diff --git a/icon.svg.import b/icon.svg.import new file mode 100644 index 0000000..c61b218 --- /dev/null +++ b/icon.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dg3obuh047f7w" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/main_scene.tscn b/main_scene.tscn new file mode 100644 index 0000000..e57b31f --- /dev/null +++ b/main_scene.tscn @@ -0,0 +1,16 @@ +[gd_scene format=3 uid="uid://bgwqqwit2n52j"] + +[ext_resource type="PackedScene" uid="uid://cbh3fab2u11vg" path="res://Splines/spline.tscn" id="1_2c62f"] +[ext_resource type="PackedScene" uid="uid://curwvxlv5wr2s" path="res://UI/Spline Editor/spline_editor.tscn" id="2_gyfs4"] +[ext_resource type="PackedScene" uid="uid://pdmq2mjt8uxg" path="res://Cart/cart.tscn" id="3_gyfs4"] + +[node name="Main Scene" type="Node2D" unique_id=1730722189] + +[node name="Spline" parent="." unique_id=1036543531 instance=ExtResource("1_2c62f")] + +[node name="Spline Editor" parent="." unique_id=1591101939 node_paths=PackedStringArray("spline", "cart") instance=ExtResource("2_gyfs4")] +spline = NodePath("../Spline") +cart = NodePath("../Cart") + +[node name="Cart" parent="." unique_id=800624852 node_paths=PackedStringArray("spline") instance=ExtResource("3_gyfs4")] +spline = NodePath("../Spline") diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..388a6bc --- /dev/null +++ b/project.godot @@ -0,0 +1,39 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Rollercoaster Derivatives" +run/main_scene="uid://bgwqqwit2n52j" +config/features=PackedStringArray("4.6", "GL Compatibility") +config/icon="res://icon.svg" + +[display] + +window/stretch/mode="canvas_items" +window/stretch/aspect="expand" + +[input] + +add_new_point={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} + +[physics] + +3d/physics_engine="Jolt Physics" + +[rendering] + +rendering_device/driver.windows="d3d12" +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility"