Compare commits

..

88 Commits
4.2 ... 4.3

Author SHA1 Message Date
Aaron Franke
52e3004465 [4.3] Simplify list of branches in the README (#1255) 2025-10-02 17:10:26 -07:00
utsav132
5557b10cfa Fix mob playback animation being started before the animation is set in Dodge the Creeps (#1175)
The '$AnimatedSprite2D.play()' is called at the beginning in the '_ready' function,
when it should actually be called at the end, after selecting the animation.
2025-03-07 19:43:58 +01:00
Hugo Locurcio
fdb2f50a20 Add a graphics tablet input demo (#1162) 2025-02-10 18:17:34 +01:00
Jason Yundt
0d46333c4e Update Platformer 2D to Godot 4.3 (#1145)
* Update Platformer 2D to Godot v4.3

Before this change, if you tries to import the Platformer 2D project
using Godot v4.3 (the latest stable version of Godot, at the moment),
you would get the following warning:

> Warning: This project was last edited in Godot 4.2.
> Opening will change it to Godot 4.3.
>
> Open anyway? Project will be modified.

This change updates the project to Godot 4.3 so that that warning no
longer appears. When you upgrade to a newer version of Godot, sometimes
certain files will automatically be updated by the Godot Editor after
the upgrade has been completed. Specifically, the files won’t get
updated until after they’re opened in the Godot Editor. When creating
this commit, I tried to open every single file for Platformer 2D in the
Godot Editor to make sure that all of those automatic changes are
included in this commit.

* Replace Platformer2D’s TileMap with a TileMapLayer

Before this change, the Platformer 2D used a TileMap Node. TileMaps are
deprecated. TileMapLayers should be used instead [1].

[1]: <https://docs.godotengine.org/en/4.3/classes/class_tilemap.html#tilemap>
2025-02-06 15:23:15 +01:00
Hugo Locurcio
c3b0331d8a Fix invalid icon reference in C# Android IAP demo (#1159) 2025-01-21 02:39:47 +01:00
Wayne Mwashuma
0e24c8eb2e Update to TileMapLayer in Multiplayer Bomber demo (#1155) 2025-01-10 22:39:38 +01:00
Mohamed Koubaa
be77353917 Move position setting code to be before direction in Dodge the Creeps (#1151) 2025-01-10 19:52:54 +01:00
Fabio Alessandrelli
d3c71ddb20 Fix typo in WebSocketServer class name (#1154) 2025-01-10 19:51:29 +01:00
David Briscoe
c49e134e13 Explain how to setup GUI in 3D (#1149)
Make it more obvious to newcomers how this demo works so they can
replicate it in their projects.

Change the text to point to how this is working.

Add Editor Descriptions to make it clearer how this is setup.

Co-authored-by: Aaron Franke <arnfranke@yahoo.com>
2024-12-23 18:55:20 +01:00
Jorrit Rouwe
81249b3f4a Increase Jolt Physics limit settings so performance tests run without errors (#1146) 2024-12-13 16:39:29 +01:00
Aaron Franke
51a7d389af Merge pull request #1138 from Calinou/truck-town-add-moods
Add moods (times of day) to Truck Town demo
2024-11-25 12:05:53 -08:00
Hugo Locurcio
5f0e0ce205 Improve GUI in 3D demo (#1140)
- Increase physics ticks per second to 120, so that UI interactions feel
  smoother and have lower input lag. This happens since input is governed
  by the physics tick due to the use of physics picking.
- Add a placeholder to the LineEdit and select a default option in the OptionButton.
2024-11-25 12:04:29 -08:00
Markus Sauermann
6f44371df1 Fix physics picking in Gui in 3D Demo (#1139)
Physics picking requires that the SubViewport has a consistent state
of the mouse-enter/exit notifications.

Godot V4.3 was changed in comparison to V4.2, so that it now requires
this additional step.

Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
Co-authored-by: Aaron Franke <arnfranke@yahoo.com>
2024-11-25 18:38:26 +01:00
Hugo Locurcio
15bcb941de Add moods (times of day) to Truck Town demo
Four moods are available: sunrise, day, sunset, night. Sunset and night
also feature artificial point lights placed in the town scene.

The mood can be set on the main menu before playing. It can also be cycled
during gameplay by pressing M or D-Pad Down.
2024-11-25 18:35:05 +01:00
Aaron Franke
5d9542113a Improve Truck Town model, fix issues, use OMI glTF Physics (#1110) 2024-11-25 06:56:02 -08:00
smix8
0fb1b4e09c Update 2D navigation demo NavigationPolygon for 4.3+ (#1135)
Updates NavigationPolygon with data that has compatibility with newer 2D navigation mesh baking.
2024-11-17 00:32:38 +01:00
Yaxian
1e02914267 Use TileMapLayer in Dynamic TileMap Layers (#1133)
TileMap is deprecated in 4.3 as TileMapLayer supersedes it.

Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
2024-11-15 19:04:15 +01:00
Bastiaan Olij
6db1062768 Fix recenter code in OpenXR Character Centric Movement (#1131)
Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
Co-authored-by: Aaron Franke <arnfranke@yahoo.com>
2024-11-15 19:03:19 +01:00
Hugo Locurcio
adf6d7e08d Disable non-functional XR demos in web exports (#1130)
These demos could work if they are redesigned to account for WebXR's
limitations when running on the web platform.
2024-11-08 11:33:19 +01:00
Danil Alexeev
c492e5fd73 Update some GDScript files for Godot 4.3 (#1129) 2024-11-04 12:00:59 +01:00
Hugo Locurcio
7ed5b1c116 Update web demo exports for Godot 4.3 (#1127)
This comes with other improvements:

- Demos now work on desktop and mobile browsers, as ETC2 import is now
  automatically enabled before exporting each demo.
- Progressive web app is available for each project.
  - Can be added to the home screen on a device for a closer-to-native experience.
  - Cross-origin isolation headers are automatically added, so that the export
    works with threads enabled despite being hosted on GitHub Pages
    (which doesn't send these headers).

Several demos will need further tweaks to look better when using
the Compatibility rendering method. Currently, many 3D demos appear
too bright due to lights with shadows enabled using sRGB blending.

Also, many demos will need to be modified to indicate which parts
of them are not supported when running on the web platform, or
when using the Compatibility rendering method.
2024-10-30 17:13:23 +01:00
Hugo Locurcio
53d3f9cdde Improve Operating System Testing demo (#1124)
- Display more return values of Engine/OS methods such as system fonts,
  memory information and security information.
- Add headless support (the generated report is also printed to stdout).
- Improve theming in the generated report.
- Hide video adapter type if this information can't be queried in the
  current rendering method.
- Update C# script for Godot 4.x platform names.
2024-10-23 23:09:23 +02:00
Hugo Locurcio
edccce8563 Fix normal map direction in 2D Lights and Shadows (#1123)
- Group Light2D nodes for easier dragging in the editor.
2024-10-18 23:30:07 +02:00
Raymond DiDonato
a87fded4cf Fix VRAM leak in compositor effect demo (#1115) 2024-09-17 01:36:20 +02:00
Montandalar
fdae025495 Add full license information for Voxel demo textures (#1113) 2024-09-15 15:04:34 +02:00
Tyler Breisacher
fa6061c623 Add static types in 2D Navigation AStar demo (#1008) 2024-08-31 03:48:17 +02:00
Ryhon
8ab921d5b4 Add FSR 2.2, exclusive fullscreen and ultra SSAO/SSIL to 3D Graphics Settings demo 2024-08-31 03:21:22 +02:00
shahriarlabib000
723331f814 updated README and Screenshots (#1111) 2024-08-28 18:09:22 -07:00
JavierStark
71630e80e4 Fix updated Android IAP project in c# (#1105)
* Update project to 4.3

Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
2024-08-28 16:58:41 -07:00
Aaron Franke
5646c6a7a8 Open and save 3D demos in Godot 4.3 stable (#1109) 2024-08-27 13:40:06 -07:00
Hugo Locurcio
582229e17c Improve Material Testers demo project (#1068)
- Add reflection probes for each test sphere, which can be toggled using
  a new dropdown with 3 options (no reflection probe, reflection only,
  reflection + ambient). The cull and reflection masks are configured
  on each reflection probe so that spheres don't self-reflect, but other
  spheres still appear in each sphere's reflections. Probe extents are made
  very large to prevent any visible fading, and the test beds don't
  receive the reflection probe's ambient or reflection.
- Improve ice material visuals by giving it some opacity.
- Use lossless compression on all textures, as their relatively low
  resolution and count by today's standards makes them not use much VRAM
  anyway.
2024-08-27 05:32:12 -07:00
Christen Lofland
7e2a55aa07 3D Inverse Kinematics Godot 4 Conversion (Partial) (#1036)
* These changes allow the project to start and run in Godot 4.2

I hit some of the files with my formatter, if whitespace updates are not wanted I can remove those.
The project doesn't entirely work yet, but it runs. I am still working on making it work properly fully, but at least it starts now instead of crashing.

* Center text to match Godot 3 example better.
2024-08-27 05:13:54 -07:00
shahriarlabib000
b05fb07d77 updated meshes to obj instead of res (#1107) 2024-08-27 05:06:22 -07:00
Mikael Hermansson
7e60538469 Change semi-truck in Truck Town demo to use 6DOF joint (#1102) 2024-08-27 04:31:10 -07:00
shahriarlabib000
9f59648c26 Update robot mesh for Godot 4 in 3D in 2D demo (#1106) 2024-08-26 00:07:36 +02:00
JavierStark
13b2787173 Update Android IAP in C# project to Godot 4.3 (#1104)
Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
2024-08-23 04:00:10 +02:00
Rémi Verschelde
6c635fe75a Merge pull request #1080 from BastiaanOlij/openxr_composition_layers
OpenXR composition layer example
2024-08-22 07:35:28 +02:00
Zi Fan
6d5ded3c7d Fix incorrect asset library link in 3D Lights and Shadows README (#1100) 2024-08-11 02:15:38 +02:00
smix8
cbb68060c6 Add navigation mesh chunks demos (#1099)
Adds 2D and 3D demo project for how to bake navigation meshes for large world chunk systems.
2024-08-08 17:22:47 +02:00
esainane
0fba875c72 Fix theme properties in various demos (#1097)
3.x -> 4.x:
`font_color_shadow` -> `font_shadow_color`
`font_color_selected` -> `font_selected_color`
`hseparation` -> `h_separation`
`vseparation` -> `v_separation`
`shadow_as_outline` -> `shadow_outline_size`

`panelf` and `panelnc` were removed in 3.2, as the options were never used.
See: godotengine/godot#28639

`font_color_shadow` is not a property of ProgressBar's theme, and there
doesn't seem to be an equivalent. The term "shadow" does not appear in any of:
{scene/{gui/{progress_bar,range,control},main/{canvas_item,node}},core/object/object}.{cpp,h}
2024-08-02 03:01:04 -07:00
Bastiaan Olij
98899881e7 OpenXR composition layer example 2024-07-31 15:44:50 +10:00
Fabio Alessandrelli
8fd41702c6 Fix typing errors in webrtc_signaling demo (#1096) 2024-07-28 01:35:33 +02:00
Russell Sanborn
34d174e315 Add JetBrains IDE files to .gitignore (#1094)
For reference, this exists in other godotengine repositories. Examples:

* https://github.com/godotengine/godot/blob/master/.gitignore#L157
* https://github.com/godotengine/godot-docs/blob/master/.gitignore#L52
2024-07-26 17:44:57 +02:00
Rémi Verschelde
3265d3fcd4 Merge pull request #1082 from Calinou/add-2d-polygons-lines-demo-4.x
Add a 2D polygons and lines demo
2024-07-25 13:31:10 +02:00
Russell Sanborn
7d42ae3c9a Rename Dodge The Creeps files to snake case (#1084)
This follows the style guide:

- https://docs.godotengine.org/en/stable/tutorials/best_practices/project_organization.html#style-guide

For reference, a documentation PR exists to update references to the
demo.
2024-07-15 00:36:11 +02:00
Matthew
e6fcf24f89 Merge pull request #973 from BastiaanOlij/openxr_hand_tracking_demo
Add OpenXR hand tracking demo
2024-07-13 15:04:58 -04:00
Hugo Locurcio
16d8ba09fb Replace instances of KinematicBody with CharacteBody in READMEs
KinematicBody was replaced by CharacterBody in Godot 4.0.

This also adds the 3D suffix to 3D physics classes.
2024-07-12 23:06:00 +02:00
Hugo Locurcio
7223aec001 Fix incorrect static typing in 2.5D demo 2024-07-03 17:18:29 +02:00
Hugo Locurcio
0ec2fff5bf Fix incorrect typed Array assignment in XR demo scripts (#1081) 2024-06-26 17:20:58 +02:00
Hugo Locurcio
78bbd99f0d Add a 2D polygons and lines demo 2024-06-25 18:09:34 +02:00
ShatteredReality
b4c73f4888 Fix README links to asset library (#1078)
This updates all links to point to the 4.2 demos instead of the 3.5 ones.

Co-authored-by: A Thousand Ships (she/her) <96648715+AThousandShips@users.noreply.github.com>
2024-06-24 19:29:58 +02:00
Bastiaan Olij
677dc46eeb Add OpenXR hand tracking demo 2024-06-15 14:04:49 +10:00
Hugo Locurcio
fbb7cb442c Fix ball speedup logic in Pong demo (#1073) 2024-06-13 12:31:10 +02:00
Bastiaan Olij
909331ac51 Add Compositor Effects (Post-Processing) demo (#1058)
Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
2024-06-07 22:19:25 +02:00
Hugo Locurcio
785e3213d5 Use higher shadow filtering quality settings in 3D demos (#1067)
The 3D demos aren't very demanding and Godot has been optimized
a bit since 4.0's release, so we can afford using higher quality
shadow settings for less noisy shadow filtering.

This also tweaks shadow bias to reduce shadow acne in the Voxel demo.

The time slider in the Physical Light and Camera units demo now
allows for more precise adjustments.
2024-06-06 22:11:18 +02:00
Hugo Locurcio
fad6cc2e1b Add turbulence example to 3D Particles demo (#1066)
- Make the attractor in the example dynamic to better showcase its functionality,
  and add a visual representation to it.
- Tweak the appearance of attracted particles.
- Fix force field particle display (it wasn't using Local Coords as intended).
- Lower the sun angle to make the background darker (and particles easier to see).
2024-06-06 22:07:00 +02:00
Hugo Locurcio
9a0c857131 Fix incorrect class_name declarations being swapped with extends
This was caused by an automatic text replacement issue.
2024-06-03 20:13:55 +02:00
Hugo Locurcio
bac1e69164 Use static typing in all demos (#1063)
This leads to code that is easier to understand and runs
faster thanks to GDScript's typed instructions.

The untyped declaration warning is now enabled on all projects
where type hints were added. All projects currently run without
any untyped declration warnings.

Dodge the Creeps and Squash the Creeps demos intentionally don't
use type hints to match the documentation, where type hints haven't
been adopted yet (given its beginner focus).
2024-06-01 12:12:18 +02:00
Sectonidse
8e9c180278 Use match case instead of if else in Audio Mic Record demo (#1053)
* Use match case instead of if else

This is my first pull request.

* Apply suggestions from code review

---------

Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
2024-05-13 19:57:04 +02:00
Christen Lofland
3859c66f0e Remove modulate/albedo mix changes from Distance Fade example in Decals (#1054) 2024-05-13 19:50:07 +02:00
Tarik Belabbas
9a5176e430 Fixed minor Godot 3 bit in "gui_in_3d" demo's billboard specific code (#1052) 2024-05-06 23:04:36 -07:00
谢天
95cfb076d1 Add missing tags to several demos (#1048) 2024-04-18 22:24:47 +02:00
Colter
9043224bb2 Fix upward movement key to be W in Multiplayer Bomber (#1049)
It was accidentally set to Z instead.
2024-04-18 22:23:59 +02:00
Lisandro Lorea
01db4a6f99 Fix joypad demo for Godot 4.x (#943) 2024-04-13 14:50:02 -07:00
Bastiaan Olij
035e905a3e XR demos: Add check for VRS/foveation in start vr script, and enable foveation in project settings (#1022)
Co-authored-by: Aaron Franke <arnfranke@yahoo.com>
2024-04-12 14:16:23 -07:00
Christen Lofland
b2ed2d6f6d Remove tiles outside of texture to elliminate these errors on loading the project: (#1035)
```
ERROR: Cannot create tile. The tile is outside the texture or tiles are already present in the space the tile would cover.
   at: (scene\resources\2d\tile_set.cpp:4963)
ERROR: The TileSetAtlasSource atlas has no tile at (1, 0).
   at: (scene\resources\2d\tile_set.cpp:5400)
ERROR: TileSetAtlasSource has no tile at (1, 0).
   at: (scene\resources\2d\tile_set.cpp:5348)
```
2024-04-12 14:16:04 -07:00
captain-redbeard
fbef18f58b Updated Dodge the Creeps C# to Godot mono 4.2 (#1000)
Co-authored-by: Ivan Shakhov <van800@gmail.com>
Co-authored-by: Aaron Franke <arnfranke@yahoo.com>
2024-04-12 00:56:02 -07:00
Hugo Locurcio
4f866f2a9a Add doors as an example of dynamic occluders in the Occlusion culling demo (#807)
The occluders don't actually move, but are toggled when the door starts
opening and finishes closing to avoid unnecessary BVH rebuilds.
2024-04-11 21:07:55 -07:00
Muller-Castro
af93126e05 Fix missing baked_exposure (#1043) 2024-04-11 20:57:52 -07:00
Hugo Locurcio
5bda007763 Update GUI Translation demo for 4.0 (#930)
- Add PO support in addition to CSV.

Co-authored-by: SkyJJ <jjchai01@hotmail.com>
2024-04-11 20:55:49 -07:00
Christen Lofland
f70868ce22 Use @onready to init previous_position to prevent errors (#1042) 2024-04-11 20:36:15 -07:00
Aaron Franke
6e44341d67 Merge pull request #1041 from chrisl8/2.5d-editor-view-update
Update 2.5D GDScript demo to display the editor plugin in Godot 4.
2024-04-11 20:33:37 -07:00
Aaron Franke
3788da41cd Fix 2.5D editor viewport and gizmo for Godot 4.x 2024-04-11 20:30:58 -07:00
Aaron Franke
57c1cb9ffa More tweaks to the 2.5D demo for Godot 4.x 2024-04-11 13:50:34 -07:00
Christen Lofland
85b8f10778 Prefer using guard clauses as suggested by aaronfranke. 2024-04-10 16:33:46 -05:00
Christen Lofland
0a35055aa0 Undue some formatting changes that were in dispute. 2024-04-10 16:31:51 -05:00
Christen Lofland
3ef6a15741 Update 2.5D GDScript demo to display the editor plugin in Godot 4. 2024-04-10 11:52:08 -05:00
Christen Lofland
d190e73ad3 Only print MIDI device list if any are found in MIDI Piano (#1039)
This is a silly "fix", but it prevents an empty `[]` from being printed every time
this demo is run without a MIDI device plugged into the computer.

The MIDI devices list is printed if one is plugged into the computer, which I have tested.
2024-04-10 01:30:09 +02:00
Clay John
79d30931c3 Switch to single safe threaded model in TextureRD demo (#1038)
Multithreaded rendering is not safe in 4.2, so it should not be used
in our official demos for now.
2024-04-09 02:09:27 +02:00
iltenahmet
56f103953d Update dodge-the-creeps asset library link (#1034) 2024-04-03 15:32:10 -07:00
Christen Lofland
be7be4c1cc Disable 2D MSAA in Dynamic TileMap Layers to avoid warning on start (#1030)
The demo uses the Compatibility rendering method, which currently
doesn't support 2D MSAA.
2024-04-02 03:19:56 +02:00
Christen Lofland
5553ecfd88 Fix font code for Godot 4 in Finite State Machine (#1027)
This clears out some errors that happen on every load of this demo in Godot 4 onward.
It also makes the fonts actually work, as they did not before.

We probably don't strictly **need** these font settings for a demo, but they were here before.

I don't think `SourceCodePro-Black.ttf` was ever used, based on looking at history. So I removed it.

Both `.tres` files are gone too, as those are not used in Godot 4.

I have updated everything that used `SourceCodePro-Bold.ttf` to the new setup.
2024-04-02 01:52:04 +02:00
Christen Lofland
ab9ffb7558 Fix font setup in Dodge the Creeps (#1026) 2024-04-02 01:50:12 +02:00
谢天
c181965682 Fix incorrect toggle_mouse_capture key in Global Illumination (#1029) 2024-04-02 01:21:01 +02:00
Hugo Locurcio
31d1c0c112 Remove old and unused project settings, update various demos for 4.2 (#1024)
- Move all demo projects that don't require Forward+/Mobile-only features
  to the Compatibility rendering method. This improves performance significantly
  on low-end devices and ensures visuals are identical to a web export
  of the demo.
- Set deadzone on all inputs to 0.2 for better gamepad usability.
- Remove reliance on `default_env.tres` to use built-in Environment
  resources in the main scene instead (which follows the preview environment
  workflow).
- Remove notices pointing to GDNative or VisualScript, since both were
  removed in 4.0.
- Various bug fixes and usability tweaks to 10+ demos.
2024-03-26 18:01:58 +01:00
A Thousand Ships
82913393a8 Improve code style (#1021)
* Remove unnecessary use of `self`
* Connect to signals directly over `connect("name")`
* Use `call_deferred` on callables over `call_deferred("name"))`
* Emit signals directly over `emit_signal("name"...)`
2024-03-25 17:06:52 +01:00
behrooz bozorgchamy
523c7d34c0 Update Pong with C# to Godot 4.2.1 (#966) 2024-03-25 16:25:51 +01:00
Hugo Locurcio
71eea49eba Fix player and mob animations not looping in Squash the Creeps (#1020)
This was missed in the upgrade to 4.0, which reset loop mode properties
in Animation.
2024-03-06 23:08:05 +01:00
1039 changed files with 22808 additions and 9954 deletions

View File

@@ -1,23 +1,41 @@
[preset.0]
name="HTML5"
platform="HTML5"
name="Web"
platform="Web"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter="*.json"
include_filter=""
exclude_filter=""
export_path=""
script_export_mode=1
script_encryption_key=""
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.0.options]
custom_template/debug=""
custom_template/release=""
variant/export_type=0
variant/extensions_support=false
variant/thread_support=true
vram_texture_compression/for_desktop=true
vram_texture_compression/for_mobile=false
vram_texture_compression/for_mobile=true
html/export_icon=true
html/custom_html_shell=""
html/head_include=""
html/full_window_size=true
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)

View File

@@ -1,20 +1,38 @@
<!-- The list of demos will be inserted above by the CI process. -->
</ul>
<h2>Unavailable demos</h2>
<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 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>
</body>
</html>

View File

@@ -4,13 +4,15 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Godot demos exported to HTML5</title>
<title>Official Godot demos exported to Web</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) {
@@ -18,7 +20,9 @@
--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);
}
}
@@ -52,6 +56,11 @@
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%);
}
@@ -88,6 +97,9 @@
margin: 20px 10px;
}
.unsupported-demos li {
margin-bottom: 1.5rem;
}
</style>
</head>
@@ -96,12 +108,12 @@
<p>
This page lists
<a href="https://github.com/godotengine/godot-demo-projects">official Godot demo projects</a>
exported to HTML5 for testing purposes. These projects are deployed automatically
exported to the web for testing purposes. These projects are deployed automatically
on every commit on the <code>master</code> branch of the repository.
</p>
<p>
The HTML5 exports on this page are provided for demonstration purposes only.
Some of these demos may not function or render correctly on HTML5,
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,
especially on mobile devices.
For best performance, it's recommended to
<a href="https://godotengine.org/download">download</a> a native editor
@@ -110,7 +122,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 HTML5.
documentation for information on exporting your own projects to the web.
</p>
<h2>List of demos</h2>

3
.gitignore vendored
View File

@@ -21,3 +21,6 @@ mono_crash.*.json
.DS_Store
*~
*.blend1
# Jetbrains IDE files
.idea/

View File

@@ -3,6 +3,6 @@
These demos are all 2D, but otherwise do not have a common theme.
Languages: Most have GDScript, some have
[GDSL](https://docs.godotengine.org/en/latest/tutorials/shaders/shader_reference/shading_language.html)
[Godot shader language](https://docs.godotengine.org/en/latest/tutorials/shaders/shader_reference/shading_language.html)
Renderers: 4 of them are GLES 3, but most are GLES 2
Renderers: Glow for 2D and Physics Platformer use Forward+, 2D Particles uses Mobile, and the rest use Compatibility

View File

@@ -9,9 +9,9 @@ in the documentation for more information.
Language: GDScript
Renderer: Vulkan Mobile
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/887
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2711
## Screenshots

View File

@@ -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
var shape := RID()
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():
func _ready() -> void:
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():
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):
func _process(_delta: float) -> void:
# Order the CanvasItem to update every frame.
queue_redraw()
func _physics_process(delta):
var transform2d = Transform2D()
var offset = get_viewport_rect().size.x + 16
for bullet in bullets:
func _physics_process(delta: float) -> void:
var transform2d := Transform2D()
var offset := get_viewport_rect().size.x + 16
for bullet: Bullet in bullets:
bullet.position.x -= bullet.speed * delta
if bullet.position.x < -16:
@@ -73,15 +73,15 @@ func _physics_process(delta):
# Instead of drawing each bullet individually in a script attached to each bullet,
# we are drawing *all* the bullets at once here.
func _draw():
var offset = -bullet_image.get_size() * 0.5
for bullet in bullets:
func _draw() -> void:
var offset := -bullet_image.get_size() * 0.5
for bullet: 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():
for bullet in bullets:
func _exit_tree() -> void:
for bullet: Bullet in bullets:
PhysicsServer2D.free_rid(bullet.body)
PhysicsServer2D.free_rid(shape)

View File

@@ -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
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
func _ready():
func _ready() -> void:
# 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):
func _input(event: InputEvent) -> void:
# 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, _body, _body_shape, _local_shape):
func _on_body_shape_entered(_body_id: RID, _body: Node2D, _body_shape_index: int, _local_shape_index: int) -> void:
# 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, _body, _body_shape, _local_shape):
func _on_body_shape_exited(_body_id: RID, _body: Node2D, _body_shape_index: int, _local_shape_index: int) -> void:
touching -= 1
# When non of the bullets are touching the player,
# sprite changes to happy face.

View File

@@ -17,6 +17,10 @@ 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"
@@ -26,10 +30,7 @@ window/stretch/aspect="expand"
2d_physics/layer_1="Player"
[physics]
2d/cell_size=64
[rendering]
renderer/rendering_method="mobile"
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"

View File

@@ -10,13 +10,11 @@ consider following the tutorial in the documentation.
Language: GDScript
Renderer: Vulkan Mobile
Renderer: Compatibility
Note: There is a C# version available [here](https://github.com/godotengine/godot-demo-projects/tree/master/mono/dodge_the_creeps).
Note: There is a GDNative C++ version available [here](https://github.com/godotengine/gdnative-demos/tree/master/cpp/dodge_the_creeps).
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/515
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2712
## Screenshots

View File

@@ -1,6 +0,0 @@
[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" )

View File

@@ -1,6 +1,7 @@
[gd_scene load_steps=4 format=3 uid="uid://ccqoreueuxdb7"]
[gd_scene load_steps=5 format=3 uid="uid://ccqoreueuxdb7"]
[ext_resource type="Script" path="res://HUD.gd" id="1"]
[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"]
[sub_resource type="InputEventAction" id="InputEventAction_fopy7"]
action = &"start_game"
@@ -16,6 +17,7 @@ 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
@@ -29,6 +31,7 @@ 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"
@@ -46,6 +49,7 @@ 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"

View File

@@ -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 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
# Set the mob's direction perpendicular to the path direction.
var direction = mob_spawn_location.rotation + PI / 2
# Add some randomness to the direction.
direction += randf_range(-PI / 4, PI / 4)
mob.rotation = direction

View File

@@ -1,11 +1,11 @@
[gd_scene load_steps=8 format=3 uid="uid://cyfwty2q3rdse"]
[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"]
[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"]
[sub_resource type="Curve2D" id="1"]
_data = {
@@ -14,8 +14,8 @@ _data = {
point_count = 5
[node name="Main" type="Node"]
script = ExtResource("1")
mob_scene = ExtResource("2")
script = ExtResource("1_0r6n5")
mob_scene = ExtResource("2_50pww")
[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")]
[node name="Player" parent="." instance=ExtResource("3_veqnc")]
[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")]
[node name="HUD" parent="." instance=ExtResource("4_0qnje")]
[node name="Music" type="AudioStreamPlayer" parent="."]
stream = ExtResource("5")
stream = ExtResource("5_55d8h")
[node name="DeathSound" type="AudioStreamPlayer" parent="."]
stream = ExtResource("6")
stream = ExtResource("6_hp1r0")
[connection signal="hit" from="Player" to="." method="game_over"]
[connection signal="timeout" from="MobTimer" to="." method="_on_MobTimer_timeout"]

View File

@@ -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():

View File

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

View File

@@ -47,7 +47,7 @@ func start(pos):
$CollisionShape2D.disabled = false
func _on_Player_body_entered(_body):
func _on_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.

View File

@@ -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_Player_body_entered"]
[connection signal="body_entered" from="." to="." method="_on_body_entered"]

View File

@@ -18,14 +18,10 @@ 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
@@ -37,7 +33,7 @@ window/stretch/mode="canvas_items"
[input]
move_left={
"deadzone": 0.5,
"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":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)
@@ -45,7 +41,7 @@ move_left={
]
}
move_right={
"deadzone": 0.5,
"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":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)
@@ -53,7 +49,7 @@ move_right={
]
}
move_up={
"deadzone": 0.5,
"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":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)
@@ -61,7 +57,7 @@ move_up={
]
}
move_down={
"deadzone": 0.5,
"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":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)
@@ -69,7 +65,7 @@ move_down={
]
}
start_game={
"deadzone": 0.5,
"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":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)
]
@@ -77,4 +73,5 @@ start_game={
[rendering]
renderer/rendering_method="mobile"
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"

View File

@@ -6,7 +6,9 @@ to disable collisions per layer.
Language: GDScript
Renderer: OpenGL
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2713
## Screenshots

View File

@@ -1,17 +1,10 @@
extends TileMap
extends TileMapLayer
var secret_layer: int # You can have multiple layers if you make this an array.
var player_in_secret: bool
# You can have multiple layers if you make this an array.
var player_in_secret := false
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)
@@ -19,30 +12,31 @@ func _ready() -> void:
func _process(delta: float) -> void:
if player_in_secret:
if layer_alpha > 0.3:
layer_alpha = move_toward(layer_alpha, 0.3, delta) # Animate the layer transparency.
set_layer_modulate(secret_layer, Color(1, 1, 1, layer_alpha))
# Animate the layer transparency.
layer_alpha = move_toward(layer_alpha, 0.3, delta)
self_modulate = 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)
set_layer_modulate(secret_layer, Color(1, 1, 1, layer_alpha))
self_modulate = Color(1, 1, 1, layer_alpha)
else:
set_process(false)
func _use_tile_data_runtime_update(layer: int, _coords: Vector2i) -> bool:
if layer == secret_layer:
return true
return false
func _use_tile_data_runtime_update(_coords: Vector2i) -> bool:
return true
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 _tile_data_runtime_update(_coords: Vector2i, tile_data: TileData) -> void:
# Remove collision for secret layer.
tile_data.set_collision_polygons_count(0, 0)
func _on_secret_detector_body_entered(body: Node2D) -> void:
if not body is CharacterBody2D: # Detect player only.
if body is not CharacterBody2D:
# Detect the player only.
return
player_in_secret = true
@@ -50,7 +44,7 @@ func _on_secret_detector_body_entered(body: Node2D) -> void:
func _on_secret_detector_body_exited(body: Node2D) -> void:
if not body is CharacterBody2D:
if body is not CharacterBody2D:
return
player_in_secret = false

View File

@@ -5,11 +5,11 @@ const WALK_MAX_SPEED = 200
const STOP_FORCE = 1300
const JUMP_SPEED = 200
@onready var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
@onready var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")
func _physics_process(delta):
func _physics_process(delta: float) -> void:
# 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.

View File

@@ -1,17 +1,17 @@
[gd_scene load_steps=4 format=2]
[gd_scene load_steps=4 format=3 uid="uid://1o70ce0fv10w"]
[ext_resource path="res://player/player.gd" type="Script" id=1]
[ext_resource path="res://player/player.png" type="Texture2D" id=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"]
[sub_resource type="RectangleShape2D" id=1]
extents = Vector2(7, 7)
[sub_resource type="RectangleShape2D" id="1"]
size = Vector2(14, 14)
[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")

View File

@@ -14,10 +14,15 @@ 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.2")
config/features=PackedStringArray("4.3")
config/icon="res://icon.png"
[debug]
gdscript/warnings/untyped_declaration=1
[display]
window/size/viewport_width=530
@@ -28,29 +33,29 @@ window/stretch/aspect="expand"
[input]
jump={
"deadzone": 0.5,
"deadzone": 0.2,
"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,"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)
, 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)
]
}
move_left={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
, 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":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)
]
}
move_right={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
, 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(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)
]
}
@@ -62,5 +67,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

View File

@@ -1,20 +1,15 @@
[gd_scene load_steps=8 format=3 uid="uid://de7qapkqfycxl"]
[gd_scene load_steps=8 format=4 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" path="res://player/player.tscn" id="3"]
[ext_resource type="PackedScene" uid="uid://1o70ce0fv10w" 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
@@ -26,19 +21,15 @@ size = Vector2(112, 48)
[node name="World" type="Node2D"]
[node name="TileMap" type="TileMap" parent="."]
z_index = 1
[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=")
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="."]
@@ -53,5 +44,5 @@ position = Vector2(280, 440)
[node name="CollisionShape2D" type="CollisionShape2D" parent="SecretDetector"]
shape = SubResource("RectangleShape2D_a2gec")
[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"]
[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"]

View File

@@ -1,6 +1,7 @@
[gd_scene load_steps=8 format=3 uid="uid://dmn8nkpogiwsf"]
[gd_scene load_steps=9 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"]
@@ -43,6 +44,9 @@ 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

View File

@@ -8,7 +8,7 @@ Language: GDScript
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/516
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2714
## Why use a state machine

View File

@@ -1,6 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://cvi13chv8g4hj"]
[gd_scene load_steps=3 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
@@ -17,6 +18,7 @@ grow_vertical = 2
[node name="Title" type="Label" parent="VBoxContainer"]
layout_mode = 2
theme_override_fonts/font = ExtResource("2_58if7")
text = "StateStack"
uppercase = true
@@ -26,6 +28,7 @@ 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
@@ -33,5 +36,6 @@ 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"

View File

@@ -1,14 +1,16 @@
extends Panel
@onready var fsm_node = get_node(^"../../Player/StateMachine")
@onready var fsm_node: Node = get_node(^"../../Player/StateMachine")
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"
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"
numbers += str(index) + "\n"
index += 1
%States.text = states_names
%Numbers.text = numbers

View File

@@ -1,12 +0,0 @@
[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" ]

View File

@@ -1,12 +0,0 @@
[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" ]

View File

@@ -1,23 +1,23 @@
extends CharacterBody2D
var direction = Vector2()
@export var speed: float = 1000.0
var direction := Vector2()
@export var speed := 1000.0
@onready var root = get_tree().root
@onready var root := get_tree().root
func _ready():
func _ready() -> void:
set_as_top_level(true)
func _physics_process(delta):
func _physics_process(delta: float) -> void:
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():
func _draw() -> void:
draw_circle(Vector2(), $CollisionShape2D.shape.radius, Color.WHITE)

View File

@@ -1,18 +1,18 @@
extends Node2D
var bullet = preload("Bullet.tscn")
var bullet := preload("Bullet.tscn")
func _unhandled_input(event):
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("fire"):
fire()
func fire():
func fire() -> void:
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

View File

@@ -3,25 +3,26 @@ 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)
signal direction_changed(new_direction: Vector2)
var look_direction = Vector2.RIGHT:
var look_direction := Vector2.RIGHT:
set(value):
look_direction = value
set_look_direction(value)
func take_damage(attacker, amount, effect = null):
func take_damage(attacker: Node, amount: float, effect: Node = null) -> void:
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):
func set_dead(value: bool) -> void:
set_process_input(not value)
set_physics_process(not value)
$CollisionPolygon2D.disabled = value
func set_look_direction(value):
emit_signal("direction_changed", value)
func set_look_direction(value: Vector2) -> void:
direction_changed.emit(value)

View File

@@ -1,12 +1,12 @@
extends "res://state_machine/state_machine.gd"
@onready var idle = $Idle
@onready var move = $Move
@onready var jump = $Jump
@onready var stagger = $Stagger
@onready var attack = $Attack
@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
func _ready():
func _ready() -> void:
states_map = {
"idle": idle,
"move": move,
@@ -16,7 +16,7 @@ func _ready():
}
func _change_state(state_name):
func _change_state(state_name: String) -> void:
# The base state_machine interface this node extends does most of the work.
if not _active:
return
@@ -24,10 +24,11 @@ func _change_state(state_name):
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):
func _unhandled_input(event: InputEvent) -> void:
# 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"):
@@ -35,4 +36,5 @@ func _unhandled_input(event):
return
_change_state("attack")
return
current_state.handle_input(event)

View File

@@ -1,8 +1,8 @@
extends "res://state_machine/state.gd"
func enter():
func enter() -> void:
owner.get_node(^"AnimationPlayer").play("idle")
func _on_Sword_attack_finished():
emit_signal("finished", "previous")
func _on_Sword_attack_finished() -> void:
finished.emit("previous")

View File

@@ -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():
func enter() -> void:
owner.get_node(^"AnimationPlayer").play("stagger")
func _on_animation_finished(anim_name):
func _on_animation_finished(anim_name: String) -> void:
assert(anim_name == "stagger")
emit_signal("finished", "previous")
finished.emit("previous")

View File

@@ -1,14 +1,14 @@
extends Label
var start_position = Vector2()
var start_position := Vector2()
func _ready():
func _ready() -> void:
start_position = position
func _physics_process(_delta):
func _physics_process(_delta: float) -> void:
position = $"../BodyPivot".position + start_position
func _on_StateMachine_state_changed(current_state):
text = String(current_state.get_name())
func _on_StateMachine_state_changed(current_state: Node) -> void:
text = String(current_state.name)

View File

@@ -1,10 +1,10 @@
extends "res://state_machine/state.gd"
# Initialize the state. E.g. change the animation.
func enter():
func enter() -> void:
owner.set_dead(true)
owner.get_node(^"AnimationPlayer").play("die")
func _on_animation_finished(_anim_name):
emit_signal("finished", "dead")
func _on_animation_finished(_anim_name: String) -> void:
finished.emit("dead")

View File

@@ -1,23 +1,23 @@
extends "../motion.gd"
@export var base_max_horizontal_speed: float = 400.0
@export var base_max_horizontal_speed := 400.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 air_acceleration := 1000.0
@export var air_deceleration := 2000.0
@export var air_steering_power := 50.0
@export var gravity: float = 1600.0
@export var gravity := 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, velocity):
func initialize(speed: float, velocity: Vector2) -> void:
horizontal_speed = speed
if speed > 0.0:
max_horizontal_speed = speed
@@ -26,8 +26,8 @@ func initialize(speed, velocity):
enter_velocity = velocity
func enter():
var input_direction = get_input_direction()
func enter() -> void:
var input_direction := get_input_direction()
update_look_direction(input_direction)
if input_direction:
@@ -39,32 +39,32 @@ func enter():
owner.get_node(^"AnimationPlayer").play("idle")
func update(delta):
var input_direction = get_input_direction()
func update(delta: float) -> void:
var input_direction := get_input_direction()
update_look_direction(input_direction)
move_horizontally(delta, input_direction)
animate_jump_height(delta)
if height <= 0.0:
emit_signal("finished", "previous")
finished.emit("previous")
func move_horizontally(delta, direction):
func move_horizontally(delta: float, direction: Vector2) -> void:
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):
func animate_jump_height(delta: float) -> void:
vertical_speed -= gravity * delta
height += vertical_speed * delta
height = max(0.0, height)

View File

@@ -1,19 +1,18 @@
extends "res://state_machine/state.gd"
# Collection of important methods to handle direction and animation.
func handle_input(event):
func handle_input(event: InputEvent) -> void:
if event.is_action_pressed("simulate_damage"):
emit_signal("finished", "stagger")
finished.emit("stagger")
func get_input_direction():
var input_direction = Vector2(
func get_input_direction() -> Vector2:
return Vector2(
Input.get_axis(&"move_left", &"move_right"),
Input.get_axis(&"move_up", &"move_down")
)
return input_direction
func update_look_direction(direction):
func update_look_direction(direction: Vector2) -> void:
if direction and owner.look_direction != direction:
owner.look_direction = direction

View File

@@ -1,14 +1,14 @@
extends "on_ground.gd"
func enter():
func enter() -> void:
owner.get_node(^"AnimationPlayer").play("idle")
func handle_input(event):
func handle_input(event: InputEvent) -> void:
return super.handle_input(event)
func update(_delta):
var input_direction = get_input_direction()
func update(_delta: float) -> void:
var input_direction: Vector2 = get_input_direction()
if input_direction:
emit_signal("finished", "move")
finished.emit("move")

View File

@@ -1,25 +1,25 @@
extends "on_ground.gd"
@export var max_walk_speed: float = 450
@export var max_run_speed: float = 700
@export var max_walk_speed := 450.0
@export var max_run_speed := 700.0
func enter():
func enter() -> void:
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):
func handle_input(event: InputEvent) -> void:
return super.handle_input(event)
func update(_delta):
var input_direction = get_input_direction()
func update(_delta: float) -> void:
var input_direction := get_input_direction()
if input_direction.is_zero_approx():
emit_signal("finished", "idle")
finished.emit("idle")
update_look_direction(input_direction)
if Input.is_action_pressed("run"):
@@ -27,16 +27,17 @@ func update(_delta):
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 null
return
func move(speed, direction):
owner.velocity = direction.normalized() * speed
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
return null
return owner.get_slide_collision(0)

View File

@@ -1,10 +1,9 @@
extends "../motion.gd"
# warning-ignore-all:unused_class_variable
var speed = 0.0
var velocity = Vector2()
var speed := 0.0
var velocity := Vector2()
func handle_input(event):
func handle_input(event: InputEvent) -> void:
if event.is_action_pressed("jump"):
emit_signal("finished", "jump")
finished.emit("jump")
return super.handle_input(event)

View File

@@ -2,41 +2,50 @@ extends Area2D
signal attack_finished
enum States { IDLE, ATTACK }
var state = null
enum States {
IDLE,
ATTACK,
}
enum AttackInputStates { IDLE, LISTENING, REGISTERED }
var attack_input_state = AttackInputStates.IDLE
var ready_for_next_attack = false
enum AttackInputStates {
IDLE,
LISTENING,
REGISTERED,
}
var state: States = States.IDLE
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():
$AnimationPlayer.animation_finished.connect(self._on_animation_finished)
body_entered.connect(self._on_body_entered)
func _ready() -> void:
$AnimationPlayer.animation_finished.connect(_on_animation_finished)
body_entered.connect(_on_body_entered)
_change_state(States.IDLE)
func _change_state(new_state):
func _change_state(new_state: States) -> void:
match state:
States.ATTACK:
hit_objects = []
@@ -57,7 +66,7 @@ func _change_state(new_state):
state = new_state
func _unhandled_input(event):
func _unhandled_input(event: InputEvent) -> void:
if not state == States.ATTACK:
return
if attack_input_state != AttackInputStates.LISTENING:
@@ -66,36 +75,37 @@ func _unhandled_input(event):
attack_input_state = AttackInputStates.REGISTERED
func _physics_process(_delta):
func _physics_process(_delta: float) -> void:
if attack_input_state == AttackInputStates.REGISTERED and ready_for_next_attack:
attack()
func attack():
func attack() -> void:
combo_count += 1
_change_state(States.ATTACK)
# Use with AnimationPlayer func track.
func set_attack_input_listening():
func set_attack_input_listening() -> void:
attack_input_state = AttackInputStates.LISTENING
# Use with AnimationPlayer func track.
func set_ready_for_next_attack():
func set_ready_for_next_attack() -> void:
ready_for_next_attack = true
func _on_body_entered(body):
func _on_body_entered(body: Node2D) -> void:
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):
func _on_animation_finished(_name: String) -> void:
if attack_current.is_empty():
return
@@ -103,9 +113,9 @@ func _on_animation_finished(_name):
attack()
else:
_change_state(States.IDLE)
emit_signal("attack_finished")
attack_finished.emit()
func _on_StateMachine_state_changed(current_state):
func _on_StateMachine_state_changed(current_state: Node) -> void:
if current_state.name == "Attack":
attack()

View File

@@ -1,13 +1,13 @@
extends Marker2D
var z_index_start = 0
var z_index_start := 0
func _ready():
owner.direction_changed.connect(self._on_Parent_direction_changed)
func _ready() -> void:
owner.direction_changed.connect(_on_Parent_direction_changed)
z_index_start = z_index
func _on_Parent_direction_changed(direction):
func _on_Parent_direction_changed(direction: Vector2) -> void:
rotation = direction.angle()
match direction:
Vector2.UP:

View File

@@ -19,6 +19,10 @@ 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
@@ -29,7 +33,7 @@ window/stretch/aspect="expand"
[input]
move_left={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -37,7 +41,7 @@ move_left={
]
}
move_up={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -45,7 +49,7 @@ move_up={
]
}
move_right={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -53,7 +57,7 @@ move_right={
]
}
move_down={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -61,31 +65,31 @@ move_down={
]
}
fire={
"deadzone": 0.5,
"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":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.5,
"deadzone": 0.2,
"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.5,
"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":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.5,
"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":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.5,
"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":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)
]

View File

@@ -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)
@warning_ignore("unused_signal")
signal finished(next_state_name: String)
# Initialize the state. E.g. change the animation.
func enter():
func enter() -> void:
pass
# Clean up the state. Reinitialize values like a timer.
func exit():
func exit() -> void:
pass
func handle_input(_event):
func handle_input(_event: InputEvent) -> void:
pass
func update(_delta):
func update(_delta: float) -> void:
pass
func _on_animation_finished(_anim_name):
func _on_animation_finished(_anim_name: String) -> void:
pass

View File

@@ -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)
signal state_changed(current_state: Node)
# 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 = null
var _active = false:
var states_stack := []
var current_state: Node = null
var _active := false:
set(value):
_active = value
set_active(value)
func _enter_tree():
func _enter_tree() -> void:
if start_state.is_empty():
start_state = get_child(0).get_path()
for child in get_children():
var err = child.finished.connect(self._change_state)
var err: bool = child.finished.connect(_change_state)
if err:
printerr(err)
initialize(start_state)
func initialize(initial_state):
func initialize(initial_state: NodePath) -> void:
_active = true
states_stack.push_front(get_node(initial_state))
current_state = states_stack[0]
current_state.enter()
func set_active(value):
func set_active(value: bool) -> void:
set_physics_process(value)
set_process_input(value)
if not _active:
@@ -45,21 +45,22 @@ func set_active(value):
current_state = null
func _unhandled_input(event):
func _unhandled_input(event: InputEvent) -> void:
current_state.handle_input(event)
func _physics_process(delta):
func _physics_process(delta: float) -> void:
current_state.update(delta)
func _on_animation_finished(anim_name):
func _on_animation_finished(anim_name: String) -> void:
if not _active:
return
current_state._on_animation_finished(anim_name)
func _change_state(state_name):
func _change_state(state_name: String) -> void:
if not _active:
return
current_state.exit()
@@ -70,7 +71,7 @@ func _change_state(state_name):
states_stack[0] = states_map[state_name]
current_state = states_stack[0]
emit_signal("state_changed", current_state)
state_changed.emit(current_state)
if state_name != "previous":
current_state.enter()

View File

@@ -6,9 +6,9 @@ Slide the cave image left and right to observe the glow effect at work.
Language: GDScript
Renderer: Forward Plus
Renderer: Forward+
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/110
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2715
## Screenshots

View File

@@ -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 = $Cave
@onready var cave: Node2D = $Cave
func _unhandled_input(event):
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseMotion and event.button_mask > 0:
cave.position.x = clampf(cave.position.x + event.relative.x, -CAVE_LIMIT, 0)

View File

@@ -37,7 +37,6 @@ environment = SubResource("1")
[node name="Camera2D" type="Camera2D" parent="."]
offset = Vector2(540, 360)
current = true
[node name="Label" type="Label" parent="."]
visible = false

View File

@@ -20,6 +20,10 @@ config/features=PackedStringArray("4.2")
config/icon="res://icon.webp"
run/name=""
[debug]
gdscript/warnings/untyped_declaration=1
[display]
window/size/viewport_width=1080
@@ -30,7 +34,7 @@ window/stretch/aspect="expand"
[input]
toggle_glow_map={
"deadzone": 0.5,
"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":71,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
]
}

View File

@@ -4,9 +4,9 @@ Very simple demo showing a hexagonal TileMap and TileSet.
Language: GDScript
Renderer: GLES 2
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/111
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2717
## Screenshots

View File

@@ -11,4 +11,5 @@ 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)

View File

@@ -17,6 +17,10 @@ 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"
@@ -25,7 +29,7 @@ window/stretch/aspect="expand"
[input]
move_down={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -33,7 +37,7 @@ move_down={
]
}
move_left={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -41,7 +45,7 @@ move_left={
]
}
move_right={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -49,7 +53,7 @@ move_right={
]
}
move_up={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -63,4 +67,6 @@ 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)

View File

@@ -4,8 +4,8 @@ const MOTION_SPEED = 30
const FRICTION_FACTOR = 0.89
const TAN30DEG = tan(deg_to_rad(30))
func _physics_process(_delta):
var motion = Vector2()
func _physics_process(_delta: float) -> void:
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.

View File

@@ -15,7 +15,9 @@ texture = ExtResource("2")
[node name="Shadow" type="Sprite2D" parent="."]
modulate = Color(0, 0, 0, 0.501961)
show_behind_parent = true
position = Vector2(3, 3)
position = Vector2(16.4422, 4.89438)
scale = Vector2(0.794259, 1.04505)
skew = 0.523599
texture = ExtResource("2")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
@@ -23,4 +25,3 @@ position = Vector2(3.24216, 19.453)
shape = SubResource("1")
[node name="Camera2D" type="Camera2D" parent="."]
current = true

View File

@@ -5,9 +5,9 @@ make many duplicates of the same object.
Language: GDScript
Renderer: Vulkan Mobile
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/148
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2716
## Screenshots

View File

@@ -1,18 +1,18 @@
[gd_scene load_steps=4 format=2]
[gd_scene load_steps=4 format=3 uid="uid://cgx884jv27maj"]
[ext_resource path="res://bowling_ball.png" type="Texture2D" id=1]
[ext_resource type="Texture2D" uid="uid://cyqshsjd3qwo0" path="res://bowling_ball.png" 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="RigidDynamicBody2D"]
physics_material_override = SubResource( 1 )
[node name="Ball" type="RigidBody2D"]
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")

View File

@@ -2,15 +2,16 @@ extends Node2D
@export var ball_scene: PackedScene = preload("res://ball.tscn")
func _unhandled_input(event):
func _unhandled_input(event: InputEvent) -> void:
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):
var instance = ball_scene.instantiate()
func spawn(spawn_global_position: Vector2) -> void:
var instance: Node2D = ball_scene.instantiate()
instance.global_position = spawn_global_position
add_child(instance)

View File

@@ -18,6 +18,10 @@ 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"
@@ -25,10 +29,11 @@ window/stretch/aspect="expand"
[physics]
common/physics_ticks_per_second=120
2d/default_gravity=300
[rendering]
renderer/rendering_method="mobile"
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"
environment/defaults/default_clear_color=Color(0.239216, 0.0823529, 0.156863, 1)
anti_aliasing/quality/msaa_2d=2

View File

@@ -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" path="res://ball.tscn" id="2"]
[ext_resource type="PackedScene" uid="uid://cgx884jv27maj" path="res://ball.tscn" id="2"]
[sub_resource type="PhysicsMaterial" id="1"]
bounce = 0.4
@@ -35,7 +35,9 @@ bounce = 0.4
[node name="SceneInstancing" type="Node2D"]
[node name="InfoLabel" type="Label" parent="."]
[node name="CanvasLayer" type="CanvasLayer" parent="."]
[node name="InfoLabel" type="Label" parent="CanvasLayer"]
offset_left = 16.0
offset_top = 16.0
offset_right = 370.0
@@ -99,4 +101,3 @@ physics_material_override = SubResource("10")
[node name="Camera2D" type="Camera2D" parent="."]
offset = Vector2(576, 324)
current = true

View File

@@ -9,7 +9,7 @@ Language: GDScript
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/112
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2718
## How does it work?

View File

@@ -35,7 +35,6 @@ 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
@@ -48,7 +47,6 @@ 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)

View File

@@ -25,19 +25,10 @@ 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.5,
"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":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)
@@ -45,7 +36,7 @@ move_down={
]
}
move_left={
"deadzone": 0.5,
"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":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)
@@ -53,7 +44,7 @@ move_left={
]
}
move_right={
"deadzone": 0.5,
"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":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)
@@ -61,7 +52,7 @@ move_right={
]
}
move_up={
"deadzone": 0.5,
"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":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)
@@ -73,13 +64,8 @@ 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

View File

@@ -1,15 +1,15 @@
# Kinematic Character 2D
Example of how to make a kinematic character controller in 2D using
[`KinematicBody2D`](https://docs.godotengine.org/en/latest/classes/class_kinematicbody2d.html).
[`CharacterBody2D`](https://docs.godotengine.org/en/latest/classes/class_characterbody2d.html).
The character moves around, is affected by moving platforms,
can jump through one-way collision platforms, etc.
Language: GDScript
Renderer: GLES 2
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/113
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2719
## Screenshots

View File

@@ -1,5 +1,5 @@
extends Node
func _on_body_entered(body):
func _on_body_entered(body: Node2D) -> void:
if body.name == "Player":
$"../WinText".show()

View File

@@ -5,11 +5,11 @@ const WALK_MAX_SPEED = 200
const STOP_FORCE = 1300
const JUMP_SPEED = 200
@onready var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
@onready var gravity := float(ProjectSettings.get_setting("physics/2d/default_gravity"))
func _physics_process(delta):
func _physics_process(delta: float) -> void:
# 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.

View File

@@ -19,6 +19,10 @@ 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
@@ -29,7 +33,7 @@ window/stretch/aspect="expand"
[input]
jump={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -39,7 +43,7 @@ jump={
]
}
move_left={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -47,7 +51,7 @@ move_left={
]
}
move_right={
"deadzone": 0.5,
"deadzone": 0.2,
"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)
@@ -62,5 +66,6 @@ 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

View File

@@ -138,11 +138,11 @@ modulate = Color(0.4, 2, 0.8, 1)
texture = ExtResource("2")
[node name="AnimationPlayer" type="AnimationPlayer" parent="MovingPlatform1"]
autoplay = "leftright"
playback_process_mode = 0
callback_mode_process = 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"]
autoplay = "updown"
playback_process_mode = 0
callback_mode_process = 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)

View File

@@ -4,9 +4,9 @@ Example of how to use 2D lights to mask objects on screen.
Language: GDScript
Renderer: GLES 2
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/115
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2720
## Screenshots

View File

@@ -8,6 +8,7 @@ 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
@@ -55,6 +56,8 @@ 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
@@ -69,22 +72,24 @@ 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

View File

@@ -17,7 +17,16 @@ 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"

View File

@@ -6,9 +6,9 @@ and [`LightOccluder2D`](https://docs.godotengine.org/en/latest/classes/class_lig
Language: GDScript
Renderer: GLES 2
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/116
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2721
## Screenshots

View File

@@ -27,7 +27,7 @@ roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/normal_map_invert_y=true
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0

View File

@@ -1,7 +1,7 @@
extends Node2D
func _input(event):
func _input(event: InputEvent) -> void:
if event.is_action_pressed("toggle_directional_light"):
$DirectionalLight2D.visible = not $DirectionalLight2D.visible

View File

@@ -107,6 +107,21 @@ _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
@@ -124,21 +139,6 @@ 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,16 +320,17 @@ 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)
@@ -338,16 +339,17 @@ 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)
@@ -356,20 +358,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="."]
@@ -396,7 +398,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"

View File

@@ -15,9 +15,13 @@ 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.2")
config/features=PackedStringArray("4.3")
config/icon="res://icon.webp"
[debug]
gdscript/warnings/untyped_declaration=1
[display]
window/size/viewport_width=800
@@ -27,22 +31,27 @@ window/stretch/aspect="expand"
[input]
toggle_directional_light={
"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)
"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)
]
}
toggle_point_lights={
"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)
"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)
]
}
cycle_directional_light_shadows_quality={
"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)
"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)
]
}
cycle_point_light_shadows_quality={
"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)
"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)
]
}
[rendering]
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"

View File

@@ -7,9 +7,9 @@ Example of using 2D navigation using:
Language: GDScript
Renderer: Forward+
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/117
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2722
## Screenshots

View File

@@ -1,11 +1,10 @@
extends CharacterBody2D
var movement_speed := 200.0
var movement_speed: float = 200.0
@onready var navigation_agent: NavigationAgent2D = $NavigationAgent2D
func _ready():
func _ready() -> void:
# These values need to be adjusted for the actor's speed
# and the navigation layout.
navigation_agent.path_desired_distance = 2.0
@@ -15,17 +14,18 @@ func _ready():
# The "click" event is a custom input action defined in
# Project > Project Settings > Input Map tab.
func _unhandled_input(event):
func _unhandled_input(event: InputEvent) -> void:
if not event.is_action_pressed("click"):
return
set_movement_target(get_global_mouse_position())
func set_movement_target(movement_target: Vector2):
func set_movement_target(movement_target: Vector2) -> void:
navigation_agent.target_position = movement_target
func _physics_process(_delta):
func _physics_process(_delta: float) -> void:
if navigation_agent.is_navigation_finished():
return

View File

@@ -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("3_6c0vu")
navigation_polygon = ExtResource("2_lph0a")
[node name="Character" parent="." instance=ExtResource("4_n6iop")]
position = Vector2(211, 141)

Binary file not shown.

View File

@@ -19,6 +19,10 @@ 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
@@ -28,11 +32,17 @@ window/stretch/aspect="expand"
[input]
click={
"deadzone": 0.5,
"deadzone": 0.2,
"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)

View File

@@ -7,7 +7,7 @@ Language: GDScript
Renderer: Compatibility
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/519
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2723
## Screenshots

View File

@@ -1,29 +1,35 @@
extends Node2D
enum State { IDLE, FOLLOW }
const PathFindAStar = preload("./pathfind_astar.gd")
const MASS = 10.0
const ARRIVE_DISTANCE = 10.0
enum State {
IDLE,
FOLLOW,
}
@export var speed: float = 200.0
const MASS: float = 10.0
const ARRIVE_DISTANCE: float = 10.0
var _state = State.IDLE
var _velocity = Vector2()
@export_range(10, 500, 0.1, "or_greater") var speed: float = 200.0
@onready var _tile_map = $"../TileMap"
var _state := State.IDLE
var _velocity := Vector2()
var _click_position = Vector2()
var _path = PackedVector2Array()
var _next_point = Vector2()
var _click_position := Vector2()
var _path := PackedVector2Array()
var _next_point := Vector2()
func _ready():
@onready var _tile_map: PathFindAStar = $"../TileMap"
func _ready() -> void:
_change_state(State.IDLE)
func _process(_delta):
func _process(_delta: float) -> void:
if _state != State.FOLLOW:
return
var arrived_to_next_point = _move_to(_next_point)
var arrived_to_next_point: bool = _move_to(_next_point)
if arrived_to_next_point:
_path.remove_at(0)
if _path.is_empty():
@@ -32,7 +38,7 @@ func _process(_delta):
_next_point = _path[0]
func _unhandled_input(event):
func _unhandled_input(event: InputEvent) -> void:
_click_position = get_global_mouse_position()
if _tile_map.is_point_walkable(_click_position):
if event.is_action_pressed(&"teleport_to", false, true):
@@ -42,16 +48,16 @@ func _unhandled_input(event):
_change_state(State.FOLLOW)
func _move_to(local_position):
var desired_velocity = (local_position - position).normalized() * speed
var steering = desired_velocity - _velocity
func _move_to(local_position: Vector2) -> bool:
var desired_velocity: Vector2 = (local_position - position).normalized() * speed
var steering: Vector2 = 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):
func _change_state(new_state: State) -> void:
if new_state == State.IDLE:
_tile_map.clear_path()
elif new_state == State.FOLLOW:

View File

@@ -1,19 +1,23 @@
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 = 3.0
const BASE_LINE_WIDTH: float = 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():
func _ready() -> void:
# 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)
@@ -26,35 +30,35 @@ func _ready():
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():
func _draw() -> void:
if _path.is_empty():
return
var last_point = _path[0]
var last_point: Vector2 = _path[0]
for index in range(1, len(_path)):
var current_point = _path[index]
var current_point: Vector2 = _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):
func round_local_position(local_position: Vector2i) -> Vector2i:
return map_to_local(local_to_map(local_position))
func is_point_walkable(local_position):
var map_position = local_to_map(local_position)
func is_point_walkable(local_position: Vector2) -> bool:
var map_position: Vector2i = 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():
func clear_path() -> void:
if not _path.is_empty():
_path.clear()
erase_cell(0, _start_point)
@@ -63,7 +67,7 @@ func clear_path():
queue_redraw()
func find_path(local_start_point, local_end_point):
func find_path(local_start_point: Vector2i, local_end_point: Vector2i) -> PackedVector2Array:
clear_path()
_start_point = local_to_map(local_start_point)

View File

@@ -18,6 +18,10 @@ 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"
@@ -26,12 +30,12 @@ window/stretch/aspect="expand"
[input]
teleport_to={
"deadzone": 0.5,
"deadzone": 0.2,
"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.5,
"deadzone": 0.2,
"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)
]
}
@@ -39,6 +43,5 @@ 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

View File

@@ -0,0 +1,15 @@
# 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
![Screenshot](screenshots/navigation_mesh_chunks.webp)

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,156 @@
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()

View File

@@ -0,0 +1,99 @@
[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

View File

@@ -0,0 +1,29 @@
; 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.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -4,9 +4,9 @@ This demo showcases how 2D particle systems work in Godot.
Language: GDScript
Renderer: Forward Mobile
Renderer: Mobile
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/118
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2724
## How does it work?

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
extends Label
func _input(event):
func _input(event: InputEvent) -> void:
if event.is_action_pressed("toggle_pause"):
get_tree().paused = not get_tree().paused

Some files were not shown because too many files have changed in this diff Show More