Initial commit

This commit is contained in:
ObeseTermite 2026-03-14 12:08:16 -07:00
commit f8ffcbb6be
21 changed files with 348 additions and 0 deletions

4
.editorconfig Normal file
View file

@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/

25
Cart/cart.gd Normal file
View file

@ -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

1
Cart/cart.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://jrmwg6neheh5

12
Cart/cart.tscn Normal file
View file

@ -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)

7
Splines/spline.gd Normal file
View file

@ -0,0 +1,7 @@
extends Node2D
class_name Spline
var points : PackedVector2Array
var curve_points : PackedVector2Array

1
Splines/spline.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://k0tl2g83mr6s

6
Splines/spline.tscn Normal file
View file

@ -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")

View file

@ -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())

View file

@ -0,0 +1 @@
uid://bpx1v5s2m4ept

View file

@ -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")

View file

@ -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()

View file

@ -0,0 +1 @@
uid://dttjp7o66ghn4

View file

@ -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"]

BIN
cart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

40
cart.png.import Normal file
View file

@ -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

1
icon.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>

After

Width:  |  Height:  |  Size: 995 B

43
icon.svg.import Normal file
View file

@ -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

16
main_scene.tscn Normal file
View file

@ -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")

39
project.godot Normal file
View file

@ -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"