Add Squash the Creeps (3D) demo

This is a 3D version of Dodge the Creeps, originally made by GDQuest
and updated to 4.0 by myself.

Some changes are included for more polish:

- Invisible walls were added so that you can't exit the playable area anymore.
- Pillars have a different color to be more visible.
- Physical keys are now used, so that you can use WASD movement
  on any keyboard layout.
- The right mouse button can now be used to jump.
- Visual settings were tweaked to match other 3D demos.
- Project icon was upscaled to 128×128 using Waifu2x, so that it
  looks better on hiDPI displays.
- `.blend` files were resaved with compression enabled.

Co-authored-by: Nathan Lovato <nathan@gdquest.com>
This commit is contained in:
Hugo Locurcio
2023-03-13 23:45:16 +01:00
parent 956875c306
commit 71d29dcf3b
33 changed files with 912 additions and 0 deletions

2
3d/squash_the_creeps/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.import
logs/

View File

@@ -0,0 +1,36 @@
extends Node
@export var mob_scene: PackedScene
func _ready():
$UserInterface/Retry.hide()
func _unhandled_input(event):
if event.is_action_pressed("ui_accept") and $UserInterface/Retry.visible:
# warning-ignore:return_value_discarded
get_tree().reload_current_scene()
func _on_mob_timer_timeout():
# Create a new instance of the Mob scene.
var mob = mob_scene.instantiate()
# Choose a random location on the SpawnPath.
var mob_spawn_location = get_node("SpawnPath/SpawnLocation")
mob_spawn_location.progress_ratio = randf()
# Communicate the spawn location and the player's location to the mob.
var player_position = $Player.position
mob.initialize(mob_spawn_location.position, player_position)
# Spawn the mob by adding it to the Main scene.
add_child(mob)
# We connect the mob to the score label to update the score upon squashing a mob.
mob.squashed.connect($UserInterface/ScoreLabel._on_Mob_squashed)
func _on_player_hit():
$MobTimer.stop()
$UserInterface/Retry.show()

View File

