Initial commit (release)

This commit is contained in:
2026-02-08 12:20:45 -03:00
commit 1497a225cc
51 changed files with 1618 additions and 0 deletions

8
src/game/basic.gdshader Normal file
View File

@@ -0,0 +1,8 @@
shader_type spatial;
uniform sampler2D texture_image : source_color;
uniform vec3 tint : source_color = vec3(1, 1, 1);
void fragment() {
ALBEDO = texture(texture_image, UV).rgb * tint.rgb;
}

View File

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

View File

@@ -0,0 +1,8 @@
[gd_resource type="ShaderMaterial" format=3 uid="uid://b6qswdhurj1l6"]
[ext_resource type="Shader" uid="uid://bvemv1371ggkd" path="res://src/game/basic.gdshader" id="1_mml0d"]
[resource]
render_priority = 0
shader = ExtResource("1_mml0d")
shader_parameter/tint = Color(1, 0.81666666, 0, 1)

120
src/game/game.gd Normal file
View File

@@ -0,0 +1,120 @@
extends Node3D
enum TutorialStep {
PRESS_J,
PRESS_D,
DONE,
}
@export var _ui_layer: CanvasLayer
@export var _press_d_prompt: Node3D
@export var _press_j_prompt: Node3D
@export var _d_anim: AnimationPlayer
@export var _d_button: Node3D
@export var _j_anim: AnimationPlayer
@export var _j_button: Node3D
@onready var _d_button_anim: AnimationPlayer = _d_button.get_node("AnimationPlayer")
@onready var _j_button_anim: AnimationPlayer = _j_button.get_node("AnimationPlayer")
var _tutorial_step := TutorialStep.PRESS_J
func _ready() -> void:
_press_d_prompt.hide()
_press_j_prompt.hide()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("d_act"):
_d_anim.play("press")
_d_button_anim.play("press")
_crusher_deactivate()
return
if event.is_action_pressed("j_act"):
_j_anim.play("press")
_j_button_anim.play("press")
_crusher_activate()
return
func _physics_process(_delta: float) -> void:
if _tutorial_step != TutorialStep.DONE:
match _tutorial_step:
TutorialStep.PRESS_J:
if _crusher_is_active:
_tutorial_step = (_tutorial_step + 1) as TutorialStep
else:
_press_d_prompt.hide()
_press_j_prompt.show()
TutorialStep.PRESS_D:
if not _crusher_is_active:
_tutorial_step = (_tutorial_step + 1) as TutorialStep
else:
_press_d_prompt.show()
_press_j_prompt.hide()
# was set in one of the match cases
if _tutorial_step == TutorialStep.DONE:
_ui_layer.hide()
_press_d_prompt.hide()
_press_j_prompt.hide()
_ghost_spawn_timer.start()
#region Ghosts
@export var _ghost_spawn_timer: Timer
@export var _ghost_scene: PackedScene
func _on_ghost_spawn_timer_timeout() -> void:
var ghost: Node3D = _ghost_scene.instantiate()
add_child(ghost)
ghost.position = Vector3(randf_range(-1, 1), -4, 0)
_ghost_spawn_timer.wait_time = randf_range(0.3, 1.3)
#endregion
#region Crusher
@export var _crusher: Node3D
@export var _slam_sfx: AudioStreamPlayer3D
@export var _splat_sfx: AudioStreamPlayer3D
@export var _crusher_anim: AnimationPlayer
@onready var _crush_range_start = _crusher.position.y + 1.8
@onready var _crush_range_end = _crusher.position.y + -1.4
# can't reactivate until deactivated, and vice versa
var _crusher_is_active := false
func _crusher_activate() -> void:
if _crusher_anim.is_playing() or _crusher_is_active:
return
_crusher_is_active = true
_crusher_anim.play("crush")
func _crusher_deactivate() -> void:
if _crusher_anim.is_playing() or not _crusher_is_active:
return
_crusher_is_active = false
_crusher_anim.play("uncrush")
func crusher_crush() -> void:
var ghosts := get_tree().get_nodes_in_group("ghosts")
var crushed_any := false
for ghost: Ghost in ghosts:
if ghost.is_crushed:
continue
if ghost.position.y > _crush_range_start or ghost.position.y < _crush_range_end:
continue
ghost.crush(0)
crushed_any = true
_slam_sfx.play()
if crushed_any:
_splat_sfx.play()
#endregion

