diff --git a/Mob.gd b/Mob.gd index 773c105..8a3754e 100644 --- a/Mob.gd +++ b/Mob.gd @@ -19,6 +19,8 @@ func initialize(start_position, player_position): velocity = Vector3.FORWARD * random_speed velocity = velocity.rotated(Vector3.UP, rotation.y) + $AnimationPlayer.speed_scale = random_speed / min_speed + func squash(): squashed.emit() queue_free() diff --git a/MusicPlayer.tscn b/MusicPlayer.tscn new file mode 100644 index 0000000..d18862e --- /dev/null +++ b/MusicPlayer.tscn @@ -0,0 +1,7 @@ +[gd_scene load_steps=2 format=3 uid="uid://8hqoev8vj3fn"] + +[ext_resource type="AudioStream" uid="uid://cx00shxtb3wu3" path="res://art/House In a Forest Loop.ogg" id="1_w2wh1"] + +[node name="AudioStreamPlayer" type="AudioStreamPlayer"] +stream = ExtResource("1_w2wh1") +autoplay = true diff --git a/Player.gd b/Player.gd index 594db56..9f46c03 100644 --- a/Player.gd +++ b/Player.gd @@ -5,6 +5,8 @@ extends CharacterBody3D @export var jump_impulse = 20 # m/s @export var bounce_impulse = 16 # m/s +signal hit + var target_velocity = Vector3.ZERO func _physics_process(delta): @@ -25,6 +27,11 @@ func _physics_process(delta): if direction != Vector3.ZERO: direction = direction.normalized() $Pivot.basis = Basis.looking_at(direction) + $AnimationPlayer.speed_scale = 4 + else: + $AnimationPlayer.speed_scale = 1 + + $Pivot.rotation.x = PI / 6 * velocity.y / jump_impulse # Ground velocity target_velocity.x = direction.x * speed @@ -54,3 +61,10 @@ func _physics_process(delta): # Move the character velocity = target_velocity move_and_slide() + +func die(): + hit.emit() + queue_free() + +func _on_mob_detector_body_entered(body): + die() diff --git a/ScoreLabel.gd b/ScoreLabel.gd new file mode 100644 index 0000000..cfb9cca --- /dev/null +++ b/ScoreLabel.gd @@ -0,0 +1,7 @@ +extends Label + +var score = 0 + +func _on_mob_squashed(): + score += 1 + text = "Score: %s" % score diff --git a/main.gd b/main.gd index a26573f..21b7285 100644 --- a/main.gd +++ b/main.gd @@ -2,6 +2,9 @@ extends Node @export var mob_scene: PackedScene +func _ready(): + $UserInterface/Retry.hide() + func _on_mob_timer_timeout(): var mob = mob_scene.instantiate() @@ -9,6 +12,17 @@ func _on_mob_timer_timeout(): mob_spawn_location.progress_ratio = randf() var player_position = $Player.position + mob.initialize(mob_spawn_location.position, player_position) add_child(mob) + + mob.squashed.connect($UserInterface/ScoreLabel._on_mob_squashed.bind()) + +func _on_player_hit(): + $MobTimer.stop() + $UserInterface/Retry.show() + +func _unhandled_input(event): + if event.is_action_pressed("ui_accept") and $UserInterface/Retry.visible: + get_tree().reload_current_scene() diff --git a/main.tscn b/main.tscn index 125154a..3f57050 100644 --- a/main.tscn +++ b/main.tscn @@ -1,8 +1,10 @@ -[gd_scene load_steps=9 format=3 uid="uid://6o4jfv4sjc42"] +[gd_scene load_steps=12 format=3 uid="uid://6o4jfv4sjc42"] [ext_resource type="Script" path="res://main.gd" id="1_git68"] [ext_resource type="PackedScene" uid="uid://bl4b5g1o8ud5y" path="res://player.tscn" id="1_qvjem"] [ext_resource type="PackedScene" uid="uid://h2hapmuai55b" path="res://mob.tscn" id="2_oiwul"] +[ext_resource type="FontFile" uid="uid://d1r2cqlplg2wb" path="res://fonts/Montserrat-Medium.ttf" id="4_o3155"] +[ext_resource type="Script" path="res://ScoreLabel.gd" id="5_y0lvi"] [sub_resource type="BoxShape3D" id="BoxShape3D_jiv4h"] size = Vector3(60, 2, 60) @@ -23,6 +25,10 @@ _data = { } point_count = 5 +[sub_resource type="Theme" id="Theme_eyu2y"] +default_font = ExtResource("4_o3155") +default_font_size = 22 + [node name="Main" type="Node"] script = ExtResource("1_git68") mob_scene = ExtResource("2_oiwul") @@ -73,10 +79,54 @@ mesh = SubResource("CylinderMesh_1gwnh") curve = SubResource("Curve3D_476rq") [node name="SpawnLocation" type="PathFollow3D" parent="SpawnPath"] -transform = Transform3D(0.00743461, 0, -0.999972, 0, 1, 0, 0.999972, 0, 0.00743461, -13.6297, 0, -15.0268) +transform = Transform3D(0.0074346, 0, -0.999971, 0, 1, 0, 0.999971, 0, 0.0074346, -13.6297, 0, -15.0268) [node name="MobTimer" type="Timer" parent="."] wait_time = 0.5 autostart = true +[node name="UserInterface" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = SubResource("Theme_eyu2y") + +[node name="ScoreLabel" type="Label" parent="UserInterface"] +layout_mode = 0 +offset_left = 38.0 +offset_top = 29.0 +offset_right = 99.0 +offset_bottom = 52.0 +theme_override_colors/font_color = Color(0, 0, 0, 1) +text = "Score: 0" +script = ExtResource("5_y0lvi") + +[node name="Retry" type="ColorRect" parent="UserInterface"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0, 0, 0, 0.392157) + +[node name="Label" type="Label" parent="UserInterface/Retry"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -106.5 +offset_top = -14.0 +offset_right = 106.5 +offset_bottom = 14.0 +grow_horizontal = 2 +grow_vertical = 2 +text = "Press Enter to retry" + +[connection signal="hit" from="Player" to="." method="_on_player_hit"] [connection signal="timeout" from="MobTimer" to="." method="_on_mob_timer_timeout"] diff --git a/mob.tscn b/mob.tscn index 1fd1bab..18c5cd2 100644 --- a/mob.tscn +++ b/mob.tscn @@ -1,10 +1,72 @@ -[gd_scene load_steps=4 format=3 uid="uid://h2hapmuai55b"] +[gd_scene load_steps=7 format=3 uid="uid://h2hapmuai55b"] [ext_resource type="Script" path="res://Mob.gd" id="1_fih7b"] [ext_resource type="PackedScene" uid="uid://gqs4tdvjq5vi" path="res://art/mob.glb" id="2_0f7cl"] [sub_resource type="BoxShape3D" id="BoxShape3D_vwmkp"] -size = Vector3(2, 1, 2.5) +size = Vector3(2.5, 1.5, 3.5) + +[sub_resource type="Animation" id="Animation_ja4nm"] +resource_name = "float" +length = 1.2 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Pivot/Character:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0.3, 0.7, 1.2), +"transitions": PackedFloat32Array(2.14126, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, 0.65, 0), Vector3(0, 0.35, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Pivot/Character:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0.1, 0.5, 1.2), +"transitions": PackedFloat32Array(0.42, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0.139626, 0, 0), Vector3(-0.15708, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_g67lg"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Pivot/Character:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Pivot/Character:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_x0i7m"] +_data = { +"RESET": SubResource("Animation_g67lg"), +"float": SubResource("Animation_ja4nm") +} [node name="Mob" type="CharacterBody3D" groups=["mob"]] collision_layer = 2 @@ -16,9 +78,16 @@ script = ExtResource("1_fih7b") [node name="Character" parent="Pivot" instance=ExtResource("2_0f7cl")] [node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, 0.25) shape = SubResource("BoxShape3D_vwmkp") [node name="VisibilityNotifier" type="VisibleOnScreenNotifier3D" parent="."] aabb = AABB(-1.5, -1, -2, 3, 2, 4) +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_x0i7m") +} +autoplay = "float" + [connection signal="screen_exited" from="VisibilityNotifier" to="." method="_on_visibility_notifier_screen_exited"] diff --git a/player.tscn b/player.tscn index 12044de..b60f0cf 100644 --- a/player.tscn +++ b/player.tscn @@ -1,10 +1,76 @@ -[gd_scene load_steps=4 format=3 uid="uid://bl4b5g1o8ud5y"] +[gd_scene load_steps=8 format=3 uid="uid://bl4b5g1o8ud5y"] [ext_resource type="Script" path="res://Player.gd" id="1_hmkw8"] [ext_resource type="PackedScene" uid="uid://cpgf40og1627r" path="res://art/player.glb" id="1_s5jny"] [sub_resource type="SphereShape3D" id="SphereShape3D_afne8"] -radius = 1.1 +radius = 1.0 + +[sub_resource type="CylinderShape3D" id="CylinderShape3D_chb66"] +height = 0.2 +radius = 1.3 + +[sub_resource type="Animation" id="Animation_ja4nm"] +resource_name = "float" +length = 1.2 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Pivot/Character:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0.3, 0.7, 1.2), +"transitions": PackedFloat32Array(2.14126, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, 0.65, 0), Vector3(0, 0.35, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Pivot/Character:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0.1, 0.5, 1.2), +"transitions": PackedFloat32Array(0.42, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0.139626, 0, 0), Vector3(-0.15708, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_g67lg"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Pivot/Character:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Pivot/Character:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_x0i7m"] +_data = { +"RESET": SubResource("Animation_g67lg"), +"float": SubResource("Animation_ja4nm") +} [node name="Player" type="CharacterBody3D"] collision_mask = 6 @@ -15,4 +81,23 @@ script = ExtResource("1_hmkw8") [node name="Character" parent="Pivot" instance=ExtResource("1_s5jny")] [node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.287413, 0) shape = SubResource("SphereShape3D_afne8") + +[node name="MobDetector" type="Area3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.201618, 0) +collision_layer = 0 +collision_mask = 2 +monitorable = false + +[node name="CollisionShape3D" type="CollisionShape3D" parent="MobDetector"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.208533, 0) +shape = SubResource("CylinderShape3D_chb66") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_x0i7m") +} +autoplay = "float" + +[connection signal="body_entered" from="MobDetector" to="." method="_on_mob_detector_body_entered"] diff --git a/project.godot b/project.godot index 866b193..da1a0c1 100644 --- a/project.godot +++ b/project.godot @@ -14,6 +14,10 @@ config/name="Godot" config/features=PackedStringArray("4.2", "Forward Plus") config/icon="res://icon.svg" +[autoload] + +MusicPlayer="*res://MusicPlayer.tscn" + [display] window/size/viewport_width=720