mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-01 13:49:12 +03:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4de36e7ea0 |
34
.github/dist/export_presets.cfg
vendored
34
.github/dist/export_presets.cfg
vendored
@@ -1,41 +1,23 @@
|
||||
[preset.0]
|
||||
|
||||
name="Web"
|
||||
platform="Web"
|
||||
name="HTML5"
|
||||
platform="HTML5"
|
||||
runnable=true
|
||||
advanced_options=false
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
include_filter="*.json"
|
||||
exclude_filter=""
|
||||
export_path=""
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
||||
script_export_mode=2
|
||||
script_export_mode=1
|
||||
script_encryption_key=""
|
||||
|
||||
[preset.0.options]
|
||||
|
||||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
variant/extensions_support=false
|
||||
variant/thread_support=true
|
||||
variant/export_type=0
|
||||
vram_texture_compression/for_desktop=true
|
||||
vram_texture_compression/for_mobile=true
|
||||
html/export_icon=true
|
||||
vram_texture_compression/for_mobile=false
|
||||
html/custom_html_shell=""
|
||||
html/head_include=""
|
||||
html/canvas_resize_policy=2
|
||||
html/focus_canvas_on_start=true
|
||||
html/experimental_virtual_keyboard=true
|
||||
progressive_web_app/enabled=true
|
||||
progressive_web_app/ensure_cross_origin_isolation_headers=true
|
||||
progressive_web_app/offline_page=""
|
||||
progressive_web_app/display=0
|
||||
progressive_web_app/orientation=1
|
||||
progressive_web_app/icon_144x144=""
|
||||
progressive_web_app/icon_180x180=""
|
||||
progressive_web_app/icon_512x512=""
|
||||
progressive_web_app/background_color=Color(0, 0, 0, 1)
|
||||
html/full_window_size=true
|
||||
|
||||
46
.github/dist/footer.html
vendored
46
.github/dist/footer.html
vendored
@@ -1,38 +1,20 @@
|
||||
<!-- The list of demos will be inserted above by the CI process. -->
|
||||
</ul>
|
||||
<h2>Unavailable demos</h2>
|
||||
<ul class="unsupported-demos">
|
||||
<li><code>2d/glow</code>: Not supported on the Compatibility rendering method (which the web platform always uses).</li>
|
||||
<li><code>2d/navigation_mesh_chunks</code>: Relies on debug-only drawing functionality which is not available in projects exported in release mode.</li>
|
||||
<li><code>2d/physics_tests</code>: Relies on debug-only drawing functionality which is not available in projects exported in release mode.</li>
|
||||
<li><code>3d/labels_and_texts</code>: Does not export in headless mode due to an engine bug (font importing infinite loop).</li>
|
||||
<li><code>3d/decals</code>: Not supported on the Compatibility rendering method (which the web platform always uses).</li>
|
||||
<li><code>3d/ik</code>: Demo is not fully ported to Godot 4 yet (even though the feature works on the web).</li>
|
||||
<li><code>3d/navigation_mesh_chunks</code>: Relies on debug-only drawing functionality which is not available in projects exported in release mode.</li>
|
||||
<li><code>3d/occlusion_culling_mesh_lod</code>: Occlusion culling is disabled by default in web builds to decrease binary size.</li>
|
||||
<li><code>3d/particles</code>: Demo mostly showcases features that are not available in Compatibility (which the web platform always uses).</li>
|
||||
<li><code>3d/physical_light_camera_units</code>: Demo is not tuned for the Compatibility rendering method (which the web platform always uses).</li>
|
||||
<li><code>3d/physics_tests</code>: Relies on debug-only drawing functionality which is not available in projects exported in release mode.</li>
|
||||
<li><code>3d/variable_rate_shading</code>: Not supported on the Compatibility rendering method (which the web platform always uses)</li>
|
||||
<li><code>3d/volumetric_fog</code>: Not supported on the Compatibility rendering method (which the web platform always uses)</li>
|
||||
<li><code>3d/voxel</code>: Freezes after a few seconds of gameplay due to web platform-specific threading issues.</li>
|
||||
<li><code>audio/bpm_sync</code>: Not functional on the web platform due to differences in the audio playback implementation.</li>
|
||||
<li><code>audio/device_changer</code>: Not relevant for the web platform, as the web browser always chooses the audio output device.</li>
|
||||
<li><code>audio/midi_piano</code>: Not functional on the web platform due to differences in the audio playback implementation.</li>
|
||||
<li><code>audio/spectrum</code>: Not functional on the web platform due to differences in the audio playback implementation.</li>
|
||||
<li><code>compute/*</code>: Not supported on the Compatibility rendering method (which the web platform always uses).</li>
|
||||
<li><code>gui/msdf_font</code>: Does not export in headless mode due to an engine bug (font importing crashes).</li>
|
||||
<li><code>gui/translation</code>: Does not export in headless mode due to an engine bug (font importing crashes).</li>
|
||||
<li><code>loading/runtime_save_load</code>: Native filesystem access is not available on the web platform.</li>
|
||||
<li><code>misc/compute_shader_heightmap</code>: Not supported on the Compatibility rendering method (which the web platform always uses).</li>
|
||||
<li><code>misc/large_world_coordinates</code>: Not supported on the Compatibility rendering method (which the web platform always uses).</li>
|
||||
<li><code>misc/matrix_transform</code>: Results are only visible in the editor.</li>
|
||||
<li><code>mobile/android_iap</code>: Only relevant on native Android.</li>
|
||||
<li><code>mobile/sensors</code>: Not supported on the web platform.</li>
|
||||
<li><code>mono/*</code>: Not available yet (requires Mono-enabled HTML5 build).</li>
|
||||
<li><code>networking/*</code>: Doesn't make sense to be hosted on a static host, as the server must be hosted on the same origin due to the browser's same-origin policy.</li>
|
||||
<li><code>plugins/*</code>: Only effective within the editor.</li>
|
||||
<li><code>xr/*</code>: Not functional on the web platform, as these demos are not designed for WebXR.</li>
|
||||
<ul>
|
||||
<li><code>2d/hdr/</code>: Not supported on HTML5 yet.</li>
|
||||
<li><code>3d/global_illumination/</code>: Not supported on HTML5 yet (freezes the browser).</li>
|
||||
<li><code>3d/voxel/</code>: Not supported on HTML5 yet.</li>
|
||||
<li><code>audio/device_changer/</code>: Not supported on HTML5 due to browser limitations.</li>
|
||||
<li><code>loading/background_load/</code>: Not supported on HTML5 yet.</li>
|
||||
<li><code>loading/multiple_threads_loading/</code>: Not supported on HTML5 yet.</li>
|
||||
<li><code>loading/threads/</code>: Not supported on HTML5 yet.</li>
|
||||
<li><code>misc/matrix_transform/</code>: Results are only visible in the editor.</li>
|
||||
<li><code>mobile/android_iap/</code>: Only relevant on native Android.</li>
|
||||
<li><code>mobile/sensors/</code>: Not supported on HTML5 yet.</li>
|
||||
<li><code>mono/*/</code>: Not available yet (requires Mono-enabled HTML5 build).</li>
|
||||
<li><code>networking/*/</code>: Doesn't make sense to be hosted on a static host, as the server must be hosted on the same origin due to the browser's same-origin policy.</li>
|
||||
<li><code>plugins/*/</code>: Only effective within the editor.</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
22
.github/dist/header.html
vendored
22
.github/dist/header.html
vendored
@@ -4,15 +4,13 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Official Godot demos exported to Web</title>
|
||||
<title>Godot demos exported to HTML5</title>
|
||||
<style>
|
||||
:root {
|
||||
--background-color: #fff;
|
||||
--text-color: #222;
|
||||
--link-color: hsl(220, 100%, 45%);
|
||||
--link-visited-color: hsl(270, 100%, 55%);
|
||||
--link-underline-color: hsla(220, 100%, 45%, 0.3);
|
||||
--link-underline-visited-color: hsla(270, 100%, 45%, 0.3);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
@@ -20,9 +18,7 @@
|
||||
--background-color: #222;
|
||||
--text-color: #eee;
|
||||
--link-color: hsl(200, 100%, 70%);
|
||||
--link-visited-color: hsl(250, 100%, 80%);
|
||||
--link-underline-color: hsla(200, 100%, 70%, 0.3);
|
||||
--link-underline-visited-color: hsla(250, 100%, 70%, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,11 +52,6 @@
|
||||
text-decoration-thickness: 0.125rem;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: var(--link-visited-color);
|
||||
text-decoration-color: var(--link-visited-color);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
filter: brightness(117.5%);
|
||||
}
|
||||
@@ -97,9 +88,6 @@
|
||||
margin: 20px 10px;
|
||||
}
|
||||
|
||||
.unsupported-demos li {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -108,12 +96,12 @@
|
||||
<p>
|
||||
This page lists
|
||||
<a href="https://github.com/godotengine/godot-demo-projects">official Godot demo projects</a>
|
||||
exported to the web for testing purposes. These projects are deployed automatically
|
||||
exported to HTML5 for testing purposes. These projects are deployed automatically
|
||||
on every commit on the <code>master</code> branch of the repository.
|
||||
</p>
|
||||
<p>
|
||||
The web exports on this page are provided for demonstration purposes only.
|
||||
Some of these demos may not function or render correctly on the web platform,
|
||||
The HTML5 exports on this page are provided for demonstration purposes only.
|
||||
Some of these demos may not function or render correctly on HTML5,
|
||||
especially on mobile devices.
|
||||
For best performance, it's recommended to
|
||||
<a href="https://godotengine.org/download">download</a> a native editor
|
||||
@@ -122,7 +110,7 @@
|
||||
<p>
|
||||
See the
|
||||
<a href="https://docs.godotengine.org/en/stable/getting_started/workflow/export/exporting_for_web.html">Exporting for the Web</a>
|
||||
documentation for information on exporting your own projects to the web.
|
||||
documentation for information on exporting your own projects to HTML5.
|
||||
</p>
|
||||
|
||||
<h2>List of demos</h2>
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -21,6 +21,3 @@ mono_crash.*.json
|
||||
.DS_Store
|
||||
*~
|
||||
*.blend1
|
||||
|
||||
# Jetbrains IDE files
|
||||
.idea/
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
These demos are all 2D, but otherwise do not have a common theme.
|
||||
|
||||
Languages: Most have GDScript, some have
|
||||
[Godot shader language](https://docs.godotengine.org/en/latest/tutorials/shaders/shader_reference/shading_language.html)
|
||||
[GDSL](https://docs.godotengine.org/en/latest/tutorials/shaders/shader_reference/shading_language.html)
|
||||
|
||||
Renderers: Glow for 2D and Physics Platformer use Forward+, 2D Particles uses Mobile, and the rest use Compatibility
|
||||
Renderers: 4 of them are GLES 3, but most are GLES 2
|
||||
|
||||
@@ -9,9 +9,9 @@ in the documentation for more information.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
Renderer: Vulkan Mobile
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2711
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/887
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -8,28 +8,28 @@ const BULLET_COUNT = 500
|
||||
const SPEED_MIN = 20
|
||||
const SPEED_MAX = 80
|
||||
|
||||
const bullet_image := preload("res://bullet.png")
|
||||
const bullet_image = preload("res://bullet.png")
|
||||
|
||||
var bullets := []
|
||||
var shape := RID()
|
||||
var shape
|
||||
|
||||
|
||||
class Bullet:
|
||||
var position := Vector2()
|
||||
var speed := 1.0
|
||||
var position = Vector2()
|
||||
var speed = 1.0
|
||||
# The body is stored as a RID, which is an "opaque" way to access resources.
|
||||
# With large amounts of objects (thousands or more), it can be significantly
|
||||
# faster to use RIDs compared to a high-level approach.
|
||||
var body := RID()
|
||||
var body = RID()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
func _ready():
|
||||
shape = PhysicsServer2D.circle_shape_create()
|
||||
# Set the collision shape's radius for each bullet in pixels.
|
||||
PhysicsServer2D.shape_set_data(shape, 8)
|
||||
|
||||
for _i in BULLET_COUNT:
|
||||
var bullet := Bullet.new()
|
||||
var bullet = Bullet.new()
|
||||
# Give each bullet its own random speed.
|
||||
bullet.speed = randf_range(SPEED_MIN, SPEED_MAX)
|
||||
bullet.body = PhysicsServer2D.body_create()
|
||||
@@ -45,22 +45,22 @@ func _ready() -> void:
|
||||
randf_range(0, get_viewport_rect().size.x) + get_viewport_rect().size.x,
|
||||
randf_range(0, get_viewport_rect().size.y)
|
||||
)
|
||||
var transform2d := Transform2D()
|
||||
var transform2d = Transform2D()
|
||||
transform2d.origin = bullet.position
|
||||
PhysicsServer2D.body_set_state(bullet.body, PhysicsServer2D.BODY_STATE_TRANSFORM, transform2d)
|
||||
|
||||
bullets.push_back(bullet)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
func _process(_delta):
|
||||
# Order the CanvasItem to update every frame.
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var transform2d := Transform2D()
|
||||
var offset := get_viewport_rect().size.x + 16
|
||||
for bullet: Bullet in bullets:
|
||||
func _physics_process(delta):
|
||||
var transform2d = Transform2D()
|
||||
var offset = get_viewport_rect().size.x + 16
|
||||
for bullet in bullets:
|
||||
bullet.position.x -= bullet.speed * delta
|
||||
|
||||
if bullet.position.x < -16:
|
||||
@@ -73,15 +73,15 @@ func _physics_process(delta: float) -> void:
|
||||
|
||||
# Instead of drawing each bullet individually in a script attached to each bullet,
|
||||
# we are drawing *all* the bullets at once here.
|
||||
func _draw() -> void:
|
||||
var offset := -bullet_image.get_size() * 0.5
|
||||
for bullet: Bullet in bullets:
|
||||
func _draw():
|
||||
var offset = -bullet_image.get_size() * 0.5
|
||||
for bullet in bullets:
|
||||
draw_texture(bullet_image, bullet.position + offset)
|
||||
|
||||
|
||||
# Perform cleanup operations (required to exit without error messages in the console).
|
||||
func _exit_tree() -> void:
|
||||
for bullet: Bullet in bullets:
|
||||
func _exit_tree():
|
||||
for bullet in bullets:
|
||||
PhysicsServer2D.free_rid(bullet.body)
|
||||
|
||||
PhysicsServer2D.free_rid(shape)
|
||||
|
||||
@@ -4,32 +4,32 @@ extends Node2D
|
||||
# efficient than using instancing and nodes, but requires more programming and
|
||||
# is less visual. Bullets are managed together in the `bullets.gd` script.
|
||||
|
||||
## The number of bullets currently touched by the player.
|
||||
var touching := 0
|
||||
# The number of bullets currently touched by the player.
|
||||
var touching = 0
|
||||
|
||||
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
|
||||
@onready var sprite = $AnimatedSprite2D
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
func _ready():
|
||||
# The player follows the mouse cursor automatically, so there's no point
|
||||
# in displaying the mouse cursor.
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
func _input(event):
|
||||
# Getting the movement of the mouse so the sprite can follow its position.
|
||||
if event is InputEventMouseMotion:
|
||||
position = event.position - Vector2(0, 16)
|
||||
|
||||
|
||||
func _on_body_shape_entered(_body_id: RID, _body: Node2D, _body_shape_index: int, _local_shape_index: int) -> void:
|
||||
func _on_body_shape_entered(_body_id, _body, _body_shape, _local_shape):
|
||||
# Player got touched by a bullet so sprite changes to sad face.
|
||||
touching += 1
|
||||
if touching >= 1:
|
||||
sprite.frame = 1
|
||||
|
||||
|
||||
func _on_body_shape_exited(_body_id: RID, _body: Node2D, _body_shape_index: int, _local_shape_index: int) -> void:
|
||||
func _on_body_shape_exited(_body_id, _body, _body_shape, _local_shape):
|
||||
touching -= 1
|
||||
# When non of the bullets are touching the player,
|
||||
# sprite changes to happy face.
|
||||
|
||||
@@ -17,10 +17,6 @@ run/main_scene="res://shower.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
@@ -30,7 +26,10 @@ window/stretch/aspect="expand"
|
||||
|
||||
2d_physics/layer_1="Player"
|
||||
|
||||
[physics]
|
||||
|
||||
2d/cell_size=64
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
renderer/rendering_method="mobile"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://ccqoreueuxdb7"]
|
||||
[gd_scene load_steps=4 format=3 uid="uid://ccqoreueuxdb7"]
|
||||
|
||||
[ext_resource type="Script" path="res://hud.gd" id="1"]
|
||||
[ext_resource type="FontFile" uid="uid://cit6gwe5px1q8" path="res://fonts/Xolonium-Regular.ttf" id="2_2jm3i"]
|
||||
[ext_resource type="Script" path="res://HUD.gd" id="1"]
|
||||
|
||||
[sub_resource type="InputEventAction" id="InputEventAction_fopy7"]
|
||||
action = &"start_game"
|
||||
@@ -17,7 +16,6 @@ anchors_preset = 10
|
||||
anchor_right = 1.0
|
||||
offset_bottom = 78.0
|
||||
grow_horizontal = 2
|
||||
theme_override_fonts/font = ExtResource("2_2jm3i")
|
||||
theme_override_font_sizes/font_size = 60
|
||||
text = "0"
|
||||
horizontal_alignment = 1
|
||||
@@ -31,7 +29,6 @@ offset_top = -79.5
|
||||
offset_bottom = 79.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_fonts/font = ExtResource("2_2jm3i")
|
||||
theme_override_font_sizes/font_size = 60
|
||||
text = "Dodge the
|
||||
Creeps"
|
||||
@@ -49,7 +46,6 @@ offset_right = 90.0
|
||||
offset_bottom = -100.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
theme_override_fonts/font = ExtResource("2_2jm3i")
|
||||
theme_override_font_sizes/font_size = 60
|
||||
shortcut = SubResource("4")
|
||||
text = "Start"
|
||||
@@ -29,12 +29,12 @@ func _on_MobTimer_timeout():
|
||||
var mob_spawn_location = get_node(^"MobPath/MobSpawnLocation")
|
||||
mob_spawn_location.progress = randi()
|
||||
|
||||
# Set the mob's position to a random location.
|
||||
mob.position = mob_spawn_location.position
|
||||
|
||||
# Set the mob's direction perpendicular to the path direction.
|
||||
var direction = mob_spawn_location.rotation + PI / 2
|
||||
|
||||
# Set the mob's position to a random location.
|
||||
mob.position = mob_spawn_location.position
|
||||
|
||||
# Add some randomness to the direction.
|
||||
direction += randf_range(-PI / 4, PI / 4)
|
||||
mob.rotation = direction
|
||||
@@ -1,11 +1,11 @@
|
||||
[gd_scene load_steps=8 format=3 uid="uid://cyfwty2q3rdse"]
|
||||
|
||||
[ext_resource type="Script" path="res://main.gd" id="1_0r6n5"]
|
||||
[ext_resource type="PackedScene" uid="uid://rkdnhqgf2hpj" path="res://mob.tscn" id="2_50pww"]
|
||||
[ext_resource type="PackedScene" uid="uid://4vwrqjegqwpj" path="res://player.tscn" id="3_veqnc"]
|
||||
[ext_resource type="PackedScene" uid="uid://ccqoreueuxdb7" path="res://hud.tscn" id="4_0qnje"]
|
||||
[ext_resource type="AudioStream" uid="uid://q2pf4fr8d0ks" path="res://art/House In a Forest Loop.ogg" id="5_55d8h"]
|
||||
[ext_resource type="AudioStream" uid="uid://dw26fpygeag8o" path="res://art/gameover.wav" id="6_hp1r0"]
|
||||
[ext_resource type="Script" path="res://Main.gd" id="1"]
|
||||
[ext_resource type="PackedScene" uid="uid://rkdnhqgf2hpj" path="res://Mob.tscn" id="2"]
|
||||
[ext_resource type="PackedScene" uid="uid://4vwrqjegqwpj" path="res://Player.tscn" id="3"]
|
||||
[ext_resource type="PackedScene" uid="uid://ccqoreueuxdb7" path="res://HUD.tscn" id="4"]
|
||||
[ext_resource type="AudioStream" uid="uid://q2pf4fr8d0ks" path="res://art/House In a Forest Loop.ogg" id="5"]
|
||||
[ext_resource type="AudioStream" uid="uid://dw26fpygeag8o" path="res://art/gameover.wav" id="6"]
|
||||
|
||||
[sub_resource type="Curve2D" id="1"]
|
||||
_data = {
|
||||
@@ -14,8 +14,8 @@ _data = {
|
||||
point_count = 5
|
||||
|
||||
[node name="Main" type="Node"]
|
||||
script = ExtResource("1_0r6n5")
|
||||
mob_scene = ExtResource("2_50pww")
|
||||
script = ExtResource("1")
|
||||
mob_scene = ExtResource("2")
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="."]
|
||||
anchors_preset = 15
|
||||
@@ -25,7 +25,7 @@ grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0.219608, 0.372549, 0.380392, 1)
|
||||
|
||||
[node name="Player" parent="." instance=ExtResource("3_veqnc")]
|
||||
[node name="Player" parent="." instance=ExtResource("3")]
|
||||
|
||||
[node name="MobTimer" type="Timer" parent="."]
|
||||
wait_time = 0.5
|
||||
@@ -44,13 +44,13 @@ curve = SubResource("1")
|
||||
|
||||
[node name="MobSpawnLocation" type="PathFollow2D" parent="MobPath"]
|
||||
|
||||
[node name="HUD" parent="." instance=ExtResource("4_0qnje")]
|
||||
[node name="HUD" parent="." instance=ExtResource("4")]
|
||||
|
||||
[node name="Music" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource("5_55d8h")
|
||||
stream = ExtResource("5")
|
||||
|
||||
[node name="DeathSound" type="AudioStreamPlayer" parent="."]
|
||||
stream = ExtResource("6_hp1r0")
|
||||
stream = ExtResource("6")
|
||||
|
||||
[connection signal="hit" from="Player" to="." method="game_over"]
|
||||
[connection signal="timeout" from="MobTimer" to="." method="_on_MobTimer_timeout"]
|
||||
@@ -1,9 +1,9 @@
|
||||
extends RigidBody2D
|
||||
|
||||
func _ready():
|
||||
$AnimatedSprite2D.play()
|
||||
var mob_types = Array($AnimatedSprite2D.sprite_frames.get_animation_names())
|
||||
$AnimatedSprite2D.animation = mob_types.pick_random()
|
||||
$AnimatedSprite2D.play()
|
||||
|
||||
|
||||
func _on_VisibilityNotifier2D_screen_exited():
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=10 format=3 uid="uid://rkdnhqgf2hpj"]
|
||||
|
||||
[ext_resource type="Script" path="res://mob.gd" id="1"]
|
||||
[ext_resource type="Script" path="res://Mob.gd" id="1"]
|
||||
[ext_resource type="Texture2D" uid="uid://yqglrrsx7j1f" path="res://art/enemyFlyingAlt_1.png" id="2"]
|
||||
[ext_resource type="Texture2D" uid="uid://bpot8awhdn6ph" path="res://art/enemyFlyingAlt_2.png" id="3"]
|
||||
[ext_resource type="Texture2D" uid="uid://bu4221t7qpa7d" path="res://art/enemyWalking_1.png" id="4"]
|
||||
@@ -47,7 +47,7 @@ func start(pos):
|
||||
$CollisionShape2D.disabled = false
|
||||
|
||||
|
||||
func _on_body_entered(_body):
|
||||
func _on_Player_body_entered(_body):
|
||||
hide() # Player disappears after being hit.
|
||||
hit.emit()
|
||||
# Must be deferred as we can't change physics properties on a physics callback.
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=13 format=3 uid="uid://4vwrqjegqwpj"]
|
||||
|
||||
[ext_resource type="Script" path="res://player.gd" id="1"]
|
||||
[ext_resource type="Script" path="res://Player.gd" id="1"]
|
||||
[ext_resource type="Texture2D" uid="uid://ftkxr8r4qghp" path="res://art/playerGrey_walk1.png" id="2"]
|
||||
[ext_resource type="Texture2D" uid="uid://couyhcegeihme" path="res://art/playerGrey_walk2.png" id="3"]
|
||||
[ext_resource type="Texture2D" uid="uid://b4yyoafu8bi0q" path="res://art/playerGrey_up1.png" id="4"]
|
||||
@@ -72,4 +72,4 @@ process_material = SubResource("7")
|
||||
texture = ExtResource("2")
|
||||
speed_scale = 2.0
|
||||
|
||||
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
|
||||
[connection signal="body_entered" from="." to="." method="_on_Player_body_entered"]
|
||||
@@ -10,11 +10,13 @@ consider following the tutorial in the documentation.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
Renderer: Vulkan Mobile
|
||||
|
||||
Note: There is a C# version available [here](https://github.com/godotengine/godot-demo-projects/tree/master/mono/dodge_the_creeps).
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2712
|
||||
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
|
||||
|
||||
|
||||
6
2d/dodge_the_creeps/fonts/Xolonium-Regular.tres
Normal file
6
2d/dodge_the_creeps/fonts/Xolonium-Regular.tres
Normal file
@@ -0,0 +1,6 @@
|
||||
[gd_resource type="Font" load_steps=2 format=3 uid="uid://dyjc58f6sdms0"]
|
||||
|
||||
[ext_resource type="FontData" uid="uid://cit6gwe5px1q8" path="res://fonts/Xolonium-Regular.ttf" id="1_mnk3h"]
|
||||
|
||||
[resource]
|
||||
data/0 = ExtResource( "1_mnk3h" )
|
||||
@@ -18,10 +18,14 @@ This is a finished version of the game featured in the 'Your first 2D game'
|
||||
tutorial in the documentation. For more details, consider
|
||||
following the tutorial in the documentation."
|
||||
config/tags=PackedStringArray("2d", "demo", "official")
|
||||
run/main_scene="res://main.tscn"
|
||||
run/main_scene="res://Main.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/redundant_await=false
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=480
|
||||
@@ -33,7 +37,7 @@ window/stretch/mode="canvas_items"
|
||||
[input]
|
||||
|
||||
move_left={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
|
||||
@@ -41,7 +45,7 @@ move_left={
|
||||
]
|
||||
}
|
||||
move_right={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
|
||||
@@ -49,7 +53,7 @@ move_right={
|
||||
]
|
||||
}
|
||||
move_up={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
@@ -57,7 +61,7 @@ move_up={
|
||||
]
|
||||
}
|
||||
move_down={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||
@@ -65,7 +69,7 @@ move_down={
|
||||
]
|
||||
}
|
||||
start_game={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
]
|
||||
@@ -73,5 +77,4 @@ start_game={
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
renderer/rendering_method="mobile"
|
||||
|
||||
@@ -6,9 +6,7 @@ to disable collisions per layer.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2713
|
||||
Renderer: OpenGL
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
extends TileMapLayer
|
||||
extends TileMap
|
||||
|
||||
# You can have multiple layers if you make this an array.
|
||||
var player_in_secret := false
|
||||
|
||||
var secret_layer: int # You can have multiple layers if you make this an array.
|
||||
var player_in_secret: bool
|
||||
var layer_alpha := 1.0
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
for i in get_layers_count(): # Find the secret layer by name.
|
||||
if get_layer_name(i) == "Secret":
|
||||
secret_layer = i
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
set_process(false)
|
||||
|
||||
@@ -12,31 +19,30 @@ func _ready() -> void:
|
||||
func _process(delta: float) -> void:
|
||||
if player_in_secret:
|
||||
if layer_alpha > 0.3:
|
||||
# Animate the layer transparency.
|
||||
layer_alpha = move_toward(layer_alpha, 0.3, delta)
|
||||
self_modulate = Color(1, 1, 1, layer_alpha)
|
||||
layer_alpha = move_toward(layer_alpha, 0.3, delta) # Animate the layer transparency.
|
||||
set_layer_modulate(secret_layer, Color(1, 1, 1, layer_alpha))
|
||||
else:
|
||||
set_process(false)
|
||||
else:
|
||||
if layer_alpha < 1.0:
|
||||
layer_alpha = move_toward(layer_alpha, 1.0, delta)
|
||||
self_modulate = Color(1, 1, 1, layer_alpha)
|
||||
set_layer_modulate(secret_layer, Color(1, 1, 1, layer_alpha))
|
||||
else:
|
||||
set_process(false)
|
||||
|
||||
|
||||
func _use_tile_data_runtime_update(_coords: Vector2i) -> bool:
|
||||
return true
|
||||
func _use_tile_data_runtime_update(layer: int, _coords: Vector2i) -> bool:
|
||||
if layer == secret_layer:
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func _tile_data_runtime_update(_coords: Vector2i, tile_data: TileData) -> void:
|
||||
# Remove collision for secret layer.
|
||||
tile_data.set_collision_polygons_count(0, 0)
|
||||
func _tile_data_runtime_update(_layer: int, _coords: Vector2i, tile_data: TileData) -> void:
|
||||
tile_data.set_collision_polygons_count(0, 0) # Remove collision for secret layer.
|
||||
|
||||
|
||||
func _on_secret_detector_body_entered(body: Node2D) -> void:
|
||||
if body is not CharacterBody2D:
|
||||
# Detect the player only.
|
||||
if not body is CharacterBody2D: # Detect player only.
|
||||
return
|
||||
|
||||
player_in_secret = true
|
||||
@@ -44,7 +50,7 @@ func _on_secret_detector_body_entered(body: Node2D) -> void:
|
||||
|
||||
|
||||
func _on_secret_detector_body_exited(body: Node2D) -> void:
|
||||
if body is not CharacterBody2D:
|
||||
if not body is CharacterBody2D:
|
||||
return
|
||||
|
||||
player_in_secret = false
|
||||
|
||||
@@ -5,11 +5,11 @@ const WALK_MAX_SPEED = 200
|
||||
const STOP_FORCE = 1300
|
||||
const JUMP_SPEED = 200
|
||||
|
||||
@onready var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")
|
||||
@onready var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
func _physics_process(delta):
|
||||
# Horizontal movement code. First, get the player's input.
|
||||
var walk := WALK_FORCE * (Input.get_axis(&"move_left", &"move_right"))
|
||||
var walk = WALK_FORCE * (Input.get_axis(&"move_left", &"move_right"))
|
||||
# Slow down the player if they're not trying to move.
|
||||
if abs(walk) < WALK_FORCE * 0.2:
|
||||
# The velocity, slowed down a bit, and then reassigned.
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://1o70ce0fv10w"]
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource type="Script" path="res://player/player.gd" id="1"]
|
||||
[ext_resource type="Texture2D" uid="uid://dfb8rr2fakwgp" path="res://player/player.png" id="2"]
|
||||
[ext_resource path="res://player/player.gd" type="Script" id=1]
|
||||
[ext_resource path="res://player/player.png" type="Texture2D" id=2]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="1"]
|
||||
size = Vector2(14, 14)
|
||||
[sub_resource type="RectangleShape2D" id=1]
|
||||
extents = Vector2(7, 7)
|
||||
|
||||
[node name="Player" type="CharacterBody2D"]
|
||||
script = ExtResource("1")
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture = ExtResource("2")
|
||||
texture = ExtResource( 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
position = Vector2(-0.315559, 0.157784)
|
||||
shape = SubResource("1")
|
||||
shape = SubResource( 1 )
|
||||
|
||||
@@ -14,15 +14,10 @@ config/name="Dynamic TileMap Layers"
|
||||
config/description="Example of how to make a kinematic character controller in 2D using
|
||||
CharacterBody2D. The character moves around, is affected by moving
|
||||
platforms, can jump through one-way collision platforms, etc."
|
||||
config/tags=PackedStringArray("2d", "demo", "official", "tilemap")
|
||||
run/main_scene="res://world.tscn"
|
||||
config/features=PackedStringArray("4.3")
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=530
|
||||
@@ -33,29 +28,29 @@ window/stretch/aspect="expand"
|
||||
[input]
|
||||
|
||||
jump={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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)
|
||||
]
|
||||
}
|
||||
move_left={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"location":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":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":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":4194319,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_right={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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)
|
||||
]
|
||||
}
|
||||
|
||||
@@ -67,5 +62,5 @@ common/physics_ticks_per_second=120
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
environment/defaults/default_clear_color=Color(0.156863, 0.133333, 0.25098, 1)
|
||||
anti_aliasing/quality/msaa_2d=2
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
[gd_scene load_steps=8 format=4 uid="uid://de7qapkqfycxl"]
|
||||
[gd_scene load_steps=8 format=3 uid="uid://de7qapkqfycxl"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://cs8h2qyuakmko" path="res://level/obstacle.png" id="2"]
|
||||
[ext_resource type="Script" path="res://level/tile_map.gd" id="2_q8fhk"]
|
||||
[ext_resource type="PackedScene" uid="uid://1o70ce0fv10w" path="res://player/player.tscn" id="3"]
|
||||
[ext_resource type="PackedScene" path="res://player/player.tscn" id="3"]
|
||||
|
||||
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_on5ov"]
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_vnjib"]
|
||||
texture = ExtResource("2")
|
||||
0:0/0 = 0
|
||||
0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
0:0/0/physics_layer_0/angular_velocity = 0.0
|
||||
0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
1:0/0 = 0
|
||||
1:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
1:0/0/physics_layer_0/angular_velocity = 0.0
|
||||
|
||||
[sub_resource type="TileSet" id="TileSet_xqlka"]
|
||||
physics_layer_0/collision_layer = 1
|
||||
@@ -21,15 +26,19 @@ size = Vector2(112, 48)
|
||||
|
||||
[node name="World" type="Node2D"]
|
||||
|
||||
[node name="Ground" type="TileMapLayer" parent="."]
|
||||
use_parent_material = true
|
||||
tile_map_data = PackedByteArray("AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAA0AAAAAAAAAAAAAAA4AAAAAAAAAAAAAAA8AAAAAAAAAAAAAABAAAAAAAAAAAAAAABEAAAAAAAAAAAAAABIAAAAAAAAAAAAAABMAAAAAAAAAAAAAABQAAAAAAAAAAAAAABUAAAAAAAAAAAAAABYAAAAAAAAAAAAAABcAAAAAAAAAAAAAABgAAAAAAAAAAAAAABkAAAAAAAAAAAAAABoAAAAAAAAAAAAAABsAAAAAAAAAAAAAABwAAAAAAAAAAAAAAB0AAAAAAAAAAAAAAB4AAAAAAAAAAAABAAAAAAAAAAAAAAABAAEAAAAAAAAAAAABAAIAAAAAAAAAAAABAAMAAAAAAAAAAAABAAQAAAAAAAAAAAABAAUAAAAAAAAAAAABAAYAAAAAAAAAAAABAAcAAAAAAAAAAAABAAgAAAAAAAAAAAABAAkAAAAAAAAAAAABAAoAAAAAAAAAAAABAAsAAAAAAAAAAAABAAwAAAAAAAAAAAABAA0AAAAAAAAAAAABAA4AAAAAAAAAAAABAA8AAAAAAAAAAAABABAAAAAAAAAAAAABABEAAAAAAAAAAAABABIAAAAAAAAAAAABABMAAAAAAAAAAAABABQAAAAAAAAAAAABABUAAAAAAAAAAAABABYAAAAAAAAAAAABABcAAAAAAAAAAAABABgAAAAAAAAAAAABABkAAAAAAAAAAAABABoAAAAAAAAAAAABABsAAAAAAAAAAAABABwAAAAAAAAAAAABAB0AAAAAAAAAAAABAB4AAAAAAAAAAAACAAAAAAAAAAAAAAACAAEAAAAAAAAAAAACAB0AAAAAAAAAAAACAB4AAAAAAAAAAAADAAAAAAAAAAAAAAADAAEAAAAAAAAAAAADAB0AAAAAAAAAAAADAB4AAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAEAAAAAAAAAAAAEAB0AAAAAAAAAAAAEAB4AAAAAAAAAAAAFAAAAAAAAAAAAAAAFAAEAAAAAAAAAAAAFAB0AAAAAAAAAAAAFAB4AAAAAAAAAAAAGAAAAAAAAAAAAAAAGAAEAAAAAAAAAAAAGAB0AAAAAAAAAAAAGAB4AAAAAAAAAAAAHAAAAAAAAAAAAAAAHAAEAAAAAAAAAAAAHAB0AAAAAAAAAAAAHAB4AAAAAAAAAAAAIAAAAAAAAAAAAAAAIAAEAAAAAAAAAAAAIAB0AAAAAAAAAAAAIAB4AAAAAAAAAAAAJAAAAAAAAAAAAAAAJAAEAAAAAAAAAAAAJAB0AAAAAAAAAAAAJAB4AAAAAAAAAAAAKAAAAAAAAAAAAAAAKAAEAAAAAAAAAAAAKAB0AAAAAAAAAAAAKAB4AAAAAAAAAAAALAAAAAAAAAAAAAAALAAEAAAAAAAAAAAALAB0AAAAAAAAAAAALAB4AAAAAAAAAAAAMAAAAAAAAAAAAAAAMAAEAAAAAAAAAAAAMAB0AAAAAAAAAAAAMAB4AAAAAAAAAAAANAAAAAAAAAAAAAAANAAEAAAAAAAAAAAANAB0AAAAAAAAAAAANAB4AAAAAAAAAAAAOAAAAAAAAAAAAAAAOAAEAAAAAAAAAAAAOAB0AAAAAAAAAAAAOAB4AAAAAAAAAAAAPAAAAAAAAAAAAAAAPAAEAAAAAAAAAAAAPAB0AAAAAAAAAAAAPAB4AAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAEAAAAAAAAAAAAQAB0AAAAAAAAAAAAQAB4AAAAAAAAAAAARAAAAAAAAAAAAAAARAAEAAAAAAAAAAAARAB0AAAAAAAAAAAARAB4AAAAAAAAAAAASAAAAAAAAAAAAAAASAAEAAAAAAAAAAAASAB0AAAAAAAAAAAASAB4AAAAAAAAAAAATAAAAAAAAAAAAAAATAAEAAAAAAAAAAAATAB0AAAAAAAAAAAATAB4AAAAAAAAAAAAUAAAAAAAAAAAAAAAUAAEAAAAAAAAAAAAUAB0AAAAAAAAAAAAUAB4AAAAAAAAAAAAVAAAAAAAAAAAAAAAVAAEAAAAAAAAAAAAVAB0AAAAAAAAAAAAVAB4AAAAAAAAAAAAWAAAAAAAAAAAAAAAWAAEAAAAAAAAAAAAWAB0AAAAAAAAAAAAWAB4AAAAAAAAAAAAXAAAAAAAAAAAAAAAXAAEAAAAAAAAAAAAXAB0AAAAAAAAAAAAXAB4AAAAAAAAAAAAYAAAAAAAAAAAAAAAYAAEAAAAAAAAAAAAYAB0AAAAAAAAAAAAYAB4AAAAAAAAAAAAZAAAAAAAAAAAAAAAZAAEAAAAAAAAAAAAZAB0AAAAAAAAAAAAZAB4AAAAAAAAAAAAaAAAAAAAAAAAAAAAaAAEAAAAAAAAAAAAaAB0AAAAAAAAAAAAaAB4AAAAAAAAAAAAbAAAAAAAAAAAAAAAbAAEAAAAAAAAAAAAbAB0AAAAAAAAAAAAbAB4AAAAAAAAAAAAcAAAAAAAAAAAAAAAcAAEAAAAAAAAAAAAcAB0AAAAAAAAAAAAcAB4AAAAAAAAAAAAdAAAAAAAAAAAAAAAdAAEAAAAAAAAAAAAdAB0AAAAAAAAAAAAdAB4AAAAAAAAAAAAeAAAAAAAAAAAAAAAeAAEAAAAAAAAAAAAeAB0AAAAAAAAAAAAeAB4AAAAAAAAAAAAfAAAAAAAAAAAAAAAfAAEAAAAAAAAAAAAfAAIAAAAAAAAAAAAfAAMAAAAAAAAAAAAfAAQAAAAAAAAAAAAfAAUAAAAAAAAAAAAfAAYAAAAAAAAAAAAfAAcAAAAAAAAAAAAfAAgAAAAAAAAAAAAfAAkAAAAAAAAAAAAfAAoAAAAAAAAAAAAfAAsAAAAAAAAAAAAfAAwAAAAAAAAAAAAfAA0AAAAAAAAAAAAfAA4AAAAAAAAAAAAfAA8AAAAAAAAAAAAfABAAAAAAAAAAAAAfABEAAAAAAAAAAAAfABIAAAAAAAAAAAAfABMAAAAAAAAAAAAfABQAAAAAAAAAAAAfABUAAAAAAAAAAAAfABYAAAAAAAAAAAAfABcAAAAAAAAAAAAfABgAAAAAAAAAAAAfABkAAAAAAAAAAAAfABoAAAAAAAAAAAAfABsAAAAAAAAAAAAfABwAAAAAAAAAAAAfAB0AAAAAAAAAAAAfAB4AAAAAAAAAAAAgAAAAAAAAAAAAAAAgAAEAAAAAAAAAAAAgAAIAAAAAAAAAAAAgAAMAAAAAAAAAAAAgAAQAAAAAAAAAAAAgAAUAAAAAAAAAAAAgAAYAAAAAAAAAAAAgAAcAAAAAAAAAAAAgAAgAAAAAAAAAAAAgAAkAAAAAAAAAAAAgAAoAAAAAAAAAAAAgAAsAAAAAAAAAAAAgAAwAAAAAAAAAAAAgAA0AAAAAAAAAAAAgAA4AAAAAAAAAAAAgAA8AAAAAAAAAAAAgABAAAAAAAAAAAAAgABEAAAAAAAAAAAAgABIAAAAAAAAAAAAgABMAAAAAAAAAAAAgABQAAAAAAAAAAAAgABUAAAAAAAAAAAAgABYAAAAAAAAAAAAgABcAAAAAAAAAAAAgABgAAAAAAAAAAAAgABkAAAAAAAAAAAAgABoAAAAAAAAAAAAgABsAAAAAAAAAAAAgABwAAAAAAAAAAAAgAB0AAAAAAAAAAAAgAB4AAAAAAAAAAAAOABgAAAAAAAAAAAAPABgAAAAAAAAAAAAQABgAAAAAAAAAAAARABgAAAAAAAAAAAASABgAAAAAAAAAAAATABgAAAAAAAAAAAAUABgAAAAAAAAAAAAUABcAAAAAAAAAAAAUABYAAAAAAAAAAAATABYAAAAAAAAAAAASABYAAAAAAAAAAAARABYAAAAAAAAAAAAQABYAAAAAAAAAAAAPABYAAAAAAAAAAAAOABYAAAAAAAAAAAAOABcAAAAAAAAAAAAPABcAAAAAAAAAAAAQABcAAAAAAAAAAAARABcAAAAAAAAAAAASABcAAAAAAAAAAAATABcAAAAAAAAAAAAOABkAAAAAAAAAAAAPABkAAAAAAAAAAAAQABkAAAAAAAAAAAARABkAAAAAAAAAAAASABkAAAAAAAAAAAATABkAAAAAAAAAAAAUABkAAAAAAAAAAAA=")
|
||||
tile_set = SubResource("TileSet_xqlka")
|
||||
|
||||
[node name="Secret" type="TileMapLayer" parent="."]
|
||||
use_parent_material = true
|
||||
tile_map_data = PackedByteArray("AAAOABoAAAAAAAAAAAAOABsAAAAAAAAAAAAOABwAAAAAAAAAAAAPABoAAAAAAAAAAAAPABsAAAAAAAAAAAAPABwAAAAAAAAAAAAQABoAAAAAAAAAAAAQABsAAAAAAAAAAAAQABwAAAAAAAAAAAARABoAAAAAAAAAAAARABsAAAAAAAAAAAARABwAAAAAAAAAAAASABoAAAAAAAAAAAASABsAAAAAAAAAAAASABwAAAAAAAAAAAATABoAAAAAAAAAAAATABsAAAAAAAAAAAATABwAAAAAAAAAAAAUABoAAAAAAAAAAAAUABsAAAAAAAAAAAAUABwAAAAAAAAAAAA=")
|
||||
[node name="TileMap" type="TileMap" parent="."]
|
||||
z_index = 1
|
||||
tile_set = SubResource("TileSet_xqlka")
|
||||
format = 2
|
||||
layer_0/name = "Ground"
|
||||
layer_0/tile_data = PackedInt32Array(0, 0, 0, 65536, 0, 0, 131072, 0, 0, 196608, 0, 0, 262144, 0, 0, 327680, 0, 0, 393216, 0, 0, 458752, 0, 0, 524288, 0, 0, 589824, 0, 0, 655360, 0, 0, 720896, 0, 0, 786432, 0, 0, 851968, 0, 0, 917504, 0, 0, 983040, 0, 0, 1048576, 0, 0, 1114112, 0, 0, 1179648, 0, 0, 1245184, 0, 0, 1310720, 0, 0, 1376256, 0, 0, 1441792, 0, 0, 1507328, 0, 0, 1572864, 0, 0, 1638400, 0, 0, 1703936, 0, 0, 1769472, 0, 0, 1835008, 0, 0, 1900544, 0, 0, 1966080, 0, 0, 1, 0, 0, 65537, 0, 0, 131073, 0, 0, 196609, 0, 0, 262145, 0, 0, 327681, 0, 0, 393217, 0, 0, 458753, 0, 0, 524289, 0, 0, 589825, 0, 0, 655361, 0, 0, 720897, 0, 0, 786433, 0, 0, 851969, 0, 0, 917505, 0, 0, 983041, 0, 0, 1048577, 0, 0, 1114113, 0, 0, 1179649, 0, 0, 1245185, 0, 0, 1310721, 0, 0, 1376257, 0, 0, 1441793, 0, 0, 1507329, 0, 0, 1572865, 0, 0, 1638401, 0, 0, 1703937, 0, 0, 1769473, 0, 0, 1835009, 0, 0, 1900545, 0, 0, 1966081, 0, 0, 2, 0, 0, 65538, 0, 0, 1900546, 0, 0, 1966082, 0, 0, 3, 0, 0, 65539, 0, 0, 1900547, 0, 0, 1966083, 0, 0, 4, 0, 0, 65540, 0, 0, 1900548, 0, 0, 1966084, 0, 0, 5, 0, 0, 65541, 0, 0, 1900549, 0, 0, 1966085, 0, 0, 6, 0, 0, 65542, 0, 0, 1900550, 0, 0, 1966086, 0, 0, 7, 0, 0, 65543, 0, 0, 1900551, 0, 0, 1966087, 0, 0, 8, 0, 0, 65544, 0, 0, 1900552, 0, 0, 1966088, 0, 0, 9, 0, 0, 65545, 0, 0, 1900553, 0, 0, 1966089, 0, 0, 10, 0, 0, 65546, 0, 0, 1900554, 0, 0, 1966090, 0, 0, 11, 0, 0, 65547, 0, 0, 1900555, 0, 0, 1966091, 0, 0, 12, 0, 0, 65548, 0, 0, 1900556, 0, 0, 1966092, 0, 0, 13, 0, 0, 65549, 0, 0, 1900557, 0, 0, 1966093, 0, 0, 14, 0, 0, 65550, 0, 0, 1900558, 0, 0, 1966094, 0, 0, 15, 0, 0, 65551, 0, 0, 1900559, 0, 0, 1966095, 0, 0, 16, 0, 0, 65552, 0, 0, 1900560, 0, 0, 1966096, 0, 0, 17, 0, 0, 65553, 0, 0, 1900561, 0, 0, 1966097, 0, 0, 18, 0, 0, 65554, 0, 0, 1900562, 0, 0, 1966098, 0, 0, 19, 0, 0, 65555, 0, 0, 1900563, 0, 0, 1966099, 0, 0, 20, 0, 0, 65556, 0, 0, 1900564, 0, 0, 1966100, 0, 0, 21, 0, 0, 65557, 0, 0, 1900565, 0, 0, 1966101, 0, 0, 22, 0, 0, 65558, 0, 0, 1900566, 0, 0, 1966102, 0, 0, 23, 0, 0, 65559, 0, 0, 1900567, 0, 0, 1966103, 0, 0, 24, 0, 0, 65560, 0, 0, 1900568, 0, 0, 1966104, 0, 0, 25, 0, 0, 65561, 0, 0, 1900569, 0, 0, 1966105, 0, 0, 26, 0, 0, 65562, 0, 0, 1900570, 0, 0, 1966106, 0, 0, 27, 0, 0, 65563, 0, 0, 1900571, 0, 0, 1966107, 0, 0, 28, 0, 0, 65564, 0, 0, 1900572, 0, 0, 1966108, 0, 0, 29, 0, 0, 65565, 0, 0, 1900573, 0, 0, 1966109, 0, 0, 30, 0, 0, 65566, 0, 0, 1900574, 0, 0, 1966110, 0, 0, 31, 0, 0, 65567, 0, 0, 131103, 0, 0, 196639, 0, 0, 262175, 0, 0, 327711, 0, 0, 393247, 0, 0, 458783, 0, 0, 524319, 0, 0, 589855, 0, 0, 655391, 0, 0, 720927, 0, 0, 786463, 0, 0, 851999, 0, 0, 917535, 0, 0, 983071, 0, 0, 1048607, 0, 0, 1114143, 0, 0, 1179679, 0, 0, 1245215, 0, 0, 1310751, 0, 0, 1376287, 0, 0, 1441823, 0, 0, 1507359, 0, 0, 1572895, 0, 0, 1638431, 0, 0, 1703967, 0, 0, 1769503, 0, 0, 1835039, 0, 0, 1900575, 0, 0, 1966111, 0, 0, 32, 0, 0, 65568, 0, 0, 131104, 0, 0, 196640, 0, 0, 262176, 0, 0, 327712, 0, 0, 393248, 0, 0, 458784, 0, 0, 524320, 0, 0, 589856, 0, 0, 655392, 0, 0, 720928, 0, 0, 786464, 0, 0, 852000, 0, 0, 917536, 0, 0, 983072, 0, 0, 1048608, 0, 0, 1114144, 0, 0, 1179680, 0, 0, 1245216, 0, 0, 1310752, 0, 0, 1376288, 0, 0, 1441824, 0, 0, 1507360, 0, 0, 1572896, 0, 0, 1638432, 0, 0, 1703968, 0, 0, 1769504, 0, 0, 1835040, 0, 0, 1900576, 0, 0, 1966112, 0, 0, 1572878, 0, 0, 1572879, 0, 0, 1572880, 0, 0, 1572881, 0, 0, 1572882, 0, 0, 1572883, 0, 0, 1572884, 0, 0, 1507348, 0, 0, 1441812, 0, 0, 1441811, 0, 0, 1441810, 0, 0, 1441809, 0, 0, 1441808, 0, 0, 1441807, 0, 0, 1441806, 0, 0, 1507342, 0, 0, 1507343, 0, 0, 1507344, 0, 0, 1507345, 0, 0, 1507346, 0, 0, 1507347, 0, 0, 1638414, 0, 0, 1638415, 0, 0, 1638416, 0, 0, 1638417, 0, 0, 1638418, 0, 0, 1638419, 0, 0, 1638420, 0, 0)
|
||||
layer_1/name = "Secret"
|
||||
layer_1/enabled = true
|
||||
layer_1/modulate = Color(1, 1, 1, 1)
|
||||
layer_1/y_sort_enabled = false
|
||||
layer_1/y_sort_origin = 0
|
||||
layer_1/z_index = 0
|
||||
layer_1/tile_data = PackedInt32Array(1703950, 0, 0, 1769486, 0, 0, 1835022, 0, 0, 1703951, 0, 0, 1769487, 0, 0, 1835023, 0, 0, 1703952, 0, 0, 1769488, 0, 0, 1835024, 0, 0, 1703953, 0, 0, 1769489, 0, 0, 1835025, 0, 0, 1703954, 0, 0, 1769490, 0, 0, 1835026, 0, 0, 1703955, 0, 0, 1769491, 0, 0, 1835027, 0, 0, 1703956, 0, 0, 1769492, 0, 0, 1835028, 0, 0)
|
||||
script = ExtResource("2_q8fhk")
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
@@ -44,5 +53,5 @@ position = Vector2(280, 440)
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="SecretDetector"]
|
||||
shape = SubResource("RectangleShape2D_a2gec")
|
||||
|
||||
[connection signal="body_entered" from="SecretDetector" to="Secret" method="_on_secret_detector_body_entered"]
|
||||
[connection signal="body_exited" from="SecretDetector" to="Secret" method="_on_secret_detector_body_exited"]
|
||||
[connection signal="body_entered" from="SecretDetector" to="TileMap" method="_on_secret_detector_body_entered"]
|
||||
[connection signal="body_exited" from="SecretDetector" to="TileMap" method="_on_secret_detector_body_exited"]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
[gd_scene load_steps=9 format=3 uid="uid://dmn8nkpogiwsf"]
|
||||
[gd_scene load_steps=8 format=3 uid="uid://dmn8nkpogiwsf"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bpdyvy2681m3i" path="res://player/Player.tscn" id="1"]
|
||||
[ext_resource type="FontFile" uid="uid://b5bspum6ffekd" path="res://fonts/SourceCodePro-Bold.ttf" id="2_r1c5f"]
|
||||
[ext_resource type="PackedScene" uid="uid://cvi13chv8g4hj" path="res://debug/StatesStackDiplayer.tscn" id="3"]
|
||||
[ext_resource type="PackedScene" uid="uid://bq6rrfy53rfvo" path="res://debug/ControlsPanel.tscn" id="4"]
|
||||
|
||||
@@ -44,9 +43,6 @@ libraries = {
|
||||
"": SubResource("AnimationLibrary_qbwwp")
|
||||
}
|
||||
|
||||
[node name="StateNameDisplayer" parent="Player" index="5"]
|
||||
theme_override_fonts/font = ExtResource("2_r1c5f")
|
||||
|
||||
[node name="Explanations" type="RichTextLabel" parent="."]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
|
||||
@@ -8,7 +8,7 @@ Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2714
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/516
|
||||
|
||||
## Why use a state machine
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cvi13chv8g4hj"]
|
||||
[gd_scene load_steps=2 format=3 uid="uid://cvi13chv8g4hj"]
|
||||
|
||||
[ext_resource type="Script" path="res://debug/states_stack_displayer.gd" id="1"]
|
||||
[ext_resource type="FontFile" uid="uid://b5bspum6ffekd" path="res://fonts/SourceCodePro-Bold.ttf" id="2_58if7"]
|
||||
|
||||
[node name="StatesStackDiplayer" type="Panel"]
|
||||
offset_right = 210.0
|
||||
@@ -18,7 +17,6 @@ grow_vertical = 2
|
||||
|
||||
[node name="Title" type="Label" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_fonts/font = ExtResource("2_58if7")
|
||||
text = "StateStack"
|
||||
uppercase = true
|
||||
|
||||
@@ -28,7 +26,6 @@ layout_mode = 2
|
||||
[node name="Numbers" type="Label" parent="VBoxContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_fonts/font = ExtResource("2_58if7")
|
||||
text = "1.
|
||||
2."
|
||||
horizontal_alignment = 2
|
||||
@@ -36,6 +33,5 @@ horizontal_alignment = 2
|
||||
[node name="States" type="Label" parent="VBoxContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_fonts/font = ExtResource("2_58if7")
|
||||
text = "Jump
|
||||
Test"
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
extends Panel
|
||||
|
||||
@onready var fsm_node: Node = get_node(^"../../Player/StateMachine")
|
||||
@onready var fsm_node = get_node(^"../../Player/StateMachine")
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var states_names := ""
|
||||
var numbers := ""
|
||||
var index := 0
|
||||
|
||||
for state: Node in fsm_node.states_stack:
|
||||
states_names += String(state.name) + "\n"
|
||||
func _process(_delta):
|
||||
var states_names = ""
|
||||
var numbers = ""
|
||||
var index = 0
|
||||
for state in fsm_node.states_stack:
|
||||
states_names += String(state.get_name()) + "\n"
|
||||
numbers += str(index) + "\n"
|
||||
index += 1
|
||||
|
||||
%States.text = states_names
|
||||
%Numbers.text = numbers
|
||||
|
||||
BIN
2d/finite_state_machine/fonts/SourceCodePro-Black.ttf
Normal file
BIN
2d/finite_state_machine/fonts/SourceCodePro-Black.ttf
Normal file
Binary file not shown.
@@ -2,13 +2,13 @@
|
||||
|
||||
importer="font_data_dynamic"
|
||||
type="FontFile"
|
||||
uid="uid://qaejxgrojp2d"
|
||||
path="res://.godot/imported/DroidSans.ttf-f4f3e617929333a8a3b131725141d728.fontdata"
|
||||
uid="uid://b7c5m4mw0jhww"
|
||||
path="res://.godot/imported/SourceCodePro-Black.ttf-5ac54eeedbdedbc63d01069716d9852f.fontdata"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://fonts/DroidSans.ttf"
|
||||
dest_files=["res://.godot/imported/DroidSans.ttf-f4f3e617929333a8a3b131725141d728.fontdata"]
|
||||
source_file="res://fonts/SourceCodePro-Black.ttf"
|
||||
dest_files=["res://.godot/imported/SourceCodePro-Black.ttf-5ac54eeedbdedbc63d01069716d9852f.fontdata"]
|
||||
|
||||
[params]
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
[gd_resource type="Font" load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://fonts/SourceCodePro-Bold.ttf" type="FontData" id=1]
|
||||
|
||||
[resource]
|
||||
|
||||
size = 20
|
||||
use_mipmaps = false
|
||||
use_filter = true
|
||||
font_data = ExtResource( 1 )
|
||||
_sections_unfolded = [ "Font", "Settings" ]
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
[gd_resource type="Font" load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://fonts/SourceCodePro-Black.ttf" type="FontData" id=1]
|
||||
|
||||
[resource]
|
||||
|
||||
size = 24
|
||||
use_mipmaps = false
|
||||
use_filter = true
|
||||
font_data = ExtResource( 1 )
|
||||
_sections_unfolded = [ "Font", "Settings" ]
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
var direction := Vector2()
|
||||
@export var speed := 1000.0
|
||||
var direction = Vector2()
|
||||
@export var speed: float = 1000.0
|
||||
|
||||
@onready var root := get_tree().root
|
||||
@onready var root = get_tree().root
|
||||
|
||||
func _ready() -> void:
|
||||
func _ready():
|
||||
set_as_top_level(true)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
func _physics_process(delta):
|
||||
if not root.get_visible_rect().has_point(position):
|
||||
queue_free()
|
||||
|
||||
var motion := direction * speed * delta
|
||||
var collision_info := move_and_collide(motion)
|
||||
var motion = direction * speed * delta
|
||||
var collision_info = move_and_collide(motion)
|
||||
if collision_info:
|
||||
queue_free()
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
func _draw():
|
||||
draw_circle(Vector2(), $CollisionShape2D.shape.radius, Color.WHITE)
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
extends Node2D
|
||||
|
||||
var bullet := preload("Bullet.tscn")
|
||||
var bullet = preload("Bullet.tscn")
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
func _unhandled_input(event):
|
||||
if event.is_action_pressed("fire"):
|
||||
fire()
|
||||
|
||||
|
||||
func fire() -> void:
|
||||
func fire():
|
||||
if not $CooldownTimer.is_stopped():
|
||||
return
|
||||
|
||||
$CooldownTimer.start()
|
||||
var new_bullet := bullet.instantiate()
|
||||
var new_bullet = bullet.instantiate()
|
||||
add_child(new_bullet)
|
||||
new_bullet.position = global_position
|
||||
new_bullet.direction = owner.look_direction
|
||||
|
||||
@@ -3,26 +3,25 @@ extends CharacterBody2D
|
||||
# It can move, collide with the world, etc...
|
||||
# The player has a state machine, but the body and the state machine are separate.
|
||||
|
||||
signal direction_changed(new_direction: Vector2)
|
||||
signal direction_changed(new_direction)
|
||||
|
||||
var look_direction := Vector2.RIGHT:
|
||||
var look_direction = Vector2.RIGHT:
|
||||
set(value):
|
||||
look_direction = value
|
||||
set_look_direction(value)
|
||||
|
||||
func take_damage(attacker: Node, amount: float, effect: Node = null) -> void:
|
||||
func take_damage(attacker, amount, effect = null):
|
||||
if is_ancestor_of(attacker):
|
||||
return
|
||||
|
||||
$States/Stagger.knockback_direction = (attacker.global_position - global_position).normalized()
|
||||
$Health.take_damage(amount, effect)
|
||||
|
||||
|
||||
func set_dead(value: bool) -> void:
|
||||
func set_dead(value):
|
||||
set_process_input(not value)
|
||||
set_physics_process(not value)
|
||||
$CollisionPolygon2D.disabled = value
|
||||
|
||||
|
||||
func set_look_direction(value: Vector2) -> void:
|
||||
direction_changed.emit(value)
|
||||
func set_look_direction(value):
|
||||
emit_signal("direction_changed", value)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
extends "res://state_machine/state_machine.gd"
|
||||
|
||||
@onready var idle: Node = $Idle
|
||||
@onready var move: Node = $Move
|
||||
@onready var jump: Node = $Jump
|
||||
@onready var stagger: Node = $Stagger
|
||||
@onready var attack: Node = $Attack
|
||||
@onready var idle = $Idle
|
||||
@onready var move = $Move
|
||||
@onready var jump = $Jump
|
||||
@onready var stagger = $Stagger
|
||||
@onready var attack = $Attack
|
||||
|
||||
func _ready() -> void:
|
||||
func _ready():
|
||||
states_map = {
|
||||
"idle": idle,
|
||||
"move": move,
|
||||
@@ -16,7 +16,7 @@ func _ready() -> void:
|
||||
}
|
||||
|
||||
|
||||
func _change_state(state_name: String) -> void:
|
||||
func _change_state(state_name):
|
||||
# The base state_machine interface this node extends does most of the work.
|
||||
if not _active:
|
||||
return
|
||||
@@ -24,11 +24,10 @@ func _change_state(state_name: String) -> void:
|
||||
states_stack.push_front(states_map[state_name])
|
||||
if state_name == "jump" and current_state == move:
|
||||
jump.initialize(move.speed, move.velocity)
|
||||
|
||||
super._change_state(state_name)
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
func _unhandled_input(event):
|
||||
# Here we only handle input that can interrupt states, attacking in this case,
|
||||
# otherwise we let the state node handle it.
|
||||
if event.is_action_pressed("attack"):
|
||||
@@ -36,5 +35,4 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
return
|
||||
_change_state("attack")
|
||||
return
|
||||
|
||||
current_state.handle_input(event)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
extends "res://state_machine/state.gd"
|
||||
|
||||
func enter() -> void:
|
||||
func enter():
|
||||
owner.get_node(^"AnimationPlayer").play("idle")
|
||||
|
||||
|
||||
func _on_Sword_attack_finished() -> void:
|
||||
finished.emit("previous")
|
||||
func _on_Sword_attack_finished():
|
||||
emit_signal("finished", "previous")
|
||||
|
||||
@@ -3,10 +3,10 @@ extends "res://state_machine/state.gd"
|
||||
# The animation only affects the Body Sprite2D's modulate property so it
|
||||
# could stack with other animations if we had two AnimationPlayer nodes.
|
||||
|
||||
func enter() -> void:
|
||||
func enter():
|
||||
owner.get_node(^"AnimationPlayer").play("stagger")
|
||||
|
||||
|
||||
func _on_animation_finished(anim_name: String) -> void:
|
||||
func _on_animation_finished(anim_name):
|
||||
assert(anim_name == "stagger")
|
||||
finished.emit("previous")
|
||||
emit_signal("finished", "previous")
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
extends Label
|
||||
|
||||
var start_position := Vector2()
|
||||
var start_position = Vector2()
|
||||
|
||||
func _ready() -> void:
|
||||
func _ready():
|
||||
start_position = position
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
func _physics_process(_delta):
|
||||
position = $"../BodyPivot".position + start_position
|
||||
|
||||
|
||||
func _on_StateMachine_state_changed(current_state: Node) -> void:
|
||||
text = String(current_state.name)
|
||||
func _on_StateMachine_state_changed(current_state):
|
||||
text = String(current_state.get_name())
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
extends "res://state_machine/state.gd"
|
||||
|
||||
# Initialize the state. E.g. change the animation.
|
||||
func enter() -> void:
|
||||
func enter():
|
||||
owner.set_dead(true)
|
||||
owner.get_node(^"AnimationPlayer").play("die")
|
||||
|
||||
|
||||
func _on_animation_finished(_anim_name: String) -> void:
|
||||
finished.emit("dead")
|
||||
func _on_animation_finished(_anim_name):
|
||||
emit_signal("finished", "dead")
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
extends "../motion.gd"
|
||||
|
||||
@export var base_max_horizontal_speed := 400.0
|
||||
@export var base_max_horizontal_speed: float = 400.0
|
||||
|
||||
@export var air_acceleration := 1000.0
|
||||
@export var air_deceleration := 2000.0
|
||||
@export var air_steering_power := 50.0
|
||||
@export var air_acceleration: float = 1000.0
|
||||
@export var air_deceleration: float = 2000.0
|
||||
@export var air_steering_power: float = 50.0
|
||||
|
||||
@export var gravity := 1600.0
|
||||
@export var gravity: float = 1600.0
|
||||
|
||||
var enter_velocity := Vector2()
|
||||
var enter_velocity = Vector2()
|
||||
|
||||
var max_horizontal_speed := 0.0
|
||||
var horizontal_speed := 0.0
|
||||
var horizontal_velocity := Vector2()
|
||||
var max_horizontal_speed = 0.0
|
||||
var horizontal_speed = 0.0
|
||||
var horizontal_velocity = Vector2()
|
||||
|
||||
var vertical_speed := 0.0
|
||||
var height := 0.0
|
||||
var vertical_speed = 0.0
|
||||
var height = 0.0
|
||||
|
||||
func initialize(speed: float, velocity: Vector2) -> void:
|
||||
func initialize(speed, velocity):
|
||||
horizontal_speed = speed
|
||||
if speed > 0.0:
|
||||
max_horizontal_speed = speed
|
||||
@@ -26,8 +26,8 @@ func initialize(speed: float, velocity: Vector2) -> void:
|
||||
enter_velocity = velocity
|
||||
|
||||
|
||||
func enter() -> void:
|
||||
var input_direction := get_input_direction()
|
||||
func enter():
|
||||
var input_direction = get_input_direction()
|
||||
update_look_direction(input_direction)
|
||||
|
||||
if input_direction:
|
||||
@@ -39,32 +39,32 @@ func enter() -> void:
|
||||
owner.get_node(^"AnimationPlayer").play("idle")
|
||||
|
||||
|
||||
func update(delta: float) -> void:
|
||||
var input_direction := get_input_direction()
|
||||
func update(delta):
|
||||
var input_direction = get_input_direction()
|
||||
update_look_direction(input_direction)
|
||||
|
||||
move_horizontally(delta, input_direction)
|
||||
animate_jump_height(delta)
|
||||
if height <= 0.0:
|
||||
finished.emit("previous")
|
||||
emit_signal("finished", "previous")
|
||||
|
||||
|
||||
func move_horizontally(delta: float, direction: Vector2) -> void:
|
||||
func move_horizontally(delta, direction):
|
||||
if direction:
|
||||
horizontal_speed += air_acceleration * delta
|
||||
else:
|
||||
horizontal_speed -= air_deceleration * delta
|
||||
horizontal_speed = clamp(horizontal_speed, 0, max_horizontal_speed)
|
||||
|
||||
var target_velocity := horizontal_speed * direction.normalized()
|
||||
var steering_velocity := (target_velocity - horizontal_velocity).normalized() * air_steering_power
|
||||
var target_velocity = horizontal_speed * direction.normalized()
|
||||
var steering_velocity = (target_velocity - horizontal_velocity).normalized() * air_steering_power
|
||||
horizontal_velocity += steering_velocity
|
||||
|
||||
owner.velocity = horizontal_velocity
|
||||
owner.move_and_slide()
|
||||
|
||||
|
||||
func animate_jump_height(delta: float) -> void:
|
||||
func animate_jump_height(delta):
|
||||
vertical_speed -= gravity * delta
|
||||
height += vertical_speed * delta
|
||||
height = max(0.0, height)
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
extends "res://state_machine/state.gd"
|
||||
# Collection of important methods to handle direction and animation.
|
||||
|
||||
func handle_input(event: InputEvent) -> void:
|
||||
func handle_input(event):
|
||||
if event.is_action_pressed("simulate_damage"):
|
||||
finished.emit("stagger")
|
||||
emit_signal("finished", "stagger")
|
||||
|
||||
|
||||
func get_input_direction() -> Vector2:
|
||||
return Vector2(
|
||||
func get_input_direction():
|
||||
var input_direction = Vector2(
|
||||
Input.get_axis(&"move_left", &"move_right"),
|
||||
Input.get_axis(&"move_up", &"move_down")
|
||||
)
|
||||
return input_direction
|
||||
|
||||
|
||||
func update_look_direction(direction: Vector2) -> void:
|
||||
func update_look_direction(direction):
|
||||
if direction and owner.look_direction != direction:
|
||||
owner.look_direction = direction
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
extends "on_ground.gd"
|
||||
|
||||
func enter() -> void:
|
||||
func enter():
|
||||
owner.get_node(^"AnimationPlayer").play("idle")
|
||||
|
||||
|
||||
func handle_input(event: InputEvent) -> void:
|
||||
func handle_input(event):
|
||||
return super.handle_input(event)
|
||||
|
||||
|
||||
func update(_delta: float) -> void:
|
||||
var input_direction: Vector2 = get_input_direction()
|
||||
func update(_delta):
|
||||
var input_direction = get_input_direction()
|
||||
if input_direction:
|
||||
finished.emit("move")
|
||||
emit_signal("finished", "move")
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
extends "on_ground.gd"
|
||||
|
||||
@export var max_walk_speed := 450.0
|
||||
@export var max_run_speed := 700.0
|
||||
@export var max_walk_speed: float = 450
|
||||
@export var max_run_speed: float = 700
|
||||
|
||||
func enter() -> void:
|
||||
func enter():
|
||||
speed = 0.0
|
||||
velocity = Vector2()
|
||||
|
||||
var input_direction := get_input_direction()
|
||||
var input_direction = get_input_direction()
|
||||
update_look_direction(input_direction)
|
||||
owner.get_node(^"AnimationPlayer").play("walk")
|
||||
|
||||
|
||||
func handle_input(event: InputEvent) -> void:
|
||||
func handle_input(event):
|
||||
return super.handle_input(event)
|
||||
|
||||
|
||||
func update(_delta: float) -> void:
|
||||
var input_direction := get_input_direction()
|
||||
func update(_delta):
|
||||
var input_direction = get_input_direction()
|
||||
if input_direction.is_zero_approx():
|
||||
finished.emit("idle")
|
||||
emit_signal("finished", "idle")
|
||||
update_look_direction(input_direction)
|
||||
|
||||
if Input.is_action_pressed("run"):
|
||||
@@ -27,17 +27,16 @@ func update(_delta: float) -> void:
|
||||
else:
|
||||
speed = max_walk_speed
|
||||
|
||||
var collision_info := move(speed, input_direction)
|
||||
var collision_info = move(speed, input_direction)
|
||||
if not collision_info:
|
||||
return
|
||||
if speed == max_run_speed and collision_info.collider.is_in_group("environment"):
|
||||
return
|
||||
|
||||
|
||||
func move(p_speed: float, direction: Vector2) -> KinematicCollision2D:
|
||||
owner.velocity = direction.normalized() * p_speed
|
||||
owner.move_and_slide()
|
||||
if owner.get_slide_collision_count() == 0:
|
||||
return null
|
||||
|
||||
|
||||
func move(speed, direction):
|
||||
owner.velocity = direction.normalized() * speed
|
||||
owner.move_and_slide()
|
||||
if owner.get_slide_collision_count() == 0:
|
||||
return
|
||||
return owner.get_slide_collision(0)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
extends "../motion.gd"
|
||||
|
||||
var speed := 0.0
|
||||
var velocity := Vector2()
|
||||
# warning-ignore-all:unused_class_variable
|
||||
var speed = 0.0
|
||||
var velocity = Vector2()
|
||||
|
||||
func handle_input(event: InputEvent) -> void:
|
||||
func handle_input(event):
|
||||
if event.is_action_pressed("jump"):
|
||||
finished.emit("jump")
|
||||
emit_signal("finished", "jump")
|
||||
return super.handle_input(event)
|
||||
|
||||
@@ -2,50 +2,41 @@ extends Area2D
|
||||
|
||||
signal attack_finished
|
||||
|
||||
enum States {
|
||||
IDLE,
|
||||
ATTACK,
|
||||
}
|
||||
enum States { IDLE, ATTACK }
|
||||
var state = null
|
||||
|
||||
enum AttackInputStates {
|
||||
IDLE,
|
||||
LISTENING,
|
||||
REGISTERED,
|
||||
}
|
||||
|
||||
var state: States = States.IDLE
|
||||
var attack_input_state := AttackInputStates.IDLE
|
||||
var ready_for_next_attack := false
|
||||
enum AttackInputStates { IDLE, LISTENING, REGISTERED }
|
||||
var attack_input_state = AttackInputStates.IDLE
|
||||
var ready_for_next_attack = false
|
||||
const MAX_COMBO_COUNT = 3
|
||||
var combo_count := 0
|
||||
var combo_count = 0
|
||||
|
||||
var attack_current := {}
|
||||
var combo := [{
|
||||
var attack_current = {}
|
||||
var combo = [{
|
||||
"damage": 1,
|
||||
"animation": "attack_fast",
|
||||
"effect": null,
|
||||
"effect": null
|
||||
},
|
||||
{
|
||||
"damage": 1,
|
||||
"animation": "attack_fast",
|
||||
"effect": null,
|
||||
"effect": null
|
||||
},
|
||||
{
|
||||
"damage": 3,
|
||||
"animation": "attack_medium",
|
||||
"effect": null,
|
||||
}
|
||||
]
|
||||
"effect": null
|
||||
}]
|
||||
|
||||
var hit_objects := []
|
||||
var hit_objects = []
|
||||
|
||||
func _ready() -> void:
|
||||
$AnimationPlayer.animation_finished.connect(_on_animation_finished)
|
||||
body_entered.connect(_on_body_entered)
|
||||
func _ready():
|
||||
$AnimationPlayer.animation_finished.connect(self._on_animation_finished)
|
||||
body_entered.connect(self._on_body_entered)
|
||||
_change_state(States.IDLE)
|
||||
|
||||
|
||||
func _change_state(new_state: States) -> void:
|
||||
func _change_state(new_state):
|
||||
match state:
|
||||
States.ATTACK:
|
||||
hit_objects = []
|
||||
@@ -66,7 +57,7 @@ func _change_state(new_state: States) -> void:
|
||||
state = new_state
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
func _unhandled_input(event):
|
||||
if not state == States.ATTACK:
|
||||
return
|
||||
if attack_input_state != AttackInputStates.LISTENING:
|
||||
@@ -75,37 +66,36 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
attack_input_state = AttackInputStates.REGISTERED
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
func _physics_process(_delta):
|
||||
if attack_input_state == AttackInputStates.REGISTERED and ready_for_next_attack:
|
||||
attack()
|
||||
|
||||
|
||||
func attack() -> void:
|
||||
func attack():
|
||||
combo_count += 1
|
||||
_change_state(States.ATTACK)
|
||||
|
||||
|
||||
# Use with AnimationPlayer func track.
|
||||
func set_attack_input_listening() -> void:
|
||||
func set_attack_input_listening():
|
||||
attack_input_state = AttackInputStates.LISTENING
|
||||
|
||||
|
||||
# Use with AnimationPlayer func track.
|
||||
func set_ready_for_next_attack() -> void:
|
||||
func set_ready_for_next_attack():
|
||||
ready_for_next_attack = true
|
||||
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
func _on_body_entered(body):
|
||||
if not body.has_node("Health"):
|
||||
return
|
||||
if body.get_rid().get_id() in hit_objects:
|
||||
return
|
||||
|
||||
hit_objects.append(body.get_rid().get_id())
|
||||
body.take_damage(self, attack_current["damage"], attack_current["effect"])
|
||||
|
||||
|
||||
func _on_animation_finished(_name: String) -> void:
|
||||
func _on_animation_finished(_name):
|
||||
if attack_current.is_empty():
|
||||
return
|
||||
|
||||
@@ -113,9 +103,9 @@ func _on_animation_finished(_name: String) -> void:
|
||||
attack()
|
||||
else:
|
||||
_change_state(States.IDLE)
|
||||
attack_finished.emit()
|
||||
emit_signal("attack_finished")
|
||||
|
||||
|
||||
func _on_StateMachine_state_changed(current_state: Node) -> void:
|
||||
func _on_StateMachine_state_changed(current_state):
|
||||
if current_state.name == "Attack":
|
||||
attack()
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
extends Marker2D
|
||||
|
||||
var z_index_start := 0
|
||||
var z_index_start = 0
|
||||
|
||||
func _ready() -> void:
|
||||
owner.direction_changed.connect(_on_Parent_direction_changed)
|
||||
func _ready():
|
||||
owner.direction_changed.connect(self._on_Parent_direction_changed)
|
||||
z_index_start = z_index
|
||||
|
||||
|
||||
func _on_Parent_direction_changed(direction: Vector2) -> void:
|
||||
func _on_Parent_direction_changed(direction):
|
||||
rotation = direction.angle()
|
||||
match direction:
|
||||
Vector2.UP:
|
||||
|
||||
@@ -19,10 +19,6 @@ run/main_scene="res://Demo.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=1280
|
||||
@@ -33,7 +29,7 @@ window/stretch/aspect="expand"
|
||||
[input]
|
||||
|
||||
move_left={
|
||||
"deadzone": 0.2,
|
||||
"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":4194319,"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)
|
||||
@@ -41,7 +37,7 @@ move_left={
|
||||
]
|
||||
}
|
||||
move_up={
|
||||
"deadzone": 0.2,
|
||||
"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)
|
||||
@@ -49,7 +45,7 @@ move_up={
|
||||
]
|
||||
}
|
||||
move_right={
|
||||
"deadzone": 0.2,
|
||||
"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)
|
||||
@@ -57,7 +53,7 @@ move_right={
|
||||
]
|
||||
}
|
||||
move_down={
|
||||
"deadzone": 0.2,
|
||||
"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)
|
||||
@@ -65,31 +61,31 @@ move_down={
|
||||
]
|
||||
}
|
||||
fire={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":82,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":7,"pressure":0.0,"pressed":false,"script":null)
|
||||
]
|
||||
}
|
||||
run={
|
||||
"deadzone": 0.2,
|
||||
"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":4194325,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
|
||||
]
|
||||
}
|
||||
jump={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
|
||||
]
|
||||
}
|
||||
simulate_damage={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":88,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null)
|
||||
]
|
||||
}
|
||||
attack={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":70,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":true,"script":null)
|
||||
]
|
||||
|
||||
@@ -3,26 +3,26 @@ extends Node
|
||||
# but forces us to pass the right arguments to the methods below
|
||||
# and makes sure every State object had all of these methods.
|
||||
|
||||
@warning_ignore("unused_signal")
|
||||
signal finished(next_state_name: String)
|
||||
# warning-ignore:unused_signal
|
||||
signal finished(next_state_name)
|
||||
|
||||
# Initialize the state. E.g. change the animation.
|
||||
func enter() -> void:
|
||||
func enter():
|
||||
pass
|
||||
|
||||
|
||||
# Clean up the state. Reinitialize values like a timer.
|
||||
func exit() -> void:
|
||||
func exit():
|
||||
pass
|
||||
|
||||
|
||||
func handle_input(_event: InputEvent) -> void:
|
||||
func handle_input(_event):
|
||||
pass
|
||||
|
||||
|
||||
func update(_delta: float) -> void:
|
||||
func update(_delta):
|
||||
pass
|
||||
|
||||
|
||||
func _on_animation_finished(_anim_name: String) -> void:
|
||||
func _on_animation_finished(_anim_name):
|
||||
pass
|
||||
|
||||
@@ -5,39 +5,39 @@ extends Node
|
||||
# and changing the current/active state.
|
||||
# See the PlayerV2 scene for an example on how to use it.
|
||||
|
||||
signal state_changed(current_state: Node)
|
||||
signal state_changed(current_state)
|
||||
|
||||
# You should set a starting node from the inspector or on the node that inherits
|
||||
# from this state machine interface. If you don't, the game will default to
|
||||
# the first state in the state machine's children.
|
||||
@export var start_state: NodePath
|
||||
var states_map := {}
|
||||
var states_map = {}
|
||||
|
||||
var states_stack := []
|
||||
var current_state: Node = null
|
||||
var _active := false:
|
||||
var states_stack = []
|
||||
var current_state = null
|
||||
var _active = false:
|
||||
set(value):
|
||||
_active = value
|
||||
set_active(value)
|
||||
|
||||
func _enter_tree() -> void:
|
||||
func _enter_tree():
|
||||
if start_state.is_empty():
|
||||
start_state = get_child(0).get_path()
|
||||
for child in get_children():
|
||||
var err: bool = child.finished.connect(_change_state)
|
||||
var err = child.finished.connect(self._change_state)
|
||||
if err:
|
||||
printerr(err)
|
||||
initialize(start_state)
|
||||
|
||||
|
||||
func initialize(initial_state: NodePath) -> void:
|
||||
func initialize(initial_state):
|
||||
_active = true
|
||||
states_stack.push_front(get_node(initial_state))
|
||||
current_state = states_stack[0]
|
||||
current_state.enter()
|
||||
|
||||
|
||||
func set_active(value: bool) -> void:
|
||||
func set_active(value):
|
||||
set_physics_process(value)
|
||||
set_process_input(value)
|
||||
if not _active:
|
||||
@@ -45,22 +45,21 @@ func set_active(value: bool) -> void:
|
||||
current_state = null
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
func _unhandled_input(event):
|
||||
current_state.handle_input(event)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
func _physics_process(delta):
|
||||
current_state.update(delta)
|
||||
|
||||
|
||||
func _on_animation_finished(anim_name: String) -> void:
|
||||
func _on_animation_finished(anim_name):
|
||||
if not _active:
|
||||
return
|
||||
|
||||
current_state._on_animation_finished(anim_name)
|
||||
|
||||
|
||||
func _change_state(state_name: String) -> void:
|
||||
func _change_state(state_name):
|
||||
if not _active:
|
||||
return
|
||||
current_state.exit()
|
||||
@@ -71,7 +70,7 @@ func _change_state(state_name: String) -> void:
|
||||
states_stack[0] = states_map[state_name]
|
||||
|
||||
current_state = states_stack[0]
|
||||
state_changed.emit(current_state)
|
||||
emit_signal("state_changed", current_state)
|
||||
|
||||
if state_name != "previous":
|
||||
current_state.enter()
|
||||
|
||||
@@ -6,9 +6,9 @@ Slide the cave image left and right to observe the glow effect at work.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Forward+
|
||||
Renderer: Forward Plus
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2715
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/110
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@ extends Node2D
|
||||
|
||||
const CAVE_LIMIT = 1000
|
||||
|
||||
var glow_map := preload("res://glow_map.webp")
|
||||
var glow_map = preload("res://glow_map.webp")
|
||||
|
||||
@onready var cave: Node2D = $Cave
|
||||
@onready var cave = $Cave
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
func _unhandled_input(event):
|
||||
if event is InputEventMouseMotion and event.button_mask > 0:
|
||||
cave.position.x = clampf(cave.position.x + event.relative.x, -CAVE_LIMIT, 0)
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ environment = SubResource("1")
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
offset = Vector2(540, 360)
|
||||
current = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
visible = false
|
||||
|
||||
@@ -20,10 +20,6 @@ config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
run/name=""
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=1080
|
||||
@@ -34,7 +30,7 @@ window/stretch/aspect="expand"
|
||||
[input]
|
||||
|
||||
toggle_glow_map={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":71,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ Very simple demo showing a hexagonal TileMap and TileSet.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
Renderer: GLES 2
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2717
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/111
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -11,5 +11,4 @@ format = 2
|
||||
layer_0/tile_data = PackedInt32Array(-458747, 0, 0, -458746, 0, 0, -393212, 0, 0, -393211, 0, 0, -393210, 0, 0, -393209, 0, 0, -393208, 0, 0, -393207, 0, 0, -327678, 0, 0, -327677, 0, 0, -327676, 0, 0, -327675, 6, 0, -327674, 6, 0, -327673, 6, 0, -327672, 6, 0, -327671, 0, 0, -327670, 0, 0, -327669, 0, 0, -262142, 0, 0, -262141, 0, 0, -262140, 6, 0, -262139, 6, 0, -262138, 6, 0, -262137, 6, 0, -262136, 6, 0, -262135, 0, 0, -262134, 0, 0, -262133, 0, 0, -262132, 0, 0, -262131, 0, 0, -196606, 0, 0, -196605, 0, 0, -196604, 6, 0, -196603, 6, 0, -196602, 6, 0, -196601, 6, 0, -196600, 1, 0, -196599, 0, 0, -196598, 1, 0, -196597, 1, 0, -196596, 0, 0, -196595, 0, 0, -196594, 0, 0, -131071, 9, 0, -131070, 0, 0, -131069, 0, 0, -131068, 2, 0, -131067, 2, 0, -131066, 0, 0, -131065, 21, 0, -131064, 19, 0, -131063, 0, 0, -131062, 0, 0, -131061, 16, 0, -131060, 0, 0, -131059, 0, 0, -131058, 0, 0, -131057, 0, 0, -131056, 0, 0, -65534, 0, 0, -65533, 1, 0, -65532, 0, 0, -65531, 0, 0, -65530, 20, 0, -65529, 19, 0, -65528, 2, 0, -65527, 0, 0, -65526, 14, 0, -65525, 0, 0, -65524, 0, 0, -65523, 0, 0, -65522, 23, 0, -65521, 0, 0, -65520, 0, 0, -65519, 0, 0, 3, 1, 0, 4, 2, 0, 5, 0, 0, 6, 1, 0, 7, 1, 0, 8, 0, 0, 9, 10, 0, 10, 12, 0, 11, 0, 0, 12, 0, 0, 13, 8, 0, 14, 0, 0, 15, 0, 0, 16, 0, 0, 17, 0, 0, 65538, 0, 0, 65539, 0, 0, 65540, 2, 0, 65541, 0, 0, 65542, 1, 0, 65543, 15, 0, 65544, 0, 0, 65545, 0, 0, 65546, 0, 0, 65547, 0, 0, 65548, 0, 0, 65549, 25, 0, 65550, 8, 0, 65551, 0, 0, 65552, 21, 0, 65553, 0, 0, 131074, 0, 0, 131075, 1, 0, 131076, 0, 0, 131077, 1, 0, 131078, 0, 0, 131079, 0, 0, 131080, 0, 0, 131081, 5, 0, 131082, 0, 0, 131083, 0, 0, 131084, 0, 0, 131085, 0, 0, 131086, 0, 0, 131087, 0, 0, 131088, 0, 0, 131089, 0, 0, 196610, 0, 0, 196611, 0, 0, 196612, 0, 0, 196613, 23, 0, 196614, 0, 0, 196615, 0, 0, 196616, 0, 0, 196617, 5, 0, 196618, 5, 0, 196619, 0, 0, 196620, 0, 0, 196621, 0, 0, 196622, 0, 0, 196623, 23, 0, 196624, 0, 0, 262148, 0, 0, 262149, 0, 0, 262150, 0, 0, 262151, 0, 0, 262152, 8, 0, 262153, 5, 0, 262154, 5, 0, 262155, 0, 0, 262156, 0, 0, 262157, 21, 0, 262158, 0, 0, 262159, 0, 0, 262160, 0, 0, 327686, 0, 0, 327687, 0, 0, 327688, 0, 0, 327689, 0, 0, 327690, 0, 0, 327691, 0, 0, 327692, 0, 0, 327693, 0, 0, 327694, 0, 0)
|
||||
|
||||
[node name="Troll" parent="." instance=ExtResource("2")]
|
||||
modulate = Color(1.5, 1.5, 1.5, 1)
|
||||
position = Vector2(602.819, -39.2876)
|
||||
|
||||
@@ -17,10 +17,6 @@ run/main_scene="res://map.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
@@ -29,7 +25,7 @@ window/stretch/aspect="expand"
|
||||
[input]
|
||||
|
||||
move_down={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
@@ -37,7 +33,7 @@ move_down={
|
||||
]
|
||||
}
|
||||
move_left={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
@@ -45,7 +41,7 @@ move_left={
|
||||
]
|
||||
}
|
||||
move_right={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
@@ -53,7 +49,7 @@ move_right={
|
||||
]
|
||||
}
|
||||
move_up={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
@@ -67,6 +63,4 @@ common/physics_ticks_per_second=120
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
environment/defaults/default_clear_color=Color(0.106667, 0.2, 0.1, 1)
|
||||
|
||||
@@ -4,8 +4,8 @@ const MOTION_SPEED = 30
|
||||
const FRICTION_FACTOR = 0.89
|
||||
const TAN30DEG = tan(deg_to_rad(30))
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
var motion := Vector2()
|
||||
func _physics_process(_delta):
|
||||
var motion = Vector2()
|
||||
motion.x = Input.get_axis(&"move_left", &"move_right")
|
||||
motion.y = Input.get_axis(&"move_up", &"move_down")
|
||||
# Make diagonal movement fit for hexagonal tiles.
|
||||
|
||||
@@ -15,9 +15,7 @@ texture = ExtResource("2")
|
||||
[node name="Shadow" type="Sprite2D" parent="."]
|
||||
modulate = Color(0, 0, 0, 0.501961)
|
||||
show_behind_parent = true
|
||||
position = Vector2(16.4422, 4.89438)
|
||||
scale = Vector2(0.794259, 1.04505)
|
||||
skew = 0.523599
|
||||
position = Vector2(3, 3)
|
||||
texture = ExtResource("2")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
@@ -25,3 +23,4 @@ position = Vector2(3.24216, 19.453)
|
||||
shape = SubResource("1")
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
current = true
|
||||
|
||||
@@ -5,9 +5,9 @@ make many duplicates of the same object.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
Renderer: Vulkan Mobile
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2716
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/148
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://cgx884jv27maj"]
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://cyqshsjd3qwo0" path="res://bowling_ball.png" id="1"]
|
||||
[ext_resource path="res://bowling_ball.png" type="Texture2D" id=1]
|
||||
|
||||
[sub_resource type="PhysicsMaterial" id="1"]
|
||||
[sub_resource type="PhysicsMaterial" id=1]
|
||||
bounce = 0.4
|
||||
|
||||
[sub_resource type="CircleShape2D" id="2"]
|
||||
[sub_resource type="CircleShape2D" id=2]
|
||||
radius = 30.0
|
||||
|
||||
[node name="Ball" type="RigidBody2D"]
|
||||
physics_material_override = SubResource("1")
|
||||
[node name="Ball" type="RigidDynamicBody2D"]
|
||||
physics_material_override = SubResource( 1 )
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture = ExtResource("1")
|
||||
texture = ExtResource( 1 )
|
||||
|
||||
[node name="Collision" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("2")
|
||||
shape = SubResource( 2 )
|
||||
|
||||
@@ -2,16 +2,15 @@ extends Node2D
|
||||
|
||||
@export var ball_scene: PackedScene = preload("res://ball.tscn")
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
func _unhandled_input(event):
|
||||
if event.is_echo():
|
||||
return
|
||||
|
||||
if event is InputEventMouseButton and event.is_pressed():
|
||||
if event.button_index == MOUSE_BUTTON_LEFT:
|
||||
spawn(get_global_mouse_position())
|
||||
|
||||
|
||||
func spawn(spawn_global_position: Vector2) -> void:
|
||||
var instance: Node2D = ball_scene.instantiate()
|
||||
func spawn(spawn_global_position):
|
||||
var instance = ball_scene.instantiate()
|
||||
instance.global_position = spawn_global_position
|
||||
add_child(instance)
|
||||
|
||||
@@ -18,10 +18,6 @@ run/main_scene="res://scene_instancing.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
@@ -29,11 +25,10 @@ window/stretch/aspect="expand"
|
||||
|
||||
[physics]
|
||||
|
||||
common/physics_ticks_per_second=120
|
||||
2d/default_gravity=300
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
renderer/rendering_method="mobile"
|
||||
environment/defaults/default_clear_color=Color(0.239216, 0.0823529, 0.156863, 1)
|
||||
anti_aliasing/quality/msaa_2d=2
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[gd_scene load_steps=13 format=3 uid="uid://rcsr8t4nw526"]
|
||||
|
||||
[ext_resource type="Script" path="res://ball_factory.gd" id="1"]
|
||||
[ext_resource type="PackedScene" uid="uid://cgx884jv27maj" path="res://ball.tscn" id="2"]
|
||||
[ext_resource type="PackedScene" path="res://ball.tscn" id="2"]
|
||||
|
||||
[sub_resource type="PhysicsMaterial" id="1"]
|
||||
bounce = 0.4
|
||||
@@ -35,9 +35,7 @@ bounce = 0.4
|
||||
|
||||
[node name="SceneInstancing" type="Node2D"]
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="InfoLabel" type="Label" parent="CanvasLayer"]
|
||||
[node name="InfoLabel" type="Label" parent="."]
|
||||
offset_left = 16.0
|
||||
offset_top = 16.0
|
||||
offset_right = 370.0
|
||||
@@ -101,3 +99,4 @@ physics_material_override = SubResource("10")
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
offset = Vector2(576, 324)
|
||||
current = true
|
||||
|
||||
@@ -9,7 +9,7 @@ Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2718
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/112
|
||||
|
||||
## How does it work?
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ func _physics_process(_delta):
|
||||
motion.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
|
||||
motion.y /= 2
|
||||
motion = motion.normalized() * MOTION_SPEED
|
||||
#warning-ignore:return_value_discarded
|
||||
set_velocity(motion)
|
||||
move_and_slide()
|
||||
var dir = velocity
|
||||
@@ -47,6 +48,7 @@ func _physics_process(_delta):
|
||||
|
||||
|
||||
func update_animation(anim_set):
|
||||
|
||||
var angle = rad_to_deg(last_direction.angle()) + 22.5
|
||||
var slice_dir = floor(angle / 45)
|
||||
|
||||
|
||||
@@ -25,10 +25,19 @@ config/icon="res://icon.webp"
|
||||
window/stretch/mode="canvas_items"
|
||||
window/stretch/aspect="expand"
|
||||
|
||||
[gdnative]
|
||||
|
||||
singletons=[]
|
||||
|
||||
[image_loader]
|
||||
|
||||
filter=false
|
||||
gen_mipmaps=false
|
||||
|
||||
[input]
|
||||
|
||||
move_down={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
|
||||
@@ -36,7 +45,7 @@ move_down={
|
||||
]
|
||||
}
|
||||
move_left={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"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":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
|
||||
@@ -44,7 +53,7 @@ move_left={
|
||||
]
|
||||
}
|
||||
move_right={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
|
||||
@@ -52,7 +61,7 @@ move_right={
|
||||
]
|
||||
}
|
||||
move_up={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
@@ -64,8 +73,13 @@ move_up={
|
||||
|
||||
common/physics_ticks_per_second=120
|
||||
|
||||
[rasterizer]
|
||||
|
||||
use_pixel_snap=true
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
environment/defaults/default_clear_color=Color(0.0784314, 0.105882, 0.145098, 1)
|
||||
quality/driver/driver_name="GLES2"
|
||||
vram_compression/import_etc=true
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# Kinematic Character 2D
|
||||
|
||||
Example of how to make a kinematic character controller in 2D using
|
||||
[`CharacterBody2D`](https://docs.godotengine.org/en/latest/classes/class_characterbody2d.html).
|
||||
[`KinematicBody2D`](https://docs.godotengine.org/en/latest/classes/class_kinematicbody2d.html).
|
||||
The character moves around, is affected by moving platforms,
|
||||
can jump through one-way collision platforms, etc.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
Renderer: GLES 2
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2719
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/113
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
extends Node
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
func _on_body_entered(body):
|
||||
if body.name == "Player":
|
||||
$"../WinText".show()
|
||||
|
||||
@@ -5,11 +5,11 @@ const WALK_MAX_SPEED = 200
|
||||
const STOP_FORCE = 1300
|
||||
const JUMP_SPEED = 200
|
||||
|
||||
@onready var gravity := float(ProjectSettings.get_setting("physics/2d/default_gravity"))
|
||||
@onready var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
func _physics_process(delta):
|
||||
# Horizontal movement code. First, get the player's input.
|
||||
var walk := WALK_FORCE * (Input.get_axis(&"move_left", &"move_right"))
|
||||
var walk = WALK_FORCE * (Input.get_axis(&"move_left", &"move_right"))
|
||||
# Slow down the player if they're not trying to move.
|
||||
if abs(walk) < WALK_FORCE * 0.2:
|
||||
# The velocity, slowed down a bit, and then reassigned.
|
||||
|
||||
@@ -19,10 +19,6 @@ run/main_scene="res://world.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=530
|
||||
@@ -33,7 +29,7 @@ window/stretch/aspect="expand"
|
||||
[input]
|
||||
|
||||
jump={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
|
||||
@@ -43,7 +39,7 @@ jump={
|
||||
]
|
||||
}
|
||||
move_left={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
@@ -51,7 +47,7 @@ move_left={
|
||||
]
|
||||
}
|
||||
move_right={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"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":0,"echo":false,"script":null)
|
||||
@@ -66,6 +62,5 @@ common/physics_ticks_per_second=120
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
environment/defaults/default_clear_color=Color(0.156863, 0.133333, 0.25098, 1)
|
||||
anti_aliasing/quality/msaa_2d=2
|
||||
|
||||
@@ -138,11 +138,11 @@ modulate = Color(0.4, 2, 0.8, 1)
|
||||
texture = ExtResource("2")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="MovingPlatform1"]
|
||||
callback_mode_process = 0
|
||||
autoplay = "leftright"
|
||||
playback_process_mode = 0
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_2v3oa")
|
||||
}
|
||||
autoplay = "leftright"
|
||||
|
||||
[node name="MovingPlatform2" type="CharacterBody2D" parent="."]
|
||||
position = Vector2(88.3493, 152)
|
||||
@@ -155,11 +155,11 @@ modulate = Color(0.4, 2, 0.8, 1)
|
||||
texture = ExtResource("2")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="MovingPlatform2"]
|
||||
callback_mode_process = 0
|
||||
autoplay = "updown"
|
||||
playback_process_mode = 0
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_j555p")
|
||||
}
|
||||
autoplay = "updown"
|
||||
|
||||
[node name="Princess" type="Area2D" parent="."]
|
||||
position = Vector2(97, 72)
|
||||
@@ -238,10 +238,10 @@ texture = ExtResource("5")
|
||||
shape = SubResource("9")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="Circle"]
|
||||
autoplay = "turn"
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_gijtf")
|
||||
}
|
||||
autoplay = "turn"
|
||||
|
||||
[node name="BoxSprite" type="Sprite2D" parent="Circle"]
|
||||
modulate = Color(0.4, 2, 0.8, 1)
|
||||
|
||||
@@ -4,9 +4,9 @@ Example of how to use 2D lights to mask objects on screen.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
Renderer: GLES 2
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2720
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/115
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ light_mode = 2
|
||||
|
||||
[sub_resource type="Animation" id="2"]
|
||||
length = 4.0
|
||||
loop_mode = 1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
@@ -56,8 +55,6 @@ layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 2
|
||||
size_flags_vertical = 2
|
||||
|
||||
@@ -72,24 +69,22 @@ texture = ExtResource("1")
|
||||
|
||||
[node name="Light1" type="PointLight2D" parent="."]
|
||||
position = Vector2(601.028, 242.639)
|
||||
blend_mode = 2
|
||||
texture = ExtResource("2")
|
||||
|
||||
[node name="Light2" type="PointLight2D" parent="."]
|
||||
position = Vector2(196.528, 185.139)
|
||||
blend_mode = 2
|
||||
texture = ExtResource("2")
|
||||
|
||||
[node name="Light3" type="PointLight2D" parent="."]
|
||||
position = Vector2(442.528, 411.139)
|
||||
blend_mode = 2
|
||||
texture = ExtResource("2")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
autoplay = "maskmotion"
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_co4us")
|
||||
}
|
||||
autoplay = "maskmotion"
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
offset = Vector2(576, 324)
|
||||
current = true
|
||||
|
||||
@@ -17,16 +17,7 @@ run/main_scene="res://lightmask.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
window/stretch/aspect="expand"
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
|
||||
@@ -6,9 +6,9 @@ and [`LightOccluder2D`](https://docs.godotengine.org/en/latest/classes/class_lig
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
Renderer: GLES 2
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2721
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/116
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=true
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extends Node2D
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
func _input(event):
|
||||
if event.is_action_pressed("toggle_directional_light"):
|
||||
$DirectionalLight2D.visible = not $DirectionalLight2D.visible
|
||||
|
||||
|
||||
@@ -107,21 +107,6 @@ _data = {
|
||||
"motion3": SubResource("7")
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_emv7u"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("DirectionalLight2D:rotation")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [0.0]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_rgbru"]
|
||||
resource_name = "rotate_directional_light"
|
||||
length = 20.0
|
||||
@@ -139,6 +124,21 @@ tracks/0/keys = {
|
||||
"values": [0.0, 6.28319]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_emv7u"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("DirectionalLight2D:rotation")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [0.0]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_6bket"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_emv7u"),
|
||||
@@ -320,17 +320,16 @@ shadow_enabled = true
|
||||
shadow_filter = 1
|
||||
shadow_filter_smooth = 1.2
|
||||
texture = ExtResource("3")
|
||||
metadata/_edit_group_ = true
|
||||
|
||||
[node name="Blob" type="Sprite2D" parent="RedLight"]
|
||||
material = SubResource("2")
|
||||
texture = ExtResource("4")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="RedLight"]
|
||||
autoplay = "motion"
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_wawvy")
|
||||
}
|
||||
autoplay = "motion"
|
||||
|
||||
[node name="GreenLight" type="PointLight2D" parent="." groups=["point_light"]]
|
||||
position = Vector2(753.756, 314.336)
|
||||
@@ -339,17 +338,16 @@ shadow_enabled = true
|
||||
shadow_filter = 1
|
||||
shadow_filter_smooth = 1.2
|
||||
texture = ExtResource("3")
|
||||
metadata/_edit_group_ = true
|
||||
|
||||
[node name="Blob" type="Sprite2D" parent="GreenLight"]
|
||||
[node name="blob" type="Sprite2D" parent="GreenLight"]
|
||||
material = SubResource("5")
|
||||
texture = ExtResource("4")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="GreenLight"]
|
||||
autoplay = "m2"
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_fig6v")
|
||||
}
|
||||
autoplay = "m2"
|
||||
|
||||
[node name="BlueLight" type="PointLight2D" parent="." groups=["point_light"]]
|
||||
position = Vector2(692.078, 29.8849)
|
||||
@@ -358,20 +356,20 @@ shadow_enabled = true
|
||||
shadow_filter = 1
|
||||
shadow_filter_smooth = 1.2
|
||||
texture = ExtResource("3")
|
||||
metadata/_edit_group_ = true
|
||||
|
||||
[node name="Blob" type="Sprite2D" parent="BlueLight"]
|
||||
[node name="blob" type="Sprite2D" parent="BlueLight"]
|
||||
material = SubResource("6")
|
||||
texture = ExtResource("4")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="BlueLight"]
|
||||
autoplay = "motion3"
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_kfxj1")
|
||||
}
|
||||
autoplay = "motion3"
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
offset = Vector2(400, 300)
|
||||
current = true
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
@@ -398,7 +396,7 @@ shadow_filter = 1
|
||||
shadow_filter_smooth = 1.2
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
autoplay = "rotate_directional_light"
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_6bket")
|
||||
}
|
||||
autoplay = "rotate_directional_light"
|
||||
|
||||
@@ -15,13 +15,9 @@ config/description="Simple demo of 2D lights and shadows,
|
||||
using PointLight2D and LightOccluder2D."
|
||||
config/tags=PackedStringArray("2d", "demo", "official", "rendering")
|
||||
run/main_scene="res://light_shadows.tscn"
|
||||
config/features=PackedStringArray("4.3")
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=800
|
||||
@@ -31,27 +27,22 @@ window/stretch/aspect="expand"
|
||||
[input]
|
||||
|
||||
toggle_directional_light={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
toggle_point_lights={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":80,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":80,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
cycle_directional_light_shadows_quality={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
cycle_point_light_shadows_quality={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":72,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":72,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
|
||||
@@ -7,9 +7,9 @@ Example of using 2D navigation using:
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
Renderer: Forward+
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2722
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/117
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
var movement_speed := 200.0
|
||||
|
||||
var movement_speed: float = 200.0
|
||||
@onready var navigation_agent: NavigationAgent2D = $NavigationAgent2D
|
||||
|
||||
func _ready() -> void:
|
||||
|
||||
func _ready():
|
||||
# These values need to be adjusted for the actor's speed
|
||||
# and the navigation layout.
|
||||
navigation_agent.path_desired_distance = 2.0
|
||||
@@ -14,18 +15,17 @@ func _ready() -> void:
|
||||
|
||||
# The "click" event is a custom input action defined in
|
||||
# Project > Project Settings > Input Map tab.
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
func _unhandled_input(event):
|
||||
if not event.is_action_pressed("click"):
|
||||
return
|
||||
|
||||
set_movement_target(get_global_mouse_position())
|
||||
|
||||
|
||||
func set_movement_target(movement_target: Vector2) -> void:
|
||||
func set_movement_target(movement_target: Vector2):
|
||||
navigation_agent.target_position = movement_target
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
func _physics_process(_delta):
|
||||
if navigation_agent.is_navigation_finished():
|
||||
return
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://bjgad00c2xiuc"]
|
||||
|
||||
[ext_resource type="NavigationPolygon" uid="uid://prlt4stfk6uh" path="res://navigation_polygon.res" id="2_lph0a"]
|
||||
[ext_resource type="Texture2D" uid="uid://bk26gi6qsuh18" path="res://map.png" id="2_nxfkp"]
|
||||
[ext_resource type="NavigationPolygon" uid="uid://bk5r48dcijlqt" path="res://navigation_polygon.res" id="3_6c0vu"]
|
||||
[ext_resource type="PackedScene" uid="uid://ct7veakwiei3h" path="res://character.tscn" id="4_n6iop"]
|
||||
|
||||
[node name="Navigation" type="Node2D"]
|
||||
@@ -12,7 +12,7 @@ position = Vector2(400, 302)
|
||||
texture = ExtResource("2_nxfkp")
|
||||
|
||||
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
|
||||
navigation_polygon = ExtResource("2_lph0a")
|
||||
navigation_polygon = ExtResource("3_6c0vu")
|
||||
|
||||
[node name="Character" parent="." instance=ExtResource("4_n6iop")]
|
||||
position = Vector2(211, 141)
|
||||
|
||||
Binary file not shown.
@@ -19,10 +19,6 @@ run/main_scene="res://navigation.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=800
|
||||
@@ -32,17 +28,11 @@ window/stretch/aspect="expand"
|
||||
[input]
|
||||
|
||||
click={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"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":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[physics]
|
||||
|
||||
common/physics_ticks_per_second=120
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
environment/defaults/default_clear_color=Color(0.160784, 0.172549, 0.278431, 1)
|
||||
|
||||
@@ -7,7 +7,7 @@ Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2723
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/519
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
||||
@@ -1,35 +1,29 @@
|
||||
extends Node2D
|
||||
|
||||
const PathFindAStar = preload("./pathfind_astar.gd")
|
||||
enum State { IDLE, FOLLOW }
|
||||
|
||||
enum State {
|
||||
IDLE,
|
||||
FOLLOW,
|
||||
}
|
||||
const MASS = 10.0
|
||||
const ARRIVE_DISTANCE = 10.0
|
||||
|
||||
const MASS: float = 10.0
|
||||
const ARRIVE_DISTANCE: float = 10.0
|
||||
@export var speed: float = 200.0
|
||||
|
||||
@export_range(10, 500, 0.1, "or_greater") var speed: float = 200.0
|
||||
var _state = State.IDLE
|
||||
var _velocity = Vector2()
|
||||
|
||||
var _state := State.IDLE
|
||||
var _velocity := Vector2()
|
||||
@onready var _tile_map = $"../TileMap"
|
||||
|
||||
var _click_position := Vector2()
|
||||
var _path := PackedVector2Array()
|
||||
var _next_point := Vector2()
|
||||
var _click_position = Vector2()
|
||||
var _path = PackedVector2Array()
|
||||
var _next_point = Vector2()
|
||||
|
||||
@onready var _tile_map: PathFindAStar = $"../TileMap"
|
||||
|
||||
func _ready() -> void:
|
||||
func _ready():
|
||||
_change_state(State.IDLE)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
func _process(_delta):
|
||||
if _state != State.FOLLOW:
|
||||
return
|
||||
|
||||
var arrived_to_next_point: bool = _move_to(_next_point)
|
||||
var arrived_to_next_point = _move_to(_next_point)
|
||||
if arrived_to_next_point:
|
||||
_path.remove_at(0)
|
||||
if _path.is_empty():
|
||||
@@ -38,7 +32,7 @@ func _process(_delta: float) -> void:
|
||||
_next_point = _path[0]
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
func _unhandled_input(event):
|
||||
_click_position = get_global_mouse_position()
|
||||
if _tile_map.is_point_walkable(_click_position):
|
||||
if event.is_action_pressed(&"teleport_to", false, true):
|
||||
@@ -48,16 +42,16 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
_change_state(State.FOLLOW)
|
||||
|
||||
|
||||
func _move_to(local_position: Vector2) -> bool:
|
||||
var desired_velocity: Vector2 = (local_position - position).normalized() * speed
|
||||
var steering: Vector2 = desired_velocity - _velocity
|
||||
func _move_to(local_position):
|
||||
var desired_velocity = (local_position - position).normalized() * speed
|
||||
var steering = desired_velocity - _velocity
|
||||
_velocity += steering / MASS
|
||||
position += _velocity * get_process_delta_time()
|
||||
rotation = _velocity.angle()
|
||||
return position.distance_to(local_position) < ARRIVE_DISTANCE
|
||||
|
||||
|
||||
func _change_state(new_state: State) -> void:
|
||||
func _change_state(new_state):
|
||||
if new_state == State.IDLE:
|
||||
_tile_map.clear_path()
|
||||
elif new_state == State.FOLLOW:
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
extends TileMap
|
||||
|
||||
enum Tile {
|
||||
OBSTACLE,
|
||||
START_POINT,
|
||||
END_POINT,
|
||||
}
|
||||
enum Tile { OBSTACLE, START_POINT, END_POINT }
|
||||
|
||||
const CELL_SIZE = Vector2i(64, 64)
|
||||
const BASE_LINE_WIDTH: float = 3.0
|
||||
const BASE_LINE_WIDTH = 3.0
|
||||
const DRAW_COLOR = Color.WHITE * Color(1, 1, 1, 0.5)
|
||||
|
||||
# The object for pathfinding on 2D grids.
|
||||
var _astar := AStarGrid2D.new()
|
||||
var _astar = AStarGrid2D.new()
|
||||
|
||||
var _start_point := Vector2i()
|
||||
var _end_point := Vector2i()
|
||||
var _path := PackedVector2Array()
|
||||
var _start_point = Vector2i()
|
||||
var _end_point = Vector2i()
|
||||
var _path = PackedVector2Array()
|
||||
|
||||
func _ready() -> void:
|
||||
func _ready():
|
||||
# Region should match the size of the playable area plus one (in tiles).
|
||||
# In this demo, the playable area is 17×9 tiles, so the rect size is 18×10.
|
||||
_astar.region = Rect2i(0, 0, 18, 10)
|
||||
@@ -30,35 +26,35 @@ func _ready() -> void:
|
||||
|
||||
for i in range(_astar.region.position.x, _astar.region.end.x):
|
||||
for j in range(_astar.region.position.y, _astar.region.end.y):
|
||||
var pos := Vector2i(i, j)
|
||||
var pos = Vector2i(i, j)
|
||||
if get_cell_source_id(0, pos) == Tile.OBSTACLE:
|
||||
_astar.set_point_solid(pos)
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
func _draw():
|
||||
if _path.is_empty():
|
||||
return
|
||||
|
||||
var last_point: Vector2 = _path[0]
|
||||
var last_point = _path[0]
|
||||
for index in range(1, len(_path)):
|
||||
var current_point: Vector2 = _path[index]
|
||||
var current_point = _path[index]
|
||||
draw_line(last_point, current_point, DRAW_COLOR, BASE_LINE_WIDTH, true)
|
||||
draw_circle(current_point, BASE_LINE_WIDTH * 2.0, DRAW_COLOR)
|
||||
last_point = current_point
|
||||
|
||||
|
||||
func round_local_position(local_position: Vector2i) -> Vector2i:
|
||||
func round_local_position(local_position):
|
||||
return map_to_local(local_to_map(local_position))
|
||||
|
||||
|
||||
func is_point_walkable(local_position: Vector2) -> bool:
|
||||
var map_position: Vector2i = local_to_map(local_position)
|
||||
func is_point_walkable(local_position):
|
||||
var map_position = local_to_map(local_position)
|
||||
if _astar.is_in_boundsv(map_position):
|
||||
return not _astar.is_point_solid(map_position)
|
||||
return false
|
||||
|
||||
|
||||
func clear_path() -> void:
|
||||
func clear_path():
|
||||
if not _path.is_empty():
|
||||
_path.clear()
|
||||
erase_cell(0, _start_point)
|
||||
@@ -67,7 +63,7 @@ func clear_path() -> void:
|
||||
queue_redraw()
|
||||
|
||||
|
||||
func find_path(local_start_point: Vector2i, local_end_point: Vector2i) -> PackedVector2Array:
|
||||
func find_path(local_start_point, local_end_point):
|
||||
clear_path()
|
||||
|
||||
_start_point = local_to_map(local_start_point)
|
||||
|
||||
@@ -18,10 +18,6 @@ run/main_scene="res://game.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
@@ -30,12 +26,12 @@ window/stretch/aspect="expand"
|
||||
[input]
|
||||
|
||||
teleport_to={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [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,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
move_to={
|
||||
"deadzone": 0.2,
|
||||
"deadzone": 0.5,
|
||||
"events": [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":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
@@ -43,5 +39,6 @@ move_to={
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
environment/defaults/default_clear_color=Color(0, 0.0627451, 0.247059, 1)
|
||||
quality/driver/driver_name="GLES2"
|
||||
vram_compression/import_etc=true
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# Navigation Mesh Chunks 2D
|
||||
|
||||
Demo that shows how to bake navigation meshes for large world chunk systems.
|
||||
|
||||
A mouse cursor left click changes the start position for the debug paths.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Compatibility
|
||||
|
||||
> Note: this demo requires Godot 4.3 or later
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,156 +0,0 @@
|
||||
extends Node2D
|
||||
|
||||
|
||||
static var map_cell_size: float = 1.0
|
||||
static var chunk_size: int = 256
|
||||
static var cell_size: float = 1.0
|
||||
static var agent_radius: float = 10.0
|
||||
static var chunk_id_to_region: Dictionary = {}
|
||||
|
||||
|
||||
var path_start_position: Vector2
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
NavigationServer2D.set_debug_enabled(true)
|
||||
|
||||
path_start_position = %DebugPaths.global_position
|
||||
|
||||
var map: RID = get_world_2d().navigation_map
|
||||
NavigationServer2D.map_set_cell_size(map, map_cell_size)
|
||||
|
||||
# Disable performance costly edge connection margin feature.
|
||||
# This feature is not needed to merge navigation mesh edges.
|
||||
# If edges are well aligned they will merge just fine by edge key.
|
||||
NavigationServer2D.map_set_use_edge_connections(map, false)
|
||||
|
||||
# Parse the collision shapes below our parse root node.
|
||||
var source_geometry: NavigationMeshSourceGeometryData2D = NavigationMeshSourceGeometryData2D.new()
|
||||
var parse_settings: NavigationPolygon = NavigationPolygon.new()
|
||||
parse_settings.parsed_geometry_type = NavigationPolygon.PARSED_GEOMETRY_STATIC_COLLIDERS
|
||||
NavigationServer2D.parse_source_geometry_data(parse_settings, source_geometry, %ParseRootNode)
|
||||
|
||||
# Add an outline to define the traversable surface that the parsed collision shapes can "cut" into.
|
||||
var traversable_outline: PackedVector2Array = PackedVector2Array([
|
||||
Vector2(0.0, 0.0),
|
||||
Vector2(1920.0, 0.0),
|
||||
Vector2(1920.0, 1080.0),
|
||||
Vector2(0.0, 1080.0),
|
||||
])
|
||||
source_geometry.add_traversable_outline(traversable_outline)
|
||||
|
||||
create_region_chunks(%ChunksContainer, source_geometry, chunk_size * cell_size, agent_radius)
|
||||
|
||||
|
||||
static func create_region_chunks(chunks_root_node: Node, p_source_geometry: NavigationMeshSourceGeometryData2D, p_chunk_size: float, p_agent_radius: float) -> void:
|
||||
# We need to know how many chunks are required for the input geometry.
|
||||
# So first get an axis aligned bounding box that covers all vertices.
|
||||
var input_geometry_bounds: Rect2 = calculate_source_geometry_bounds(p_source_geometry)
|
||||
|
||||
# Rasterize bounding box into chunk grid to know range of required chunks.
|
||||
var start_chunk: Vector2 = floor(
|
||||
input_geometry_bounds.position / p_chunk_size
|
||||
)
|
||||
var end_chunk: Vector2 = floor(
|
||||
(input_geometry_bounds.position + input_geometry_bounds.size)
|
||||
/ p_chunk_size
|
||||
)
|
||||
|
||||
for chunk_y in range(start_chunk.y, end_chunk.y + 1):
|
||||
for chunk_x in range(start_chunk.x, end_chunk.x + 1):
|
||||
var chunk_id: Vector2i = Vector2i(chunk_x, chunk_y)
|
||||
|
||||
var chunk_bounding_box: Rect2 = Rect2(
|
||||
Vector2(chunk_x, chunk_y) * p_chunk_size,
|
||||
Vector2(p_chunk_size, p_chunk_size),
|
||||
)
|
||||
# We grow the chunk bounding box to include geometry
|
||||
# from all the neighbor chunks so edges can align.
|
||||
# The border size is the same value as our grow amount so
|
||||
# the final navigation mesh ends up with the intended chunk size.
|
||||
var baking_bounds: Rect2 = chunk_bounding_box.grow(p_chunk_size)
|
||||
|
||||
var chunk_navmesh: NavigationPolygon = NavigationPolygon.new()
|
||||
chunk_navmesh.parsed_geometry_type = NavigationPolygon.PARSED_GEOMETRY_STATIC_COLLIDERS
|
||||
chunk_navmesh.baking_rect = baking_bounds
|
||||
chunk_navmesh.border_size = p_chunk_size
|
||||
chunk_navmesh.agent_radius = p_agent_radius
|
||||
NavigationServer2D.bake_from_source_geometry_data(chunk_navmesh, p_source_geometry)
|
||||
|
||||
# The only reason we reset the baking bounds here is to not render its debug.
|
||||
chunk_navmesh.baking_rect = Rect2()
|
||||
|
||||
# Snap vertex positions to avoid most rasterization issues with float precision.
|
||||
var navmesh_vertices: PackedVector2Array = chunk_navmesh.vertices
|
||||
for i in navmesh_vertices.size():
|
||||
var vertex: Vector2 = navmesh_vertices[i]
|
||||
navmesh_vertices[i] = vertex.snappedf(map_cell_size * 0.1)
|
||||
chunk_navmesh.vertices = navmesh_vertices
|
||||
|
||||
var chunk_region: NavigationRegion2D = NavigationRegion2D.new()
|
||||
chunk_region.navigation_polygon = chunk_navmesh
|
||||
chunks_root_node.add_child(chunk_region)
|
||||
|
||||
chunk_id_to_region[chunk_id] = chunk_region
|
||||
|
||||
|
||||
static func calculate_source_geometry_bounds(p_source_geometry: NavigationMeshSourceGeometryData2D) -> Rect2:
|
||||
if p_source_geometry.has_method("get_bounds"):
|
||||
# Godot 4.3 Patch added get_bounds() function that does the same but faster.
|
||||
return p_source_geometry.call("get_bounds")
|
||||
|
||||
var bounds: Rect2 = Rect2()
|
||||
var first_vertex: bool = true
|
||||
|
||||
for traversable_outline: PackedVector2Array in p_source_geometry.get_traversable_outlines():
|
||||
for traversable_point: Vector2 in traversable_outline:
|
||||
if first_vertex:
|
||||
first_vertex = false
|
||||
bounds.position = traversable_point
|
||||
else:
|
||||
bounds = bounds.expand(traversable_point)
|
||||
|
||||
for obstruction_outline: PackedVector2Array in p_source_geometry.get_obstruction_outlines():
|
||||
for obstruction_point: Vector2 in obstruction_outline:
|
||||
if first_vertex:
|
||||
first_vertex = false
|
||||
bounds.position = obstruction_point
|
||||
else:
|
||||
bounds = bounds.expand(obstruction_point)
|
||||
|
||||
for projected_obstruction: Dictionary in p_source_geometry.get_projected_obstructions():
|
||||
var projected_obstruction_vertices: PackedFloat32Array = projected_obstruction["vertices"]
|
||||
for i in projected_obstruction_vertices.size() / 2:
|
||||
var vertex: Vector2 = Vector2(projected_obstruction_vertices[i * 2], projected_obstruction_vertices[i * 2 + 1])
|
||||
if first_vertex:
|
||||
first_vertex = false
|
||||
bounds.position = vertex
|
||||
else:
|
||||
bounds = bounds.expand(vertex)
|
||||
|
||||
return bounds
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var mouse_cursor_position: Vector2 = get_global_mouse_position()
|
||||
|
||||
var map: RID = get_world_2d().navigation_map
|
||||
# Do not query when the map has never synchronized and is empty.
|
||||
if NavigationServer2D.map_get_iteration_id(map) == 0:
|
||||
return
|
||||
|
||||
var closest_point_on_navmesh: Vector2 = NavigationServer2D.map_get_closest_point(
|
||||
map,
|
||||
mouse_cursor_position
|
||||
)
|
||||
|
||||
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
|
||||
path_start_position = closest_point_on_navmesh
|
||||
|
||||
%DebugPaths.global_position = path_start_position
|
||||
|
||||
%PathDebugCorridorFunnel.target_position = closest_point_on_navmesh
|
||||
%PathDebugEdgeCentered.target_position = closest_point_on_navmesh
|
||||
|
||||
%PathDebugCorridorFunnel.get_next_path_position()
|
||||
%PathDebugEdgeCentered.get_next_path_position()
|
||||
@@ -1,99 +0,0 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://svfku2i5n033"]
|
||||
|
||||
[ext_resource type="Script" path="res://navmesh_chhunks_demo_2d.gd" id="1_d68tl"]
|
||||
|
||||
[node name="NavMeshChunksDemo2D" type="Node2D"]
|
||||
script = ExtResource("1_d68tl")
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
position = Vector2(960, 540)
|
||||
zoom = Vector2(0.8, 0.8)
|
||||
|
||||
[node name="ParseRootNode" type="Node2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="StaticBody2D" type="StaticBody2D" parent="ParseRootNode"]
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="ParseRootNode/StaticBody2D"]
|
||||
polygon = PackedVector2Array(244, 147, 636, 155, 376, 391, 460, 655, 804, 795, 756, 971, 484, 839, 308, 963, 132, 811, 128, 559)
|
||||
|
||||
[node name="CollisionPolygon2D2" type="CollisionPolygon2D" parent="ParseRootNode/StaticBody2D"]
|
||||
polygon = PackedVector2Array(1312, 207, 1596, 91, 1832, 175, 1739, 926, 1562, 796, 1508, 935, 1184, 811, 1324, 533, 1499, 599, 1684, 511, 1596, 322)
|
||||
|
||||
[node name="CollisionPolygon2D3" type="CollisionPolygon2D" parent="ParseRootNode/StaticBody2D"]
|
||||
polygon = PackedVector2Array(661, 339, 943, 397, 1112, 178, 1172, 443, 960, 639, 700, 579)
|
||||
|
||||
[node name="DebugPaths" type="Node2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="PathDebugCorridorFunnel" type="NavigationAgent2D" parent="DebugPaths"]
|
||||
unique_name_in_owner = true
|
||||
debug_enabled = true
|
||||
debug_use_custom = true
|
||||
debug_path_custom_color = Color(1, 0, 1, 1)
|
||||
debug_path_custom_point_size = 10.0
|
||||
debug_path_custom_line_width = 4.0
|
||||
|
||||
[node name="PathDebugEdgeCentered" type="NavigationAgent2D" parent="DebugPaths"]
|
||||
unique_name_in_owner = true
|
||||
path_postprocessing = 1
|
||||
debug_enabled = true
|
||||
debug_use_custom = true
|
||||
debug_path_custom_color = Color(1, 1, 0, 1)
|
||||
debug_path_custom_point_size = 10.0
|
||||
debug_path_custom_line_width = 4.0
|
||||
|
||||
[node name="ChunksContainer" type="Node2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="CanvasLayer"]
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="CanvasLayer/PanelContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 15
|
||||
theme_override_constants/margin_top = 15
|
||||
theme_override_constants/margin_right = 15
|
||||
theme_override_constants/margin_bottom = 15
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/PanelContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label" type="Label" parent="CanvasLayer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Use cursor button to set path start position"
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="CanvasLayer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="CanvasLayer/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
custom_minimum_size = Vector2(128, 8)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
color = Color(1, 0, 1, 1)
|
||||
|
||||
[node name="Label" type="Label" parent="CanvasLayer/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Path corridor-funnel"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="CanvasLayer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="CanvasLayer/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2"]
|
||||
custom_minimum_size = Vector2(128, 8)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
color = Color(1, 1, 0, 1)
|
||||
|
||||
[node name="Label" type="Label" parent="CanvasLayer/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
text = "Path edge-centered"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
@@ -1,29 +0,0 @@
|
||||
; 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="Navigation Mesh Chunks 2D"
|
||||
config/tags=PackedStringArray("2d", "ai", "demo", "official")
|
||||
run/main_scene="res://navmesh_chhunks_demo_2d.tscn"
|
||||
config/features=PackedStringArray("4.3", "GL Compatibility")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[display]
|
||||
|
||||
window/size/viewport_width=1920
|
||||
window/size/viewport_height=1080
|
||||
window/stretch/mode="canvas_items"
|
||||
window/stretch/aspect="expand"
|
||||
|
||||
[rendering]
|
||||
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB |
@@ -4,9 +4,9 @@ This demo showcases how 2D particle systems work in Godot.
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: Mobile
|
||||
Renderer: Forward Mobile
|
||||
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2724
|
||||
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/118
|
||||
|
||||
## How does it work?
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user