1
src/game/game.gd.uid Normal file
View File

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

646
src/game/game.tscn Normal file
View File

@@ -0,0 +1,646 @@
[gd_scene format=3 uid="uid://0t1khpumpjk6"]
[ext_resource type="Script" uid="uid://cagqlqi6ahncv" path="res://src/game/game.gd" id="1_s6lek"]
[ext_resource type="Material" uid="uid://b6qswdhurj1l6" path="res://src/game/basic_untinted_material.tres" id="2_kgj8g"]
[ext_resource type="PackedScene" uid="uid://sdd62ogittlq" path="res://src/game/ghost.tscn" id="2_l80un"]
[ext_resource type="Material" uid="uid://di0etogxlb5dq" path="res://src/game/wall_material.tres" id="2_s6lek"]
[ext_resource type="AudioStream" uid="uid://bj2ksich3ki3b" path="res://assets/fandanguillo-de-almeria-la-argentinita.ogg" id="3_htx8b"]
[ext_resource type="FontFile" uid="uid://dsnbywa4hscr0" path="res://assets/the-nautigal.ttf" id="4_etvrb"]
[ext_resource type="PackedScene" uid="uid://fbqbcvko5rla" path="res://assets/button.glb" id="4_xptat"]
[ext_resource type="AudioStream" uid="uid://l3eewf8v21rl" path="res://assets/button.wav" id="5_6kr85"]
[ext_resource type="AudioStream" uid="uid://c1stp6572r2qg" path="res://assets/slam.wav" id="6_jhw8o"]
[ext_resource type="PackedScene" uid="uid://cwtmdaxfjpek5" path="res://assets/arrow.glb" id="6_yarin"]
[ext_resource type="AudioStream" uid="uid://g5227ljhgxba" path="res://assets/in.wav" id="7_7r0dx"]
[ext_resource type="AudioStream" uid="uid://d2fttu4hq27nb" path="res://assets/splat.wav" id="7_n7s5x"]
[ext_resource type="AudioStream" uid="uid://cb2cly1p33pue" path="res://assets/out.wav" id="8_htx8b"]
[ext_resource type="FontFile" uid="uid://c4p2j3cqdcx8x" path="res://assets/rhodium-libre.ttf" id="12_ueio8"]
[sub_resource type="Environment" id="Environment_jn5yv"]
background_mode = 1
ambient_light_source = 1
reflected_light_source = 1
[sub_resource type="Animation" id="Animation_clwl7"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:light_energy")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [3.0]
}
[sub_resource type="Animation" id="Animation_7r0dx"]
resource_name = "flicker"
length = 0.8
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:light_energy")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.4),
"transitions": PackedFloat32Array(0.5, 1),
"update": 0,
"values": [3.0, 5.0]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_htx8b"]
_data = {
&"RESET": SubResource("Animation_clwl7"),
&"flicker": SubResource("Animation_7r0dx")
}
[sub_resource type="CylinderMesh" id="CylinderMesh_s6lek"]
top_radius = 1.0
radial_segments = 6
rings = 0
[sub_resource type="PlaneMesh" id="PlaneMesh_qnjlk"]
material = ExtResource("2_s6lek")
size = Vector2(15, 15)
[sub_resource type="Animation" id="Animation_jhw8o"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Hand:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(-0.4000001, -0.100000024, 0.30000004)]
}
[sub_resource type="Animation" id="Animation_yarin"]
resource_name = "press"
length = 0.1667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Hand:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.033333335, 0.16666667),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(-0.4000001, -0.100000024, 0.30000004), Vector3(-0.4000001, -0.30000007, 0.30000004), Vector3(-0.4000001, -0.100000024, 0.30000004)]
}
tracks/1/type = "audio"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Button/ButtonSfx")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.0,
"stream": ExtResource("5_6kr85")
}],
"times": PackedFloat32Array(0.033333335)
}
tracks/1/use_blend = true
[sub_resource type="AnimationLibrary" id="AnimationLibrary_jhw8o"]
_data = {
&"RESET": SubResource("Animation_jhw8o"),
&"press": SubResource("Animation_yarin")
}
[sub_resource type="SphereMesh" id="SphereMesh_kgj8g"]
lightmap_size_hint = Vector2i(14, 8)
material = ExtResource("2_kgj8g")
radius = 0.4
height = 0.8
radial_segments = 8
rings = 6
[sub_resource type="Gradient" id="Gradient_s6lek"]
interpolation_mode = 1
offsets = PackedFloat32Array(0, 0.6)
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_kgj8g"]
gradient = SubResource("Gradient_s6lek")
width = 8
height = 16
fill = 1
fill_from = Vector2(0.5, 0.5)
[sub_resource type="SphereMesh" id="SphereMesh_l80un"]
material = ExtResource("2_kgj8g")
radius = 0.1
height = 0.2
radial_segments = 8
rings = 6
[sub_resource type="Animation" id="Animation_6kr85"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Hand:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0.4, -0.1, 0.3)]
}
[sub_resource type="Animation" id="Animation_n7s5x"]
resource_name = "press"
length = 0.1667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Hand:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.033333335, 0.16666667),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(0.4, -0.1, 0.3), Vector3(0.4000001, -0.30000007, 0.3), Vector3(0.4, -0.1, 0.3)]
}
tracks/1/type = "audio"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Button/ButtonSfx")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.0,
"stream": ExtResource("5_6kr85")
}],
"times": PackedFloat32Array(0.033333335)
}
tracks/1/use_blend = true
[sub_resource type="AnimationLibrary" id="AnimationLibrary_6kr85"]
_data = {
&"RESET": SubResource("Animation_6kr85"),
&"press": SubResource("Animation_n7s5x")
}
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_jhw8o"]
random_pitch = 1.122462
streams_count = 1
stream_0/stream = ExtResource("7_n7s5x")
[sub_resource type="Animation" id="Animation_l80un"]
length = 0.001
tracks/0/type = "position_3d"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("TubeLeft")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, -10, 0, 0)
tracks/1/type = "position_3d"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("TubeRight")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = PackedFloat32Array(0, 1, 10, 0, 0)
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("TubeLeft:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(-10, 0, 0)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("TubeRight:position")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(10, 0, 0)]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("TubeLeft/MashyPlate:scale")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(1, 1, 1)]
}
tracks/5/type = "value"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("TubeRight/MashyPlate:scale")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(1, 1, 1)]
}
[sub_resource type="Animation" id="Animation_s6lek"]
resource_name = "crush"
length = 0.13333334
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("TubeLeft:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.0666, 0.13333334),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(-10, 0, 0), Vector3(-4.157, 0, 0), Vector3(-4.19, 0, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("TubeRight:position")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.0666, 0.13333334),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(10, 0, 0), Vector3(4.15, 0, 0), Vector3(4.2, 0, 0)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("TubeLeft/MashyPlate:scale")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.06666667, 0.13333334),
"transitions": PackedFloat32Array(0, 1, 1),
"update": 0,
"values": [Vector3(1, 1, 1), Vector3(0.6, 1.4, 1), Vector3(1, 1, 1)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("TubeRight/MashyPlate:scale")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 0.06666667, 0.13333334),
"transitions": PackedFloat32Array(0, 1, 1),
"update": 0,
"values": [Vector3(1, 1, 1), Vector3(0.6, 1.4, 1), Vector3(1, 1, 1)]
}
tracks/4/type = "method"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("..")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0.06666667),
"transitions": PackedFloat32Array(1),
"values": [{
"args": [],
"method": &"crusher_crush"
}]
}
tracks/5/type = "audio"
tracks/5/imported = false
tracks/5/enabled = true
tracks/5/path = NodePath("MoveSfx")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.0,
"stream": ExtResource("7_7r0dx")
}],
"times": PackedFloat32Array(0)
}
tracks/5/use_blend = true
[sub_resource type="Animation" id="Animation_kgj8g"]
resource_name = "idle"
length = 0.001
tracks/0/type = "position_3d"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("TubeLeft")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = PackedFloat32Array(0, 1, -10, 0, 0)
tracks/1/type = "position_3d"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("TubeRight")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = PackedFloat32Array(0, 1, 10, 0, 0)
[sub_resource type="Animation" id="Animation_xptat"]
resource_name = "uncrush"
length = 0.1998
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("TubeLeft:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1998),
"transitions": PackedFloat32Array(3.5, 1),
"update": 0,
"values": [Vector3(-4.209, 0, 0), Vector3(-10, 0, 0)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("TubeRight:position")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.1998),
"transitions": PackedFloat32Array(3.5, 1),
"update": 0,
"values": [Vector3(4.2, 0, 0), Vector3(10, 0, 0)]
}
tracks/2/type = "audio"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("MoveSfx")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.0,
"stream": ExtResource("8_htx8b")
}],
"times": PackedFloat32Array(0)
}
tracks/2/use_blend = true
[sub_resource type="AnimationLibrary" id="AnimationLibrary_kgj8g"]
_data = {
&"RESET": SubResource("Animation_l80un"),
&"crush": SubResource("Animation_s6lek"),
&"idle": SubResource("Animation_kgj8g"),
&"uncrush": SubResource("Animation_xptat")
}
[sub_resource type="BoxMesh" id="BoxMesh_qnjlk"]
size = Vector3(8, 0.2, 0.2)
[sub_resource type="BoxMesh" id="BoxMesh_s6lek"]
size = Vector3(0.205, 2.5, 1.5)
[sub_resource type="TextMesh" id="TextMesh_xptat"]
material = ExtResource("2_kgj8g")
text = "Press J"
font = ExtResource("12_ueio8")
font_size = 64
[sub_resource type="TextMesh" id="TextMesh_yarin"]
material = ExtResource("2_kgj8g")
text = "Press D"
font = ExtResource("12_ueio8")
font_size = 64
[node name="Game" type="Node3D" unique_id=133158643 node_paths=PackedStringArray("_ui_layer", "_press_d_prompt", "_press_j_prompt", "_d_anim", "_d_button", "_j_anim", "_j_button", "_ghost_spawn_timer", "_crusher", "_slam_sfx", "_splat_sfx", "_crusher_anim")]
script = ExtResource("1_s6lek")
_ui_layer = NodePath("UI")
_press_d_prompt = NodePath("PressDPrompt")
_press_j_prompt = NodePath("PressJPrompt")
_d_anim = NodePath("D/AnimationPlayer")
_d_button = NodePath("D/Button")
_j_anim = NodePath("J/AnimationPlayer")
_j_button = NodePath("J/Button")
_ghost_spawn_timer = NodePath("GhostSpawnTimer")
_ghost_scene = ExtResource("2_l80un")
_crusher = NodePath("Crusher")
_slam_sfx = NodePath("Crusher/SlamSfx")
_splat_sfx = NodePath("Crusher/SplatSfx")
_crusher_anim = NodePath("Crusher/AnimationPlayer")
[node name="MusicPlayer" type="AudioStreamPlayer" parent="." unique_id=220746864]
stream = ExtResource("3_htx8b")
autoplay = true
bus = &"music"
[node name="UI" type="CanvasLayer" parent="." unique_id=697702645]
[node name="TitleLabel" type="Label" parent="UI" unique_id=1741345152]
offset_left = 8.0
offset_top = 12.0
offset_right = 170.0
offset_bottom = 40.0
theme_override_fonts/font = ExtResource("4_etvrb")
theme_override_font_sizes/font_size = 72
text = "“D 'n' J Crusher”"
[node name="WanpLabel" type="Label" parent="UI" unique_id=531736359]
offset_left = 17.0
offset_top = 100.0
offset_right = 179.0
offset_bottom = 128.0
theme_override_fonts/font = ExtResource("12_ueio8")
text = "manifested by wanp"
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1729807054]
environment = SubResource("Environment_jn5yv")
[node name="Camera3D" type="Camera3D" parent="." unique_id=1917918356]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 4)
[node name="OmniLight3D" type="OmniLight3D" parent="." unique_id=1281532038]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1.6)
light_color = Color(1, 0.75, 0, 1)
light_energy = 2.0
omni_shadow_mode = 0
[node name="OmniLight3D2" type="OmniLight3D" parent="." unique_id=387250400]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3000001, 1.6)
light_color = Color(1, 0.75, 0, 1)
light_energy = 2.0
omni_shadow_mode = 0
[node name="OmniLight3D3" type="OmniLight3D" parent="." unique_id=1580815460]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2.6999998, 0.100000024)
light_color = Color(1, 0.18333334, 0, 1)
light_energy = 3.0
omni_shadow_mode = 0
[node name="AnimationPlayer" type="AnimationPlayer" parent="OmniLight3D3" unique_id=1586322282]
libraries/ = SubResource("AnimationLibrary_htx8b")
autoplay = &"flicker"
[node name="PlatformLeft" type="MeshInstance3D" parent="." unique_id=1783405889]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -2.7, 0)
mesh = SubResource("CylinderMesh_s6lek")
[node name="PlatformRight" type="MeshInstance3D" parent="." unique_id=1346653145]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -2.7, 0)
mesh = SubResource("CylinderMesh_s6lek")
[node name="Wall" type="MeshInstance3D" parent="." unique_id=1308282145]
transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, -1, -2)
mesh = SubResource("PlaneMesh_qnjlk")
[node name="D" type="Node3D" parent="." unique_id=928869159]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -1.3000001, 0.20000002)
[node name="AnimationPlayer" type="AnimationPlayer" parent="D" unique_id=7005501]
libraries/ = SubResource("AnimationLibrary_jhw8o")
[node name="Orb" type="MeshInstance3D" parent="D" unique_id=762810288]
mesh = SubResource("SphereMesh_kgj8g")
skeleton = NodePath("../..")
[node name="Eye" type="Sprite3D" parent="D" unique_id=1973646501]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.100000024, 0.100000024, 0.29999998)
pixel_size = 0.02
billboard = 1
no_depth_test = true
texture_filter = 0
texture = SubResource("GradientTexture2D_kgj8g")
[node name="Eye2" type="Sprite3D" parent="D" unique_id=1067064441]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.20000005, 0.4)
pixel_size = 0.02
billboard = 1
no_depth_test = true
texture_filter = 0
texture = SubResource("GradientTexture2D_kgj8g")
[node name="Hand" type="MeshInstance3D" parent="D" unique_id=179301020]
transform = Transform3D(1, 0, 0, 0, 1.0000001, 0, 0, 0, 1, -0.4000001, -0.100000024, 0.30000004)
mesh = SubResource("SphereMesh_l80un")
[node name="Button" parent="D" unique_id=1703705526 instance=ExtResource("4_xptat")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.3849659, -0.39247894, 0.30321684)
[node name="ButtonSfx" type="AudioStreamPlayer3D" parent="D/Button" unique_id=1459135632]
panning_strength = 2.0
bus = &"sfx"
[node name="J" type="Node3D" parent="." unique_id=794820390]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -1.3, 0.2)
[node name="AnimationPlayer" type="AnimationPlayer" parent="J" unique_id=1956217934]
libraries/ = SubResource("AnimationLibrary_6kr85")
[node name="Orb" type="MeshInstance3D" parent="J" unique_id=1264857338]
mesh = SubResource("SphereMesh_kgj8g")
skeleton = NodePath("../..")
[node name="Eye" type="Sprite3D" parent="J" unique_id=1330761631]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.1, 0.1, 0.3)
pixel_size = 0.02
billboard = 1
no_depth_test = true
texture_filter = 0
texture = SubResource("GradientTexture2D_kgj8g")
[node name="Eye2" type="Sprite3D" parent="J" unique_id=1441343203]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 0.2, 0.4)
pixel_size = 0.02
billboard = 1
no_depth_test = true
texture_filter = 0
texture = SubResource("GradientTexture2D_kgj8g")
[node name="Hand" type="MeshInstance3D" parent="J" unique_id=2003843339]
transform = Transform3D(1, 0, 0, 0, 1.0000001, 0, 0, 0, 1, 0.4, -0.1, 0.3)
mesh = SubResource("SphereMesh_l80un")
skeleton = NodePath("../../D")
[node name="Button" parent="J" unique_id=1343560287 instance=ExtResource("4_xptat")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.385, -0.392, 0.303)
[node name="ButtonSfx" type="AudioStreamPlayer3D" parent="J/Button" unique_id=2054923244]
panning_strength = 2.0
bus = &"sfx"
[node name="Crusher" type="Node3D" parent="." unique_id=135343329]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.7, 0)
[node name="MoveSfx" type="AudioStreamPlayer3D" parent="Crusher" unique_id=154564713]
bus = &"sfx"
[node name="SlamSfx" type="AudioStreamPlayer3D" parent="Crusher" unique_id=1867676118]
stream = ExtResource("6_jhw8o")
volume_db = -9.0
bus = &"sfx"
[node name="SplatSfx" type="AudioStreamPlayer3D" parent="Crusher" unique_id=995157383]
stream = SubResource("AudioStreamRandomizer_jhw8o")
volume_db = -8.0
bus = &"sfx"
[node name="AnimationPlayer" type="AnimationPlayer" parent="Crusher" unique_id=1632097092]
libraries/ = SubResource("AnimationLibrary_kgj8g")
[node name="TubeLeft" type="MeshInstance3D" parent="Crusher" unique_id=5559250]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10, 0, 0)
mesh = SubResource("BoxMesh_qnjlk")
[node name="MashyPlate" type="MeshInstance3D" parent="Crusher/TubeLeft" unique_id=1333803171]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.1, 0, 0)
mesh = SubResource("BoxMesh_s6lek")
[node name="TubeRight" type="MeshInstance3D" parent="Crusher" unique_id=1854970319]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10, 0, 0)
mesh = SubResource("BoxMesh_qnjlk")
[node name="MashyPlate" type="MeshInstance3D" parent="Crusher/TubeRight" unique_id=773801297]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.1, 0, 0)
mesh = SubResource("BoxMesh_s6lek")
skeleton = NodePath("../../TubeLeft")
[node name="GhostSpawnTimer" type="Timer" parent="." unique_id=1851782317]
[node name="PressJPrompt" type="MeshInstance3D" parent="." unique_id=1875037720]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.6, 0.2, 0)
mesh = SubResource("TextMesh_xptat")
[node name="Arrow" parent="PressJPrompt" unique_id=1726557209 instance=ExtResource("6_yarin")]
transform = Transform3D(0.93969274, 0.34202018, 0, -0.34202018, 0.93969274, 0, 0, 0, 1, 0.8000001, -0.6000001, 0)
[node name="PressDPrompt" type="MeshInstance3D" parent="." unique_id=1772110792]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.6, 0.2, 0)
mesh = SubResource("TextMesh_yarin")
[node name="Arrow" parent="PressDPrompt" unique_id=596720032 instance=ExtResource("6_yarin")]
transform = Transform3D(0.76604456, 0.64278764, 0, -0.64278764, 0.76604456, 0, 0, 0, 1, 0.6000002, -0.6000001, 0)
[connection signal="timeout" from="GhostSpawnTimer" to="." method="_on_ghost_spawn_timer_timeout"]