@@ -0,0 +1,185 @@
[gd_scene load_steps=15 format=3 uid="uid://2y3ar4s86yra"]
[ext_resource type="Script" path="res://Main.gd" id="1"]
[ext_resource type="PackedScene" uid="uid://dp478jyugrn7o" path="res://Player.tscn" id="2"]
[ext_resource type="PackedScene" uid="uid://ha0ar5s2c3m4" path="res://Mob.tscn" id="3"]
[ext_resource type="Theme" uid="uid://cqquurjk1i7yw" path="res://ui_theme.tres" id="4_gnyca"]
[ext_resource type="Script" path="res://ScoreLabel.gd" id="6"]
[sub_resource type="BoxShape3D" id="1"]
size = Vector3(60, 2, 60)
[sub_resource type="BoxMesh" id="2"]
size = Vector3(60, 2, 60)
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_i5n5q"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_m3njk"]
sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
[sub_resource type="Sky" id="Sky_yutuu"]
sky_material = SubResource("ProceduralSkyMaterial_m3njk")
[sub_resource type="Environment" id="Environment_0tcge"]
background_mode = 2
sky = SubResource("Sky_yutuu")
tonemap_mode = 2
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cr5ed"]
albedo_color = Color(0.635294, 0.211765, 0.0235294, 1)
[sub_resource type="CylinderMesh" id="3"]
material = SubResource("StandardMaterial3D_cr5ed")
radial_segments = 24
rings = 1
[sub_resource type="Curve3D" id="5"]
_data = {
"points": PackedVector3Array(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": PackedFloat32Array(0, 0, 0, 0, 0)
}
point_count = 5
[node name="Main" type="Node"]
script = ExtResource("1")
mob_scene = ExtResource("3")
[node name="Ground" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0)
collision_layer = 4
collision_mask = 0
[node name="CollisionShape" type="CollisionShape3D" parent="Ground"]
shape = SubResource("1")
[node name="MeshInstance" type="MeshInstance3D" parent="Ground"]
mesh = SubResource("2")
[node name="Walls" type="StaticBody3D" parent="."]
editor_description = "These invisible walls are used to prevent the player from escaping the playable area.
These walls use WorldBoundaryShape3D collision shapes, which are infinitely large planes
(even though they look finite in the editor)."
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 5)
collision_layer = 4
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="Walls"]
transform = Transform3D(1, 0, 0, 0, 1.31134e-07, 1, 0, -1, 1.31134e-07, 0, 10, 11)
shape = SubResource("WorldBoundaryShape3D_i5n5q")
[node name="CollisionShape3D2" type="CollisionShape3D" parent="Walls"]
transform = Transform3D(-4.37114e-08, 1, -1.31134e-07, 0, 1.31134e-07, 1, 1, 4.37114e-08, -5.73206e-15, -13, 10, -4.76837e-07)
shape = SubResource("WorldBoundaryShape3D_i5n5q")
[node name="CollisionShape3D3" type="CollisionShape3D" parent="Walls"]
transform = Transform3D(4.37114e-08, -1, 2.18557e-07, 3.82137e-15, -2.18557e-07, -1, 1, 4.37114e-08, -5.73206e-15, 14, 10, -4.76837e-07)
shape = SubResource("WorldBoundaryShape3D_i5n5q")
[node name="CollisionShape3D4" type="CollisionShape3D" parent="Walls"]
transform = Transform3D(1, 5.96046e-08, -1.42109e-14, 3.82137e-15, -2.18557e-07, -1, -5.96046e-08, 1, -2.18557e-07, 9.53674e-07, 10, -20)
shape = SubResource("WorldBoundaryShape3D_i5n5q")
[node name="DirectionalLight" type="DirectionalLight3D" parent="."]
transform = Transform3D(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
shadow_bias = 0.04
shadow_blur = 1.5
directional_shadow_mode = 0
directional_shadow_fade_start = 1.0
directional_shadow_max_distance = 40.0
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_0tcge")
[node name="Player" parent="." instance=ExtResource("2")]
[node name="CameraPivot" type="Marker3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0.183514, 0, 0)
[node name="Camera" type="Camera3D" parent="CameraPivot"]
transform = Transform3D(1, 0, 0, 0, 1, -2.98023e-08, 0, 2.98023e-08, 1, 0, 9.53674e-07, 19)
projection = 1
fov = 48.6
size = 24.0
far = 40.0
[node name="Cylinders" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8, 0, 0)
[node name="MeshInstance" type="MeshInstance3D" parent="Cylinders"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 1, -15)
mesh = SubResource("3")
[node name="MeshInstance3" type="MeshInstance3D" parent="Cylinders"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21, 1, -15)
mesh = SubResource("3")
[node name="MeshInstance2" type="MeshInstance3D" parent="Cylinders"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -21, 1, 16)
mesh = SubResource("3")
[node name="MeshInstance4" type="MeshInstance3D" parent="Cylinders"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 1, 16)
mesh = SubResource("3")
[node name="SpawnPath" type="Path3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
curve = SubResource("5")
[node name="SpawnLocation" type="PathFollow3D" parent="SpawnPath"]
transform = Transform3D(-4.37113e-08, 0, -0.999999, 0, 1, 0, 0.999999, 0, -4.37113e-08, 14, 0, -15)
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="."]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("4_gnyca")
[node name="ScoreLabel" type="Label" parent="UserInterface"]
layout_mode = 0
offset_left = 16.0
offset_top = 16.0
offset_right = 77.0
offset_bottom = 42.0
theme_override_colors/font_color = Color(0, 0, 0, 1)
theme_override_font_sizes/font_size = 32
text = "Score: 0"
script = ExtResource("6")
[node name="Retry" type="ColorRect" parent="UserInterface"]
visible = false
layout_mode = 0
anchor_right = 1.0
anchor_bottom = 1.0
color = Color(0, 0, 0, 0.447059)
[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 = -75.0
offset_top = -13.0
offset_right = 75.0
offset_bottom = 13.0
grow_horizontal = 2
grow_vertical = 2
theme_override_font_sizes/font_size = 32
text = "Press Space or Enter to retry"
[connection signal="hit" from="Player" to="." method="_on_player_hit"]
[connection signal="timeout" from="MobTimer" to="." method="_on_mob_timer_timeout"]

View File

@@ -0,0 +1,35 @@
extends CharacterBody3D
# 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
func _physics_process(_delta):
move_and_slide()
func initialize(start_position, player_position):
look_at_from_position(start_position, player_position, Vector3.UP)
rotate_y(randf_range(-PI / 4, PI / 4))
var random_speed = randf_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.speed_scale = random_speed / min_speed
func squash():
squashed.emit()
queue_free()
func _on_visible_on_screen_notifier_screen_exited():
queue_free()

View File

@@ -0,0 +1,66 @@
[gd_scene load_steps=6 format=3 uid="uid://ha0ar5s2c3m4"]
[ext_resource type="Script" path="res://Mob.gd" id="1"]
[ext_resource type="PackedScene" uid="uid://bicorb7we351t" path="res://art/mob.glb" id="2"]
[sub_resource type="BoxShape3D" id="1"]
size = Vector3(1.35822, 1.08835, 2.20058)
[sub_resource type="Animation" id="2"]
length = 1.2
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.22, 0.7, 1.18),
"transitions": PackedFloat32Array(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/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Pivot/Character:rotation_degrees")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0.1, 0.46, 1.18),
"transitions": PackedFloat32Array(0.482968, 0.535887, 1),
"update": 0,
"values": [Vector3(-5.0326, 0, 0), Vector3(10, 0, 0), Vector3(-10, 0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_5n6vs"]
_data = {
"float": SubResource("2")
}
[node name="Mob" type="CharacterBody3D" groups=["mob"]]
transform = Transform3D(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="Node3D" parent="."]
[node name="Character" parent="Pivot" instance=ExtResource("2")]
transform = Transform3D(1, 0, 0, 0, 0.996145, 0.0877225, 0, -0.0877225, 0.996145, 0, 0.329753, 0)
[node name="CollisionShape" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.52793, 0)
shape = SubResource("1")
[node name="VisibleOnScreenNotifier3D" type="VisibleOnScreenNotifier3D" parent="."]
transform = Transform3D(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"
libraries = {
"": SubResource("AnimationLibrary_5n6vs")
}
[connection signal="screen_exited" from="VisibleOnScreenNotifier3D" to="." method="_on_visible_on_screen_notifier_screen_exited"]

View File

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

View File

@@ -0,0 +1,73 @@
extends CharacterBody3D
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.
@export var fall_acceleration = 75
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(position + direction, Vector3.UP)
$AnimationPlayer.speed_scale = 4
else:
$AnimationPlayer.speed_scale = 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
move_and_slide()
# 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_collision_count()):
var collision = get_slide_collision(index)
if collision.get_collider().is_in_group("mob"):
var mob = collision.get_collider()
if Vector3.UP.dot(collision.get_normal()) > 0.1:
mob.squash()
velocity.y = bounce_impulse
# Prevent this block from running more than once,
# which would award the player more than 1 point for squashing a single mob.
break
# 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()

View File

@@ -0,0 +1,73 @@
[gd_scene load_steps=7 format=3 uid="uid://dp478jyugrn7o"]
[ext_resource type="Script" path="res://Player.gd" id="1"]
[ext_resource type="PackedScene" uid="uid://d0ypm0v45pwdv" path="res://art/player.glb" id="2"]
[sub_resource type="SphereShape3D" id="1"]
radius = 0.792278
[sub_resource type="CylinderShape3D" id="2"]
height = 0.1438
radius = 0.907607
[sub_resource type="Animation" id="3"]
length = 1.2
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.22, 0.7, 1.18),
"transitions": PackedFloat32Array(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/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Pivot/Character:rotation_degrees")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0.1, 0.46, 1.18),
"transitions": PackedFloat32Array(0.482968, 0.535887, 1),
"update": 0,
"values": [Vector3(-5.0326, 0, 0), Vector3(10, 0, 0), Vector3(-10, 0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_aq6tr"]
_data = {
"float": SubResource("3")
}
[node name="Player" type="CharacterBody3D"]
collision_mask = 2147483654
script = ExtResource("1")
[node name="Pivot" type="Node3D" parent="."]
[node name="Character" parent="Pivot" instance=ExtResource("2")]
transform = Transform3D(1, 0, 0, 0, 0.996145, 0.0877225, 0, -0.0877225, 0.996145, 0, 0.329753, 0)
[node name="CollisionShape" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.771765, 0)
shape = SubResource("1")
[node name="MobDetector" type="Area3D" parent="."]
collision_layer = 0
collision_mask = 2
monitorable = false
[node name="CollisionShape" type="CollisionShape3D" parent="MobDetector"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.06491, 0)
shape = SubResource("2")
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
autoplay = "float"
libraries = {
"": SubResource("AnimationLibrary_aq6tr")
}
[connection signal="body_entered" from="MobDetector" to="." method="_on_MobDetector_body_entered"]

View File

@@ -0,0 +1,40 @@
# Squash the Creeps (3D)
This is a simple game where your character must move
and jump to squash as many enemies for as long as possible.
You gain 1 point for every enemy squashed.
Controls:
- <kbd>Up Arrow</kbd>, <kbd>W</kbd>, <kbd>Gamepad Left Stick</kbd>: Move up
- <kbd>Down Arrow</kbd>, <kbd>S</kbd>, <kbd>Gamepad Left Stick</kbd>: Move down
- <kbd>Left Arrow</kbd>, <kbd>Gamepad Left Stick</kbd>: Move left
- <kbd>Right Arrow</kbd>, <kbd>Gamepad Left Stick</kbd>: Move right
- <kbd>Space</kbd>, <kbd>Right Mouse Button</kbd>, <kbd>Gamepad A/Cross</kbd>: Jump
This is a finished version of the game featured in the
["Your first 3D game"](https://docs.godotengine.org/en/latest/getting_started/first_3d_game/index.html)
tutorial in the documentation. For more details,
consider following the tutorial in the documentation.
This demo covers:
- Handling player input.
- Moving and jumping in a 3D game.
- Spawning enemies randomly around the game arena.
- Using the built-in animation editor to breathe life to your game.
- Creating a complete game loop with lose conditions, score, and the ability to restart.
Language: GDScript
Renderer: Forward+
## Screenshots
![Screenshot](screenshots/squash_the_creeps.webp)
## Copying
`art/House In a Forest Loop.ogg` Copyright &copy; 2012 [HorrorPen](https://opengameart.org/users/horrorpen), [CC-BY 3.0: Attribution](http://creativecommons.org/licenses/by/3.0/). Source: https://opengameart.org/content/loop-house-in-a-forest
Font is "Montserrat Medium". Copyright 2011 [The Montserrat Project Authors](https://github.com/JulietaUla/Montserrat). Details are in `fonts/LICENSE.txt`.

View File

@@ -0,0 +1,7 @@
extends Label
var score = 0
func _on_Mob_squashed():
score += 1
text = "Score: %s" % score

Binary file not shown.

View File

@@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://c5qpnfga41t4p"
path="res://.godot/imported/House In a Forest Loop.ogg-1a6a72ae843ad792b7039931227e8d50.oggvorbisstr"
[deps]
source_file="res://art/House In a Forest Loop.ogg"
dest_files=["res://.godot/imported/House In a Forest Loop.ogg-1a6a72ae843ad792b7039931227e8d50.oggvorbisstr"]
[params]
loop=true
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

View File

@@ -0,0 +1,12 @@
[gd_resource type="SpatialMaterial" format=2]
[resource]
resource_name = "body"
params_cull_mode = 2
albedo_color = Color( 0.906332, 0.353653, 0, 1 )
roughness = 0.5
emission_enabled = true
emission = Color( 0, 0, 0, 1 )
emission_energy = 1.0
emission_operator = 0
emission_on_uv2 = false

View File

@@ -0,0 +1,14 @@
[gd_resource type="SpatialMaterial" format=2]
[resource]
resource_name = "eye"
params_cull_mode = 2
albedo_color = Color( 0.858824, 0.858824, 0.858824, 1 )
metallic = 0.05
metallic_specular = 1.0
roughness = 0.1
emission_enabled = true
emission = Color( 0.254902, 0.254902, 0.27451, 1 )
emission_energy = 1.0
emission_operator = 0
emission_on_uv2 = false

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,32 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://bicorb7we351t"
path="res://.godot/imported/mob.glb-3afb43c03b9d1598b6af5154e2543eac.scn"
[deps]
source_file="res://art/mob.glb"
dest_files=["res://.godot/imported/mob.glb-3afb43c03b9d1598b6af5154e2543eac.scn"]
[params]
nodes/root_type="Spatial"
nodes/root_name="Scene Root"
nodes/apply_root_scale=true
nodes/root_scale=1.0
meshes/ensure_tangents=true
meshes/generate_lods=false
meshes/create_shadow_meshes=true
meshes/light_baking=0
meshes/lightmap_texel_size=0.1
skins/use_named_skins=true
animation/import=true
animation/fps=15
animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/embedded_image_handling=1

View File

@@ -0,0 +1,7 @@
[gd_resource type="SpatialMaterial" format=2]
[resource]
resource_name = "mob_body"
params_cull_mode = 2
albedo_color = Color( 0.0588235, 0.266667, 0.490196, 1 )
roughness = 0.43

View File

@@ -0,0 +1,14 @@
[gd_resource type="SpatialMaterial" format=2]
[resource]
resource_name = "mob_eye"
params_cull_mode = 2
albedo_color = Color( 0.760784, 0.113725, 0.188235, 1 )
metallic = 0.48
metallic_specular = 1.0
roughness = 0.25
emission_enabled = true
emission = Color( 0.74902, 0.0784314, 0.0784314, 1 )
emission_energy = 1.0
emission_operator = 0
emission_on_uv2 = false

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,32 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://d0ypm0v45pwdv"
path="res://.godot/imported/player.glb-08dcfb373480a049995065542e37637b.scn"
[deps]
source_file="res://art/player.glb"
dest_files=["res://.godot/imported/player.glb-08dcfb373480a049995065542e37637b.scn"]
[params]
nodes/root_type="Spatial"
nodes/root_name="Scene Root"
nodes/apply_root_scale=true
nodes/root_scale=1.0
meshes/ensure_tangents=true
meshes/generate_lods=false
meshes/create_shadow_meshes=true
meshes/light_baking=0
meshes/lightmap_texel_size=0.1
skins/use_named_skins=true
animation/import=true
animation/fps=15
animation/trimming=false
animation/remove_immutable_tracks=true
import_script/path=""
_subresources={}
gltf/embedded_image_handling=1

View File

@@ -0,0 +1,16 @@
[gd_resource type="SpatialMaterial" format=2]
[resource]
resource_name = "pupil"
params_cull_mode = 2
albedo_color = Color( 0, 0, 0, 1 )
metallic_specular = 1.0
roughness = 0.3
emission_enabled = true
emission = Color( 0, 0, 0, 1 )
emission_energy = 1.0
emission_operator = 0
emission_on_uv2 = false
rim_enabled = true
rim = 1.0
rim_tint = 0.5

View File

@@ -0,0 +1,43 @@
Copyright 2011 The Montserrat Project Authors (https://github.com/JulietaUla/Montserrat)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
—————————————————————————————-
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
—————————————————————————————-
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
DEFINITIONS
“Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
“Reserved Font Name” refers to any names specified as such after the copyright statement(s).
“Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s).
“Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
“Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

View File

@@ -0,0 +1,33 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://cyxhh7ddkn62q"
path="res://.godot/imported/Montserrat-Medium.ttf-e832861e4ad4110e172112dc430c04b0.fontdata"
[deps]
source_file="res://fonts/Montserrat-Medium.ttf"
dest_files=["res://.godot/imported/Montserrat-Medium.ttf-e832861e4ad4110e172112dc430c04b0.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://nev7b6ohgeo"
path="res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.webp"
dest_files=["res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
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/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

View File

@@ -0,0 +1,93 @@
; 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="Squash the Creeps (3D)"
config/description="In this game, your goal is to chase and kick out the creeps!
This is a finished version of the game featured in the \"Your first 3D game\"
tutorial in the official documentation."
run/main_scene="res://Main.tscn"
config/features=PackedStringArray("4.0")
config/icon="res://icon.webp"
[autoload]
MusicPlayer="*res://MusicPlayer.tscn"
[display]
window/stretch/mode="canvas_items"
window/stretch/aspect="expand"
window/size/width=720
window/size/height=540
window/size/test_width=480
window/size/test_height=360
[filesystem]
import/blender/enabled=false
[input]
move_left={
"deadzone": 0.5,
"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":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, 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":113,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
]
}
move_right={
"deadzone": 0.5,
"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":4194321,"key_label":0,"unicode":0,"echo":false,"script":null)
, 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":68,"key_label":0,"unicode":100,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
]
}
move_forward={
"deadzone": 0.5,
"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":4194320,"key_label":0,"unicode":0,"echo":false,"script":null)
, 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":87,"key_label":0,"unicode":122,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
]
}
move_back={
"deadzone": 0.5,
"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":4194322,"key_label":0,"unicode":0,"echo":false,"script":null)
, 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":83,"key_label":0,"unicode":115,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
]
}
jump={
"deadzone": 0.5,
"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":32,"key_label":0,"unicode":32,"echo":false,"script":null)
, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"pressed":false,"double_click":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
[layer_names]
3d_physics/layer_1="player"
3d_physics/layer_2="enemies"
3d_physics/layer_3="world"
[physics]
common/physics_ticks_per_second=120
[rendering]
anti_aliasing/quality/msaa_3d=2
quality/driver/driver_name="GLES2"
vram_compression/import_etc=true
vram_compression/import_etc2=false
quality/filters/msaa=3

View File

@@ -0,0 +1,33 @@
# Dodge the Creeps
This is a simple game where your character must move
and avoid the enemies for as long as possible.
This is a finished version of the game featured in the
["Your first 2D game"](https://docs.godotengine.org/en/latest/getting_started/first_2d_game/index.html)
tutorial in the documentation. For more details,
consider following the tutorial in the documentation.
Language: GDScript
Renderer: Vulkan Mobile
Note: There is a C# version available [here](https://github.com/godotengine/godot-demo-projects/tree/master/mono/dodge_the_creeps).
Note: There is a GDNative C++ version available [here](https://github.com/godotengine/gdnative-demos/tree/master/cpp/dodge_the_creeps).
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/515
## Screenshots
![GIF from the documentation](https://docs.godotengine.org/en/latest/_images/dodge_preview.gif)
![Screenshot](screenshots/dodge.png)
## Copying
`art/House In a Forest Loop.ogg` Copyright &copy; 2012 [HorrorPen](https://opengameart.org/users/horrorpen), [CC-BY 3.0: Attribution](http://creativecommons.org/licenses/by/3.0/). Source: https://opengameart.org/content/loop-house-in-a-forest
Images are from "Abstract Platformer". Created in 2016 by kenney.nl, [CC0 1.0 Universal](http://creativecommons.org/publicdomain/zero/1.0/). Source: https://www.kenney.nl/assets/abstract-platformer
Font is "Xolonium". Copyright &copy; 2011-2016 Severin Meyer <sev.ch@web.de>, with Reserved Font Name Xolonium, SIL open font license version 1.1. Details are in `fonts/LICENSE.txt`.

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=3 uid="uid://cqquurjk1i7yw"]
[ext_resource type="FontFile" uid="uid://cyxhh7ddkn62q" path="res://fonts/Montserrat-Medium.ttf" id="1"]
[resource]
default_font = ExtResource("1")