forked from gdquest-demos/godot-3-getting-started-2021
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add 3D game project, squash the creeps
- Loading branch information
1 parent
7a7816e
commit 31ff416
Showing
47 changed files
with
4,989 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.import | ||
logs/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
extends Node | ||
|
||
export(PackedScene) var mob_scene | ||
|
||
|
||
func _ready(): | ||
randomize() | ||
$UserInterface/Retry.hide() | ||
|
||
|
||
func _unhandled_input(event): | ||
if event.is_action_pressed("ui_accept") and $UserInterface/Retry.visible: | ||
get_tree().reload_current_scene() | ||
|
||
|
||
func _on_MobTimer_timeout(): | ||
# Create a Mob instance and add it to the scene. | ||
var mob = mob_scene.instance() | ||
|
||
# Choose a random location on Path2D. | ||
var mob_spawn_location = get_node("SpawnPath/SpawnLocation") | ||
mob_spawn_location.unit_offset = randf() | ||
|
||
var player_position = $Player.transform.origin | ||
|
||
add_child(mob) | ||
# We connect the mob to the score label to update the score upon squashing a mob. | ||
mob.connect("squashed", $UserInterface/ScoreLabel, "_on_Mob_squashed") | ||
mob.initialize(mob_spawn_location.translation, player_position) | ||
|
||
|
||
func _on_Player_hit(): | ||
$MobTimer.stop() | ||
$UserInterface/Retry.show() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
[gd_scene load_steps=12 format=2] | ||
|
||
[ext_resource path="res://Main.gd" type="Script" id=1] | ||
[ext_resource path="res://Player.tscn" type="PackedScene" id=2] | ||
[ext_resource path="res://Mob.tscn" type="PackedScene" id=3] | ||
[ext_resource path="res://default_env.tres" type="Environment" id=4] | ||
[ext_resource path="res://ScoreLabel.gd" type="Script" id=6] | ||
[ext_resource path="res://ui_theme.tres" type="Theme" id=7] | ||
|
||
[sub_resource type="BoxShape" id=1] | ||
extents = Vector3( 30, 1, 30 ) | ||
|
||
[sub_resource type="CubeMesh" id=2] | ||
size = Vector3( 60, 2, 60 ) | ||
|
||
[sub_resource type="CylinderMesh" id=3] | ||
|
||
[sub_resource type="SpatialMaterial" id=4] | ||
albedo_color = Color( 0.960784, 0.486275, 0.0313726, 1 ) | ||
|
||
[sub_resource type="Curve3D" id=5] | ||
_data = { | ||
"points": PoolVector3Array( 0, 0, 0, 0, 0, 0, 14, 0, -15, 0, 0, 0, 0, 0, 0, -13, 0, -15, 0, 0, 0, 0, 0, 0, -13, 0, 16, 0, 0, 0, 0, 0, 0, 14, 0, 16, 0, 0, 0, 0, 0, 0, 14, 0, -15 ), | ||
"tilts": PoolRealArray( 0, 0, 0, 0, 0 ) | ||
} | ||
|
||
[node name="Main" type="Node"] | ||
script = ExtResource( 1 ) | ||
mob_scene = ExtResource( 3 ) | ||
|
||
[node name="Ground" type="StaticBody" parent="."] | ||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0 ) | ||
collision_layer = 4 | ||
collision_mask = 0 | ||
|
||
[node name="CollisionShape" type="CollisionShape" parent="Ground"] | ||
shape = SubResource( 1 ) | ||
|
||
[node name="MeshInstance" type="MeshInstance" parent="Ground"] | ||
mesh = SubResource( 2 ) | ||
material/0 = null | ||
|
||
[node name="DirectionalLight" type="DirectionalLight" parent="."] | ||
transform = Transform( 0.5, -0.777049, 0.382355, 0, 0.441506, 0.897258, -0.866025, -0.448629, 0.220753, 0, 12.5592, 14.7757 ) | ||
shadow_enabled = true | ||
|
||
[node name="Player" parent="." instance=ExtResource( 2 )] | ||
|
||
[node name="CameraPivot" type="Position3D" parent="."] | ||
transform = Transform( 1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0.183514, 0, 0 ) | ||
|
||
[node name="Camera" type="Camera" parent="CameraPivot"] | ||
transform = Transform( 1, 0, 0, 0, 1, -2.98023e-08, 0, 2.98023e-08, 1, 0, 9.53674e-07, 19 ) | ||
projection = 1 | ||
fov = 48.6 | ||
size = 19.0 | ||
|
||
[node name="Cylinders" type="Spatial" parent="."] | ||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 8, 0, 0 ) | ||
|
||
[node name="MeshInstance" type="MeshInstance" parent="Cylinders"] | ||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 0, -15 ) | ||
mesh = SubResource( 3 ) | ||
material/0 = SubResource( 4 ) | ||
|
||
[node name="MeshInstance3" type="MeshInstance" parent="Cylinders"] | ||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -21, 0, -15 ) | ||
mesh = SubResource( 3 ) | ||
material/0 = SubResource( 4 ) | ||
|
||
[node name="MeshInstance2" type="MeshInstance" parent="Cylinders"] | ||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -21, 0, 16 ) | ||
mesh = SubResource( 3 ) | ||
material/0 = SubResource( 4 ) | ||
|
||
[node name="MeshInstance4" type="MeshInstance" parent="Cylinders"] | ||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 0, 16 ) | ||
mesh = SubResource( 3 ) | ||
material/0 = SubResource( 4 ) | ||
|
||
[node name="SpawnPath" type="Path" parent="."] | ||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0 ) | ||
curve = SubResource( 5 ) | ||
|
||
[node name="SpawnLocation" type="PathFollow" parent="SpawnPath"] | ||
transform = Transform( -0.491811, 0, -0.870701, 0, 1, 0, 0.870701, 0, -0.491811, -12.9746, 0, -14.9397 ) | ||
offset = 26.9729 | ||
rotation_mode = 1 | ||
cubic_interp = false | ||
loop = false | ||
|
||
[node name="MobTimer" type="Timer" parent="."] | ||
wait_time = 0.5 | ||
autostart = true | ||
|
||
[node name="UserInterface" type="Control" parent="."] | ||
anchor_right = 1.0 | ||
anchor_bottom = 1.0 | ||
theme = ExtResource( 7 ) | ||
__meta__ = { | ||
"_edit_use_anchors_": false | ||
} | ||
|
||
[node name="ScoreLabel" type="Label" parent="UserInterface"] | ||
margin_left = 20.0226 | ||
margin_top = 16.0181 | ||
margin_right = 126.023 | ||
margin_bottom = 71.0181 | ||
custom_colors/font_color = Color( 0.2, 0.184314, 0.215686, 1 ) | ||
text = "Score: 0" | ||
script = ExtResource( 6 ) | ||
__meta__ = { | ||
"_edit_use_anchors_": false | ||
} | ||
|
||
[node name="Retry" type="ColorRect" parent="UserInterface"] | ||
visible = false | ||
anchor_right = 1.0 | ||
anchor_bottom = 1.0 | ||
color = Color( 0, 0, 0, 0.447059 ) | ||
__meta__ = { | ||
"_edit_use_anchors_": false | ||
} | ||
|
||
[node name="Label" type="Label" parent="UserInterface/Retry"] | ||
anchor_right = 1.0 | ||
anchor_bottom = 1.0 | ||
text = "Press Enter to retry" | ||
align = 1 | ||
valign = 1 | ||
__meta__ = { | ||
"_edit_use_anchors_": false, | ||
"_editor_description_": "" | ||
} | ||
|
||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."] | ||
environment = ExtResource( 4 ) | ||
|
||
[connection signal="hit" from="Player" to="." method="_on_Player_hit"] | ||
[connection signal="timeout" from="MobTimer" to="." method="_on_MobTimer_timeout"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
extends KinematicBody | ||
|
||
# Emitted when the player jumped on the mob. | ||
signal squashed | ||
|
||
# Minimum speed of the mob in meters per second. | ||
export var min_speed = 10 | ||
# Maximum speed of the mob in meters per second. | ||
export var max_speed = 18 | ||
|
||
var velocity = Vector3.ZERO | ||
|
||
|
||
func _physics_process(_delta): | ||
move_and_slide(velocity) | ||
|
||
|
||
func initialize(start_position, player_position): | ||
translation = start_position | ||
look_at(player_position, Vector3.UP) | ||
rotate_y(rand_range(-PI / 4, PI / 4)) | ||
|
||
var random_speed = rand_range(min_speed, max_speed) | ||
# We calculate a forward velocity first, which represents the speed. | ||
velocity = Vector3.FORWARD * random_speed | ||
# We then rotate the vector based on the mob's Y rotation to move in the direction it's looking. | ||
velocity = velocity.rotated(Vector3.UP, rotation.y) | ||
|
||
$AnimationPlayer.playback_speed = random_speed / min_speed | ||
|
||
|
||
func squash(): | ||
emit_signal("squashed") | ||
queue_free() | ||
|
||
|
||
func _on_VisibilityNotifier_screen_exited(): | ||
queue_free() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
[gd_scene load_steps=5 format=2] | ||
|
||
[ext_resource path="res://Mob.gd" type="Script" id=1] | ||
[ext_resource path="res://art/mob.glb" type="PackedScene" id=2] | ||
|
||
[sub_resource type="BoxShape" id=1] | ||
extents = Vector3( 0.679112, 0.544173, 1.10029 ) | ||
|
||
[sub_resource type="Animation" id=2] | ||
length = 1.2 | ||
loop = true | ||
tracks/0/type = "value" | ||
tracks/0/path = NodePath("Pivot/Character:translation") | ||
tracks/0/interp = 1 | ||
tracks/0/loop_wrap = true | ||
tracks/0/imported = false | ||
tracks/0/enabled = true | ||
tracks/0/keys = { | ||
"times": PoolRealArray( 0.22, 0.7, 1.18 ), | ||
"transitions": PoolRealArray( 0.435275, 2.21914, 1 ), | ||
"update": 0, | ||
"values": [ Vector3( 0, 0.329753, 0 ), Vector3( 0, 0.660351, 0 ), Vector3( 0, 0.349734, 0 ) ] | ||
} | ||
tracks/1/type = "value" | ||
tracks/1/path = NodePath("Pivot/Character:rotation_degrees") | ||
tracks/1/interp = 1 | ||
tracks/1/loop_wrap = true | ||
tracks/1/imported = false | ||
tracks/1/enabled = true | ||
tracks/1/keys = { | ||
"times": PoolRealArray( 0.1, 0.46, 1.18 ), | ||
"transitions": PoolRealArray( 0.482968, 0.535887, 1 ), | ||
"update": 0, | ||
"values": [ Vector3( -5.0326, 0, 0 ), Vector3( 10, 0, 0 ), Vector3( -10, 0, 0 ) ] | ||
} | ||
|
||
[node name="Mob" type="KinematicBody" groups=[ | ||
"mob", | ||
]] | ||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0114588, 0 ) | ||
collision_layer = 2 | ||
collision_mask = 2147483648 | ||
script = ExtResource( 1 ) | ||
|
||
[node name="Pivot" type="Spatial" parent="."] | ||
|
||
[node name="Character" parent="Pivot" instance=ExtResource( 2 )] | ||
transform = Transform( 1, 0, 0, 0, 0.989268, 0.146113, 0, -0.146113, 0.989268, 0, 0.34652, 0 ) | ||
|
||
[node name="CollisionShape" type="CollisionShape" parent="."] | ||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.52793, 0 ) | ||
shape = SubResource( 1 ) | ||
|
||
[node name="VisibilityNotifier" type="VisibilityNotifier" parent="."] | ||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.062134, 0.331645 ) | ||
aabb = AABB( -1.19986, 0.251327, -1.57098, 2.41047, 1.09305, 3.17223 ) | ||
|
||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."] | ||
autoplay = "float" | ||
anims/float = SubResource( 2 ) | ||
[connection signal="screen_exited" from="VisibilityNotifier" to="." method="_on_VisibilityNotifier_screen_exited"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[gd_scene load_steps=2 format=2] | ||
|
||
[ext_resource path="res://art/House In a Forest Loop.ogg" type="AudioStream" id=1] | ||
|
||
[node name="MusicPlayer" type="AudioStreamPlayer"] | ||
stream = ExtResource( 1 ) | ||
autoplay = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
extends KinematicBody | ||
|
||
signal hit | ||
|
||
# How fast the player moves in meters per second. | ||
export var speed = 14 | ||
# Vertical impulse applied to the character upon jumping in meters per second. | ||
export var jump_impulse = 20 | ||
# Vertical impulse applied to the character upon bouncing over a mob in meters per second. | ||
export var bounce_impulse = 16 | ||
# The downward acceleration when in the air, in meters per second per second. | ||
export var fall_acceleration = 75 | ||
|
||
var velocity = Vector3.ZERO | ||
|
||
|
||
func _physics_process(delta): | ||
var direction = Vector3.ZERO | ||
if Input.is_action_pressed("move_right"): | ||
direction.x += 1 | ||
if Input.is_action_pressed("move_left"): | ||
direction.x -= 1 | ||
if Input.is_action_pressed("move_back"): | ||
direction.z += 1 | ||
if Input.is_action_pressed("move_forward"): | ||
direction.z -= 1 | ||
|
||
if direction != Vector3.ZERO: | ||
# In the lines below, we turn the character when moving and make the animation play faster. | ||
direction = direction.normalized() | ||
$Pivot.look_at(translation + direction, Vector3.UP) | ||
$AnimationPlayer.playback_speed = 4 | ||
else: | ||
$AnimationPlayer.playback_speed = 1 | ||
|
||
velocity.x = direction.x * speed | ||
velocity.z = direction.z * speed | ||
|
||
# Jumping. | ||
if is_on_floor() and Input.is_action_just_pressed("jump"): | ||
velocity.y += jump_impulse | ||
|
||
# We apply gravity every frame so the character always collides with the ground when moving. | ||
# This is necessary for the is_on_floor() function to work as a body can always detect | ||
# the floor, walls, etc. when a collision happens the same frame. | ||
velocity.y -= fall_acceleration * delta | ||
velocity = move_and_slide(velocity, Vector3.UP) | ||
|
||
# Here, we check if we landed on top of a mob and if so, we kill it and bounce. | ||
# With move_and_slide(), Godot makes the body move sometimes multiple times in a row to | ||
# smooth out the character's motion. So we have to loop over all collisions that may have | ||
# happened. | ||
# If there are no "slides" this frame, the loop below won't run. | ||
for index in range(get_slide_count()): | ||
var collision = get_slide_collision(index) | ||
if collision.collider.is_in_group("mob"): | ||
var mob = collision.collider | ||
if Vector3.UP.dot(collision.normal) > 0.1: | ||
mob.squash() | ||
velocity.y = bounce_impulse | ||
|
||
# This makes the character follow a nice arc when jumping | ||
$Pivot.rotation.x = PI / 6 * velocity.y / jump_impulse | ||
|
||
|
||
func die(): | ||
emit_signal("hit") | ||
queue_free() | ||
|
||
|
||
func _on_MobDetector_body_entered(_body): | ||
die() |
Oops, something went wrong.