43
src/game/ghost.gd Normal file
View File

@@ -0,0 +1,43 @@
class_name Ghost
extends Node3D
static var _models: Array[PackedScene] = [
load("res://assets/ghost1.glb"),
load("res://assets/ghost2.glb"),
load("res://assets/ghost3.glb"),
]
var _rise_speed := 0.0
var _turn_speed := 0.0
var _fall_velocity := 0.0
var is_crushed := false
func _ready() -> void:
add_child(_models.pick_random().instantiate())
_rise_speed = randf_range(0.06, 0.1)
_turn_speed = randf_range(0.06, 0.2) * [1, -1].pick_random()
func _physics_process(_delta: float) -> void:
if not is_crushed:
position.y += _rise_speed
rotate_y(_turn_speed)
else:
_fall_velocity += -0.002
position.y += _fall_velocity
func crush(final_position_x: float) -> void:
is_crushed = true
position.x = final_position_x
rotation.y = 0
scale.x = 0.2
scale.y = 1.4
reset_physics_interpolation()
func _on_screen_exited() -> void:
queue_free()

1
src/game/ghost.gd.uid Normal file
View File

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

7
src/game/ghost.gdshader Normal file
View File

@@ -0,0 +1,7 @@
shader_type spatial;
render_mode unshaded;
void fragment() {
ALBEDO = vec3(1);
ALPHA = 0.5;
}

View File

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

11
src/game/ghost.tscn Normal file
View File

@@ -0,0 +1,11 @@
[gd_scene format=3 uid="uid://sdd62ogittlq"]
[ext_resource type="Script" uid="uid://duakb2887lc64" path="res://src/game/ghost.gd" id="1_jtw1h"]
[node name="Ghost" type="Node3D" unique_id=80173777 groups=["ghosts"]]
script = ExtResource("1_jtw1h")
[node name="VisibleOnScreenNotifier3D" type="VisibleOnScreenNotifier3D" parent="." unique_id=1773071315]
aabb = AABB(-0.4, -0.4, -0.4, 0.8, 0.8, 0.8)
[connection signal="screen_exited" from="VisibleOnScreenNotifier3D" to="." method="_on_screen_exited"]

View File

@@ -0,0 +1,7 @@
[gd_resource type="ShaderMaterial" format=3 uid="uid://b2fsxx7piy766"]
[ext_resource type="Shader" uid="uid://dwh2j57d7dtt7" path="res://src/game/ghost.gdshader" id="1_n2xwl"]
[resource]
render_priority = 0
shader = ExtResource("1_n2xwl")

8
src/game/wall.gdshader Normal file
View File

@@ -0,0 +1,8 @@
shader_type spatial;
render_mode unshaded;
uniform sampler2D texture_image : source_color;
void fragment() {
ALBEDO = texture(texture_image, UV).rgb;
}

View File

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

View File

@@ -0,0 +1,30 @@
[gd_resource type="ShaderMaterial" format=3 uid="uid://di0etogxlb5dq"]
[ext_resource type="Shader" uid="uid://dyjjgyovssd7s" path="res://src/game/wall.gdshader" id="1_q0bvm"]
[sub_resource type="Gradient" id="Gradient_igrk8"]
interpolation_mode = 2
offsets = PackedFloat32Array(0.23913044, 1)
colors = PackedColorArray(0, 0, 0, 1, 0.26, 0, 0.004333267, 1)
[sub_resource type="FastNoiseLite" id="FastNoiseLite_5bnbn"]
noise_type = 2
seed = 255
frequency = 0.0879
fractal_type = 0
domain_warp_enabled = true
domain_warp_type = 2
domain_warp_fractal_gain = 0.0
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_igrk8"]
width = 64
height = 64
generate_mipmaps = false
noise = SubResource("FastNoiseLite_5bnbn")
color_ramp = SubResource("Gradient_igrk8")
seamless = true
[resource]
render_priority = 0
shader = ExtResource("1_q0bvm")
shader_parameter/texture_image = SubResource("NoiseTexture2D_igrk8")