From ffd600917d4a2fed327de2b3db4a02ded964a163 Mon Sep 17 00:00:00 2001 From: Jonathan Nicholl Date: Tue, 21 Feb 2023 17:16:26 -0500 Subject: [PATCH] Update, clean up, and reorganize the 2D platformer --- 2d/platformer/README.md | 33 +- .../assets/art/background/cloud_1.png | Bin 219 -> 0 bytes .../assets/art/background/cloud_2.png | Bin 298 -> 0 bytes .../assets/art/background/cloud_3.png | Bin 185 -> 0 bytes .../art/background/distant_platforms_1.png | Bin 3892 -> 0 bytes .../art/background/distant_platforms_2.png | Bin 4324 -> 0 bytes 2d/platformer/assets/art/background/sky.png | Bin 833 -> 0 bytes 2d/platformer/assets/art/coin/coin.png | Bin 212 -> 0 bytes 2d/platformer/assets/art/enemy/enemy.png | Bin 817 -> 0 bytes .../assets/art/platforms/moving_platform.png | Bin 604 -> 0 bytes .../assets/art/platforms/one_way_platform.png | Bin 543 -> 0 bytes .../assets/art/player/bullet/bullet.png | Bin 146 -> 0 bytes .../assets/art/player/robot_demo.png | Bin 2087 -> 0 bytes .../assets/art/tileset/tiles_demo.png | Bin 2583 -> 0 bytes 2d/platformer/assets/art/tileset/tileset.tres | 335 -------- .../assets/art/ui/touch_button_fire.png | Bin 1444 -> 0 bytes .../assets/art/ui/touch_button_jump.png | Bin 802 -> 0 bytes .../assets/art/ui/touch_button_left.png | Bin 777 -> 0 bytes .../assets/art/ui/touch_button_right.png | Bin 785 -> 0 bytes .../assets/audio/music/music.ogg.import | 19 - .../theme/fonts/kenney_mini_square.tres | 5 - 2d/platformer/enemy/enemy.gd | 59 ++ .../Actors/Enemy.tscn => enemy/enemy.tscn} | 250 +++--- 2d/platformer/enemy/enemy.webp | Bin 0 -> 786 bytes .../enemy.webp.import} | 10 +- .../{assets/audio/sfx => enemy}/explode.wav | Bin .../audio/sfx => enemy}/explode.wav.import | 6 +- .../{assets/audio/sfx => enemy}/hit.wav | Bin .../audio/sfx => enemy}/hit.wav.import | 6 +- 2d/platformer/game.gd | 24 + 2d/platformer/game_singleplayer.tscn | 25 + 2d/platformer/game_splitscreen.gd | 10 + 2d/platformer/game_splitscreen.tscn | 82 ++ 2d/platformer/gui/coins_counter.gd | 16 + 2d/platformer/gui/coins_counter.tscn | 70 ++ .../fonts => gui}/kenney_mini_square.ttf | Bin .../kenney_mini_square.ttf.import | 7 +- 2d/platformer/gui/pause_menu.gd | 77 ++ .../PauseMenu.tscn => gui/pause_menu.tscn} | 48 +- .../gui/pause_menu_singleplayer.tscn | 11 + 2d/platformer/gui/pause_menu_splitscreen.tscn | 11 + .../user_interface.tres => gui/theme.tres} | 4 +- 2d/platformer/gui/touch_button_fire.webp | Bin 0 -> 930 bytes .../touch_button_fire.webp.import} | 8 +- 2d/platformer/gui/touch_button_jump.webp | Bin 0 -> 552 bytes .../touch_button_jump.webp.import} | 8 +- 2d/platformer/gui/touch_button_left.webp | Bin 0 -> 534 bytes .../touch_button_left.webp.import} | 8 +- 2d/platformer/gui/touch_button_right.webp | Bin 0 -> 538 bytes .../touch_button_right.webp.import} | 8 +- 2d/platformer/icon.png | Bin 527 -> 0 bytes 2d/platformer/icon.webp | Bin 0 -> 1212 bytes .../{icon.png.import => icon.webp.import} | 8 +- 2d/platformer/level/cloud_1.webp | Bin 0 -> 138 bytes .../cloud_1.webp.import} | 8 +- 2d/platformer/level/cloud_2.webp | Bin 0 -> 214 bytes .../cloud_2.webp.import} | 8 +- 2d/platformer/level/cloud_3.webp | Bin 0 -> 104 bytes .../cloud_3.webp.import} | 8 +- 2d/platformer/level/coin.gd | 10 + .../Objects/Coin.tscn => level/coin.tscn} | 169 ++-- 2d/platformer/level/coin.webp | Bin 0 -> 148 bytes .../coin.webp.import} | 8 +- 2d/platformer/level/distant_platforms_1.webp | Bin 0 -> 3602 bytes .../distant_platforms_1.webp.import} | 8 +- 2d/platformer/level/distant_platforms_2.webp | Bin 0 -> 3906 bytes .../distant_platforms_2.webp.import} | 8 +- 2d/platformer/level/level.tscn | 284 +++++++ 2d/platformer/level/moving_platform.webp | Bin 0 -> 544 bytes .../moving_platform.webp.import} | 8 +- .../one_way_platform.import} | 8 +- 2d/platformer/level/one_way_platform.webp | Bin 0 -> 484 bytes .../level/one_way_platform.webp.import | 34 + .../parallax_background.tscn} | 72 +- 2d/platformer/level/platform.tscn | 19 + 2d/platformer/level/sky.webp | Bin 0 -> 558 bytes .../sky.png.import => level/sky.webp.import} | 8 +- 2d/platformer/level/tiles.webp | Bin 0 -> 2550 bytes .../tiles.webp.import} | 8 +- 2d/platformer/level/tileset.tres | 729 ++++++++++++++++++ .../{assets/audio/music => }/music.ogg | Bin 2d/platformer/music.ogg.import | 19 + 2d/platformer/music.tscn | 8 + 2d/platformer/player/bullet.gd | 13 + .../Bullet.tscn => player/bullet.tscn} | 59 +- 2d/platformer/player/bullet.webp | Bin 0 -> 100 bytes .../bullet.webp.import} | 8 +- .../audio/sfx => player}/coin_pickup.wav | Bin .../sfx => player}/coin_pickup.wav.import | 6 +- 2d/platformer/player/gun.gd | 25 + .../{assets/audio/sfx => player}/jump.wav | Bin .../audio/sfx => player}/jump.wav.import | 6 +- 2d/platformer/player/player.gd | 88 +++ .../Actors/Player.tscn => player/player.tscn} | 155 ++-- 2d/platformer/player/player.webp | Bin 0 -> 2092 bytes .../player.webp.import} | 8 +- .../{assets/audio/sfx => player}/shoot.wav | Bin .../audio/sfx => player}/shoot.wav.import | 6 +- 2d/platformer/project.godot | 105 +-- 2d/platformer/screenshots/layout.png | Bin 65037 -> 0 bytes 2d/platformer/screenshots/layout.webp | Bin 0 -> 41010 bytes 2d/platformer/screenshots/shoot.png | Bin 18478 -> 0 bytes 2d/platformer/screenshots/shoot.webp | Bin 0 -> 12284 bytes 2d/platformer/src/Actors/Actor.gd | 17 - 2d/platformer/src/Actors/Enemy.gd | 77 -- 2d/platformer/src/Actors/Gun.gd | 26 - 2d/platformer/src/Actors/Player.gd | 133 ---- 2d/platformer/src/Level/Level.gd | 15 - 2d/platformer/src/Level/Level.tscn | 267 ------- 2d/platformer/src/Level/Music.gd | 16 - 2d/platformer/src/Main/Game.gd | 43 -- 2d/platformer/src/Main/Game.tscn | 22 - 2d/platformer/src/Main/Splitscreen.tscn | 80 -- 2d/platformer/src/Objects/Bullet.gd | 14 - 2d/platformer/src/Objects/Coin.gd | 16 - 2d/platformer/src/Platforms/Platform.tscn | 21 - .../src/UserInterface/CoinsCounter.gd | 25 - .../src/UserInterface/CoinsCounter.tscn | 63 -- 2d/platformer/src/UserInterface/PauseMenu.gd | 58 -- 119 files changed, 2169 insertions(+), 1775 deletions(-) delete mode 100644 2d/platformer/assets/art/background/cloud_1.png delete mode 100644 2d/platformer/assets/art/background/cloud_2.png delete mode 100644 2d/platformer/assets/art/background/cloud_3.png delete mode 100644 2d/platformer/assets/art/background/distant_platforms_1.png delete mode 100644 2d/platformer/assets/art/background/distant_platforms_2.png delete mode 100644 2d/platformer/assets/art/background/sky.png delete mode 100644 2d/platformer/assets/art/coin/coin.png delete mode 100644 2d/platformer/assets/art/enemy/enemy.png delete mode 100644 2d/platformer/assets/art/platforms/moving_platform.png delete mode 100644 2d/platformer/assets/art/platforms/one_way_platform.png delete mode 100644 2d/platformer/assets/art/player/bullet/bullet.png delete mode 100644 2d/platformer/assets/art/player/robot_demo.png delete mode 100644 2d/platformer/assets/art/tileset/tiles_demo.png delete mode 100644 2d/platformer/assets/art/tileset/tileset.tres delete mode 100644 2d/platformer/assets/art/ui/touch_button_fire.png delete mode 100644 2d/platformer/assets/art/ui/touch_button_jump.png delete mode 100644 2d/platformer/assets/art/ui/touch_button_left.png delete mode 100644 2d/platformer/assets/art/ui/touch_button_right.png delete mode 100644 2d/platformer/assets/audio/music/music.ogg.import delete mode 100644 2d/platformer/assets/theme/fonts/kenney_mini_square.tres create mode 100644 2d/platformer/enemy/enemy.gd rename 2d/platformer/{src/Actors/Enemy.tscn => enemy/enemy.tscn} (57%) create mode 100644 2d/platformer/enemy/enemy.webp rename 2d/platformer/{assets/art/enemy/enemy.png.import => enemy/enemy.webp.import} (66%) rename 2d/platformer/{assets/audio/sfx => enemy}/explode.wav (100%) rename 2d/platformer/{assets/audio/sfx => enemy}/explode.wav.import (55%) rename 2d/platformer/{assets/audio/sfx => enemy}/hit.wav (100%) rename 2d/platformer/{assets/audio/sfx => enemy}/hit.wav.import (57%) create mode 100644 2d/platformer/game.gd create mode 100644 2d/platformer/game_singleplayer.tscn create mode 100644 2d/platformer/game_splitscreen.gd create mode 100644 2d/platformer/game_splitscreen.tscn create mode 100644 2d/platformer/gui/coins_counter.gd create mode 100644 2d/platformer/gui/coins_counter.tscn rename 2d/platformer/{assets/theme/fonts => gui}/kenney_mini_square.ttf (100%) rename 2d/platformer/{assets/theme/fonts => gui}/kenney_mini_square.ttf.import (61%) create mode 100644 2d/platformer/gui/pause_menu.gd rename 2d/platformer/{src/UserInterface/PauseMenu.tscn => gui/pause_menu.tscn} (58%) create mode 100644 2d/platformer/gui/pause_menu_singleplayer.tscn create mode 100644 2d/platformer/gui/pause_menu_splitscreen.tscn rename 2d/platformer/{assets/theme/user_interface.tres => gui/theme.tres} (94%) create mode 100644 2d/platformer/gui/touch_button_fire.webp rename 2d/platformer/{assets/art/ui/touch_button_fire.png.import => gui/touch_button_fire.webp.import} (66%) create mode 100644 2d/platformer/gui/touch_button_jump.webp rename 2d/platformer/{assets/art/ui/touch_button_jump.png.import => gui/touch_button_jump.webp.import} (66%) create mode 100644 2d/platformer/gui/touch_button_left.webp rename 2d/platformer/{assets/art/ui/touch_button_left.png.import => gui/touch_button_left.webp.import} (66%) create mode 100644 2d/platformer/gui/touch_button_right.webp rename 2d/platformer/{assets/art/ui/touch_button_right.png.import => gui/touch_button_right.webp.import} (66%) delete mode 100644 2d/platformer/icon.png create mode 100644 2d/platformer/icon.webp rename 2d/platformer/{icon.png.import => icon.webp.import} (70%) create mode 100644 2d/platformer/level/cloud_1.webp rename 2d/platformer/{assets/art/background/cloud_1.png.import => level/cloud_1.webp.import} (68%) create mode 100644 2d/platformer/level/cloud_2.webp rename 2d/platformer/{assets/art/background/cloud_2.png.import => level/cloud_2.webp.import} (68%) create mode 100644 2d/platformer/level/cloud_3.webp rename 2d/platformer/{assets/art/background/cloud_3.png.import => level/cloud_3.webp.import} (68%) create mode 100644 2d/platformer/level/coin.gd rename 2d/platformer/{src/Objects/Coin.tscn => level/coin.tscn} (59%) create mode 100644 2d/platformer/level/coin.webp rename 2d/platformer/{assets/art/coin/coin.png.import => level/coin.webp.import} (70%) create mode 100644 2d/platformer/level/distant_platforms_1.webp rename 2d/platformer/{assets/art/background/distant_platforms_1.png.import => level/distant_platforms_1.webp.import} (65%) create mode 100644 2d/platformer/level/distant_platforms_2.webp rename 2d/platformer/{assets/art/background/distant_platforms_2.png.import => level/distant_platforms_2.webp.import} (65%) create mode 100644 2d/platformer/level/level.tscn create mode 100644 2d/platformer/level/moving_platform.webp rename 2d/platformer/{assets/art/platforms/moving_platform.png.import => level/moving_platform.webp.import} (66%) rename 2d/platformer/{assets/art/platforms/one_way_platform.png.import => level/one_way_platform.import} (66%) create mode 100644 2d/platformer/level/one_way_platform.webp create mode 100644 2d/platformer/level/one_way_platform.webp.import rename 2d/platformer/{src/Level/ParallaxBackground.tscn => level/parallax_background.tscn} (72%) create mode 100644 2d/platformer/level/platform.tscn create mode 100644 2d/platformer/level/sky.webp rename 2d/platformer/{assets/art/background/sky.png.import => level/sky.webp.import} (69%) create mode 100644 2d/platformer/level/tiles.webp rename 2d/platformer/{assets/art/tileset/tiles_demo.png.import => level/tiles.webp.import} (68%) create mode 100644 2d/platformer/level/tileset.tres rename 2d/platformer/{assets/audio/music => }/music.ogg (100%) create mode 100644 2d/platformer/music.ogg.import create mode 100644 2d/platformer/music.tscn create mode 100644 2d/platformer/player/bullet.gd rename 2d/platformer/{src/Objects/Bullet.tscn => player/bullet.tscn} (64%) create mode 100644 2d/platformer/player/bullet.webp rename 2d/platformer/{assets/art/player/bullet/bullet.png.import => player/bullet.webp.import} (68%) rename 2d/platformer/{assets/audio/sfx => player}/coin_pickup.wav (100%) rename 2d/platformer/{assets/audio/sfx => player}/coin_pickup.wav.import (54%) create mode 100644 2d/platformer/player/gun.gd rename 2d/platformer/{assets/audio/sfx => player}/jump.wav (100%) rename 2d/platformer/{assets/audio/sfx => player}/jump.wav.import (56%) create mode 100644 2d/platformer/player/player.gd rename 2d/platformer/{src/Actors/Player.tscn => player/player.tscn} (69%) create mode 100644 2d/platformer/player/player.webp rename 2d/platformer/{assets/art/player/robot_demo.png.import => player/player.webp.import} (68%) rename 2d/platformer/{assets/audio/sfx => player}/shoot.wav (100%) rename 2d/platformer/{assets/audio/sfx => player}/shoot.wav.import (56%) delete mode 100644 2d/platformer/screenshots/layout.png create mode 100644 2d/platformer/screenshots/layout.webp delete mode 100644 2d/platformer/screenshots/shoot.png create mode 100644 2d/platformer/screenshots/shoot.webp delete mode 100644 2d/platformer/src/Actors/Actor.gd delete mode 100644 2d/platformer/src/Actors/Enemy.gd delete mode 100644 2d/platformer/src/Actors/Gun.gd delete mode 100644 2d/platformer/src/Actors/Player.gd delete mode 100644 2d/platformer/src/Level/Level.gd delete mode 100644 2d/platformer/src/Level/Level.tscn delete mode 100644 2d/platformer/src/Level/Music.gd delete mode 100644 2d/platformer/src/Main/Game.gd delete mode 100644 2d/platformer/src/Main/Game.tscn delete mode 100644 2d/platformer/src/Main/Splitscreen.tscn delete mode 100644 2d/platformer/src/Objects/Bullet.gd delete mode 100644 2d/platformer/src/Objects/Coin.gd delete mode 100644 2d/platformer/src/Platforms/Platform.tscn delete mode 100644 2d/platformer/src/UserInterface/CoinsCounter.gd delete mode 100644 2d/platformer/src/UserInterface/CoinsCounter.tscn delete mode 100644 2d/platformer/src/UserInterface/PauseMenu.gd diff --git a/2d/platformer/README.md b/2d/platformer/README.md index 7d8db3c4..67f6a198 100644 --- a/2d/platformer/README.md +++ b/2d/platformer/README.md @@ -1,46 +1,41 @@ # 2D Platformer -This demo is a pixel art 2D platformer with graphics and sound. +This demo is a pixel art 2D platformer with single-player +and two player splitscreen multiplayer. -It shows you how to code characters and physics-based objects +It demonstrates how to code characters and physics-based objects in a real game context. This is a relatively complete demo where the player can jump, walk on slopes, fire bullets, -interact with enemies, and more. It contains one closed -level, and the player is invincible, unlike the enemies. - -You will find most of the demo’s content in the `Level.tscn` scene. -You can open it from the default `Game.tscn` scene, or double -click on `Level.tscn` in the `src/Level/` directory. - -We invite you to open the demo's GDScript files in the editor as -they contain a lot of comments that explain how each class works. +interact with enemies, and collect items. It contains one +level. The player is invincible, unlike the enemies. Language: GDScript -Renderer: GLES 2 +Renderer: Forward Plus Check out this demo on the asset library: https://godotengine.org/asset-library/asset/120 ## Features -- Side-scrolling player controller using [`KinematicBody2D`](https://docs.godotengine.org/en/latest/classes/class_kinematicbody2d.html). - - Can walk on and snap to slopes. - - Can shoot, including while jumping. +- Side-scrolling player controller using [`CharacterBody2D`](https://docs.godotengine.org/en/latest/classes/class_characterbody2d.html). + - Can walk smoothly up and down slopes. + - Can shoot, including while jumping. + - Has a double jump that provides a horizontal momentum boost. - Enemies that crawl on the floor and change direction when they encounter an obstacle. - Camera that stays within the level’s bounds. -- Supports keyboard and gamepad controls. +- Keyboard and gamepad control support. - Platforms that can move in any direction. - Gun that shoots bullets with rigid body (natural) physics. - Collectible coins. -- Pause and pause menu. +- Pausing and a pause menu. - Pixel art visuals. - Sound effects and music. ## Screenshots -![Player shooting in the direction of an enemy](screenshots/shoot.png) +![Player shooting in the direction of an enemy](screenshots/shoot.webp) -![The entire level layout viewed in the editor](screenshots/layout.png) +![The entire level layout viewed in the editor](screenshots/layout.webp) ## Music diff --git a/2d/platformer/assets/art/background/cloud_1.png b/2d/platformer/assets/art/background/cloud_1.png deleted file mode 100644 index 5f01d1b8d5489451d99e56362f4d70586ce45503..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH#0(_wf1V}|q&Ne7LR^9L-ix=37w%g1qCpeL zVJr#q3ubV5b|VeQY4CJ$45_%4B*E5@DLSh`Y{A!!W)2D*i!@$}I(g>n9^BfMo#auN zD-?Nuj(A^9V0&4?(~Eb$H?8)w@@qK#`>+7_3cHtUQ<)D~ywtqO_@PVvkSOC6nWmNv zADG)eHjC$oG~C@$ps-`Pe1!cAF{Ufb?k=(0>l_|FH1$|ww*Jrq`x=IQ3J$8(agTe~DWM4fKe$n< diff --git a/2d/platformer/assets/art/background/cloud_2.png b/2d/platformer/assets/art/background/cloud_2.png deleted file mode 100644 index 68c985f276c9c47307eed4b8668b81c961dd8fc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!VDw>HYaZfQv3lvA+A9B^26s4RI}p1%$;U= zKq2OmAirRSzyBB$TTFr6#Ar-gQPHN0NU?9NET+y6&=`usx^?$}w|2;moGTC`y zlZ9f;68HJ9`Lo`oADGk0_QHjw;rqX~$*$a9`|fQ2cjHCvm9T#TEEVYj3v7Pz1u*`w zZ9Fis;TIo6Aw$UZSr^~PcWYefzsf50zI%;&B^QU>DSf+R8q>lV{#fcbZEiMRCRNE? zV!n#eq?K*Lk~-!aIt_UT7=;(u7#+LW`jMw+>h-%fo5B{%V)`mm*z3{xgRSC>g8C;0 qG2Vt>_S2`SyYHN~_xe} diff --git a/2d/platformer/assets/art/background/cloud_3.png b/2d/platformer/assets/art/background/cloud_3.png deleted file mode 100644 index 998d6ff0646ba8777dd31685e136bed696660025..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^3P3Et#0(_4@}`~wQk(%kA+A7r_k~-<3wI`@)I9q)iP9l!YK2Qxl3oY%TlDrWq6`q6-WitBaHPpL6KdO^@>{f^VpdjdnPJpa0T g)^LB^srHy{$!QhS-m}dtK${pmUHx3vIVCg!07|z(umAu6 diff --git a/2d/platformer/assets/art/background/distant_platforms_1.png b/2d/platformer/assets/art/background/distant_platforms_1.png deleted file mode 100644 index a513c820ddac3fd597b350529b12d4c928786051..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3892 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 diff --git a/2d/platformer/assets/art/background/distant_platforms_2.png b/2d/platformer/assets/art/background/distant_platforms_2.png deleted file mode 100644 index da67ebe771c9c0f4978be7f9f8010db41d00b9a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4324 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 m4`sP+i9BkEJZXkIXoWjxg*s=1 zI%R}9WP&+kfjMG-IbnY|VSYGZem7oyH(h%-TzfWLdNx~nHd=T!S$8&Acr;jcHCJ~u zR(3R1bTm|SGgNaT#fq>100L1-L_t(|+G4Z-@LC^9w%|q;Aj{IKVsC^YD%b?*cr)0r1NMH>`z)!`2$Ixx>tW z-2ndl+EXBaOBMm{&;Ypa0h|Z-eE@vme!jrx%jXNu*M|>ZeEIOX{lh=l-oDyDchF?g zZm=w@4u~A$0PwzNx|W6M4r>hA4TOab0DXrr0N}p!9Pd29?ah~C`*OT7o3R=hmq7e_v|KQOL(FR6fJERvIPW}%$35UUaK2ST0NjUD01mvL zBV1U_0gYwq@F!tw!nbu$&~N%nQU%2aaSY+Oo}3U6l#mc$ zl#q~+*pQ$m9?r%#m4S`TR3VLtYsHQ!>;^Mu7#VD1U{zslV0x#@=yPnDfT)au=u_!@*8IFSnp;2Z44mc)I$ztaD0e F0stweMfCsx diff --git a/2d/platformer/assets/art/enemy/enemy.png b/2d/platformer/assets/art/enemy/enemy.png deleted file mode 100644 index 5fcf9503a0faf38ba8810d9c6b028106ad62733c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 817 zcmV-11J3-3P)mEXW876)+eJymK0;w$UYa{T;u06j5EY3lE}jbyjtmZt3JowSD0m19YzGP^A|Yc3 z2_hdJ9vd4=1qT2C09fm1-v9sr0d!JMQvg8b*k%9#0-8xgK~#9!?No`b+b|4!_vO@$ zJ*WTwsgoRjT&23&Ll8e6 zSbGBs;m!f|`SAtM^&-KNqNJic2gD0O{x=c&`V`3HjL_+i$P5?)0+R3f2?oRt*ZLP8z|S5~ zf79VeAF@lFctu$j&{(^8q?m}{>Kf{0bdFLluK<=>Z2>EgiD8C>m z5dvJuqVpH-EeIJ?B;N$;hdI^(G!_C32<2%e-|5c|PzuI3cAJXi?!0kJ&IhIjqB3nQN#|M3yy$A|M%u?OT13wNaC zvg9r4{wYWlU_c^3QTzu(o)dhAIhy_;sP!qJ+4490GXwPP9r~%@fwvR6Za7Q6r=);D z15%**gx61B@}iFEm@8{n_WiCjof-g7qfd0&2 diff --git a/2d/platformer/assets/art/platforms/moving_platform.png b/2d/platformer/assets/art/platforms/moving_platform.png deleted file mode 100644 index 42554b7865cc4c1002054caa55d0a34c79609a72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 604 zcmV-i0;BzjP)GOj;I8Fgg zG-@&;u0HrLV;*`x=OIhVBsf6`F?*xN-K|8U6NkjJwF5g|m2e zmzO2KrugiD9mKqQm%qBal-v-JV{4_PC6y(+Z4q&|rc_eOj(E`0+hta81yJipZ2-zz zR(Nz@>mDt;UlV{_eF5M$D>z=!YgHeLA$m&l=5^fM&Xa=kmG?kJ)q7q!Ht!Jhx8tnf zzaudtylo1Py@Mi1euDE0SN*8ul&kQu%PU7AYt6i_0Wp| qJnjL*otped_B%A*pa!F06aWB@0~OaKIR{q&0000lQh<Knw-Zf~;PwM<{@; z(h(qF#=k{DBDd{)>_Qa#nVI~T7`c@#v!#_{B`{84Yku&jLWOK((MRtWxv}j6ifHUi zdp>-*0~@ewDYyfo1Su2Lu?m?dp)&bh3c4;$T?z(tVHj%x1zC{&{5z9E!T}S=inU;n z9GrruGq(w98Y)4c8W|t}#99zBX4v|a6;b;b6V+%U47}BlHGH!D+L>dV2x1rtpgsUT zFWMupqGm`$`b`8U7+InOw1wNO_3whMMG-J5Xz1n@qxt@JXye_-DIHS0v&6Uh?V&77 zdC2M3i+CgI*n6U_^Ia_+2_^MjYhH3)ipQRi4lU=JbMYz`dVW09*4weQ1{1WaH9l}{ z82#y0~O+^_8#0;2d{KkZp1%PKJzV6L24PfB=98l1p h^cVUo?f%zp_X*5Kinz>vdXNAB002ovPDHLkV1iI^4kEuMKmu9~NdV+hCfxV15WSK kHUWoqiY`r#HzqJLl!dVV2-Lyg>FVdQ&MBb@0Kq{lWB>pF diff --git a/2d/platformer/assets/art/player/robot_demo.png b/2d/platformer/assets/art/player/robot_demo.png deleted file mode 100644 index 914a5efb799ec47dc4716bff535d367bbf4bbac1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2087 zcmZuydpy$%8~@E@qiN{w+EH}%5*5*gC=;)_9)&QvJCRZryOp_zq~qw&XsRj7Wx}bM z35}-Y#0Z(|nXKcso0)BAo%i4O`8=QJ`~360{PTRCOkW=lT^&Om004A7QSSZ#prKv? z7bsXgLov=dYN+(}4m_qt6><0fZzs;^jm45e+)ZE6KY1IjYiYxf1vDnAI+@M}c zqyojt3klS7@nt9Ct4?1mK6UOv$k`$wg&T;uAAl+F3A+p6YJh}yKy1Am`qrKhoQpSM zhhG8^R9Gdk-K>tQo#5{i0B9fdj>Koy(aB4#=K%m>?&7SaUTEh~=D{i*8fq*cbueXVO(wMjj$sS_w<4}``kcFf$;tJLQNXzi* zvP~^wfHk;nD<)H3^FVl>0Br_`u+Ds;?=u-&{XowW+PC*mWDw12wm7uKjzI@w z5igxDA29|BI;vt>Hw#h3pFY~Ees~ZB&PAg|2Zk?sWFLty*O#yJ%HI#Qh$h zj07wm`NYiyTB?3Xd z)|p6FTdUrn+;ObO9)F|+Uem&0Fqy{Vu*IYoLHN5I8L`f$ zNi|$R{>o|~AzZtpraZ~f5Mpzk*4U1qNOPG?5RH?Wzk~gc)`E*KMBs5|Queoa()jno zfhL{057UjTBH<*2OC2wL6tw=*EUzl~BG9e9>$%WLRXhBUIr=x$zVq*RMJ_=(Nu*Wt zdgU~@FL8u`1z`I0U)-1>yl2AxoJ~*(U_&obTsAc33a-b(ST~Gfzbk_YXanVQ!-VVl z+sn27KvcxdR%Y9AwOW7VCh6zDZj=C3uSgx2(3up_1;Y{>tug|;RvsarU2rDi)|M)( z^IS)^wRnj8D}5xDqf}Sok0q3 z`?>gd%7F<_47Mp84>yMtRkt|b?B$~mP{v)6-uaYIcrZz)q~!71ut6}18!V1T4#yQh z&KJ#`ieRk>dmuo+b>*DVl&rzA_0#4Wy@_z1(WgF#(wB|Z#5J9?V3qR&ctHOlp%)c- ztKZP1&C*(j!_S**y<;Lc8$lTm&%TZh;+mmOc9B>dWWEx=kfBEu=*=J$8$ zDA3)}gAE~Tl=g?Fzfzo%DK@1UDM?&;w7WX1_>PHv_Tml^_rDoFhoLcFM?t2e@lIeV>0%MD9*5wA{Hva@f+sif4M3K^LC6`L@|;AnVqy6s z+QS<@I4F>Q1c6M;je>`B5_>2ZUS`B0;utzO5@F4H7cTy0z46qc5jjLN`A%$D^TutQ zn)!FuoU3EBy(G$JEWdF@cp{X-#C7dq;$&Y-H<3(T^JlO;^IqS1Wx|?IpHmJ=RuINE zd=u!~%t=zWTeJN0Mi(@ENbNeOcD+^~A5?ToE1CU64xXfZzjsqhA{@o0g}Rw5jwu!z z+skt*k9M~;PpWA>keb?oZzkZ|^Pk#?-A%_TYuSq?rMX4=SIN9&Nc)2MpJF$j!S$HS zv{sfA@-#^F-NE?yQZC5Pn(E&N$7KgL^mB(ezJ)`PVEGh4i-l^a`e^v zXD*w|jC-B5P#OIK0G6B`7zGP`(>mB#EF^kv$ozBhWuAw3UO1`FnC%2Xq43hJIXv?e z@|NG5yRxSLJM=*&)}U-;I&J@jzw4yWP zCAq_hx{eyK&)X)j@Q?EL&!~k6`AhU;JNkmlU~lb&SvM+F`ac&+GKQ1+H3Kr3k8`L< zXQ2wOm(+pJv)SV{=fprkSw=^)=21_Sd&{XzlHV?ORLk4E19 E2Y81q=>Px# diff --git a/2d/platformer/assets/art/tileset/tiles_demo.png b/2d/platformer/assets/art/tileset/tiles_demo.png deleted file mode 100644 index bbb7d44a3ae8879dc76936b7396323ac2afc5d89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2583 zcmV+y3h4ETP)pJ_>=QzVC4KVV6JfjkpwLMu@}XH7p}R5NE!FJVA7PD(6XMk`f1G(tfk zQ!yi=I_W(R9)pKmyd2UMbzGG8wWvCaa_6{7|X@RvV-F^XR#vO`UkaCtC60nhn* z;r~Iq3OFA|1LFM~qQ4*y7}^K9e0e_S>qT|vO?c(GhaVU)Rhj8OZh$WwHE=fI2?00j zF>&>xyL})X1Kems`~>6+gbc8*1A={?0_N(Am;(y_SOE&@m+Rk8OutWG=ON&By^U56 zs9`5}2dICx|LOPXZ}QJlhWh+{Jt9|6sEUq|2*yAB{`;rjr@zUU^6>RlY6e}@bLq3; zqyP0Ll~d1Ozg6VbW{rs3{k!jy`n&@w*0iaReq_{Qw%kLrvKP4WLS( z=iMgX+3R(lrx~z{!T^b3=nr4l*FpvyH&LrM;NnZD7@*bx<01{v_jM?4z|fxQ@0d5> zNjPj}fz5!Q9KIb9t4VVXSLuUg|fZj6T(;yF{7x1UNE6`FK zhk>TqEDC+qyAt-;>;He~Au||OfOvX}z-{MPyvdl0GW9y~Si!OJG{Coc8O|<-T`9*t zU@BAV7yW*~Rj&{pPaFKtMFkMlPVjRpa0+nQ<$sAkJf1dq3}=@EE`u&euY~CIrLiJB zo;LWO-#ZYXU1+~{y$OE6HUGT}0dOCpak>u)kEad34*?Fax!`!(;5!f?dLI(^0}=%A z#}|k{?g!)xV8<7ZKja5w3*e8>AHUBJXn-M-EPyvYfBX(VKm&%zQg|=#mH>8qk@)TT z^@o1ILckcX2_OT4Hz}^-yS6_3@$+T;8!r+Bz~oR9;5buKi((AN{g_d9CqSv5c!2=Z zd8+KaSm)0ia5Izut|qm-07VSp)(6z~fLT)G_{@wl5`UmmS+AEJ4!0ICy|>8`XMFzn zBYuE3M8b}U2=MWFIad^l?-tLj;HT|W@ptA2v=(rH!>Dz4_4yTn_&fCjwtu@Hu>C#!fOV<> z`F_AU=m)G97hu~aMsE56%)F!@unzhG>*WQo{Qwp`h>zJ3f1)1{XaV=<|5*_C19}?{ z8!bS`hw~3$o);A$*AxxpFIW@&D*lik@H_#G_?R8>GpqPRen7e{?vIaco|!M>?1 zXwW|X^8~malg+c7{{dylYypY+3I2S1H7H%F_#r1mPCo@B`A|pPnXBAmWhNen8g(02mxA34$#kEk7ad z2Wa5C^w1Ng=Lh5q;GdtTIoK2a*t-0HbX(k?KQQW^Ff2eIKOqi({s1vXM(79Pe*%&3 zFNnjRKR`S}f|UG#IsW|x9{BSIh`2c{9;Vfgb0h}+dLIX@s>0Dt~Kb4bt; zj_H2D>!G8=$VhjDmn#j79sw>fp87?0N&5o7pv{;J1?vn*y+iq}tuyeg606F}9(nC{ z+ug@MpOptOlodX-l6U#N9!@q^fqB{7`~f=M5nU&C;{UcqUx0_ctZPso8u%^yG;5HNm0fpUdE5)_)pFDsPwTkObl z=ye8aiT|W>lD*+_?1!x0U zXFv+Nz0SZ!ies%AyV{R%Qe(jOsOyyg^8ErDH&|z&tv+yGXW--4vl>jpQf^!Lw z*H19{2AY9lqA$N-#?Niumgu~b0eq^w7Rx{1k1frE!UoVq3rKms-+>ZFe*QozU*gEm zAIRjp^aFHanZXM}e6N1M+>p$dSHr(P0rPzxRSdqNBLN)G?=$nghn=z8`!IKx!(ju= zCgVr{0_33S)tw*U{gbeHR5JKp{QyU&Xz{3I@O}FMKqg;o^p-ym=jFZeJqYmRTi;gx tHh#du{H*vt&ktyv!T)`JfWem_{s%biLV134zkmP$002ovPDHLkV1lju#;5=Q diff --git a/2d/platformer/assets/art/tileset/tileset.tres b/2d/platformer/assets/art/tileset/tileset.tres deleted file mode 100644 index 917e2afa..00000000 --- a/2d/platformer/assets/art/tileset/tileset.tres +++ /dev/null @@ -1,335 +0,0 @@ -[gd_resource type="TileSet" load_steps=14 format=2] - -[ext_resource path="res://assets/art/tileset/tiles_demo.png" type="Texture2D" id=1] - -[sub_resource type="ConvexPolygonShape2D" id=1] -points = PackedVector2Array( 0, 6, 32, 6, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=2] -points = PackedVector2Array( 0, 6, 28, 6, 28, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=3] -points = PackedVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=4] -points = PackedVector2Array( 0, 6, 32, 6, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=5] -points = PackedVector2Array( 32, 38, 32, 64, 0, 64, 0, 6 ) - -[sub_resource type="ConvexPolygonShape2D" id=6] -points = PackedVector2Array( 0, 0, 28, 0, 28, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=7] -points = PackedVector2Array( 28, 6, 32, 6, 32, 32, 0, 32, 0, 0, 28, 0 ) - -[sub_resource type="ConvexPolygonShape2D" id=8] -points = PackedVector2Array( 0, 6, 32, 6, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=9] -points = PackedVector2Array( 0, 6, 28, 6, 28, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=10] -points = PackedVector2Array( 0, 0, 32, 0, 32, 32, 0, 32 ) - -[sub_resource type="ConvexPolygonShape2D" id=11] -points = PackedVector2Array( 0, 0, 32, 0, 32, 24, 0, 24 ) - -[sub_resource type="ConvexPolygonShape2D" id=12] -points = PackedVector2Array( 0, 0, 28, 0, 28, 24, 0, 24 ) - -[resource] -0/name = "ground" -0/texture = ExtResource( 1 ) -0/tex_offset = Vector2( 0, 0 ) -0/modulate = Color( 1, 1, 1, 1 ) -0/region = Rect2( 0, 0, 32, 32 ) -0/tile_mode = 0 -0/occluder_offset = Vector2( 0, 0 ) -0/navigation_offset = Vector2( 0, 0 ) -0/shape_offset = Vector2( 0, 0 ) -0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -0/shape = SubResource( 1 ) -0/shape_one_way = false -0/shape_one_way_margin = 1.0 -0/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 1 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -0/z_index = 0 -1/name = "ground_end" -1/texture = ExtResource( 1 ) -1/tex_offset = Vector2( 0, 0 ) -1/modulate = Color( 1, 1, 1, 1 ) -1/region = Rect2( 32, 0, 32, 32 ) -1/tile_mode = 0 -1/occluder_offset = Vector2( 0, 0 ) -1/navigation_offset = Vector2( 0, 0 ) -1/shape_offset = Vector2( 0, 0 ) -1/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -1/shape = SubResource( 2 ) -1/shape_one_way = false -1/shape_one_way_margin = 1.0 -1/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 2 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -1/z_index = 0 -2/name = "slope" -2/texture = ExtResource( 1 ) -2/tex_offset = Vector2( 0, 0 ) -2/modulate = Color( 1, 1, 1, 1 ) -2/region = Rect2( 64, 64, 32, 64 ) -2/tile_mode = 0 -2/occluder_offset = Vector2( 0, 0 ) -2/navigation_offset = Vector2( 0, 0 ) -2/shape_offset = Vector2( 0, 0 ) -2/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -2/shape = SubResource( 5 ) -2/shape_one_way = false -2/shape_one_way_margin = 1.0 -2/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 5 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -2/z_index = 0 -3/name = "wall" -3/texture = ExtResource( 1 ) -3/tex_offset = Vector2( 0, 0 ) -3/modulate = Color( 1, 1, 1, 1 ) -3/region = Rect2( 32, 32, 32, 32 ) -3/tile_mode = 0 -3/occluder_offset = Vector2( 0, 0 ) -3/navigation_offset = Vector2( 0, 0 ) -3/shape_offset = Vector2( 0, 0 ) -3/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -3/shape = SubResource( 6 ) -3/shape_one_way = false -3/shape_one_way_margin = 1.0 -3/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 6 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -3/z_index = 0 -4/name = "slope_top" -4/texture = ExtResource( 1 ) -4/tex_offset = Vector2( 0, 0 ) -4/modulate = Color( 1, 1, 1, 1 ) -4/region = Rect2( 32, 64, 32, 32 ) -4/tile_mode = 0 -4/occluder_offset = Vector2( 0, 0 ) -4/navigation_offset = Vector2( 0, 0 ) -4/shape_offset = Vector2( 0, 0 ) -4/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -4/shape = SubResource( 7 ) -4/shape_one_way = false -4/shape_one_way_margin = 1.0 -4/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 7 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -4/z_index = 0 -5/name = "one_way" -5/texture = ExtResource( 1 ) -5/tex_offset = Vector2( 0, 0 ) -5/modulate = Color( 1, 1, 1, 1 ) -5/region = Rect2( 64, 0, 32, 32 ) -5/tile_mode = 0 -5/occluder_offset = Vector2( 0, 0 ) -5/navigation_offset = Vector2( 0, 0 ) -5/shape_offset = Vector2( 0, 0 ) -5/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -5/shape = SubResource( 8 ) -5/shape_one_way = true -5/shape_one_way_margin = 1.0 -5/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 8 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -5/z_index = 0 -6/name = "one_way_end" -6/texture = ExtResource( 1 ) -6/tex_offset = Vector2( 0, 0 ) -6/modulate = Color( 1, 1, 1, 1 ) -6/region = Rect2( 96, 0, 32, 32 ) -6/tile_mode = 0 -6/occluder_offset = Vector2( 0, 0 ) -6/navigation_offset = Vector2( 0, 0 ) -6/shape_offset = Vector2( 0, 0 ) -6/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -6/shape = SubResource( 9 ) -6/shape_one_way = true -6/shape_one_way_margin = 1.0 -6/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": true, -"one_way_margin": 1.0, -"shape": SubResource( 9 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -6/z_index = 0 -7/name = "rock" -7/texture = ExtResource( 1 ) -7/tex_offset = Vector2( 0, 0 ) -7/modulate = Color( 1, 1, 1, 1 ) -7/region = Rect2( 0, 32, 32, 32 ) -7/tile_mode = 0 -7/occluder_offset = Vector2( 0, 0 ) -7/navigation_offset = Vector2( 0, 0 ) -7/shape_offset = Vector2( 0, 0 ) -7/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -7/shape = SubResource( 10 ) -7/shape_one_way = false -7/shape_one_way_margin = 1.0 -7/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 10 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -7/z_index = 0 -8/name = "bottom" -8/texture = ExtResource( 1 ) -8/tex_offset = Vector2( 0, 0 ) -8/modulate = Color( 1, 1, 1, 1 ) -8/region = Rect2( 192, 32, 32, 32 ) -8/tile_mode = 0 -8/occluder_offset = Vector2( 0, 0 ) -8/navigation_offset = Vector2( 0, 0 ) -8/shape_offset = Vector2( 0, 0 ) -8/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -8/shape = SubResource( 11 ) -8/shape_one_way = false -8/shape_one_way_margin = 1.0 -8/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 11 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -8/z_index = 0 -9/name = "bottom_end" -9/texture = ExtResource( 1 ) -9/tex_offset = Vector2( 0, 0 ) -9/modulate = Color( 1, 1, 1, 1 ) -9/region = Rect2( 224, 32, 32, 32 ) -9/tile_mode = 0 -9/occluder_offset = Vector2( 0, 0 ) -9/navigation_offset = Vector2( 0, 0 ) -9/shape_offset = Vector2( 0, 0 ) -9/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -9/shape = SubResource( 12 ) -9/shape_one_way = false -9/shape_one_way_margin = 1.0 -9/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 12 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -9/z_index = 0 -10/name = "bottom_corner" -10/texture = ExtResource( 1 ) -10/tex_offset = Vector2( 0, 0 ) -10/modulate = Color( 1, 1, 1, 1 ) -10/region = Rect2( 160, 32, 32, 32 ) -10/tile_mode = 0 -10/occluder_offset = Vector2( 0, 0 ) -10/navigation_offset = Vector2( 0, 0 ) -10/shape_offset = Vector2( 0, 0 ) -10/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -10/shape = SubResource( 3 ) -10/shape_one_way = false -10/shape_one_way_margin = 1.0 -10/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 3 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -10/z_index = 0 -11/name = "tree_trunk_0" -11/texture = ExtResource( 1 ) -11/tex_offset = Vector2( 0, 0 ) -11/modulate = Color( 1, 1, 1, 1 ) -11/region = Rect2( 128, 64, 32, 32 ) -11/tile_mode = 0 -11/occluder_offset = Vector2( 0, 0 ) -11/navigation_offset = Vector2( 0, 0 ) -11/shape_offset = Vector2( 0, 0 ) -11/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -11/shape_one_way = false -11/shape_one_way_margin = 0.0 -11/shapes = [ ] -11/z_index = 0 -12/name = "tree_trunk_1" -12/texture = ExtResource( 1 ) -12/tex_offset = Vector2( 0, 0 ) -12/modulate = Color( 1, 1, 1, 1 ) -12/region = Rect2( 128, 32, 32, 32 ) -12/tile_mode = 0 -12/occluder_offset = Vector2( 0, 0 ) -12/navigation_offset = Vector2( 0, 0 ) -12/shape_offset = Vector2( 0, 0 ) -12/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -12/shape_one_way = false -12/shape_one_way_margin = 0.0 -12/shapes = [ ] -12/z_index = 0 -13/name = "tree_base" -13/texture = ExtResource( 1 ) -13/tex_offset = Vector2( 0, 0 ) -13/modulate = Color( 1, 1, 1, 1 ) -13/region = Rect2( 128, 96, 32, 32 ) -13/tile_mode = 0 -13/occluder_offset = Vector2( 0, 0 ) -13/navigation_offset = Vector2( 0, 0 ) -13/shape_offset = Vector2( 0, 0 ) -13/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -13/shape = SubResource( 4 ) -13/shape_one_way = false -13/shape_one_way_margin = 1.0 -13/shapes = [ { -"autotile_coord": Vector2( 0, 0 ), -"one_way": false, -"one_way_margin": 1.0, -"shape": SubResource( 4 ), -"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) -} ] -13/z_index = 0 -14/name = "tree_top" -14/texture = ExtResource( 1 ) -14/tex_offset = Vector2( 0, 0 ) -14/modulate = Color( 1, 1, 1, 1 ) -14/region = Rect2( 128, 0, 32, 32 ) -14/tile_mode = 0 -14/occluder_offset = Vector2( 0, 0 ) -14/navigation_offset = Vector2( 0, 0 ) -14/shape_offset = Vector2( 0, 0 ) -14/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) -14/shape_one_way = false -14/shape_one_way_margin = 0.0 -14/shapes = [ ] -14/z_index = 0 diff --git a/2d/platformer/assets/art/ui/touch_button_fire.png b/2d/platformer/assets/art/ui/touch_button_fire.png deleted file mode 100644 index 1d7ed2d58a59e2a59fa5d4a909cab13f1c87448b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1444 zcmbtThgZ{A6#gM7k>LP}fL4a0peVzlaa7cTfQKR_RK->VS#kgil@=8dl+nhj2nE@w zKoY`ABqR_LAPGW%3?d;iQf5eq8X$y`kOBSG_CM%7_l^6#d+&F?_s)a+`Fa}aS?B=( zVCe1T?hmeK{uvN$a4v0nC;dLPLsrzID(g`Quob2XfvrY0)S_{9 z)s6MFcuXw_V$nzfwvO2NrnMPQAvM#;EwonBzr1g1s>p=K?hY!ehyISm;P$Zx-t`f2 zZ>VHqZ)Zn8n>GBNH~tr2FflF^Oo0wowcs1xwzu{%dZxz5#51B<$tUUjylg=#TUY>3 zJ1K4bY~~n$WJWkWH!E3`$ySz^6$-`bXZw$|x~dt6{UDx^Nu~0Y6_rY*QL8nd4NSnG zk$6lUg+yfc_Kc1UgJ}x6T%}U3X*6qVYYjDM5+2v{mNv{A04Wxv^B}msz77_0Sd7WB z(K(3(WK=1YbQ)!d#}$i&i?Ri6`@5msJ%V8JB!6Lx7EJ*P8 zg#k9_f)diR@*IPoyx8RF{)cU%*LCff*wFlf0^fq7;*!$RLxp9pD^X~)R%&qtrm>ks zeqDtn(t6na-0kHx1oq&VKr|CjOQiEAKg`RPmNz~xdNnMXS148LQ-x(HJbh?Ep;;>~ z$5ID`>+6ta=J=evj=~eGzOBTKY9f(MtSP0YDXFUEop9;#GB-!u&8%&rk$zrkNd|xo zi{9>M1MZC6FdGOq0qhEY(}8Q*0p(u`=!99OX6rG=6?{s@D>L8cCLTu6Oq=VjEG!lt zE|wPwHbdbP#KfR&lQ!Soq1u|?%0cYMP`>GHy*%l>oEd$B>@|2;cN4j{S+*|*7sHR= z#V0rnMU*8aqP}*6R6zB#$8m}Ja_0UY$~FZC<$ixH&!cSPhg;dZlDYM*-0)=ACtUTh zivqvpz?qmWv5S3y$HnK(JkCPr_BedJQ$dL46JmGbW99MD%=V_!@weECu8|_XK8L;! z`s42FRwi)U8`*x8nfT+zp-VqGS|gS&_D<_P^hdnE`ODR(R}m(5(+%DS&YsZWbXeRz z7vWUIG_7IH#hs8Gt?7($u?REv(GjCHhmY-|2=aDjoKB&b8)WR6^y8RIRq5x6gK3^| zB)e3*CHfRR>_8nOtb?eA32DPm4wqioH|4z7y}jS6!p|Y^AkW7s2g7?={US@}2=4+h zz`?1lKUCYa3rS>MB5{*vQ>+tC&c1g@ERsEY+UMbJDPK{h-KEo#){R4`&Te8kRIudu zwh@v_>u-oc{CSNv=vGazkkl5u$k&5h(VeF|bFFs;ZIm{FXw z0aTaL?N~oy*+zquO}J(Kz8`Ac=Ir%AV0&L6-6_#{dL>n9SLa4jc@Oyk0Bc0AY-Tc982 zVr?V3Yk2vh0pGc>JEqb~Y#@S#kVB6?C}wZnqmwHoY=vk?kq?>B&Xn{YHR`PUN{V9)t~DMK!jc3Czl%oi;Y4+5tfLbJ!L~yFe}Qivr#rzV7wsf*<`2j9W#$ diff --git a/2d/platformer/assets/art/ui/touch_button_jump.png b/2d/platformer/assets/art/ui/touch_button_jump.png deleted file mode 100644 index 819ba6119217657d89b805c65498cf48996d0464..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 802 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!ZU^{;xB}@lOBa!W7S5jG>}U_v z*w$DlDk3Z#pSLFy6B9(s z;yE*QwY9ohnnXoFh5$`qXJ-d8RxX-vV`T|SY)+d z`p2$A&eq>2zG6EhJa_3k0lQz!Yg0EqFpyw+n0&rewY0o^`}g`qU;lDT9}=3ae5NLM zQhdin2b+lsjsx2dM@RXW|TMA$DF>Z&#Vj$PV>TwBi$QZdyWeISrMYbds;JI zZJU>9&nnSNTAzPP8D5ocxUyn$TJLG|&ZSq`7L|2xnfT!~`!sW!+(ryJ^O{IEHYR9hHoC z1RlI&EpTsW7eBzvI4_RDpQWRM(WT};^ZoY+zK4I<%U84hh{E?n7r7stxbKm`~i*&`}e-Fy$FD>jE`j4K9bsSrbJV zyk}h!X^06kROf0~k`y$RVdIAM)c==%{r>PxT;uh|fE($H6eU<07R#zopr0F3o=e*gdg diff --git a/2d/platformer/assets/art/ui/touch_button_left.png b/2d/platformer/assets/art/ui/touch_button_left.png deleted file mode 100644 index 60e48d690ff06234642d7f163a163e94e63de28b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 777 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!ZUp#*xB}@lOBc}@tz0yJ`GUEN z=geFjQ4vuQAQI-~<>BSwVP|J&V`XJ#W@chy0{RFDICkd90V(&AAirP+MrKwv z4nZYVU40uT7k3X|zmT~2gyi&`+>-L@hL*1Gp8g4wrcRqaW9F>ca~CgNwR+8lt=kS9 zJaOji^@mSiy?Xue)At|0|NM*C9+AMnz&O*>#WAGf*4yc!Nv{nATo0c)^X7Nl%$b3| z;{z=w-i=cBoq6uRts3u*&r5$Q&pB~D%J%fDtyw=^X3Xvr-Cb}&_t=@sjUn86TY?xj z*KA^Dox8-*CWzh9cG2nO3l)8zb6*Hjc(jj;XT^^xONBJHIvM z^*kYk*VFo)Hr45RFfKa(`JUReKi0xhj+edd4s4vjbh(|wantt|;tF3}CLEsB8=a_d z!t(P!JFzt}T*8j`-wPbs_#{MvQy_fKLFa`66P_D(uv+skV`90>ckx$m0LP2NQx5k0 zf1Y&kpc$iDN=}ne+8hpJgM~T5CI+eT1uVR?7xZ$@F4u9qttOFh=GD{$PByc~Rzr7j zo5s}r%ux&WH=F(C_*H&kLHweB+EZShUt!NK`OmRv-jNsHeMMIyd;cVH?fS;NX-?-) zk>}=9cC1pL$K~cf<;f0T)8+HH({gQHeAFf%oTQrmc%#Am-botiJKSFWb+Ep-`4(?$ zoPpOb+0K~4Rc_I@r0TsNzwdm%apkA-)PLLlG5+WNB7fTbukqi5i7Zo@rdC{i*3$rt OcLq;aKbLh*2~7YPGi74{ diff --git a/2d/platformer/assets/art/ui/touch_button_right.png b/2d/platformer/assets/art/ui/touch_button_right.png deleted file mode 100644 index 8f0c57c4b6ae207c420c33f2b413aa8f0eac781a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 785 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!ZU^{;xB}@lOBYdy=1!jiG$A)L zJ;2u+$Y5q>t}ZJ9GJuBj^771>)DJOVK~8SvqWLyfmJq4r_*fu=ot?d_r3s=yR77O) zoS8tjuC|t+wXQ-xsq^cs0}J`azCAYd-m|emW!lZ1uLTA4?~_p7rX4PAz9R z0|Vn+PZ!6Kid%25w^nI6@~}R*^7Kk{%(8dyj?VpFuOy>ZvnFNp_5A<-8=F%n>HNL8 z@9bH99X;LkYjpH=_0F6RbXcAJnqm9CZC**zv%L#8Y}x6k6n(p3<6hT)Wn~W&%iC+- z96T;pd8>VWZBe;Eqr;PiJ1!5k*tEU$9u-XYIMg+Hv51YzCCLcQq6w|jTP$swrY@B{ zu5QQp>u`teKp2bj+6ygq$LL;ZoLqHDNkmFaRAm~a2qmp!YfT%Xf`zh7eae&u(Z zix@uVyswh_RHum&T&!XJCq2c) zKFKqheVI)(`}|o>kEYJJI;CjZe7CcSRiR&)>*g$8)ptbd)Z}IAv(lH(vnY_=vNG=U z^QPkH{Q*8|b`e2cH#5%3rYTRJ${!x)660leFSv`hRbQg;Xy1|WIV;k void: + if _state == State.WALKING and velocity.is_zero_approx(): + velocity.x = WALK_SPEED + velocity.y += gravity * delta + if not floor_detector_left.is_colliding(): + velocity.x = WALK_SPEED + elif not floor_detector_right.is_colliding(): + velocity.x = -WALK_SPEED + + if is_on_wall(): + velocity.x = -velocity.x + + move_and_slide() + + if velocity.x > 0.0: + sprite.scale.x = 1.0 + elif velocity.x < 0.0: + sprite.scale.x = -1.0 + + var animation := get_new_animation() + if animation != animation_player.current_animation: + animation_player.play(animation) + + +func destroy() -> void: + _state = State.DEAD + velocity = Vector2.ZERO + + +func get_new_animation() -> StringName: + var animation_new: StringName + if _state == State.WALKING: + if velocity.x == 0: + animation_new = &"idle" + else: + animation_new = &"walk" + else: + animation_new = &"destroy" + return animation_new diff --git a/2d/platformer/src/Actors/Enemy.tscn b/2d/platformer/enemy/enemy.tscn similarity index 57% rename from 2d/platformer/src/Actors/Enemy.tscn rename to 2d/platformer/enemy/enemy.tscn index accdf2ea..d49c950a 100644 --- a/2d/platformer/src/Actors/Enemy.tscn +++ b/2d/platformer/enemy/enemy.tscn @@ -1,22 +1,85 @@ -[gd_scene load_steps=13 format=2] +[gd_scene load_steps=15 format=3 uid="uid://bd478yrtijbfn"] -[ext_resource path="res://assets/art/player/bullet/bullet.png" type="Texture2D" id=1] -[ext_resource path="res://assets/audio/sfx/explode.wav" type="AudioStream" id=2] -[ext_resource path="res://assets/audio/sfx/hit.wav" type="AudioStream" id=3] -[ext_resource path="res://assets/art/enemy/enemy.png" type="Texture2D" id=4] -[ext_resource path="res://src/Actors/Enemy.gd" type="Script" id=5] +[ext_resource type="Texture2D" uid="uid://c2aisfmq85suf" path="res://player/bullet.webp" id="1"] +[ext_resource type="AudioStream" uid="uid://bbxjxs8sms61b" path="res://enemy/explode.wav" id="2"] +[ext_resource type="AudioStream" uid="uid://brtn51vs7jaet" path="res://enemy/hit.wav" id="3"] +[ext_resource type="Texture2D" uid="uid://cdy6gikv8wka7" path="res://enemy/enemy.webp" id="4"] +[ext_resource type="Script" path="res://enemy/enemy.gd" id="5"] -[sub_resource type="CanvasItemMaterial" id=1] +[sub_resource type="CanvasItemMaterial" id="1"] -[sub_resource type="Animation" id=2] +[sub_resource type="Animation" id="Animation_67t2c"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:collision_layer") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [2] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Sprite2D:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Sprite2D:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Sprite2D:rotation") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Sprite2D:self_modulate") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(1, 1, 1, 1)] +} + +[sub_resource type="Animation" id="2"] resource_name = "destroy" length = 1.5 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), @@ -24,11 +87,11 @@ tracks/0/keys = { "values": [7] } tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true tracks/1/path = NodePath("Sprite2D:rotation_degrees") tracks/1/interp = 1 tracks/1/loop_wrap = true -tracks/1/imported = false -tracks/1/enabled = true tracks/1/keys = { "times": PackedFloat32Array(0, 0.8), "transitions": PackedFloat32Array(0.0796601, 1), @@ -36,23 +99,23 @@ tracks/1/keys = { "values": [0.0, 180.0] } tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true tracks/2/path = NodePath("Sprite2D:self_modulate") tracks/2/interp = 1 tracks/2/loop_wrap = true -tracks/2/imported = false -tracks/2/enabled = true tracks/2/keys = { -"times": PackedFloat32Array(0, 0.5, 1.1), +"times": PackedFloat32Array(0, 0.9, 1.3), "transitions": PackedFloat32Array(1, 1, 1), "update": 0, "values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)] } tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true tracks/3/path = NodePath("Explosion:emitting") tracks/3/interp = 1 tracks/3/loop_wrap = true -tracks/3/imported = false -tracks/3/enabled = true tracks/3/keys = { "times": PackedFloat32Array(0, 1), "transitions": PackedFloat32Array(1, 1), @@ -60,90 +123,77 @@ tracks/3/keys = { "values": [false, true] } tracks/4/type = "value" -tracks/4/path = NodePath("Explosion:process_material:scale") -tracks/4/interp = 1 -tracks/4/loop_wrap = true tracks/4/imported = false tracks/4/enabled = true +tracks/4/path = NodePath("Hit:playing") +tracks/4/interp = 1 +tracks/4/loop_wrap = true tracks/4/keys = { -"times": PackedFloat32Array(0.6, 1), -"transitions": PackedFloat32Array(1, 1), -"update": 0, -"values": [1.0, 4.0] -} -tracks/5/type = "value" -tracks/5/path = NodePath("Hit:playing") -tracks/5/interp = 1 -tracks/5/loop_wrap = true -tracks/5/imported = false -tracks/5/enabled = true -tracks/5/keys = { "times": PackedFloat32Array(0.00999999), "transitions": PackedFloat32Array(1), "update": 1, "values": [true] } -tracks/6/type = "value" -tracks/6/path = NodePath("Explode:playing") -tracks/6/interp = 1 -tracks/6/loop_wrap = true -tracks/6/imported = false -tracks/6/enabled = true -tracks/6/keys = { +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Explode:playing") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { "times": PackedFloat32Array(0.8), "transitions": PackedFloat32Array(1), "update": 1, "values": [true] } -tracks/7/type = "method" -tracks/7/path = NodePath(".") -tracks/7/interp = 1 -tracks/7/loop_wrap = true -tracks/7/imported = false -tracks/7/enabled = true -tracks/7/keys = { +tracks/6/type = "method" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath(".") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { "times": PackedFloat32Array(1.5), "transitions": PackedFloat32Array(1), "values": [{ "args": [], -"method": "queue_free" +"method": &"queue_free" }] } -tracks/8/type = "value" -tracks/8/path = NodePath(".:collision_layer") -tracks/8/interp = 1 -tracks/8/loop_wrap = true -tracks/8/imported = false -tracks/8/enabled = true -tracks/8/keys = { +tracks/7/type = "value" +tracks/7/imported = false +tracks/7/enabled = true +tracks/7/path = NodePath(".:collision_layer") +tracks/7/interp = 1 +tracks/7/loop_wrap = true +tracks/7/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 1, "values": [0] } -tracks/9/type = "value" -tracks/9/path = NodePath("Sprite2D:position") -tracks/9/interp = 1 -tracks/9/loop_wrap = true -tracks/9/imported = false -tracks/9/enabled = true -tracks/9/keys = { +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Sprite2D:position") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { "times": PackedFloat32Array(0, 0.2, 0.4), "transitions": PackedFloat32Array(2.2974, 0.183011, 1), "update": 0, "values": [Vector2(0, 0), Vector2(0, -32), Vector2(0, 0)] } -[sub_resource type="Animation" id=3] +[sub_resource type="Animation" id="3"] length = 6.75 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0, 0.75, 1.5, 2.25, 3, 3.75, 4.5, 5.25, 6, 6.75), "transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), @@ -151,16 +201,15 @@ tracks/0/keys = { "values": [5, 6, 5, 6, 5, 6, 7, 6, 7, 5] } -[sub_resource type="Animation" id=4] +[sub_resource type="Animation" id="4"] length = 1.25 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0, 0.25, 0.5, 0.75, 1, 1.25), "transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), @@ -168,60 +217,61 @@ tracks/0/keys = { "values": [0, 1, 2, 3, 4, 0] } -[sub_resource type="CapsuleShape2D" id=5] -radius = 11.0 -height = 7.0 +[sub_resource type="AnimationLibrary" id="AnimationLibrary_nnb1f"] +_data = { +"RESET": SubResource("Animation_67t2c"), +"destroy": SubResource("2"), +"idle": SubResource("3"), +"walk": SubResource("4") +} -[sub_resource type="CanvasItemMaterial" id=6] +[sub_resource type="CapsuleShape2D" id="5"] +radius = 8.0 +height = 22.0 + +[sub_resource type="CanvasItemMaterial" id="6"] blend_mode = 1 -[sub_resource type="Gradient" id=7] +[sub_resource type="Gradient" id="7"] offsets = PackedFloat32Array(0.5, 1) colors = PackedColorArray(1, 1, 1, 1, 0, 0, 0, 1) [node name="Enemy" type="CharacterBody2D"] collision_layer = 2 -collision_mask = 24 -script = ExtResource( 5 ) -speed = Vector2(75, 250) +collision_mask = 26 +collision_priority = 2.0 +script = ExtResource("5") [node name="PlatformDetector" type="RayCast2D" parent="."] position = Vector2(0, 6) -enabled = true -cast_to = Vector2(0, 8) collision_mask = 8 [node name="FloorDetectorLeft" type="RayCast2D" parent="."] position = Vector2(-15, -4) -enabled = true -cast_to = Vector2(0, 35) collision_mask = 24 [node name="FloorDetectorRight" type="RayCast2D" parent="."] position = Vector2(15.5, -3) -enabled = true -cast_to = Vector2(0, 35) collision_mask = 24 [node name="Sprite2D" type="Sprite2D" parent="."] -material = SubResource( 1 ) -texture = ExtResource( 4 ) +material = SubResource("1") +texture = ExtResource("4") flip_h = true hframes = 8 -frame = 7 [node name="AnimationPlayer" type="AnimationPlayer" parent="."] -anims/destroy = SubResource( 2 ) -anims/idle = SubResource( 3 ) -anims/walk = SubResource( 4 ) +libraries = { +"": SubResource("AnimationLibrary_nnb1f") +} [node name="CollisionShape2D" type="CollisionShape2D" parent="."] rotation = -1.5708 -shape = SubResource( 5 ) +shape = SubResource("5") [node name="Explosion" type="CPUParticles2D" parent="."] self_modulate = Color(1, 1, 1, 0.12) -material = SubResource( 6 ) +material = SubResource("6") emitting = false amount = 32 lifetime = 0.5 @@ -229,21 +279,19 @@ one_shot = true speed_scale = 1.2 explosiveness = 0.76 draw_order = 215832976 -texture = ExtResource( 1 ) +texture = ExtResource("1") emission_shape = 1 emission_sphere_radius = 8.0 spread = 180.0 gravity = Vector2(0, 250) -initial_velocity = 120.0 -initial_velocity_random = 0.5 -angle_random = 1.0 -scale_amount_random = 1.0 -color_ramp = SubResource( 7 ) -hue_variation = 0.05 -hue_variation_random = 0.46 +initial_velocity_min = 25.0 +initial_velocity_max = 80.0 +angular_velocity_max = 45.0 +scale_amount_max = 1.2 +color_ramp = SubResource("7") [node name="Hit" type="AudioStreamPlayer2D" parent="."] -stream = ExtResource( 3 ) +stream = ExtResource("3") [node name="Explode" type="AudioStreamPlayer2D" parent="."] -stream = ExtResource( 2 ) +stream = ExtResource("2") diff --git a/2d/platformer/enemy/enemy.webp b/2d/platformer/enemy/enemy.webp new file mode 100644 index 0000000000000000000000000000000000000000..8d90bdb507384315675a6df92a0dc84a5bd8939e GIT binary patch literal 786 zcmV+t1MU1$Nk&Er0{{S5MM6+kP&iEe0ssIn|G)uXJ98@m#KBE3havnFxd5~y!pnGlYdT+&)TgF1bhr!la_P>VKd+0QOXdb(=5AKr3x0xL-C3{h<=mn)W{wd6 z@O~Aby{f4?ZFXn|tf^UqA5+NK5rhkXC2j@{79{bOh%554OM8)UU1qq}$X$7_z#M7@ zsC9}(m<0nHfx%XRDG`b3=zgxD0k}ArngxRn684URsiA#vTM*%$QuOC!4yGjs4s+|VlOR%jSaknT%uk?UIQ)_ zaQ)^i5zB(PbBVy_3}{Agt@V4h8fFMgIT+tdpSd;cHI0G8#TkPR@@YPB>>ys|xWv6= z_a>-i4crI}+$!!R@~ZbfR|OZt&qu8Z3}&tgWtl==(GeE_1JG$NzATi@a>2 zUIe`Yt{9AKE!y&;k{oAH&Tn}kU~pZoTgTr=b4we&~Py1Wi@j%Ruq7Cp4XZgyYjIIht6|x zFfQyWr?>tINtiVsu^fB|T_p!0JWcPuV~CVc!U0Yg(~xG)Yt$Z(B8 zVTP1TT3bbGadYMh%*X_&1rVT@Ld0{?R5f!%U|{MjmuT$Gb7cxZ<{&fH35Fx%5_nnV QQ-Pt@F!mO3{TJX=0HIrP?*IS* literal 0 HcmV?d00001 diff --git a/2d/platformer/assets/art/enemy/enemy.png.import b/2d/platformer/enemy/enemy.webp.import similarity index 66% rename from 2d/platformer/assets/art/enemy/enemy.png.import rename to 2d/platformer/enemy/enemy.webp.import index 94f8895c..4401c116 100644 --- a/2d/platformer/assets/art/enemy/enemy.png.import +++ b/2d/platformer/enemy/enemy.webp.import @@ -2,23 +2,23 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dq7svs8qmf7h6" -path="res://.godot/imported/enemy.png-c2f48b2558d3b68a547452306041a310.ctex" +uid="uid://cdy6gikv8wka7" +path="res://.godot/imported/enemy.webp-c5e00d5c5f64233c41f70dc392999636.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/art/enemy/enemy.png" -dest_files=["res://.godot/imported/enemy.png-c2f48b2558d3b68a547452306041a310.ctex"] +source_file="res://enemy/enemy.webp" +dest_files=["res://.godot/imported/enemy.webp-c5e00d5c5f64233c41f70dc392999636.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/platformer/assets/audio/sfx/explode.wav b/2d/platformer/enemy/explode.wav similarity index 100% rename from 2d/platformer/assets/audio/sfx/explode.wav rename to 2d/platformer/enemy/explode.wav diff --git a/2d/platformer/assets/audio/sfx/explode.wav.import b/2d/platformer/enemy/explode.wav.import similarity index 55% rename from 2d/platformer/assets/audio/sfx/explode.wav.import rename to 2d/platformer/enemy/explode.wav.import index 885dbf47..c7ac2881 100644 --- a/2d/platformer/assets/audio/sfx/explode.wav.import +++ b/2d/platformer/enemy/explode.wav.import @@ -3,12 +3,12 @@ importer="wav" type="AudioStreamWAV" uid="uid://bbxjxs8sms61b" -path="res://.godot/imported/explode.wav-302a3de6d016432bf47477d337a4d553.sample" +path="res://.godot/imported/explode.wav-2389d0cf62710ef336bf397194eae82e.sample" [deps] -source_file="res://assets/audio/sfx/explode.wav" -dest_files=["res://.godot/imported/explode.wav-302a3de6d016432bf47477d337a4d553.sample"] +source_file="res://enemy/explode.wav" +dest_files=["res://.godot/imported/explode.wav-2389d0cf62710ef336bf397194eae82e.sample"] [params] diff --git a/2d/platformer/assets/audio/sfx/hit.wav b/2d/platformer/enemy/hit.wav similarity index 100% rename from 2d/platformer/assets/audio/sfx/hit.wav rename to 2d/platformer/enemy/hit.wav diff --git a/2d/platformer/assets/audio/sfx/hit.wav.import b/2d/platformer/enemy/hit.wav.import similarity index 57% rename from 2d/platformer/assets/audio/sfx/hit.wav.import rename to 2d/platformer/enemy/hit.wav.import index 8f81b3b7..29f3e849 100644 --- a/2d/platformer/assets/audio/sfx/hit.wav.import +++ b/2d/platformer/enemy/hit.wav.import @@ -3,12 +3,12 @@ importer="wav" type="AudioStreamWAV" uid="uid://brtn51vs7jaet" -path="res://.godot/imported/hit.wav-27e178036f6cee6545e9f025a3865a36.sample" +path="res://.godot/imported/hit.wav-02ea2b331eef4f150ed1e5cb9477122b.sample" [deps] -source_file="res://assets/audio/sfx/hit.wav" -dest_files=["res://.godot/imported/hit.wav-27e178036f6cee6545e9f025a3865a36.sample"] +source_file="res://enemy/hit.wav" +dest_files=["res://.godot/imported/hit.wav-02ea2b331eef4f150ed1e5cb9477122b.sample"] [params] diff --git a/2d/platformer/game.gd b/2d/platformer/game.gd new file mode 100644 index 00000000..0ec75a89 --- /dev/null +++ b/2d/platformer/game.gd @@ -0,0 +1,24 @@ +class_name Game extends Node + + +@onready var _pause_menu := $InterfaceLayer/PauseMenu as PauseMenu + + +func _unhandled_input(event: InputEvent) -> void: + if event.is_action_pressed(&"toggle_fullscreen"): + var mode := DisplayServer.window_get_mode() + if mode == DisplayServer.WINDOW_MODE_FULLSCREEN or \ + mode == DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN: + DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) + else: + DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN) + get_tree().root.set_input_as_handled() + + elif event.is_action_pressed(&"toggle_pause"): + var tree := get_tree() + tree.paused = not tree.paused + if tree.paused: + _pause_menu.open() + else: + _pause_menu.close() + get_tree().root.set_input_as_handled() diff --git a/2d/platformer/game_singleplayer.tscn b/2d/platformer/game_singleplayer.tscn new file mode 100644 index 00000000..a1688eee --- /dev/null +++ b/2d/platformer/game_singleplayer.tscn @@ -0,0 +1,25 @@ +[gd_scene load_steps=6 format=3 uid="uid://bf3wnwihk7ymg"] + +[ext_resource type="Script" path="res://game.gd" id="2"] +[ext_resource type="PackedScene" uid="uid://dr2p70jo7e4kn" path="res://level/level.tscn" id="3"] +[ext_resource type="PackedScene" uid="uid://d0ni64ucb3ym2" path="res://player/player.tscn" id="4"] +[ext_resource type="PackedScene" uid="uid://c7ai4bigaryci" path="res://gui/pause_menu_singleplayer.tscn" id="4_x6l06"] +[ext_resource type="PackedScene" uid="uid://do7htx4sqmcnh" path="res://music.tscn" id="5_rkna2"] + +[node name="Game" type="Node"] +process_mode = 3 +script = ExtResource("2") + +[node name="Level" parent="." instance=ExtResource("3")] + +[node name="Player" parent="Level" instance=ExtResource("4")] +position = Vector2(90, 546) + +[node name="InterfaceLayer" type="CanvasLayer" parent="."] +layer = 100 + +[node name="PauseMenu" parent="InterfaceLayer" instance=ExtResource("4_x6l06")] + +[node name="Music" parent="." instance=ExtResource("5_rkna2")] + +[connection signal="coin_collected" from="Level/Player" to="InterfaceLayer/PauseMenu" method="_on_coin_collected"] diff --git a/2d/platformer/game_splitscreen.gd b/2d/platformer/game_splitscreen.gd new file mode 100644 index 00000000..c082666f --- /dev/null +++ b/2d/platformer/game_splitscreen.gd @@ -0,0 +1,10 @@ +extends Game + + +func _ready() -> void: + var player_2 := %Player2 as Player + var viewport_1 := %Viewport1 as SubViewport + var viewport_2 := %Viewport2 as SubViewport + viewport_2.world_2d = viewport_1.world_2d + player_2.camera.custom_viewport = viewport_2 + player_2.camera.make_current() diff --git a/2d/platformer/game_splitscreen.tscn b/2d/platformer/game_splitscreen.tscn new file mode 100644 index 00000000..22424c61 --- /dev/null +++ b/2d/platformer/game_splitscreen.tscn @@ -0,0 +1,82 @@ +[gd_scene load_steps=7 format=3 uid="uid://2elur2m0il32"] + +[ext_resource type="Script" path="res://game_splitscreen.gd" id="1_60qgt"] +[ext_resource type="PackedScene" uid="uid://dggactv0aho4p" path="res://gui/pause_menu_splitscreen.tscn" id="2_xkexm"] +[ext_resource type="PackedScene" uid="uid://dr2p70jo7e4kn" path="res://level/level.tscn" id="3_e0nyr"] +[ext_resource type="PackedScene" uid="uid://d0ni64ucb3ym2" path="res://player/player.tscn" id="4_8j0va"] +[ext_resource type="PackedScene" uid="uid://bkyw3e13rupar" path="res://level/parallax_background.tscn" id="5_47vt4"] +[ext_resource type="PackedScene" uid="uid://do7htx4sqmcnh" path="res://music.tscn" id="6_q2yet"] + +[node name="GameSplitscreen" type="Node"] +process_mode = 3 +script = ExtResource("1_60qgt") + +[node name="Black" type="ColorRect" parent="."] +process_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_right = 6.10352e-05 +offset_bottom = 3.05176e-05 +color = Color(0, 0, 0, 1) + +[node name="SplitContainer" type="HSplitContainer" parent="Black"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +dragger_visibility = 1 + +[node name="ViewportContainer1" type="SubViewportContainer" parent="Black/SplitContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +stretch = true + +[node name="Viewport1" type="SubViewport" parent="Black/SplitContainer/ViewportContainer1"] +unique_name_in_owner = true +handle_input_locally = false +canvas_item_default_texture_filter = 0 +audio_listener_enable_2d = true +size = Vector2i(394, 480) +render_target_update_mode = 4 + +[node name="Level" parent="Black/SplitContainer/ViewportContainer1/Viewport1" instance=ExtResource("3_e0nyr")] + +[node name="Player1" parent="Black/SplitContainer/ViewportContainer1/Viewport1" instance=ExtResource("4_8j0va")] +unique_name_in_owner = true +position = Vector2(90, 546) +action_suffix = "_p1" + +[node name="Player2" parent="Black/SplitContainer/ViewportContainer1/Viewport1" instance=ExtResource("4_8j0va")] +unique_name_in_owner = true +position = Vector2(120, 546) +action_suffix = "_p2" + +[node name="ViewportContainer2" type="SubViewportContainer" parent="Black/SplitContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +stretch = true + +[node name="Viewport2" type="SubViewport" parent="Black/SplitContainer/ViewportContainer2"] +unique_name_in_owner = true +handle_input_locally = false +canvas_item_default_texture_filter = 0 +audio_listener_enable_2d = true +size = Vector2i(394, 480) +render_target_update_mode = 4 + +[node name="ParallaxBackground" parent="Black/SplitContainer/ViewportContainer2/Viewport2" instance=ExtResource("5_47vt4")] + +[node name="InterfaceLayer" type="CanvasLayer" parent="."] +layer = 100 + +[node name="PauseMenu" parent="InterfaceLayer" instance=ExtResource("2_xkexm")] + +[node name="Music" parent="." instance=ExtResource("6_q2yet")] + +[connection signal="coin_collected" from="Black/SplitContainer/ViewportContainer1/Viewport1/Player1" to="InterfaceLayer/PauseMenu" method="_on_coin_collected"] +[connection signal="coin_collected" from="Black/SplitContainer/ViewportContainer1/Viewport1/Player2" to="InterfaceLayer/PauseMenu" method="_on_coin_collected"] diff --git a/2d/platformer/gui/coins_counter.gd b/2d/platformer/gui/coins_counter.gd new file mode 100644 index 00000000..a1ff99ab --- /dev/null +++ b/2d/platformer/gui/coins_counter.gd @@ -0,0 +1,16 @@ +class_name CoinsCounter extends Panel + + +var _coins_collected: int = 0 + +@onready var _coins_label := $Label as Label + + +func _ready() -> void: + _coins_label.set_text(str(_coins_collected)) + ($AnimatedSprite2D as AnimatedSprite2D).play() + + +func collect_coin() -> void: + _coins_collected += 1 + _coins_label.set_text(str(_coins_collected)) diff --git a/2d/platformer/gui/coins_counter.tscn b/2d/platformer/gui/coins_counter.tscn new file mode 100644 index 00000000..4a904a29 --- /dev/null +++ b/2d/platformer/gui/coins_counter.tscn @@ -0,0 +1,70 @@ +[gd_scene load_steps=9 format=3 uid="uid://bsyqg6eh3wl5i"] + +[ext_resource type="Theme" uid="uid://da4noqsij73it" path="res://gui/theme.tres" id="1"] +[ext_resource type="Texture2D" uid="uid://l42us5qso8v4" path="res://level/coin.webp" id="2"] +[ext_resource type="Script" path="res://gui/coins_counter.gd" id="3"] + +[sub_resource type="AtlasTexture" id="2"] +atlas = ExtResource("2") +region = Rect2(0, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="3"] +atlas = ExtResource("2") +region = Rect2(8, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="4"] +atlas = ExtResource("2") +region = Rect2(16, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="5"] +atlas = ExtResource("2") +region = Rect2(24, 0, 8, 8) + +[sub_resource type="SpriteFrames" id="6"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("2") +}, { +"duration": 1.0, +"texture": SubResource("3") +}, { +"duration": 1.0, +"texture": SubResource("4") +}, { +"duration": 1.0, +"texture": SubResource("5") +}, { +"duration": 1.0, +"texture": SubResource("4") +}, { +"duration": 1.0, +"texture": SubResource("3") +}], +"loop": true, +"name": &"coin_spinning", +"speed": 6.5 +}] + +[node name="CoinsCounter" type="Panel"] +offset_left = 5.0 +offset_top = 5.0 +offset_right = 100.0 +offset_bottom = 45.0 +theme = ExtResource("1") +script = ExtResource("3") + +[node name="Label" type="Label" parent="."] +layout_mode = 0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_right = -8.0 +text = "100" +horizontal_alignment = 2 +vertical_alignment = 1 + +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] +position = Vector2(21.5, 22.5) +scale = Vector2(4.375, 4.375) +sprite_frames = SubResource("6") +animation = &"coin_spinning" diff --git a/2d/platformer/assets/theme/fonts/kenney_mini_square.ttf b/2d/platformer/gui/kenney_mini_square.ttf similarity index 100% rename from 2d/platformer/assets/theme/fonts/kenney_mini_square.ttf rename to 2d/platformer/gui/kenney_mini_square.ttf diff --git a/2d/platformer/assets/theme/fonts/kenney_mini_square.ttf.import b/2d/platformer/gui/kenney_mini_square.ttf.import similarity index 61% rename from 2d/platformer/assets/theme/fonts/kenney_mini_square.ttf.import rename to 2d/platformer/gui/kenney_mini_square.ttf.import index 32284136..c5ebd6c6 100644 --- a/2d/platformer/assets/theme/fonts/kenney_mini_square.ttf.import +++ b/2d/platformer/gui/kenney_mini_square.ttf.import @@ -3,12 +3,12 @@ importer="font_data_dynamic" type="FontFile" uid="uid://bk80b6owsrioj" -path="res://.godot/imported/kenney_mini_square.ttf-d79fb84878832e276f7b282a10aa19c8.fontdata" +path="res://.godot/imported/kenney_mini_square.ttf-14b0a28a89225c31efd7626f5228f467.fontdata" [deps] -source_file="res://assets/theme/fonts/kenney_mini_square.ttf" -dest_files=["res://.godot/imported/kenney_mini_square.ttf-d79fb84878832e276f7b282a10aa19c8.fontdata"] +source_file="res://gui/kenney_mini_square.ttf" +dest_files=["res://.godot/imported/kenney_mini_square.ttf-14b0a28a89225c31efd7626f5228f467.fontdata"] [params] @@ -18,6 +18,7 @@ generate_mipmaps=false multichannel_signed_distance_field=false msdf_pixel_range=8 msdf_size=48 +allow_system_fallback=true force_autohinter=false hinting=1 subpixel_positioning=1 diff --git a/2d/platformer/gui/pause_menu.gd b/2d/platformer/gui/pause_menu.gd new file mode 100644 index 00000000..0aecfbff --- /dev/null +++ b/2d/platformer/gui/pause_menu.gd @@ -0,0 +1,77 @@ +class_name PauseMenu extends Control + + +@export var fade_in_duration := 0.3 +@export var fade_out_duration := 0.2 + +@onready var center_cont := $ColorRect/CenterContainer as CenterContainer +@onready var resume_button := center_cont.get_node(^"VBoxContainer/ResumeButton") as Button +@onready var coins_counter := $ColorRect/CoinsCounter as CoinsCounter + + +func _ready(): + hide() + + +func close(): + var tween := create_tween() + get_tree().paused = false + tween.tween_property( + self, + ^"modulate:a", + 0.0, + fade_out_duration + ).set_trans(Tween.TRANS_LINEAR).set_ease(Tween.EASE_OUT) + tween.parallel().tween_property( + center_cont, + ^"anchor_bottom", + 0.5, + fade_out_duration + ).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT) + tween.tween_callback(hide) + + +func open(): + show() + resume_button.grab_focus() + + modulate.a = 0.0 + center_cont.anchor_bottom = 0.5 + var tween := create_tween() + tween.tween_property( + self, + ^"modulate:a", + 1.0, + fade_in_duration + ).set_trans(Tween.TRANS_LINEAR).set_ease(Tween.EASE_IN) + tween.parallel().tween_property( + center_cont, + ^"anchor_bottom", + 1.0, + fade_out_duration + ).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT) + + +func _on_coin_collected() -> void: + coins_counter.collect_coin() + + +func _on_resume_button_pressed(): + close() + + +func _on_singleplayer_button_pressed() -> void: + if visible: + get_tree().paused = false + get_tree().change_scene_to_file("res://game_singleplayer.tscn") + + +func _on_splitscreen_button_pressed() -> void: + if visible: + get_tree().paused = false + get_tree().change_scene_to_file("res://game_splitscreen.tscn") + + +func _on_quit_button_pressed(): + if visible: + get_tree().quit() diff --git a/2d/platformer/src/UserInterface/PauseMenu.tscn b/2d/platformer/gui/pause_menu.tscn similarity index 58% rename from 2d/platformer/src/UserInterface/PauseMenu.tscn rename to 2d/platformer/gui/pause_menu.tscn index 3b480f85..b77f1311 100644 --- a/2d/platformer/src/UserInterface/PauseMenu.tscn +++ b/2d/platformer/gui/pause_menu.tscn @@ -1,8 +1,8 @@ -[gd_scene load_steps=4 format=3 uid="uid://0oqbyhiw1abi"] +[gd_scene load_steps=4 format=3 uid="uid://dh71g61cm8k44"] -[ext_resource type="Theme" uid="uid://chubprkmexsng" path="res://assets/theme/user_interface.tres" id="1"] -[ext_resource type="Script" path="res://src/UserInterface/PauseMenu.gd" id="2"] -[ext_resource type="PackedScene" path="res://src/UserInterface/CoinsCounter.tscn" id="4"] +[ext_resource type="Theme" uid="uid://da4noqsij73it" path="res://gui/theme.tres" id="1"] +[ext_resource type="Script" path="res://gui/pause_menu.gd" id="2"] +[ext_resource type="PackedScene" uid="uid://bsyqg6eh3wl5i" path="res://gui/coins_counter.tscn" id="4"] [node name="PauseMenu" type="Control"] process_mode = 3 @@ -10,6 +10,8 @@ layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 theme = ExtResource("1") script = ExtResource("2") @@ -18,64 +20,46 @@ layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 color = Color(0, 0, 0, 0.294118) [node name="CenterContainer" type="CenterContainer" parent="ColorRect"] layout_mode = 1 -anchors_preset = 15 +anchors_preset = -1 anchor_right = 1.0 anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 [node name="VBoxContainer" type="VBoxContainer" parent="ColorRect/CenterContainer"] layout_mode = 2 -offset_left = 347.0 -offset_top = 194.0 -offset_right = 453.0 -offset_bottom = 285.0 alignment = 1 [node name="Label" type="Label" parent="ColorRect/CenterContainer/VBoxContainer"] layout_mode = 2 -offset_right = 106.0 -offset_bottom = 23.0 text = "Game Paused" +horizontal_alignment = 1 [node name="MarginContainer" type="MarginContainer" parent="ColorRect/CenterContainer/VBoxContainer"] layout_mode = 2 -offset_top = 27.0 -offset_right = 106.0 -offset_bottom = 27.0 [node name="ResumeButton" type="Button" parent="ColorRect/CenterContainer/VBoxContainer"] layout_mode = 2 -offset_left = 16.0 -offset_top = 31.0 -offset_right = 90.0 -offset_bottom = 59.0 size_flags_horizontal = 4 text = "Resume" [node name="QuitButton" type="Button" parent="ColorRect/CenterContainer/VBoxContainer"] layout_mode = 2 -offset_left = 31.0 -offset_top = 63.0 -offset_right = 75.0 -offset_bottom = 91.0 size_flags_horizontal = 4 text = "Quit" [node name="CoinsCounter" parent="ColorRect" instance=ExtResource("4")] layout_mode = 0 +offset_left = 0.0 +offset_top = 0.0 offset_right = 105.0 offset_bottom = 50.0 -[node name="Tween" type="Tween" parent="."] -_import_path = NodePath("") -unique_name_in_owner = false -process_mode = 0 -process_priority = 0 -editor_description = "" -script = null - -[connection signal="pressed" from="ColorRect/CenterContainer/VBoxContainer/ResumeButton" to="." method="_on_ResumeButton_pressed"] -[connection signal="pressed" from="ColorRect/CenterContainer/VBoxContainer/QuitButton" to="." method="_on_QuitButton_pressed"] +[connection signal="pressed" from="ColorRect/CenterContainer/VBoxContainer/ResumeButton" to="." method="_on_resume_button_pressed"] +[connection signal="pressed" from="ColorRect/CenterContainer/VBoxContainer/QuitButton" to="." method="_on_quit_button_pressed"] diff --git a/2d/platformer/gui/pause_menu_singleplayer.tscn b/2d/platformer/gui/pause_menu_singleplayer.tscn new file mode 100644 index 00000000..8eb0b73d --- /dev/null +++ b/2d/platformer/gui/pause_menu_singleplayer.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=2 format=3 uid="uid://c7ai4bigaryci"] + +[ext_resource type="PackedScene" uid="uid://dh71g61cm8k44" path="res://gui/pause_menu.tscn" id="1_pwe1t"] + +[node name="PauseMenu" instance=ExtResource("1_pwe1t")] + +[node name="SplitscreenButton" type="Button" parent="ColorRect/CenterContainer/VBoxContainer" index="3"] +layout_mode = 2 +text = "Change to 2-Player" + +[connection signal="pressed" from="ColorRect/CenterContainer/VBoxContainer/SplitscreenButton" to="." method="_on_splitscreen_button_pressed"] diff --git a/2d/platformer/gui/pause_menu_splitscreen.tscn b/2d/platformer/gui/pause_menu_splitscreen.tscn new file mode 100644 index 00000000..d027bdbb --- /dev/null +++ b/2d/platformer/gui/pause_menu_splitscreen.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=2 format=3 uid="uid://dggactv0aho4p"] + +[ext_resource type="PackedScene" uid="uid://dh71g61cm8k44" path="res://gui/pause_menu.tscn" id="1_x3hgi"] + +[node name="PauseMenu" instance=ExtResource("1_x3hgi")] + +[node name="SingleplayerButton" type="Button" parent="ColorRect/CenterContainer/VBoxContainer" index="3"] +layout_mode = 2 +text = "Change to 1-player" + +[connection signal="pressed" from="ColorRect/CenterContainer/VBoxContainer/SingleplayerButton" to="." method="_on_singleplayer_button_pressed"] diff --git a/2d/platformer/assets/theme/user_interface.tres b/2d/platformer/gui/theme.tres similarity index 94% rename from 2d/platformer/assets/theme/user_interface.tres rename to 2d/platformer/gui/theme.tres index 9218df04..d4626865 100644 --- a/2d/platformer/assets/theme/user_interface.tres +++ b/2d/platformer/gui/theme.tres @@ -1,6 +1,6 @@ -[gd_resource type="Theme" load_steps=7 format=3 uid="uid://chubprkmexsng"] +[gd_resource type="Theme" load_steps=7 format=3 uid="uid://da4noqsij73it"] -[ext_resource type="FontFile" uid="uid://bk80b6owsrioj" path="res://assets/theme/fonts/kenney_mini_square.ttf" id="1_f0sjs"] +[ext_resource type="FontFile" uid="uid://bk80b6owsrioj" path="res://gui/kenney_mini_square.ttf" id="1_f0sjs"] [sub_resource type="StyleBoxFlat" id="1"] content_margin_left = 6.0 diff --git a/2d/platformer/gui/touch_button_fire.webp b/2d/platformer/gui/touch_button_fire.webp new file mode 100644 index 0000000000000000000000000000000000000000..563205d6796d9bbdd46f50f5d67db01a90ae712c GIT binary patch literal 930 zcmV;T16}-5Nk&GR0{{S5MM6+kP&iDE0{{RoKfn(Vzhoe7oA}rKy*3P_Z4>{R|J6X+ zHu10dUm>=QEnDqE?ERVw?x zP)S<_l`5!wn<@~g-=+dp`#YsXxw~75ph8uoK$S>QQ`vs1D%Do1D!*+?Pz6=_ZL2~> zRf&}Cw?s-cl}Hs-iIkM6N(C@jzyRPM7Y7%EKfuAo0N@+{fCCsT{_%muF9r|%U;&Fw zFlZae(X_j7^Zfblk%;L31OOm0&6(jgfmHvE#?=v}b)3^4JPAs+?I@C@|0VN`%winY zuouVND=22JH8NwAoAeuH9zN=xMZ^T)|I54ccH4WvTia}=AJ=y4{QDX8>HMt~J^1+g zGnU*xap=2sTz~NeOYfcjeFb-3e84UbpWfN_33k2R(To+&yLi;G%Km7vZ-kZVo24A1 z5(E$g2jB}$s7sk4h@d;k8m2||QI?_yqyU_RH&+e&3+x{ZL@0tYL`-t$(82!L5tNk~ zJtQ+Kll11P8jcLz!$?QBBoi>nvSA4KMlMxILSID6Xh13{Q6O2mH1P2Ein$Zn8>S=x z$Y%5gx?Ab@hqar(RNSVG(~TgEN(jpE&17EsFJxOaWC`nM#C1%9JYbG{QPmnkrs_ds68cC=zC2mdrraD^rDrhNhmhEsW9zL!CFt#wsfF#qqF#Pyo z4R1#1-prT*xGA#-hu&cD-U#Syrip-NW>;YN-U!Z)HG|QCP$K)-Sqz^z7yxN*ASGm^ zG;;9O*w<%90D=Sn3BvHXi(|m&p`Culvh#XoEFEhJEdGe=;G^a6O0ssJ4MM6+kP&iB!0ssInKfn(VKjN^BBt?#S=$QT)wvD7X^Mk*!FHB~v+bDcA#ROd{@K<7-xNTmcoPyhh{2Zmq-8$d7u z00s_#0D{87i^4+CF;M`80xa3KO;9K`Y2F5+_WY#LW7h*#z1>5TeFxZe_BvdKAZmCK+X7KJ7AphM zR%ii)ye|;&<$-7+@tOc3=~7B5R}zROFTOG0su5)=QU$y*+YE5Uph5~30dK~%23*FY z&^#HyTeF-27k4NkM;!3Z4DUXw5>|}D6;%H%yRG0?to#MhO*g=#+=`hy1z0!A3Q>#N z6+3&hhFB4vO=P%)l&DbAs`YE>nA+&Mts7l#5ohJ(SL_er8HUslfXYu z2|l~yW0qAGlLc01%*KojW@^S1GcaR->6+2SG|XsV>SoljJM-iID=l|- zGw%2n&xA3t-ZSAyt#|cnKB@J-ek*djqu-6*YU{S^Mk*!FHB~v+bDcA#ROd{@K<7-xNTmcoPyhh{2Zmq-8$d7u z00s_#0D{87i^4+CF;M`80xa2f(@4=UHV?C!nVEV2Ynnuno(KOT`tQhXBS)fVX5+Dg z`wQOxCCf>-R?4N*xl*k=S;EcQc@9awJp@( zFd!X^U4tQM?DXm^d9hq|wH8Z~w`@sEsn3#!BOC6k%vth$Mn*hW*q0?A*JM`S+rEpD z5B94SOKuJjcon86c{(A8UWjd0@OD8M*{y8Kf(U`|R6F7m1XCBSIq2>Xhu5kx`+Q13 zbIBm!{fdH;_ony^B+Y;*q2kk&RQyteRgn~Z9*@C_lFX;qa{|jq(x2j&Xle1`=kQSs zd~o-5#m!$TigA|$Yih=Q6l);PJNUc_pLc6F^L8z-J1*9Zx^~@5;7rx)ZiJkyyIv2! zZudg>9sItr3g7q8`&Qq!@5ac*zU$4g`}SPdJCMDhukAg!-qJ$!uB1sF)B9dbz0Y;; Ybl!WN_iop{-}$-2@wvzKx$Dmw4>gSmSpWb4 literal 0 HcmV?d00001 diff --git a/2d/platformer/assets/art/ui/touch_button_left.png.import b/2d/platformer/gui/touch_button_left.webp.import similarity index 66% rename from 2d/platformer/assets/art/ui/touch_button_left.png.import rename to 2d/platformer/gui/touch_button_left.webp.import index 421ef162..b0441f10 100644 --- a/2d/platformer/assets/art/ui/touch_button_left.png.import +++ b/2d/platformer/gui/touch_button_left.webp.import @@ -3,22 +3,22 @@ importer="texture" type="CompressedTexture2D" uid="uid://byv1xhmnegdap" -path="res://.godot/imported/touch_button_left.png-e48f16cfdaae98fdc92a21f20c157c53.ctex" +path="res://.godot/imported/touch_button_left.webp-f44154539d59fd4f5b3597e8703bbc6a.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/art/ui/touch_button_left.png" -dest_files=["res://.godot/imported/touch_button_left.png-e48f16cfdaae98fdc92a21f20c157c53.ctex"] +source_file="res://gui/touch_button_left.webp" +dest_files=["res://.godot/imported/touch_button_left.webp-f44154539d59fd4f5b3597e8703bbc6a.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/platformer/gui/touch_button_right.webp b/2d/platformer/gui/touch_button_right.webp new file mode 100644 index 0000000000000000000000000000000000000000..a60b669f3975ea8523f64e41b308a49e7195769a GIT binary patch literal 538 zcmV+#0_FWuNk&Ez0ssJ4MM6+kP&iBm0ssInKfn(VKjN^BBt?#S=$QT)wvD7X^Mk*!FHB~v+bDcA#ROd{@K<7-xNTmcoPyhh{2Zmq-8$d7u z00s_#0D{87i^4+CF;M`80xa2f(@4?uFf*gl%*>4YU(+PA{51F%(SJv7+ei}Kv(GU} zrN0pTUosoE%K3B{rt{_2a0WMSWZ02RV+^$H=UJ6}e+e?kvO3uT!nDL*DNVig*gHK> zO$MatV_juPs%yOpdw5|f6}3A1xV>U2b)^pb*?wRt9hC`tqWx!sC|u6Pv!7h<$IR6n+bnbWV1{3VLJ<;tQ$i1PX-Ft9*OI^Qrq4uVV$=>%O c?|s&Lr}^G%zIR*i{pR-_#`ite_g#P11fBv6eEhtD3Pjj#TU%BPJ?dktB7oBXMu(PsleOCD*hURMwd0VuiYJdhNTsi9oG@ZXB$S;^d zT*WD=yr!xz3(_#mShKu0`8NK*46ZA`u7I@ zy0ZZZkDknTRQ2uSn$$UyTS!RZrMvr=4Hb?rT36a;FdkXNS}og^azRQZBQ#X8r) zcGrys3%15DZLsfakmCH{zGes4Ua9}GAMOiQPM#}qZbc(6*CrK_-bGPc6_!mGb-1xU z#9_f@F4Ik6Hx3K2-rm1p=ML}Xrq`0+FPpzvB*nk5Jbm8E2krguHtqlY-(zN`Xw>)2 rt@rMIl>hOrX79s`#j-!{Su-%cOWeGraM@B|*fV&#`njxgN@xNAbGht* diff --git a/2d/platformer/icon.webp b/2d/platformer/icon.webp new file mode 100644 index 0000000000000000000000000000000000000000..14a20244077d74e01f6723e0e9842a4c2f8bc660 GIT binary patch literal 1212 zcmWIYbaUIn!oU#j>J$(bU=hK^z`$St#Pwk0>FgY^fCVF%>$ax6aitUfY>!4c5Y57&~0D<@*z)Z zUT83oRsmue26qNe2498%1_g#BhEj%1h8%_x23;VX2NWr02m;DG;m|Jy)*k@Wl?2q4 z$&d`x;lhy5kjsz=*3STn1E3lpK!j~^nz0dBh>^#Mfr0hj|Noy=85r0nGcf#}@c;ks zh5!HmUBtk^e20PIKpsMW{sIODi?2ZO2?#Nj`3wyFEes6Xjv&O6rZX^XZ)aeTxLJ@` zlnAzm8Avjvr7Re1U<1D;g4RKsk^+!{X}<3?aa<@;S@EFmo0IgIYS! z>=+#W<^XDdhZ|ls(C`DMT%Wg$3=I192jm6bA5fdL)-Mp0`;u*Ar zN9F;`dI={ssdsz#pVpY9;`%cF!mbcRj2_ScVQ z$XtK&Tkr9UUek(oXYJCLhIsXSc<6Mzzp;VW-tJCDhlfQnhowr8->N>wrrg_JvnxC% z@4Eemo$LMQpI5_e)ffHmyWj>z}pQj(P5`oO@fQ`!&k!V0m@) zq5l3Y8DU#OUdvpO*}?GY$iw-}tNb0lEU;VkdDSBWSDvQY(4QY!R$L2=?Fo}xrordG zPv`2qW|OS__qz{I(4T$rRq4@JD^@-0&XSow-SS&3<6ghJtA854U7G$N^?Yry`_}4> z-?Ap{iEwW|@aj_*d(PDpjrt-`j>ycKX-nu^r^okbnQgZ+G_m$H(`tdi*GR zXUO*0+1u9swkze_Qor^dSH|~Cj%ORCzkUtKeJ=9jkM{rf3)lLEu9cr>cJ8VS!w#lf cTKdnw9=`mnK74+C{{Q;<^Q(d6{Y(Z109T8A)c^nh literal 0 HcmV?d00001 diff --git a/2d/platformer/icon.png.import b/2d/platformer/icon.webp.import similarity index 70% rename from 2d/platformer/icon.png.import rename to 2d/platformer/icon.webp.import index 6fc13e7e..d4ea02ae 100644 --- a/2d/platformer/icon.png.import +++ b/2d/platformer/icon.webp.import @@ -3,22 +3,22 @@ importer="texture" type="CompressedTexture2D" uid="uid://dpxlcfssx0etu" -path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" +path="res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://icon.png" -dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] +source_file="res://icon.webp" +dest_files=["res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/platformer/level/cloud_1.webp b/2d/platformer/level/cloud_1.webp new file mode 100644 index 0000000000000000000000000000000000000000..fa38f59389eebe367c3e1ec4cb2297b05d23dd63 GIT binary patch literal 138 zcmV;50CoRTNk&G300012MM6+kP&iC>0000lKfnhN3P_P8Igh{b!|tH1jWT09*FNo< spkl~TH_)yD=!A_Xij7NDjVp9=_z|D$OF&hPvKd=;OC@6ntu(KYXbR(Tukat>ajRj5#ShgMaoH1YP^mcQXnak^N+SbLY2{kE3f&G>dgPUR QQHJ9==vJK3_nvGkQ+@H@J!v_}uPu zwfjE--{}v0_wm2DrX_c@>jD!DIZ}hlkOR%8hHU9oSF&M}nU=5@m6jAA+C)o@=(aL+ KpI0NF#~%PJxhy9D literal 0 HcmV?d00001 diff --git a/2d/platformer/assets/art/background/cloud_3.png.import b/2d/platformer/level/cloud_3.webp.import similarity index 68% rename from 2d/platformer/assets/art/background/cloud_3.png.import rename to 2d/platformer/level/cloud_3.webp.import index b5af3c62..36e00ff6 100644 --- a/2d/platformer/assets/art/background/cloud_3.png.import +++ b/2d/platformer/level/cloud_3.webp.import @@ -3,22 +3,22 @@ importer="texture" type="CompressedTexture2D" uid="uid://5tho6j8r4eam" -path="res://.godot/imported/cloud_3.png-a1b7dc71aa84bea9cb4f78f585dcc65d.ctex" +path="res://.godot/imported/cloud_3.webp-a303ee6af47d3df137be263a98a9fa7d.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/art/background/cloud_3.png" -dest_files=["res://.godot/imported/cloud_3.png-a1b7dc71aa84bea9cb4f78f585dcc65d.ctex"] +source_file="res://level/cloud_3.webp" +dest_files=["res://.godot/imported/cloud_3.webp-a303ee6af47d3df137be263a98a9fa7d.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/platformer/level/coin.gd b/2d/platformer/level/coin.gd new file mode 100644 index 00000000..152cfb1e --- /dev/null +++ b/2d/platformer/level/coin.gd @@ -0,0 +1,10 @@ +class_name Coin extends Area2D +## Collectible that disappears when the player touches it. + + +@onready var animation_player := $AnimationPlayer as AnimationPlayer + + +func _on_body_entered(body: Node2D) -> void: + animation_player.play(&"picked") + (body as Player).coin_collected.emit() diff --git a/2d/platformer/src/Objects/Coin.tscn b/2d/platformer/level/coin.tscn similarity index 59% rename from 2d/platformer/src/Objects/Coin.tscn rename to 2d/platformer/level/coin.tscn index e4ec37b1..62df1f9a 100644 --- a/2d/platformer/src/Objects/Coin.tscn +++ b/2d/platformer/level/coin.tscn @@ -1,19 +1,71 @@ -[gd_scene load_steps=7 format=2] +[gd_scene load_steps=9 format=3 uid="uid://b2xsfn7h7komw"] -[ext_resource path="res://assets/art/coin/coin.png" type="Texture2D" id=2] -[ext_resource path="res://assets/audio/sfx/coin_pickup.wav" type="AudioStream" id=3] -[ext_resource path="res://src/Objects/Coin.gd" type="Script" id=4] +[ext_resource type="Texture2D" uid="uid://l42us5qso8v4" path="res://level/coin.webp" id="2"] +[ext_resource type="AudioStream" uid="uid://bw67pgdlhpqd0" path="res://player/coin_pickup.wav" id="3"] +[ext_resource type="Script" path="res://level/coin.gd" id="4"] -[sub_resource type="Animation" id=1] +[sub_resource type="Animation" id="Animation_mfug7"] +resource_name = "RESET" +length = 0.01 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:monitoring") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Sprite2D:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(0, 0)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Sprite2D:frame") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Sprite2D:self_modulate") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(1, 1, 1, 1)] +} + +[sub_resource type="Animation" id="1"] resource_name = "picked" length = 1.5 step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), @@ -21,25 +73,25 @@ tracks/0/keys = { "values": [0] } tracks/1/type = "method" +tracks/1/imported = false +tracks/1/enabled = true tracks/1/path = NodePath(".") tracks/1/interp = 1 tracks/1/loop_wrap = true -tracks/1/imported = false -tracks/1/enabled = true tracks/1/keys = { -"times": PackedFloat32Array(1), +"times": PackedFloat32Array(1.5), "transitions": PackedFloat32Array(1), "values": [{ "args": [], -"method": "queue_free" +"method": &"queue_free" }] } tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true tracks/2/path = NodePath("Sprite2D:self_modulate") tracks/2/interp = 1 tracks/2/loop_wrap = true -tracks/2/imported = false -tracks/2/enabled = true tracks/2/keys = { "times": PackedFloat32Array(0.25, 1.25), "transitions": PackedFloat32Array(1, 1), @@ -47,52 +99,55 @@ tracks/2/keys = { "values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0)] } tracks/3/type = "value" -tracks/3/path = NodePath("Pickup:playing") -tracks/3/interp = 1 -tracks/3/loop_wrap = true tracks/3/imported = false tracks/3/enabled = true +tracks/3/path = NodePath(".:monitoring") +tracks/3/interp = 1 +tracks/3/loop_wrap = true tracks/3/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), -"update": 2, -"values": [true] -} -tracks/4/type = "value" -tracks/4/path = NodePath(".:monitoring") -tracks/4/interp = 1 -tracks/4/loop_wrap = true -tracks/4/imported = false -tracks/4/enabled = true -tracks/4/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), "update": 1, "values": [false] } -tracks/5/type = "value" -tracks/5/path = NodePath("Sprite2D:position") -tracks/5/interp = 1 -tracks/5/loop_wrap = true -tracks/5/imported = false -tracks/5/enabled = true -tracks/5/keys = { +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Sprite2D:position") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { "times": PackedFloat32Array(0, 1.5), "transitions": PackedFloat32Array(1, 1), "update": 0, "values": [Vector2(0, 0), Vector2(0, -42)] } +tracks/5/type = "audio" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Pickup") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"clips": [{ +"end_offset": 0.0, +"start_offset": 0.0, +"stream": ExtResource("3") +}], +"times": PackedFloat32Array(0) +} +tracks/5/use_blend = true -[sub_resource type="Animation" id=2] +[sub_resource type="Animation" id="2"] length = 1.5 -loop = true +loop_mode = 1 step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0, 0.25, 0.5, 0.75, 1, 1.25, 1.5), "transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1), @@ -100,11 +155,11 @@ tracks/0/keys = { "values": [0, 1, 2, 3, 2, 1, 0] } tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true tracks/1/path = NodePath("Sprite2D:position") tracks/1/interp = 1 tracks/1/loop_wrap = true -tracks/1/imported = false -tracks/1/enabled = true tracks/1/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), @@ -112,11 +167,11 @@ tracks/1/keys = { "values": [Vector2(0, 0)] } tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true tracks/2/path = NodePath("Sprite2D:self_modulate") tracks/2/interp = 1 tracks/2/loop_wrap = true -tracks/2/imported = false -tracks/2/enabled = true tracks/2/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), @@ -124,11 +179,11 @@ tracks/2/keys = { "values": [Color(1, 1, 1, 1)] } tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true tracks/3/path = NodePath(".:monitoring") tracks/3/interp = 1 tracks/3/loop_wrap = true -tracks/3/imported = false -tracks/3/enabled = true tracks/3/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), @@ -136,29 +191,33 @@ tracks/3/keys = { "values": [true] } -[sub_resource type="CircleShape2D" id=3] +[sub_resource type="AnimationLibrary" id="AnimationLibrary_fwb0h"] +_data = { +"RESET": SubResource("Animation_mfug7"), +"picked": SubResource("1"), +"spinning": SubResource("2") +} + +[sub_resource type="CircleShape2D" id="3"] radius = 5.0 [node name="Coin" type="Area2D"] collision_layer = 0 -monitoring = false -monitorable = false -script = ExtResource( 4 ) +script = ExtResource("4") [node name="Sprite2D" type="Sprite2D" parent="."] -texture = ExtResource( 2 ) +texture = ExtResource("2") hframes = 4 [node name="AnimationPlayer" type="AnimationPlayer" parent="."] autoplay = "spinning" -playback_speed = 1.5 -anims/picked = SubResource( 1 ) -anims/spinning = SubResource( 2 ) +libraries = { +"": SubResource("AnimationLibrary_fwb0h") +} [node name="CollisionShape2D" type="CollisionShape2D" parent="."] -shape = SubResource( 3 ) +shape = SubResource("3") [node name="Pickup" type="AudioStreamPlayer2D" parent="."] -stream = ExtResource( 3 ) [connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/2d/platformer/level/coin.webp b/2d/platformer/level/coin.webp new file mode 100644 index 0000000000000000000000000000000000000000..e508c603fc7df5c05a82411a2a2ec90cee03843d GIT binary patch literal 148 zcmV;F0BiqJNk&GD00012MM6+kP&iC~0000lAHV?+632}sNs9mfHD`b80bcOsd&ATU zOvn~0b#cmQ+cy8d+HSbe2H8fsoyT##;w=BN{}TW^S;bhjJdqoTHe=bIw!#rLr=w~p z+grB-wLG0^3+!pnR{yiVC)I5cK|K{;M7LLbPl;{|FHbA4c_6j}5Qm451QA8h82|uE C96u}o literal 0 HcmV?d00001 diff --git a/2d/platformer/assets/art/coin/coin.png.import b/2d/platformer/level/coin.webp.import similarity index 70% rename from 2d/platformer/assets/art/coin/coin.png.import rename to 2d/platformer/level/coin.webp.import index 2be6965e..f460a7eb 100644 --- a/2d/platformer/assets/art/coin/coin.png.import +++ b/2d/platformer/level/coin.webp.import @@ -3,22 +3,22 @@ importer="texture" type="CompressedTexture2D" uid="uid://l42us5qso8v4" -path="res://.godot/imported/coin.png-87689993f83db6056500d4fa153313d8.ctex" +path="res://.godot/imported/coin.webp-1d50c095672512acb2df6e9dbf7e85c6.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/art/coin/coin.png" -dest_files=["res://.godot/imported/coin.png-87689993f83db6056500d4fa153313d8.ctex"] +source_file="res://level/coin.webp" +dest_files=["res://.godot/imported/coin.webp-1d50c095672512acb2df6e9dbf7e85c6.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/platformer/level/distant_platforms_1.webp b/2d/platformer/level/distant_platforms_1.webp new file mode 100644 index 0000000000000000000000000000000000000000..8f83fec3453ffb97ef4e4afbfb937396375014eb GIT binary patch literal 3602 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 literal 0 HcmV?d00001 diff --git a/2d/platformer/assets/art/background/distant_platforms_2.png.import b/2d/platformer/level/distant_platforms_2.webp.import similarity index 65% rename from 2d/platformer/assets/art/background/distant_platforms_2.png.import rename to 2d/platformer/level/distant_platforms_2.webp.import index 5583686d..1593f330 100644 --- a/2d/platformer/assets/art/background/distant_platforms_2.png.import +++ b/2d/platformer/level/distant_platforms_2.webp.import @@ -3,22 +3,22 @@ importer="texture" type="CompressedTexture2D" uid="uid://d003shl6ntver" -path="res://.godot/imported/distant_platforms_2.png-ba010b30987da6d74062ce964ab450ef.ctex" +path="res://.godot/imported/distant_platforms_2.webp-cfb64fd24d51633ea9b69670abc2c765.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/art/background/distant_platforms_2.png" -dest_files=["res://.godot/imported/distant_platforms_2.png-ba010b30987da6d74062ce964ab450ef.ctex"] +source_file="res://level/distant_platforms_2.webp" +dest_files=["res://.godot/imported/distant_platforms_2.webp-cfb64fd24d51633ea9b69670abc2c765.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/platformer/level/level.tscn b/2d/platformer/level/level.tscn new file mode 100644 index 00000000..69365f63 --- /dev/null +++ b/2d/platformer/level/level.tscn @@ -0,0 +1,284 @@ +[gd_scene load_steps=12 format=3 uid="uid://dr2p70jo7e4kn"] + +[ext_resource type="TileSet" uid="uid://dmpguegs1kkkl" path="res://level/tileset.tres" id="1"] +[ext_resource type="PackedScene" uid="uid://bd478yrtijbfn" path="res://enemy/enemy.tscn" id="2"] +[ext_resource type="PackedScene" uid="uid://bfylfwu4pwywv" path="res://level/platform.tscn" id="3"] +[ext_resource type="PackedScene" uid="uid://b2xsfn7h7komw" path="res://level/coin.tscn" id="4"] +[ext_resource type="Texture2D" uid="uid://8p65ui1ydnff" path="res://level/moving_platform.webp" id="6"] +[ext_resource type="PackedScene" uid="uid://bkyw3e13rupar" path="res://level/parallax_background.tscn" id="7"] + +[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_vsviu"] +normal = Vector2(1, 0) + +[sub_resource type="Animation" id="1"] +resource_name = "move" +length = 4.0 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(707, 400), Vector2(566, 303)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_twp1p"] +_data = { +"move": SubResource("1") +} + +[sub_resource type="Animation" id="2"] +length = 8.0 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 4), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(-47, 80), Vector2(-47, 407)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_61huy"] +_data = { +"move": SubResource("2") +} + +[node name="Level" type="Node2D"] +process_mode = 1 + +[node name="TileMap" type="TileMap" parent="."] +tile_set = ExtResource("1") +format = 2 +layer_0/tile_data = PackedInt32Array(-65546, 1, 65536, -65545, 1, 0, -131044, 1, 65536, -131043, 1, 0, -10, 3, 65536, -9, 3, 0, -65508, 3, 65536, -65507, 3, 0, 65526, 3, 65536, 65527, 3, 0, 28, 3, 65536, 29, 3, 0, 131062, 3, 65536, 131063, 3, 0, 131069, 6, 65536, 131070, 5, 0, 131071, 5, 0, 65536, 5, 0, 65537, 5, 0, 65538, 5, 0, 65539, 5, 0, 65540, 6, 0, 65564, 3, 65536, 65565, 3, 0, 196598, 3, 65536, 196599, 3, 0, 131080, 1, 65536, 131081, 0, 0, 131082, 0, 0, 131083, 0, 0, 131084, 0, 0, 131085, 1, 0, 131100, 3, 65536, 131101, 3, 0, 262134, 3, 65536, 262135, 3, 0, 196616, 9, 65536, 196617, 8, 0, 196618, 8, 0, 196619, 8, 0, 196620, 8, 0, 196621, 9, 0, 196626, 1, 65536, 196627, 0, 0, 196628, 0, 0, 196629, 0, 0, 196630, 0, 0, 196631, 0, 0, 196632, 0, 0, 196633, 0, 0, 196634, 0, 0, 196635, 0, 0, 196636, 4, 65536, 196637, 3, 0, 327670, 3, 65536, 327671, 3, 0, 262149, 6, 65536, 262150, 6, 0, 262162, 9, 65536, 262163, 8, 65536, 262164, 8, 65536, 262165, 8, 65536, 262166, 8, 65536, 262167, 10, 65536, 262168, 7, 0, 262169, 7, 0, 262170, 7, 0, 262171, 7, 0, 262172, 7, 0, 262173, 3, 0, 393206, 3, 65536, 393207, 3, 0, 327682, 6, 65536, 327683, 6, 0, 327703, 9, 65536, 327704, 8, 65536, 327705, 10, 65536, 327706, 7, 0, 327707, 7, 0, 327708, 7, 0, 327709, 3, 0, 458742, 3, 65536, 458743, 4, 0, 458744, 0, 0, 458745, 0, 0, 458746, 1, 0, 393241, 9, 65536, 393242, 8, 65536, 393243, 8, 65536, 393244, 10, 65536, 393245, 3, 0, 524278, 3, 65536, 524279, 7, 65536, 524280, 7, 65536, 524281, 7, 65536, 524282, 3, 0, 458754, 1, 65536, 458755, 0, 0, 458756, 0, 0, 458764, 1, 65536, 458765, 1, 0, 458780, 3, 65536, 458781, 3, 0, 589814, 3, 65536, 589815, 7, 65536, 589816, 7, 65536, 589817, 7, 65536, 589818, 3, 0, 524290, 3, 65536, 524291, 7, 0, 524292, 7, 0, 524294, 0, 65536, 524295, 0, 65536, 524296, 0, 65536, 524297, 0, 65536, 524298, 0, 65536, 524299, 0, 65536, 524300, 4, 65536, 524301, 3, 0, 524316, 3, 65536, 524317, 3, 0, 655350, 3, 65536, 655351, 7, 65536, 655352, 7, 65536, 655353, 7, 65536, 655354, 3, 0, 589826, 3, 65536, 589827, 7, 0, 589828, 7, 0, 589829, 7, 0, 589830, 7, 0, 589831, 7, 0, 589832, 7, 0, 589833, 7, 0, 589834, 7, 0, 589835, 7, 0, 589836, 7, 0, 589837, 4, 0, 589838, 0, 0, 589839, 1, 0, 589852, 3, 65536, 589853, 3, 0, 720886, 3, 65536, 720887, 7, 65536, 720888, 7, 65536, 720889, 7, 65536, 720890, 3, 0, 655362, 9, 65536, 655363, 8, 65536, 655364, 8, 65536, 655365, 8, 65536, 655366, 8, 65536, 655367, 8, 65536, 655368, 8, 65536, 655369, 8, 65536, 655370, 8, 65536, 655371, 8, 65536, 655372, 8, 65536, 655373, 8, 65536, 655374, 8, 65536, 655375, 9, 0, 655388, 3, 65536, 655389, 3, 0, 786422, 3, 65536, 786423, 7, 65536, 786424, 7, 65536, 786425, 7, 65536, 786426, 3, 0, 720924, 3, 65536, 720925, 3, 0, 851958, 3, 65536, 851959, 7, 65536, 851960, 7, 65536, 851961, 7, 65536, 851962, 3, 0, 786456, 6, 65536, 786457, 5, 65536, 786458, 6, 0, 786460, 3, 65536, 786461, 3, 0, 917494, 3, 65536, 917495, 7, 65536, 917496, 7, 65536, 917497, 7, 65536, 917498, 4, 0, 917499, 0, 0, 917500, 0, 0, 917501, 0, 0, 917502, 0, 0, 917503, 0, 0, 851968, 0, 0, 851969, 1, 0, 851996, 3, 65536, 851997, 3, 0, 983030, 3, 65536, 983031, 7, 65536, 983032, 7, 65536, 983033, 7, 65536, 983034, 7, 65536, 983035, 7, 65536, 983036, 7, 65536, 983037, 7, 65536, 983038, 7, 65536, 983039, 7, 65536, 917504, 7, 65536, 917505, 3, 0, 917526, 1, 65536, 917527, 0, 65536, 917528, 0, 65536, 917529, 0, 0, 917530, 0, 65536, 917531, 0, 65536, 917532, 4, 65536, 917533, 3, 0, 1048566, 3, 65536, 1048567, 7, 65536, 1048568, 7, 65536, 1048569, 7, 65536, 1048570, 7, 65536, 1048571, 7, 65536, 1048572, 7, 65536, 1048573, 7, 65536, 1048574, 7, 65536, 1048575, 7, 65536, 983040, 7, 65536, 983041, 3, 0, 983057, 6, 65536, 983058, 5, 0, 983059, 6, 0, 983062, 3, 65536, 983063, 7, 0, 983064, 7, 0, 983065, 7, 0, 983066, 7, 0, 983067, 7, 0, 983068, 7, 0, 983069, 3, 0, 1114102, 3, 65536, 1114103, 7, 65536, 1114104, 7, 65536, 1114105, 7, 65536, 1114106, 7, 65536, 1114107, 7, 65536, 1114108, 7, 65536, 1114109, 7, 65536, 1114110, 7, 65536, 1114111, 7, 65536, 1048576, 7, 65536, 1048577, 3, 0, 1048579, 14, 65536, 1048598, 3, 65536, 1048599, 7, 0, 1048600, 7, 0, 1048601, 7, 0, 1048602, 7, 0, 1048603, 7, 0, 1048604, 7, 0, 1048605, 3, 0, 1179638, 3, 65536, 1179639, 7, 65536, 1179640, 7, 65536, 1179641, 7, 65536, 1179642, 7, 65536, 1179643, 7, 65536, 1179644, 7, 65536, 1179645, 7, 65536, 1179646, 7, 65536, 1179647, 7, 65536, 1114112, 7, 65536, 1114113, 4, 0, 1114114, 0, 0, 1114115, 13, 65536, 1114116, 0, 0, 1114117, 2, 0, 1114123, 14, 65536, 1114126, 6, 65536, 1114127, 5, 0, 1114128, 6, 0, 1114133, 2, 65536, 1114134, 4, 65536, 1114135, 7, 0, 1114136, 7, 0, 1114137, 7, 0, 1114138, 7, 0, 1114139, 7, 0, 1114140, 7, 0, 1114141, 3, 0, 1245174, 3, 65536, 1245175, 7, 65536, 1245176, 7, 65536, 1245177, 7, 65536, 1245178, 7, 65536, 1245179, 7, 65536, 1245180, 7, 65536, 1245181, 7, 65536, 1245182, 7, 65536, 1245183, 7, 65536, 1179648, 7, 65536, 1179649, 7, 65536, 1179650, 7, 65536, 1179651, 7, 65536, 1179652, 7, 0, 1179654, 2, 0, 1179658, 1, 65536, 1179659, 13, 65536, 1179660, 1, 0, 1179668, 2, 65536, 1179670, 7, 0, 1179671, 7, 0, 1179672, 7, 0, 1179673, 7, 0, 1179674, 7, 0, 1179675, 7, 0, 1179676, 7, 0, 1179677, 3, 0, 1310710, 3, 65536, 1310711, 7, 65536, 1310712, 7, 65536, 1310713, 7, 65536, 1310714, 7, 65536, 1310715, 7, 65536, 1310716, 7, 65536, 1310717, 7, 65536, 1310718, 7, 65536, 1310719, 7, 65536, 1245184, 7, 65536, 1245185, 7, 65536, 1245186, 7, 65536, 1245187, 7, 65536, 1245188, 7, 65536, 1245189, 7, 0, 1245191, 2, 0, 1245194, 3, 65536, 1245195, 7, 0, 1245196, 3, 0, 1245205, 7, 0, 1245206, 7, 0, 1245207, 7, 0, 1245208, 7, 0, 1245209, 7, 0, 1245210, 7, 0, 1245211, 7, 0, 1245212, 7, 0, 1245213, 3, 0, 1376246, 3, 65536, 1376247, 7, 65536, 1376248, 7, 65536, 1376249, 7, 65536, 1376250, 7, 65536, 1376251, 7, 65536, 1376252, 7, 65536, 1376253, 7, 65536, 1376254, 7, 65536, 1376255, 7, 65536, 1310720, 7, 65536, 1310721, 7, 65536, 1310722, 7, 65536, 1310723, 7, 65536, 1310724, 7, 65536, 1310725, 7, 65536, 1310726, 7, 0, 1310728, 0, 65536, 1310729, 0, 65536, 1310730, 4, 65536, 1310731, 7, 0, 1310732, 4, 0, 1310733, 0, 0, 1310734, 0, 0, 1310735, 0, 0, 1310736, 0, 0, 1310737, 0, 0, 1310738, 0, 65536, 1310740, 7, 0, 1310741, 7, 0, 1310742, 7, 0, 1310743, 7, 0, 1310744, 7, 0, 1310745, 7, 0, 1310746, 7, 0, 1310747, 7, 0, 1310748, 7, 0, 1310749, 3, 0, 1441782, 9, 65536, 1441783, 8, 65536, 1441784, 8, 65536, 1441785, 8, 65536, 1441786, 8, 65536, 1441787, 8, 65536, 1441788, 8, 65536, 1441789, 8, 65536, 1441790, 8, 65536, 1441791, 8, 65536, 1376256, 8, 65536, 1376257, 8, 65536, 1376258, 8, 65536, 1376259, 8, 65536, 1376260, 8, 65536, 1376261, 8, 65536, 1376262, 8, 65536, 1376263, 8, 65536, 1376264, 8, 65536, 1376265, 8, 65536, 1376266, 8, 65536, 1376267, 8, 65536, 1376268, 8, 65536, 1376269, 8, 65536, 1376270, 8, 65536, 1376271, 8, 65536, 1376272, 8, 65536, 1376273, 8, 65536, 1376274, 8, 65536, 1376275, 8, 65536, 1376276, 8, 65536, 1376277, 8, 65536, 1376278, 8, 65536, 1376279, 8, 65536, 1376280, 8, 65536, 1376281, 8, 65536, 1376282, 8, 65536, 1376283, 8, 65536, 1376284, 8, 0, 1376285, 9, 0, 458757, 2, 0, 1245203, 2, 65536) + +[node name="WorldBoundaries" type="StaticBody2D" parent="."] +collision_layer = 16 + +[node name="Left" type="CollisionShape2D" parent="WorldBoundaries"] +position = Vector2(-318, 0) +shape = SubResource("WorldBoundaryShape2D_vsviu") + +[node name="Right" type="CollisionShape2D" parent="WorldBoundaries"] +position = Vector2(958, 0) +rotation = 3.14159 +shape = SubResource("WorldBoundaryShape2D_vsviu") + +[node name="Coins" type="Node" parent="."] + +[node name="CoinsArc" type="Node2D" parent="Coins"] +position = Vector2(269.878, 573.77) + +[node name="Coin" parent="Coins/CoinsArc" instance=ExtResource("4")] +position = Vector2(-14.7314, 29.9809) + +[node name="Coin2" parent="Coins/CoinsArc" instance=ExtResource("4")] +position = Vector2(0.0855715, 0.070923) + +[node name="Coin3" parent="Coins/CoinsArc" instance=ExtResource("4")] +position = Vector2(31.2736, -17.854) + +[node name="CoinsVertical" type="Node2D" parent="Coins"] +position = Vector2(366.022, 518.94) + +[node name="Coin" parent="Coins/CoinsVertical" instance=ExtResource("4")] +position = Vector2(-0.0551455, 15.9351) + +[node name="Coin2" parent="Coins/CoinsVertical" instance=ExtResource("4")] +position = Vector2(-0.0551455, -0.0649415) + +[node name="Coin3" parent="Coins/CoinsVertical" instance=ExtResource("4")] +position = Vector2(-0.0551455, -16.065) + +[node name="CoinsVertical2" type="Node2D" parent="Coins"] +position = Vector2(509.055, -8.98655) + +[node name="Coin" parent="Coins/CoinsVertical2" instance=ExtResource("4")] +position = Vector2(-0.0551455, 15.9351) + +[node name="Coin2" parent="Coins/CoinsVertical2" instance=ExtResource("4")] +position = Vector2(-0.0551455, -0.0649415) + +[node name="Coin3" parent="Coins/CoinsVertical2" instance=ExtResource("4")] +position = Vector2(-0.0551455, -16.065) + +[node name="CoinsSquare" type="Node2D" parent="Coins"] +position = Vector2(-214.835, 161.6) + +[node name="Coin" parent="Coins/CoinsSquare" instance=ExtResource("4")] +position = Vector2(-16, -16) + +[node name="Coin2" parent="Coins/CoinsSquare" instance=ExtResource("4")] +position = Vector2(16, -16) + +[node name="Coin3" parent="Coins/CoinsSquare" instance=ExtResource("4")] +position = Vector2(-16, 16) + +[node name="Coin4" parent="Coins/CoinsSquare" instance=ExtResource("4")] +position = Vector2(16, 16) + +[node name="CoinsSquare2" type="Node2D" parent="Coins"] +position = Vector2(347.552, 33.4742) + +[node name="Coin" parent="Coins/CoinsSquare2" instance=ExtResource("4")] +position = Vector2(-16, -16) + +[node name="Coin2" parent="Coins/CoinsSquare2" instance=ExtResource("4")] +position = Vector2(16, -16) + +[node name="Coin3" parent="Coins/CoinsSquare2" instance=ExtResource("4")] +position = Vector2(-16, 16) + +[node name="Coin4" parent="Coins/CoinsSquare2" instance=ExtResource("4")] +position = Vector2(16, 16) + +[node name="CoinsSquare3" type="Node2D" parent="Coins"] +position = Vector2(676.585, 58.6425) + +[node name="Coin" parent="Coins/CoinsSquare3" instance=ExtResource("4")] +position = Vector2(-16, -16) + +[node name="Coin2" parent="Coins/CoinsSquare3" instance=ExtResource("4")] +position = Vector2(16, -16) + +[node name="Coin3" parent="Coins/CoinsSquare3" instance=ExtResource("4")] +position = Vector2(-16, 16) + +[node name="Coin4" parent="Coins/CoinsSquare3" instance=ExtResource("4")] +position = Vector2(16, 16) + +[node name="CoinsSquare4" type="Node2D" parent="Coins"] +position = Vector2(796.29, 58.6425) + +[node name="Coin" parent="Coins/CoinsSquare4" instance=ExtResource("4")] +position = Vector2(-16, -16) + +[node name="Coin2" parent="Coins/CoinsSquare4" instance=ExtResource("4")] +position = Vector2(16, -16) + +[node name="Coin3" parent="Coins/CoinsSquare4" instance=ExtResource("4")] +position = Vector2(-16, 16) + +[node name="Coin4" parent="Coins/CoinsSquare4" instance=ExtResource("4")] +position = Vector2(16, 16) + +[node name="CoinsHorizontal" type="Node2D" parent="Coins"] +position = Vector2(36.6204, 402.991) + +[node name="Coin" parent="Coins/CoinsHorizontal" instance=ExtResource("4")] +position = Vector2(-16, 0) + +[node name="Coin2" parent="Coins/CoinsHorizontal" instance=ExtResource("4")] + +[node name="Coin3" parent="Coins/CoinsHorizontal" instance=ExtResource("4")] +position = Vector2(16, 0) + +[node name="CoinsHorizontal2" type="Node2D" parent="Coins"] +position = Vector2(668.605, 431.544) + +[node name="Coin" parent="Coins/CoinsHorizontal2" instance=ExtResource("4")] +position = Vector2(-16, 0) + +[node name="Coin2" parent="Coins/CoinsHorizontal2" instance=ExtResource("4")] + +[node name="Coin3" parent="Coins/CoinsHorizontal2" instance=ExtResource("4")] +position = Vector2(16, 0) + +[node name="CoinsHorizontal3" type="Node2D" parent="Coins"] +position = Vector2(335.585, 155.872) + +[node name="Coin" parent="Coins/CoinsHorizontal3" instance=ExtResource("4")] +position = Vector2(-16, 0) + +[node name="Coin2" parent="Coins/CoinsHorizontal3" instance=ExtResource("4")] + +[node name="Coin3" parent="Coins/CoinsHorizontal3" instance=ExtResource("4")] +position = Vector2(16, 0) + +[node name="CoinsHorizontal4" type="Node2D" parent="Coins"] +position = Vector2(-63.444, 20.5902) + +[node name="Coin" parent="Coins/CoinsHorizontal4" instance=ExtResource("4")] +position = Vector2(-16, 0) + +[node name="Coin2" parent="Coins/CoinsHorizontal4" instance=ExtResource("4")] + +[node name="Coin3" parent="Coins/CoinsHorizontal4" instance=ExtResource("4")] +position = Vector2(16, 0) + +[node name="CoinsHorizontal5" type="Node2D" parent="Coins"] +position = Vector2(127.607, 20.5902) + +[node name="Coin" parent="Coins/CoinsHorizontal5" instance=ExtResource("4")] +position = Vector2(-16, 0) + +[node name="Coin2" parent="Coins/CoinsHorizontal5" instance=ExtResource("4")] + +[node name="Coin3" parent="Coins/CoinsHorizontal5" instance=ExtResource("4")] +position = Vector2(16, 0) + +[node name="Platforms" type="Node" parent="."] + +[node name="Platform" parent="Platforms" instance=ExtResource("3")] +position = Vector2(707, 400) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="Platforms/Platform"] +autoplay = "move" +playback_process_mode = 0 +libraries = { +"": SubResource("AnimationLibrary_twp1p") +} + +[node name="Platform2" parent="Platforms" instance=ExtResource("3")] +position = Vector2(-47, 80) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="Platforms/Platform2"] +autoplay = "move" +playback_process_mode = 0 +libraries = { +"": SubResource("AnimationLibrary_61huy") +} + +[node name="PlatformStatic" type="StaticBody2D" parent="Platforms"] +z_index = -1 +position = Vector2(569.935, 105.877) +rotation = 0.355618 +collision_layer = 16 +collision_mask = 0 + +[node name="Sprite2" type="Sprite2D" parent="Platforms/PlatformStatic"] +position = Vector2(-88.692, 10.5003) +rotation = -0.246293 +texture = ExtResource("6") + +[node name="Sprite2D" type="Sprite2D" parent="Platforms/PlatformStatic"] +texture = ExtResource("6") + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Platforms/PlatformStatic"] +position = Vector2(-0.0684814, 0.0254364) +polygon = PackedVector2Array(-129.699, 9.94633, -47, -10.5, 8, -7, 10, -1.5, -46.75, -4, -130, 15) + +[node name="Enemies" type="Node" parent="."] + +[node name="Enemy" parent="Enemies" instance=ExtResource("2")] +position = Vector2(271.04, 245.639) + +[node name="Enemy2" parent="Enemies" instance=ExtResource("2")] +position = Vector2(346.109, 48.5631) + +[node name="Enemy3" parent="Enemies" instance=ExtResource("2")] +position = Vector2(632.725, 78.5545) + +[node name="Enemy4" parent="Enemies" instance=ExtResource("2")] +position = Vector2(23, 16) + +[node name="ParallaxBackground" parent="." instance=ExtResource("7")] diff --git a/2d/platformer/level/moving_platform.webp b/2d/platformer/level/moving_platform.webp new file mode 100644 index 0000000000000000000000000000000000000000..22e74077c03a7fee406a23cfe2c42672d72f278a GIT binary patch literal 544 zcmV+*0^j{oNk&E(0ssJ4MM6+kP&iBs0ssInf4~P2mB?`bH;$wiO*WY5*m&dp!T!Y` zZ&p!kqQgCk2?@x76g85h>@hP*Sq1k#1E*xwD~V)<^87UNNfOZN6(AuNMIC}{8-fWO z<^EoE;I@q;CEMH4GxrKT)4$%)qA%iNv?$~vTI*6eME(62K3CvaJg1E)ZAYdZ;1$Vp zZ&hiRZDsFiS8cm~5x*~-z)>cGF9D#cNV$6M!m$sFMInftuzcQU!YY2wBhXnuMrPTfNGz&4)Gx()$d+wO#*m~NsqG}p!$T?;LAZy17a9Vd--Glw%lXagn zjSh=t*C|am!C(l`1u#_h!;P}RzO(8_2CUjguCyoYK{W*Wwabe)ZJO78_F5K&@7*ETr)A3%k^Aot8|lAICZgTNRgGEV9`b- z$XkU2s*xTA@43;&Q4A0zE&uN9^4ug(EMY1q7eL%uHVBdg1iY?cX}w|0tZ)fD?AtwE9@lHM9q4go+nLzT($rfU;McM literal 0 HcmV?d00001 diff --git a/2d/platformer/assets/art/platforms/moving_platform.png.import b/2d/platformer/level/moving_platform.webp.import similarity index 66% rename from 2d/platformer/assets/art/platforms/moving_platform.png.import rename to 2d/platformer/level/moving_platform.webp.import index 205452a1..bbe8195a 100644 --- a/2d/platformer/assets/art/platforms/moving_platform.png.import +++ b/2d/platformer/level/moving_platform.webp.import @@ -3,22 +3,22 @@ importer="texture" type="CompressedTexture2D" uid="uid://8p65ui1ydnff" -path="res://.godot/imported/moving_platform.png-479aa8f802d1a4964b138893ada8d372.ctex" +path="res://.godot/imported/moving_platform.webp-dd4a79a18c99da84f4c06de09878b0a4.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/art/platforms/moving_platform.png" -dest_files=["res://.godot/imported/moving_platform.png-479aa8f802d1a4964b138893ada8d372.ctex"] +source_file="res://level/moving_platform.webp" +dest_files=["res://.godot/imported/moving_platform.webp-dd4a79a18c99da84f4c06de09878b0a4.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/platformer/assets/art/platforms/one_way_platform.png.import b/2d/platformer/level/one_way_platform.import similarity index 66% rename from 2d/platformer/assets/art/platforms/one_way_platform.png.import rename to 2d/platformer/level/one_way_platform.import index fefc8591..6c47017e 100644 --- a/2d/platformer/assets/art/platforms/one_way_platform.png.import +++ b/2d/platformer/level/one_way_platform.import @@ -3,22 +3,22 @@ importer="texture" type="CompressedTexture2D" uid="uid://dpdd5ioofxcur" -path="res://.godot/imported/one_way_platform.png-aaf0179c7171228f27cb489e99e339bd.ctex" +path="res://.godot/imported/one_way_platform.png-ff82db5f4cf9bbd816ae5115d1b41cf7.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/art/platforms/one_way_platform.png" -dest_files=["res://.godot/imported/one_way_platform.png-aaf0179c7171228f27cb489e99e339bd.ctex"] +source_file="res://level/one_way_platform.png" +dest_files=["res://.godot/imported/one_way_platform.png-ff82db5f4cf9bbd816ae5115d1b41cf7.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/platformer/level/one_way_platform.webp b/2d/platformer/level/one_way_platform.webp new file mode 100644 index 0000000000000000000000000000000000000000..86f92543e42671f64cc4a8b902ca1024a19555c2 GIT binary patch literal 484 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 M_vQKy`FVu{0D#*H9smFU literal 0 HcmV?d00001 diff --git a/2d/platformer/assets/art/tileset/tiles_demo.png.import b/2d/platformer/level/tiles.webp.import similarity index 68% rename from 2d/platformer/assets/art/tileset/tiles_demo.png.import rename to 2d/platformer/level/tiles.webp.import index 1e664a5d..4c9cd232 100644 --- a/2d/platformer/assets/art/tileset/tiles_demo.png.import +++ b/2d/platformer/level/tiles.webp.import @@ -3,22 +3,22 @@ importer="texture" type="CompressedTexture2D" uid="uid://c1hixfwf86y2q" -path="res://.godot/imported/tiles_demo.png-f720a7de2b60b01f690cfa3cb881996b.ctex" +path="res://.godot/imported/tiles.webp-4f56cd8ea452f8ba920d65a0b9099010.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/art/tileset/tiles_demo.png" -dest_files=["res://.godot/imported/tiles_demo.png-f720a7de2b60b01f690cfa3cb881996b.ctex"] +source_file="res://level/tiles.webp" +dest_files=["res://.godot/imported/tiles.webp-4f56cd8ea452f8ba920d65a0b9099010.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/platformer/level/tileset.tres b/2d/platformer/level/tileset.tres new file mode 100644 index 00000000..f1429a94 --- /dev/null +++ b/2d/platformer/level/tileset.tres @@ -0,0 +1,729 @@ +[gd_resource type="TileSet" load_steps=17 format=3 uid="uid://dmpguegs1kkkl"] + +[ext_resource type="Texture2D" uid="uid://c1hixfwf86y2q" path="res://level/tiles.webp" id="1"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_24d4o"] +texture = ExtResource("1") +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(-16, -10, 16, -10, 16, 16, -16, 16) +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -16, -10, -16, 16, 16, 16) +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 10, 16, 10, 16, -16, -16, -16) +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(16, 10, -16, 10, -16, -16, 16, -16) +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -10, 16, -10, 16, 16, -16, 16) +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -16, -10, -16, 16, 16, 16) +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 10, 16, 10, 16, -16, -16, -16) +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(16, 10, -16, 10, -16, -16, 16, -16) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_opo1u"] +texture = ExtResource("1") +margins = Vector2i(32, 0) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(-16, -10, 12, -10, 12, 16, -16, 16) +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -12, -10, -12, 16, 16, 16) +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 10, 12, 10, 12, -16, -16, -16) +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(16, 10, -12, 10, -12, -16, 16, -16) +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -10, 12, -10, 12, 16, -16, 16) +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -12, -10, -12, 16, 16, 16) +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 10, 12, 10, 12, -16, -16, -16) +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(16, 10, -12, 10, -12, -16, 16, -16) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_val0e"] +texture = ExtResource("1") +margins = Vector2i(160, 32) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(-16, -16, 16, -16, 16, 16, -16, 16) +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -16, -16, -16, -16, 16, 16, 16) +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 16, 16, 16, 16, -16, -16, -16) +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(16, 16, -16, 16, -16, -16, 16, -16) +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16) +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(16, -16, -16, -16, -16, 16, 16, 16) +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 16, 16, 16, 16, -16, -16, -16) +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(16, 16, -16, 16, -16, -16, 16, -16) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_vw3dp"] +texture = ExtResource("1") +margins = Vector2i(128, 64) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_ofvgn"] +texture = ExtResource("1") +margins = Vector2i(128, 32) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_suguu"] +texture = ExtResource("1") +margins = Vector2i(128, 96) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(-16, -10, 16, -10, 16, 16, -16, 16) +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -16, -10, -16, 16, 16, 16) +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 10, 16, 10, 16, -16, -16, -16) +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(16, 10, -16, 10, -16, -16, 16, -16) +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -10, 16, -10, 16, 16, -16, 16) +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -16, -10, -16, 16, 16, 16) +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 10, 16, 10, 16, -16, -16, -16) +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(16, 10, -16, 10, -16, -16, 16, -16) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_erd6k"] +texture = ExtResource("1") +margins = Vector2i(128, 0) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_l8f8l"] +texture = ExtResource("1") +margins = Vector2i(64, 32) +texture_region_size = Vector2i(32, 96) +0:0/next_alternative_id = 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(-16, -10, 16, 22.5, 16, 48, -16, 48) +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -16, 22, -16, 48, 16, 48) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_5pwh6"] +texture = ExtResource("1") +margins = Vector2i(32, 32) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(-16, -16, 12, -16, 12, 16, -16, 16) +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -16, -12, -16, -12, 16, 16, 16) +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 16, 12, 16, 12, -16, -16, -16) +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(16, 16, -12, 16, -12, -16, 16, -16) +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 12, -16, 12, 16, -16, 16) +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(16, -16, -12, -16, -12, 16, 16, 16) +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 16, 12, 16, 12, -16, -16, -16) +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(16, 16, -12, 16, -12, -16, 16, -16) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_seqgr"] +texture = ExtResource("1") +margins = Vector2i(32, 64) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(12, -10, 16, -10, 16, 16, -16, 16, -16, -16, 12, -16) +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(-12, -10, -16, -10, -16, 16, 16, 16, 16, -16, -12, -16) +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(12, 10, 16, 10, 16, -16, -16, -16, -16, 16, 12, 16) +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(-12, 10, -16, 10, -16, -16, 16, -16, 16, 16, -12, 16) +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(12, -10, 16, -10, 16, 16, -16, 16, -16, -16, 12, -16) +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(-12, -10, -16, -10, -16, 16, 16, 16, 16, -16, -12, -16) +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(12, 10, 16, 10, 16, -16, -16, -16, -16, 16, 12, 16) +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(-12, 10, -16, 10, -16, -16, 16, -16, 16, 16, -12, 16) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_5an2c"] +texture = ExtResource("1") +margins = Vector2i(64, 0) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(-16, -10, 16, -10, 16, 16, -16, 16) +0:0/0/physics_layer_0/polygon_0/one_way = true +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -16, -10, -16, 16, 16, 16) +0:0/1/physics_layer_0/polygon_0/one_way = true +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 10, 16, 10, 16, -16, -16, -16) +0:0/2/physics_layer_0/polygon_0/one_way = true +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(16, 10, -16, 10, -16, -16, 16, -16) +0:0/3/physics_layer_0/polygon_0/one_way = true +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -10, 16, -10, 16, 16, -16, 16) +0:0/4/physics_layer_0/polygon_0/one_way = true +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -16, -10, -16, 16, 16, 16) +0:0/5/physics_layer_0/polygon_0/one_way = true +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 10, 16, 10, 16, -16, -16, -16) +0:0/6/physics_layer_0/polygon_0/one_way = true +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(16, 10, -16, 10, -16, -16, 16, -16) +0:0/7/physics_layer_0/polygon_0/one_way = true + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_diy7l"] +texture = ExtResource("1") +margins = Vector2i(96, 0) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(-16, -10, 12, -10, 12, 16, -16, 16) +0:0/0/physics_layer_0/polygon_0/one_way = true +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -12, -10, -12, 16, 16, 16) +0:0/1/physics_layer_0/polygon_0/one_way = true +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 10, 12, 10, 12, -16, -16, -16) +0:0/2/physics_layer_0/polygon_0/one_way = true +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(16, 10, -12, 10, -12, -16, 16, -16) +0:0/3/physics_layer_0/polygon_0/one_way = true +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -10, 12, -10, 12, 16, -16, 16) +0:0/4/physics_layer_0/polygon_0/one_way = true +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(16, -10, -12, -10, -12, 16, 16, 16) +0:0/5/physics_layer_0/polygon_0/one_way = true +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 10, 12, 10, 12, -16, -16, -16) +0:0/6/physics_layer_0/polygon_0/one_way = true +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(16, 10, -12, 10, -12, -16, 16, -16) +0:0/7/physics_layer_0/polygon_0/one_way = true + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_05unx"] +texture = ExtResource("1") +margins = Vector2i(0, 32) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(-16, -16, 16, -16, 16, 16, -16, 16) +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -16, -16, -16, -16, 16, 16, 16) +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 16, 16, 16, 16, -16, -16, -16) +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(16, 16, -16, 16, -16, -16, 16, -16) +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16) +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(16, -16, -16, -16, -16, 16, 16, 16) +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 16, 16, 16, 16, -16, -16, -16) +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(16, 16, -16, 16, -16, -16, 16, -16) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_ucjks"] +texture = ExtResource("1") +margins = Vector2i(192, 32) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(-16, -16, 16, -16, 16, 8, -16, 8) +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -16, -16, -16, -16, 8, 16, 8) +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 16, 16, 16, 16, -8, -16, -8) +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(16, 16, -16, 16, -16, -8, 16, -8) +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 8, -16, 8) +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(16, -16, -16, -16, -16, 8, 16, 8) +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 16, 16, 16, 16, -8, -16, -8) +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(16, 16, -16, 16, -16, -8, 16, -8) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_dq2ee"] +texture = ExtResource("1") +margins = Vector2i(224, 32) +texture_region_size = Vector2i(32, 32) +0:0/next_alternative_id = 8 +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(-16, -16, 12, -16, 12, 8, -16, 8) +0:0/1 = 1 +0:0/1/flip_h = true +0:0/1/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/1/physics_layer_0/angular_velocity = 0.0 +0:0/1/physics_layer_0/polygon_0/points = PackedVector2Array(16, -16, -12, -16, -12, 8, 16, 8) +0:0/2 = 2 +0:0/2/flip_v = true +0:0/2/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/2/physics_layer_0/angular_velocity = 0.0 +0:0/2/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 16, 12, 16, 12, -8, -16, -8) +0:0/3 = 3 +0:0/3/flip_h = true +0:0/3/flip_v = true +0:0/3/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/3/physics_layer_0/angular_velocity = 0.0 +0:0/3/physics_layer_0/polygon_0/points = PackedVector2Array(16, 16, -12, 16, -12, -8, 16, -8) +0:0/4 = 4 +0:0/4/transpose = true +0:0/4/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/4/physics_layer_0/angular_velocity = 0.0 +0:0/4/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 12, -16, 12, 8, -16, 8) +0:0/5 = 5 +0:0/5/flip_h = true +0:0/5/transpose = true +0:0/5/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/5/physics_layer_0/angular_velocity = 0.0 +0:0/5/physics_layer_0/polygon_0/points = PackedVector2Array(16, -16, -12, -16, -12, 8, 16, 8) +0:0/6 = 6 +0:0/6/flip_v = true +0:0/6/transpose = true +0:0/6/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/6/physics_layer_0/angular_velocity = 0.0 +0:0/6/physics_layer_0/polygon_0/points = PackedVector2Array(-16, 16, 12, 16, 12, -8, -16, -8) +0:0/7 = 7 +0:0/7/flip_h = true +0:0/7/flip_v = true +0:0/7/transpose = true +0:0/7/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/7/physics_layer_0/angular_velocity = 0.0 +0:0/7/physics_layer_0/polygon_0/points = PackedVector2Array(16, 16, -12, 16, -12, -8, 16, -8) + +[resource] +tile_size = Vector2i(32, 32) +physics_layer_0/collision_layer = 16 +physics_layer_0/collision_mask = 0 +sources/0 = SubResource("TileSetAtlasSource_24d4o") +sources/1 = SubResource("TileSetAtlasSource_opo1u") +sources/2 = SubResource("TileSetAtlasSource_l8f8l") +sources/3 = SubResource("TileSetAtlasSource_5pwh6") +sources/4 = SubResource("TileSetAtlasSource_seqgr") +sources/5 = SubResource("TileSetAtlasSource_5an2c") +sources/6 = SubResource("TileSetAtlasSource_diy7l") +sources/7 = SubResource("TileSetAtlasSource_05unx") +sources/8 = SubResource("TileSetAtlasSource_ucjks") +sources/9 = SubResource("TileSetAtlasSource_dq2ee") +sources/10 = SubResource("TileSetAtlasSource_val0e") +sources/11 = SubResource("TileSetAtlasSource_vw3dp") +sources/12 = SubResource("TileSetAtlasSource_ofvgn") +sources/13 = SubResource("TileSetAtlasSource_suguu") +sources/14 = SubResource("TileSetAtlasSource_erd6k") diff --git a/2d/platformer/assets/audio/music/music.ogg b/2d/platformer/music.ogg similarity index 100% rename from 2d/platformer/assets/audio/music/music.ogg rename to 2d/platformer/music.ogg diff --git a/2d/platformer/music.ogg.import b/2d/platformer/music.ogg.import new file mode 100644 index 00000000..30d59955 --- /dev/null +++ b/2d/platformer/music.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://cx6hrmvjvhkt5" +path="res://.godot/imported/music.ogg-3bd46d3a4b41702b152014078d12a390.oggvorbisstr" + +[deps] + +source_file="res://music.ogg" +dest_files=["res://.godot/imported/music.ogg-3bd46d3a4b41702b152014078d12a390.oggvorbisstr"] + +[params] + +loop=true +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/2d/platformer/music.tscn b/2d/platformer/music.tscn new file mode 100644 index 00000000..9efe63fe --- /dev/null +++ b/2d/platformer/music.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=2 format=3 uid="uid://do7htx4sqmcnh"] + +[ext_resource type="AudioStream" uid="uid://cx6hrmvjvhkt5" path="res://music.ogg" id="1_8pjkj"] + +[node name="Music" type="AudioStreamPlayer"] +process_mode = 1 +stream = ExtResource("1_8pjkj") +autoplay = true diff --git a/2d/platformer/player/bullet.gd b/2d/platformer/player/bullet.gd new file mode 100644 index 00000000..67ce6bf3 --- /dev/null +++ b/2d/platformer/player/bullet.gd @@ -0,0 +1,13 @@ +class_name Bullet extends RigidBody2D + + +@onready var animation_player := $AnimationPlayer as AnimationPlayer + + +func destroy() -> void: + animation_player.play(&"destroy") + + +func _on_body_entered(body: Node) -> void: + if body is Enemy: + (body as Enemy).destroy() diff --git a/2d/platformer/src/Objects/Bullet.tscn b/2d/platformer/player/bullet.tscn similarity index 64% rename from 2d/platformer/src/Objects/Bullet.tscn rename to 2d/platformer/player/bullet.tscn index bb98800c..6fca3a1b 100644 --- a/2d/platformer/src/Objects/Bullet.tscn +++ b/2d/platformer/player/bullet.tscn @@ -1,41 +1,41 @@ -[gd_scene load_steps=8 format=2] +[gd_scene load_steps=9 format=3 uid="uid://bdeyraansvyga"] -[ext_resource path="res://assets/art/player/bullet/bullet.png" type="Texture2D" id=1] -[ext_resource path="res://src/Objects/Bullet.gd" type="Script" id=2] +[ext_resource type="Script" path="res://player/bullet.gd" id="1_cokcn"] +[ext_resource type="Texture2D" uid="uid://c2aisfmq85suf" path="res://player/bullet.webp" id="2_4bup8"] -[sub_resource type="CanvasItemMaterial" id=1] +[sub_resource type="CanvasItemMaterial" id="1"] -[sub_resource type="CanvasItemMaterial" id=2] +[sub_resource type="CanvasItemMaterial" id="2"] blend_mode = 1 -[sub_resource type="CanvasItemMaterial" id=3] +[sub_resource type="CanvasItemMaterial" id="3"] -[sub_resource type="CircleShape2D" id=4] +[sub_resource type="CircleShape2D" id="4"] radius = 4.5 -[sub_resource type="Animation" id=5] +[sub_resource type="Animation" id="5"] resource_name = "destroy" length = 0.3 tracks/0/type = "method" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath(".") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0.3), "transitions": PackedFloat32Array(1), "values": [{ "args": [], -"method": "queue_free" +"method": &"queue_free" }] } tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true tracks/1/path = NodePath("Sprite2D:self_modulate") tracks/1/interp = 1 tracks/1/loop_wrap = true -tracks/1/imported = false -tracks/1/enabled = true tracks/1/keys = { "times": PackedFloat32Array(0, 0.3), "transitions": PackedFloat32Array(1, 1), @@ -43,11 +43,11 @@ tracks/1/keys = { "values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0)] } tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true tracks/2/path = NodePath("GPUParticles2D:self_modulate") tracks/2/interp = 1 tracks/2/loop_wrap = true -tracks/2/imported = false -tracks/2/enabled = true tracks/2/keys = { "times": PackedFloat32Array(0, 0.3), "transitions": PackedFloat32Array(1, 1), @@ -55,40 +55,45 @@ tracks/2/keys = { "values": [Color(1, 1, 1, 1), Color(1, 1, 1, 0)] } -[node name="Bullet" type="RigidDynamicBody2D"] -material = SubResource( 1 ) +[sub_resource type="AnimationLibrary" id="AnimationLibrary_li3y6"] +_data = { +"destroy": SubResource("5") +} + +[node name="Bullet" type="RigidBody2D"] +material = SubResource("1") collision_layer = 0 collision_mask = 26 continuous_cd = 2 -contacts_reported = 1 +max_contacts_reported = 4 contact_monitor = true -script = ExtResource( 2 ) +script = ExtResource("1_cokcn") [node name="GPUParticles2D" type="CPUParticles2D" parent="."] -material = SubResource( 2 ) +material = SubResource("2") emitting = false lifetime = 0.3 speed_scale = 3.0 -local_coords = false -texture = ExtResource( 1 ) +texture = ExtResource("2_4bup8") spread = 0.0 gravity = Vector2(0, 0) -scale_amount = 0.8 color = Color(1, 1, 1, 0.705882) [node name="Sprite2D" type="Sprite2D" parent="."] -material = SubResource( 3 ) -texture = ExtResource( 1 ) +material = SubResource("3") +texture = ExtResource("2_4bup8") [node name="CollisionShape2D" type="CollisionShape2D" parent="."] -shape = SubResource( 4 ) +shape = SubResource("4") [node name="Timer" type="Timer" parent="."] one_shot = true autostart = true [node name="AnimationPlayer" type="AnimationPlayer" parent="."] -anims/destroy = SubResource( 5 ) +libraries = { +"": SubResource("AnimationLibrary_li3y6") +} [connection signal="body_entered" from="." to="." method="_on_body_entered"] [connection signal="timeout" from="Timer" to="." method="destroy"] diff --git a/2d/platformer/player/bullet.webp b/2d/platformer/player/bullet.webp new file mode 100644 index 0000000000000000000000000000000000000000..ce3faace6ef880bf7bf85f2921196a5f47f74c15 GIT binary patch literal 100 zcmV-q0Gt0(Nk&Fo00012MM6+kP&iCb0000l2fzUkm9T0gsgnPXwSouaoDe+pCVjj~ z6tr!_#-sq~+laJn{QIhaq2o&t2qfC0ZPy$?pa1~^Ta@8rS${H99QpbF9JZP)o@4lc Gr3(O(7b=Ya literal 0 HcmV?d00001 diff --git a/2d/platformer/assets/art/player/bullet/bullet.png.import b/2d/platformer/player/bullet.webp.import similarity index 68% rename from 2d/platformer/assets/art/player/bullet/bullet.png.import rename to 2d/platformer/player/bullet.webp.import index afa1337e..89deb15b 100644 --- a/2d/platformer/assets/art/player/bullet/bullet.png.import +++ b/2d/platformer/player/bullet.webp.import @@ -3,22 +3,22 @@ importer="texture" type="CompressedTexture2D" uid="uid://c2aisfmq85suf" -path="res://.godot/imported/bullet.png-a148438922f3743d5615622ef8134c9f.ctex" +path="res://.godot/imported/bullet.webp-afcd8f50a20e81f25285b6f580e633e3.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/art/player/bullet/bullet.png" -dest_files=["res://.godot/imported/bullet.png-a148438922f3743d5615622ef8134c9f.ctex"] +source_file="res://player/bullet.webp" +dest_files=["res://.godot/imported/bullet.webp-afcd8f50a20e81f25285b6f580e633e3.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/2d/platformer/assets/audio/sfx/coin_pickup.wav b/2d/platformer/player/coin_pickup.wav similarity index 100% rename from 2d/platformer/assets/audio/sfx/coin_pickup.wav rename to 2d/platformer/player/coin_pickup.wav diff --git a/2d/platformer/assets/audio/sfx/coin_pickup.wav.import b/2d/platformer/player/coin_pickup.wav.import similarity index 54% rename from 2d/platformer/assets/audio/sfx/coin_pickup.wav.import rename to 2d/platformer/player/coin_pickup.wav.import index 05aec83b..078cd01b 100644 --- a/2d/platformer/assets/audio/sfx/coin_pickup.wav.import +++ b/2d/platformer/player/coin_pickup.wav.import @@ -3,12 +3,12 @@ importer="wav" type="AudioStreamWAV" uid="uid://bw67pgdlhpqd0" -path="res://.godot/imported/coin_pickup.wav-69d455f3063e30fd994846647c281aea.sample" +path="res://.godot/imported/coin_pickup.wav-cc06e43e2f58c4fe505090708655bec0.sample" [deps] -source_file="res://assets/audio/sfx/coin_pickup.wav" -dest_files=["res://.godot/imported/coin_pickup.wav-69d455f3063e30fd994846647c281aea.sample"] +source_file="res://player/coin_pickup.wav" +dest_files=["res://.godot/imported/coin_pickup.wav-cc06e43e2f58c4fe505090708655bec0.sample"] [params] diff --git a/2d/platformer/player/gun.gd b/2d/platformer/player/gun.gd new file mode 100644 index 00000000..d6af8b3c --- /dev/null +++ b/2d/platformer/player/gun.gd @@ -0,0 +1,25 @@ +class_name Gun extends Marker2D +## Represents a weapon that spawns and shoots bullets. +## The Cooldown timer controls the cooldown duration between shots. + + +const BULLET_VELOCITY = 500.0 +const Bullet = preload("res://player/bullet.tscn") + +@onready var sound_shoot := $Shoot as AudioStreamPlayer2D +@onready var timer := $Cooldown as Timer + + +# This method is only called by Player.gd. +func shoot(direction: float = 1.0) -> bool: + if not timer.is_stopped(): + return false + var bullet := Bullet.instantiate() as Bullet + bullet.global_position = global_position + bullet.linear_velocity = Vector2(direction * BULLET_VELOCITY, 0.0) + + bullet.set_as_top_level(true) + add_child(bullet) + sound_shoot.play() + timer.start() + return true diff --git a/2d/platformer/assets/audio/sfx/jump.wav b/2d/platformer/player/jump.wav similarity index 100% rename from 2d/platformer/assets/audio/sfx/jump.wav rename to 2d/platformer/player/jump.wav diff --git a/2d/platformer/assets/audio/sfx/jump.wav.import b/2d/platformer/player/jump.wav.import similarity index 56% rename from 2d/platformer/assets/audio/sfx/jump.wav.import rename to 2d/platformer/player/jump.wav.import index 28eafef4..86566d30 100644 --- a/2d/platformer/assets/audio/sfx/jump.wav.import +++ b/2d/platformer/player/jump.wav.import @@ -3,12 +3,12 @@ importer="wav" type="AudioStreamWAV" uid="uid://i2vnokf2khqj" -path="res://.godot/imported/jump.wav-127418ac4fc0b61a7fed0684053202c7.sample" +path="res://.godot/imported/jump.wav-d94eb6ad27159bf77e7ba7ab65914fbd.sample" [deps] -source_file="res://assets/audio/sfx/jump.wav" -dest_files=["res://.godot/imported/jump.wav-127418ac4fc0b61a7fed0684053202c7.sample"] +source_file="res://player/jump.wav" +dest_files=["res://.godot/imported/jump.wav-d94eb6ad27159bf77e7ba7ab65914fbd.sample"] [params] diff --git a/2d/platformer/player/player.gd b/2d/platformer/player/player.gd new file mode 100644 index 00000000..d6fb1357 --- /dev/null +++ b/2d/platformer/player/player.gd @@ -0,0 +1,88 @@ +class_name Player extends CharacterBody2D + + +signal coin_collected() + +const WALK_SPEED = 200.0 +const ACCELERATION_SPEED = WALK_SPEED * 6.0 +const JUMP_VELOCITY = -400.0 +## Maximum speed at which the player can fall. +const TERMINAL_VELOCITY = 400 + +## The player listens for input actions appended with this suffix.[br] +## Used to separate controls for multiple players in splitscreen. +@export var action_suffix := "" + +var gravity: int = ProjectSettings.get("physics/2d/default_gravity") +@onready var platform_detector := $PlatformDetector as RayCast2D +@onready var animation_player := $AnimationPlayer as AnimationPlayer +@onready var shoot_timer := $ShootAnimation as Timer +@onready var sprite := $Sprite2D as Sprite2D +@onready var jump_sound := $Jump as AudioStreamPlayer2D +@onready var gun = sprite.get_node(^"Gun") as Gun +@onready var camera := $Camera as Camera2D +var _double_jump_charged := false + + +func _physics_process(delta: float) -> void: + if is_on_floor(): + _double_jump_charged = true + if Input.is_action_just_pressed("jump" + action_suffix): + try_jump() + elif Input.is_action_just_released("jump" + action_suffix) and velocity.y < 0.0: + # The player let go of jump early, reduce vertical momentum. + velocity.y *= 0.6 + # Fall. + velocity.y = minf(TERMINAL_VELOCITY, velocity.y + gravity * delta) + + var direction := Input.get_axis("move_left" + action_suffix, "move_right" + action_suffix) * WALK_SPEED + velocity.x = move_toward(velocity.x, direction, ACCELERATION_SPEED * delta) + + if not is_zero_approx(velocity.x): + if velocity.x > 0.0: + sprite.scale.x = 1.0 + else: + sprite.scale.x = -1.0 + + floor_stop_on_slope = not platform_detector.is_colliding() + move_and_slide() + + var is_shooting := false + if Input.is_action_just_pressed("shoot" + action_suffix): + is_shooting = gun.shoot(sprite.scale.x) + + var animation := get_new_animation(is_shooting) + if animation != animation_player.current_animation and shoot_timer.is_stopped(): + if is_shooting: + shoot_timer.start() + animation_player.play(animation) + + +func get_new_animation(is_shooting := false) -> String: + var animation_new: String + if is_on_floor(): + if absf(velocity.x) > 0.1: + animation_new = "run" + else: + animation_new = "idle" + else: + if velocity.y > 0.0: + animation_new = "falling" + else: + animation_new = "jumping" + if is_shooting: + animation_new += "_weapon" + return animation_new + + +func try_jump() -> void: + if is_on_floor(): + jump_sound.pitch_scale = 1.0 + elif _double_jump_charged: + _double_jump_charged = false + velocity.x *= 2.5 + jump_sound.pitch_scale = 1.5 + else: + return + velocity.y = JUMP_VELOCITY + jump_sound.play() diff --git a/2d/platformer/src/Actors/Player.tscn b/2d/platformer/player/player.tscn similarity index 69% rename from 2d/platformer/src/Actors/Player.tscn rename to 2d/platformer/player/player.tscn index 2bc6212c..7bd84bb1 100644 --- a/2d/platformer/src/Actors/Player.tscn +++ b/2d/platformer/player/player.tscn @@ -1,26 +1,21 @@ -[gd_scene load_steps=21 format=2] +[gd_scene load_steps=18 format=3 uid="uid://d0ni64ucb3ym2"] -[ext_resource path="res://src/Actors/Player.gd" type="Script" id=1] -[ext_resource path="res://assets/art/player/robot_demo.png" type="Texture2D" id=2] -[ext_resource path="res://assets/audio/sfx/jump.wav" type="AudioStream" id=3] -[ext_resource path="res://assets/audio/sfx/shoot.wav" type="AudioStream" id=4] -[ext_resource path="res://assets/art/ui/touch_button_left.png" type="Texture2D" id=5] -[ext_resource path="res://assets/art/ui/touch_button_right.png" type="Texture2D" id=6] -[ext_resource path="res://assets/art/ui/touch_button_jump.png" type="Texture2D" id=7] -[ext_resource path="res://assets/art/ui/touch_button_fire.png" type="Texture2D" id=8] -[ext_resource path="res://src/Actors/Gun.gd" type="Script" id=9] +[ext_resource type="Script" path="res://player/player.gd" id="1"] +[ext_resource type="Texture2D" uid="uid://go76jbr7e1px" path="res://player/player.webp" id="2"] +[ext_resource type="AudioStream" uid="uid://i2vnokf2khqj" path="res://player/jump.wav" id="3"] +[ext_resource type="AudioStream" uid="uid://bpxywy45eqgwy" path="res://player/shoot.wav" id="4"] +[ext_resource type="Script" path="res://player/gun.gd" id="9"] -[sub_resource type="Animation" id=1] +[sub_resource type="Animation" id="1"] resource_name = "crouch" length = 0.01 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), @@ -28,17 +23,16 @@ tracks/0/keys = { "values": [22] } -[sub_resource type="Animation" id=2] +[sub_resource type="Animation" id="2"] resource_name = "falling" length = 0.01 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), @@ -46,17 +40,16 @@ tracks/0/keys = { "values": [21] } -[sub_resource type="Animation" id=3] +[sub_resource type="Animation" id="3"] resource_name = "falling_weapon" length = 0.5 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), @@ -64,16 +57,15 @@ tracks/0/keys = { "values": [26] } -[sub_resource type="Animation" id=4] +[sub_resource type="Animation" id="4"] length = 7.0 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0, 1.25, 1.5, 2, 4.5, 4.75, 5, 5.25), "transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1), @@ -81,16 +73,15 @@ tracks/0/keys = { "values": [16, 17, 18, 16, 19, 20, 19, 16] } -[sub_resource type="Animation" id=5] +[sub_resource type="Animation" id="5"] length = 0.5 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), @@ -98,16 +89,15 @@ tracks/0/keys = { "values": [25] } -[sub_resource type="Animation" id=6] +[sub_resource type="Animation" id="6"] length = 0.5 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0, 0.25, 0.5), "transitions": PackedFloat32Array(1, 1, 1), @@ -115,16 +105,15 @@ tracks/0/keys = { "values": [23, 24, 23] } -[sub_resource type="Animation" id=7] +[sub_resource type="Animation" id="7"] length = 0.5 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), @@ -132,16 +121,15 @@ tracks/0/keys = { "values": [26] } -[sub_resource type="Animation" id=8] +[sub_resource type="Animation" id="8"] length = 1.25 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0, 0.25, 0.5, 0.75, 1, 1.25), "transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), @@ -149,16 +137,15 @@ tracks/0/keys = { "values": [0, 1, 2, 3, 4, 0] } -[sub_resource type="Animation" id=9] +[sub_resource type="Animation" id="9"] length = 1.25 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0, 0.25, 0.5, 0.75, 1, 1.25), "transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), @@ -166,16 +153,15 @@ tracks/0/keys = { "values": [5, 6, 7, 8, 9, 5] } -[sub_resource type="Animation" id=10] +[sub_resource type="Animation" id="10"] length = 1.25 -loop = true step = 0.25 tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true tracks/0/path = NodePath("Sprite2D:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true tracks/0/keys = { "times": PackedFloat32Array(0, 0.25, 0.5, 0.75, 1, 1.25), "transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), @@ -183,68 +169,75 @@ tracks/0/keys = { "values": [10, 11, 12, 13, 14, 5] } -[sub_resource type="RectangleShape2D" id=11] -extents = Vector2(10, 14) +[sub_resource type="AnimationLibrary" id="AnimationLibrary_r678v"] +_data = { +"crouch": SubResource("1"), +"falling": SubResource("2"), +"falling_weapon": SubResource("3"), +"idle": SubResource("4"), +"idle_weapon": SubResource("5"), +"jumping": SubResource("6"), +"jumping_weapon": SubResource("7"), +"run": SubResource("8"), +"run_weapon": SubResource("9"), +"standing_weapon_ready": SubResource("10") +} + +[sub_resource type="RectangleShape2D" id="11"] +size = Vector2(20, 28) [node name="Player" type="CharacterBody2D"] -collision_mask = 30 -script = ExtResource( 1 ) +collision_mask = 28 +floor_max_angle = 0.907571 +floor_snap_length = 20.0 +safe_margin = 0.2 +script = ExtResource("1") [node name="ShootAnimation" type="Timer" parent="."] -process_mode = 0 wait_time = 0.2 one_shot = true [node name="PlatformDetector" type="RayCast2D" parent="."] -enabled = true -cast_to = Vector2(0, 6) collision_mask = 8 [node name="Sprite2D" type="Sprite2D" parent="."] position = Vector2(0, -14) -texture = ExtResource( 2 ) +texture = ExtResource("2") hframes = 16 vframes = 2 frame = 16 -[node name="Gun" type="Position2D" parent="Sprite2D"] +[node name="Gun" type="Marker2D" parent="Sprite2D"] position = Vector2(14, 1) -script = ExtResource( 9 ) +script = ExtResource("9") [node name="Shoot" type="AudioStreamPlayer2D" parent="Sprite2D/Gun"] position = Vector2(-30.6589, -6.13176) -stream = ExtResource( 4 ) +stream = ExtResource("4") [node name="Cooldown" type="Timer" parent="Sprite2D/Gun"] -process_mode = 0 wait_time = 0.3 one_shot = true [node name="AnimationPlayer" type="AnimationPlayer" parent="."] -playback_speed = 2.6 -anims/crouch = SubResource( 1 ) -anims/falling = SubResource( 2 ) -anims/falling_weapon = SubResource( 3 ) -anims/idle = SubResource( 4 ) -anims/idle_weapon = SubResource( 5 ) -anims/jumping = SubResource( 6 ) -anims/jumping_weapon = SubResource( 7 ) -anims/run = SubResource( 8 ) -anims/run_weapon = SubResource( 9 ) -anims/standing_weapon_ready = SubResource( 10 ) +libraries = { +"": SubResource("AnimationLibrary_r678v") +} -[node name="Camera3D" type="Camera2D" parent="."] +[node name="Camera" type="Camera2D" parent="."] position = Vector2(0, -28) -current = true -zoom = Vector2(0.5, 0.5) -process_mode = 0 +zoom = Vector2(2, 2) +limit_left = -315 +limit_top = -250 +limit_right = 955 +limit_bottom = 690 [node name="CollisionShape2D" type="CollisionShape2D" parent="."] position = Vector2(0, -14) -shape = SubResource( 11 ) +shape = SubResource("11") [node name="Jump" type="AudioStreamPlayer2D" parent="."] -stream = ExtResource( 3 ) +stream = ExtResource("3") [node name="UI" type="CanvasLayer" parent="."] layer = 0 @@ -252,7 +245,6 @@ layer = 0 [node name="Left" type="TouchScreenButton" parent="UI"] position = Vector2(27.7593, 360.87) scale = Vector2(1.49157, 1.46265) -normal = ExtResource( 5 ) passby_press = true action = "move_left" visibility_mode = 1 @@ -260,7 +252,6 @@ visibility_mode = 1 [node name="Right" type="TouchScreenButton" parent="UI"] position = Vector2(121.542, 361.415) scale = Vector2(1.49157, 1.46265) -normal = ExtResource( 6 ) passby_press = true action = "move_right" visibility_mode = 1 @@ -268,13 +259,11 @@ visibility_mode = 1 [node name="Jump" type="TouchScreenButton" parent="UI"] position = Vector2(666.224, 359.02) scale = Vector2(1.49157, 1.46265) -normal = ExtResource( 7 ) action = "jump" visibility_mode = 1 [node name="Fire" type="TouchScreenButton" parent="UI"] position = Vector2(668.073, 262.788) scale = Vector2(1.49157, 1.46265) -normal = ExtResource( 8 ) action = "shoot" visibility_mode = 1 diff --git a/2d/platformer/player/player.webp b/2d/platformer/player/player.webp new file mode 100644 index 0000000000000000000000000000000000000000..6343dfc73cd4a1ac0f615c1faaf4898419e16802 GIT binary patch literal 2092 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�l_%wrW$oa`(aA_@1Q*MM0m(?cQ^ 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 diff --git a/2d/platformer/screenshots/layout.webp b/2d/platformer/screenshots/layout.webp new file mode 100644 index 0000000000000000000000000000000000000000..fca43ae68a61357287af134c26d944d7288af761 GIT binary patch literal 41010 zcmV)+K#0FmNk&F0pa1|@MM6+kP&iB-pa1|bqr{*9^$x?fZ6oFC$WHekx%Z6_5ff0? zwInHt&eqrHtn0cuufOD8lA>FF9X&#Ykd&wBsuURv#eEb4u!!rWE2)|)FjWBS=;o}c zvO85S+hr%oR(CgjyB@FZZrg2}=_;~!H`Bel_u6Z%z1H+hH`9V?*x7q;VD@wEJu|a6 zGqafs&qZhJD7Fp$^g1iCZQVnXJmdhdP0pvJ63wx6YYRY+No=rfo!8wX zWn1D_=biitmlJLijhraA?*IquHae}3-rG`Q8`-ub#SaN6wj|kBWb1A2KF-Xb&wxMt ze|f+EUv(Sj|JsY0?lNN-hAETbnJ{OVnVFf_l)1f_nfbczGV{%=xBE|AOMAcfd%w@t zwlYvU^609ffE)KXaYh--a%M@fyjCk1Tn}nNw-l zww=xMB%N*Bwr%{fZQHiD;MIp?{rDKU~HMUpbBvZn8zNrKm38)p7rW@;GdzXP{z97*0@ zFZT7D+Xr};|Nn8@=KoUeW^yYz08b8}-HRJTiJe-O$boye)ur@)AT9@yW63Gu-9Dcs zkzO}iz)jT0As`_`K)^s84#bO|h|unEy^xn2T>TP0c zA~&;j-Mv*}W@e4BBZbP8`Dg53a>V`vW@ct)TQvQ8w&ay8+g2Mp>IP+@;J$JmWq*Ok z@Bar56sp2GN9n@l!pouhPm7Txp^=qobHIYP2lPfT?ty!@bRU+b{Zk}exfcdts%Q!L~cCtE+zb&)>h|n;x9TeR*VyQzVi|;?DZ`$v81fyjDb1)EBHH zNfv2Fzm-WYsZCVPOc#uaG8}8$R3{Vk-kZ#i zJH*rdEmEaRO{*(m3#=tx;x22Tgat(A`(`5Nz;OV{k+Lqrd+)vJXwAKV=puCg-~;>) zG}m}&d`g5ytx{j(3HvV#lBBS$b{#!ik?gbfz<}<=OZm^1tZi!~IScWfH^J;Hykchd zP98sR^HgmVtP!K~orfNkwd#JLb3ye*s&WR~U zwz(k<6`jK~vfBUv%qX_GXeLOXWpZ6q+IX7-SdE)%+m_|~b#i;(?{}O20)G)@bB6+~ zWFP_s=)mmIfk_L{e+sni#%-ey+1->5Aa<|OM-Y-S$CmqliX=H}Iteo~vwa6uBc%UKWL|{6YbjFVRe~x4~M`A>#j43bOfZluWGC`s4 zz#E81QS2gJL{)!RJyo^c``lnaQ>={H0`ur10<+mGlnh8gOZ2XT1-ct> z699k`;qDNE2*jZX5oo}61=w6hcjx_o{*~QrY}-l|;i1D7Tq61}fO#o3P=LF9>Ax)6 zwt_agH?a+Ba=MULlSm-V3?IH_ZCmCx+qU(|d~Uwyn8gai^nEW0E%RMI&*Rw7>l&C7{KMQ7z_p*1JQq3v~9(0b8qeC z1qcYZK}017P&yh*WUvG#<3T4B8#2Kk;|Y$F z?fdAj|Fme^3fo5abZKm@sJY@P7|_G16L~&vN_Zb0<;yu+;vY;h5c}2XwJXDQw0A*wctYm3n>VEpxV%FG|Fo>!0*BGDfVXuuh#3R*P zU76_K_E_DFdze1FU1#TY<K*2JS>-96%Y_!72}FamuQ(D`5x~P-B34MEi%oy7JKD_4RRA z&hvGhzujm)4cE-et*0>#pp5LGl_)JvSv7Vg450#Qj8Avrm8bsdisa&Sp0B;(e2{+o z^c$Zu#sQR(9jx+@7N@KlyAp;_0X2rFn>zox$qcBjNc2#<_I2?%ov%M%5}*2$IS!x9 z>|m9Lv^Ztf*qJbd3aBwWJsa;TZ;^7F>8-9bG>{!m8d@fZzHbI23g7eAEs1)9`Py42 z?Ws@VaR5cwA39!B?6wQOYa;4)lsw}T|MgA(agID40;Sb7p1(*)-9{?W&K=j9k+fR3Ar#PbzWu^iA zH^2je-}vwn9YcV#R;bz%4N+WtyZ{K$XC+AaXec@`Sv5ud$#HFn;-S?=c}i0NSYRd5 zNXQ6wiZk|5-EIK+2N3`9a3>98MXYYEX$xbS8{Gql(L;1YxqSIJfigQjt_6Qci04EI z8u0!|;I4=20J%yg=^8r4`EbZivf_*_#9y}x)m{MS0X%^E$`8OmleO{)AVaxoAV;kU zi3E_!rU*eS(-oLwYr#&-hyz7c911JW$m3!Zz@Gx(TD^dtA;1Kd8g4qk_f?6y#Lggn zBt(ggr^H9V5g;{w5YdgPD%iHTrNv!vOvhfJHFD%a%O> zw$f6dIuh^rX#ij%2bSAtJChX3aCp8ks!s&!=oepO!TmA7M?X1DkJhUbhH$19u2U#f z&eyg;OU$v=ilan@-UIfu3C2*RDG&xa62k$7 z2y2djRC7WkF|^_4kw8n-M1z5zpdbA3w|xG7^J`h2h`=Um+cn@Pv$GUvh(KL{{bD66 zqd*N{_OEcJIr7rZobl2dqEQedE+7zq%@QU?fR3`dk=i(`sl=zq9IgmQCC}6=iR@t8|&I#Uv~zqcf0HBpE*9pFVOA& z_E-^sOHnf^xDz?jB{vF-w*r7SklHq;A4n;ns~r=N>Jq5Lt%oJrE@DH3_Jqy^L_~w) zO{Jd$QL=XE*K4ocZue3*6!VE3xc9m3qy;GmlmBKXgx>> z26V9znt=l7PwXW3IY(jfj;N4BsPA(*DBm?i|Mh!Yt-qM979XDL8!QeM;SpG{_*<(x zi$6z?a)DE2#nPYXQNNsp#Tzm}o>ErxvacuVzXR7r`69*}$2`J72n9moVr+H0>5qym zCf;?)=9~A0wTVO*3sLT$8L@TV6=cBRj3{T_QJNN6OuQW-z3=+fma{Kf$1F~)oGgtL)M_HRdZaQG)TX8t*krak+P7DZ-_w<{d$W?3j69QsH$ z@v$R1eDXw&0K}Nh+x%dS8XPBx1e4cT| zC)nM3OTL?YAUeF{axEuYrBY;+c%RiK7oT7?W{G;eNoi4K)o7qT!BR@0u_h%>;_(R< z=^aZ?G>66zo$r|4)zy;nND3!LysKnKdX}`__f!S=fyMdJiI<0(U35+4E;A|+3$-e z48ssY4Qewh>-%>MnOUzdr`rLaLc`2@eU6he%lDV2CvO9|`>a%F>IsgxJi$?P^on?R zy90l5&9`3?*qB+x|7~U+3gCN7@uPhJd>igozy4?AY%}Wy&Uc@V=izDi-SsCnW>)cj zn^}hdRL%zYQ^Vuy0ZJmXCWDz}&{UbNd0phbQIC^39!l9e^*w74glRJ9o~a zX;Gw&j}DM~J#uCh&vwW6G1P5jn%*TN|No;?r$?nHBT^;iRj3)74_{dM*F*LNx6h=@ zE}r8xTsoUB`-9l#TYEM8uIty?bJEdk`gi;K$`6}&bxz{L=U&r^f7+l2dtS-!7W<0- z{O17i-TTKsJn*0YT=C_In24EKKJJpaf8<+#Q<%0-4)l$7bMF1^QjuTrvCI}%?E74) zA3Kay1d_O7_sEB`$~87IczLR!Q0xcqqABQfxmo}S0sg9VQxL&)Ro7QxFp_A_hr2UJ%z^ZkKFqWBR zdj!0hq?uXo)Q)c7es`z1TWpk>6_qDRGqbjR?sId{;+W^+13w4-{+FmYa{ftyE1$nx zY?hgIC?bZJnbkN%@84W86njtp>q}k3FOhL-y+~$OTqG}M7TJnGU=ThDwu-Wc^pXU@ z|B`1=6IDO0`(l|{F_E~KS+ErW>eadfjbp3>tx_+GU7^Q*OVI?Iha6jiQ*?YdtG5wt z`R~pWoG?3BGxaxe5BQzRFtZ+-d}U`(uoZy`wJ4y& zB!y$3U>AElbkpQ$r_&i#Vhr`1;aV+kY`jX&Ax_cpIGr@GSiD{ZIA4F6uReT9uf9s~ zPw`*USf4uQW!0ehKBB2vX4c_|Sidw(tg77S;B3GB*R{7>ms=4C2}&c-IPx=mJhmNd z5qkNF&!XLKfANKELMuRM{Q028{N}el#3?!+uaoYDep&m~jKDv|e|fex)72W&(`D2` z^LlC$fr1|4V6%&KK6^s6tUlTc{8-KH=d!LL9I`4Bc=T`O5;)?pp1K>qK; zbDy`$va01q<(QfEF=eN&#)ka(HT8HV6v|{mnt5i%-M^aPM$cEMwJ2vonLC*isr>%i$}?n(uQ#?XJGTGP6$Um^+h<@k~ZH{rP^GSs#1#v?lYTvIXq;(QIhf%na`v z37y9ivFxj_^66Us*k@)k%d{HOduw{D^zaE=O@BLIf5>U|e;m|5aZIf3Sw)sJ9xO8} zX4?C^fYg3%Uz1m67A^gteHA*Y2j-xbb^9?P6R5k#3; zd0K%jdaBY&Z629foY2Ftv6ViR;C;iZN_sef2P;UuO6cwJ<3Y`K&VP(oHDDU0Q>;nk z$D1#rq4jti&KVDsnH9CCJwFZ8U)rw9B{PfDcI!8-ne3<()RNJqc18;fN(5Q@i-O1N zw0mHwHQ-!PK}~A6#Dnwjq5;!g5nfzjO(4Id`TlmkMw_qkF~}JYmYKB@5$lz*hqi6= znJ38nLUvBE8lXrik~#4%#|JDVj2SG8H>4MN5AdMBuNAt1)V4C5uFm(k z-kWC2xS8)v(+siF3<-B|h&c}F%LT{z`JfdFae&i%-wQzyjaO>juOo)8?+$;d*iBkR6L3fRYf$NPP1 zf@;+n_rsUOm=wO6st8GsS%w8|`?0Y<<>=9?D8y8lI!S0u&p=hC(V526dV6c;%X`p zjo%%MYYT6_R4I5opkuj_GByY2dPWl;k45gXh9qaayNsV*Y$;AWn!sW9O&58Ode6>! zzYWG=LZ2I=x1#o{cM6=q zAyddk{gLGK-+50{v>7bdY8c}c6*M@q0>N?KX8#njL$*C;{IDG|ZIg}J41j~!THtV- z0EiQD2#8{mb(k?W67ZU3 zOXOlWH8o3=#xYs*ZT?630K;x>mN(y@7E5Du^RHs|)Gp2O;=X1<=HOg~_(Y6{n^p=9 z{b{{6(VwccBE-xhyHl`lw8(pEI_FaC>8oUJTkji{G{pap~1_gArOyOjqs zO>j66z!GWz$&Xfbi^(=v%Y_dX8}cNzDmLt|oQ(s4ui1=Nd}A7JZ(p%OB;g0O8&OwK zkoK0w5u?HiS5wm9l{ZuHnq?6=KgTIVBF`!`Z@w}WP;~{NjLi)qmYMZuCd(aBw3t!4Rmam}UymExFY2aJW9!n2ieqAKMY|yQ?{eMA zglrP&YFb2PV(Ds%0Y!2(H3gb#3Tg$LFRGdX6WV+Q)fC(-l$k|~91qW=tk*dh9GjKl zL1>;Jw)PRDWmj(@EjJVVp9K}H@DFcNdErII>4oza-M9t(u$L$>fOI zk}9KhVkh2M)e#0^$dlE|0MQ9l#OrHgDc+?jrp4UPRIK1ME$@6!;lC0JRxMvmJ&Z`J zsi3QFCb2@H5Q`nB%ut_JT(bIDjJ>KE!%<~I^KJgiI|0LPZk9LS=4Lf>lXncV?H)or z;&O2M;sB<{qe(a0t6EDJ5}|luX1NkOf6ws1YLWL?hHC(mgBt`py>L(@E17qjgnvN@ zj1~0Tz2o8d)k5tIU(7)yyWL=6?oh=Su_xoEiq9avITF_}MJ;Hd4-^aIr!R9>ij zIB(TY@rVT^i*Fj?I5HeppX^ZWs>O0w@zNbdt^X#;>@|6R-;@8kzIF`fj%`M{_6<;W zb6iJ#tbOH7RBO*;nJ8Fg3$0qdnjWXjbaBP|I#QEYQ-B3F)nZb93`bo-aDQ|2uU+M& z=9~Lzv8=lDoO0{3M00TH1wS61rlQCs&iy`G=ZMMJC=easl2e# z+Yy|l-VSk~EZ_{U$0M5sJdTZcy_<1R@#=8~LH9zkt7y&{@)WhA&Qh)aw#VDgzPVy( z?bq(ZUt(IyF4v50Mwc>wJMTZ!vn&(EHHc>@X1dIMAt>?jOsbhLJ-8xYJH&573$Rzx zY-E<2+70-M*+IE~J6{K>ZdX1}&uHQtFIXPUgB;c`X6+g}B6Bl?a&V-1G%y4vr9{jk z!sTjJS4ti@=p>e7jWdWG9}}$|4yXq}IbCd2MAz23Mwr%oX$g+1qfoIGh)Y z)z(t^XLv8QdjS8`9)1tD45p{K9Gt7JdN3hYs%j}JGyt_TM*tZFb%1f091yUCm<0$p ziWWG6AP7QKl$EQ!?A7D)Ysz$m7{qtyN2aJ%)>ZLagG;k z4$hjkuevr-+1?&a9c|k-o{i^3o~D#^pc7HFdBcXa;T>UyuyzNygRdCgQ@LS7c(W1y z8Q#lJcmQAD#rE)fuw}sVXx0fa$8$5Yw>_GvlZXg+|Aq2srW1{r`Qt@i6Id}P@-&sA z1D%Az%~S*<{4+h5PO8j2fN$txd-y%rG8m0UR1S^;e8(vz#9YtK%-Z&7rd)FFS%~G) zq(m`Z2fQiR(--eah~&{sY&prniMl50W3BB$R1JL+iZ)l{#%QRXuGH1lGd-72uE@2v zN3@^kvkNMBEL=oj4vt&&Fl(nWz4j5?sy)8Pj2|Y&Gy)qU38slihJ(pO6_6=kh{k?m z55EUn25b(_g@jmyYbh$@GOPJ(Ay=EB5Ch-{Ec1;SGEK9(`j8Q$A(O*!784*a2EcKm zW9Lk|7tNQ0;2drKe$ETSq~Vw$#y_!ZL(JUs#m-LrOI6Ys7c|0!oToscJes5^#NdalqVT%yXuX*KrUZQzcL`UUgXhZ;>)RYsb{&Dg7fa|P zN%hlFDDOU`?k;sMj9oL6&|otqIc}+=-9j9p_}u(5qTFyS(NhOU5rQ*wr%K6AFp>cF{l#e7B+Du6;*n045zYN$~ik3$K zP5FPg!mYF9;8er5t#qiR#m$|KWw?=R>ZA|wIVUAwPMbqZqw}0Y&aT5pkc2*jd_U&( zl&HdqCXG_(&Ok|Qrry@qoyT9j0WW2S#pd8Fmq)Q!M-n&js_1KqRw%ZSDKcnoDvse6 z@rzK%Hbb@z0wMTUz_QDLDG=Xmao?5=Gc?;a-{WPQA%O_NX>&p}93ErsUh(^iN_2J- zzEmZBAS~sHsrLMO)kYpP%{w@~EbR;gUU}seUJq`GWWie8W~wmOl_(qzFJ1aAZ%B8y zEFfJ+CM;)`R02+zqT4**k)Gyq*OQurQzzooO|F{9N|v?SmIYJYz_d3Y|4l24X_f^+r1^5jfAdd#&__$7Q@e_sUFXL*$F}ytPhtsu zC|{~l(TQt2mwlpbFPFv!eYu;KXU?1<4w6`$6u;0!c-78;Ow!HNP&^!!Hq}?)Vo}@a?hx?NHKk=!KRGiRIA{ zk4I$m!V53FAlgCkGV#rRzwf1%B5LAQ?lvp3W7`yMOmtOMRhz~p$Sqx4TQZpxUuV>I zESn=RFZxJRWE?7Jqh`js)Vg?{Uf#h zKxyaVJIkeU2i8H7UGIq}nwur}g6vW|qcmeDTcb!#CU!P`7<{0Q5 zw$T)Mu6!vHj;<#YkTWZ_5jE#$IE6wA;C$-r-tMyI^c#v(3jsC(Cs*@JIpaTl`VYf# zWDB9?(6eptNS5UtgKQ&fDY9grj%ZuqCs6oBU5PNC(18yg4Lb2EPn&Uegp-(kr<9rsY0QUl1ac>lllo#uHX0#{*R%lHc)g&dd9E``kB)B z_a6m4g%{p)$#R^p*^Q&;CfQ_;ty?$I!<=Z8-O~E|fc({coLC+Wx%(bD5+fP)WYT;> z2QF$Uq9$JDZZpr0P{Q8Pf$owg)61w=o|yK=ayAob96^>8hl_+GC~bIsD@ICt9loaQ zF~qsypZ`=_{-xiSV|VcVgYUCjVgk=Rd7x}=7PjcH<0Xz-O7hKgxi(Qp^r|GA%&|%q zj#yM$*x$c!-8Y;?Au$}K)~sQd6s=kF6Qp!l7_@QvDMf2Yz1h>V<~{en{`4WyV@emo zS9k8i#MV+o@4iuzVNWJa-YUhQPwna=2ghLIRjILR71W>tB3vy_HkKjd+R>?s&`n#Ve8X{tuW1?~v-BMuJfxxFb{oYgPv#*tPA2nsZ&{dd8oVb) zK}JKQgfh0i)uHq~{c$H9ilam$%sYPg$Zd8n!5k>Xt5(3hWl!rnp%=K_pCde+>xPk@ z`xCOLEj?;8eU9;)&Zsac9Nj=98^dH@^s5L1)8B-Z8nxdX>HiH&EjHhtU%V1=MT?6o zD<^sw6C2r=ItY;eY%N9L?mMq(MHD=fNdwK~$pJIVYT{LGzX8Kxq3^pFe}_>_5tfr6 zI4Tn+Y32LYC26|6BF>#k=lDAPpJ}2k_c!zY`rMNL)jUEX#9cTC(cOr(-Yb@7CP!&-Hn81=HaNMqy&bebBYtPKRU{4yM6;o zeF6dt(-Tko&56@cnH}M}afpJ2u)tYxa`Fh1_`%7^t-oO6=bcNDwD=BA+An4%lMW_y zV9d<2nRrzSfD8w&Vlz7Mw#lX67itGntx^k7t&&AcTU(pPfZ)dY9>q`n{S9a+>Jmu6 zDeS!^^ly=j!Iw&{V?{kT_W|pY*YA>(1JnW~6n@HEnZ_DJngVnmkJDlwB578X85mljMIm=<0o@lv|;8Q#*PBSl{Z zJ)93kMr`pTSvGlOsBCht+s}|=At)ll^!>X)+nY}-gy5z;EkPjr6Pkvx!%=`;Lp@*j&l7!n4j;@nspp zHTDD!ElP22B!S=t7xH8i5%TdP3CV`@&u9}0@k>=g>Q|)8O0T;rngG;GcRdSXGc6u3 zQSAHihx0$W_P=FCn6twalj4yOU4ejXHNETz)4)ongHWcoq|{nuxHnP|Q|*DU+cou*u{pkDY_#ICy9S zSKAsmGz|&KhVxG@zCA%w2wE+hl^}d_am$VgkPJNPO$>0SzEH;oTvyL#BZDPVp9pk{ z6&lJ2%ogL$=b30H+b|K|=g@r1jDvGz)xav+O2b^|vhy95foftw?$NE$b;cPtXI0H&0M-xU94wr$Nj_HthK1aEDmrv!Ce1 zP93;AN*<-``o?D%4 z5~p$0TBy?lV1sU8Ak7Ch@_}+TLA}Yo0)FD6j^`S6>eNIMZ_TW=)Ms6^sF_)hoTIe; zts0h=@cp78q77}p0deTiZaGg7#|fJ!cw0*gbvm7A7LS8Sv%fBumuFc;gzvWRtkb7j z`M5jI81?h{JO(5(+?=bQ&l7M=`#y?u%!~7VobtivhKtDZ+nNJ7*z&m`S(4i21b6E+8@zoP~VoKExl0b#%@=ezCo zcWN0I@AAg{74W-e%amu+-FnLsJ}m`A%6Ee4F425-0ur3H##w9B_c;@a1Ht>?Y&sY| ze&<~x$5|_c&s_h{CM@yebw_sV!|w>e}h`CD9Pj77nph zK%*L*CrCYX!COh#HKg6bkMr7V_mWNGq_w=W20M)X^~c96BG!C|s-B(-PE@xCgfb z-cki!Wl8#}f0~>phWlgCIq<5~l@V zkCPVy6Mtva%o+xknps{E-tQkT?uwroQ5hD}S~azI4h~mhmo^pF^y|ViEBMz%ZFk*O za+lxdO!#b>RtXzKl1;9wO`A?90mu5d4#mm5IA>u>wxveHS#7%xbZO&+ENnSA`?|7< zoCY#%S}83Im>Y`v*9K}$2(>+taQO8Ccv7!GXW$Ix=M7>zK*Lek8x$w=;%rb#9+Kra zUFr0qSVzIm;nJ(|%>mgZT7o_fc=hIErgpq7$z`d1Vmar>@yNmXxtxQu?C+|%b!h{4;DSQ|cQOXYO?$s$`k?CqQ{%vxwnt&W(fN>u*0rILqF;!kT6(2eUQkm7l4| ze;q>jY?-bRM6^%Kl)d$qMgI^@&jCPjDlblpQ=Ui%^W`{tl#ae*P$Dk14oJtB5q)cB z?b-6d%!;}mI{`U!yGjrz4V))vX>*=nFG!wXe|LpeI-NGQ>tw>dZ-Lf?Fh(Geh$a$j z0l=hQ2u^l>nub$KJwR~^FHVb7X0H=T3QnyTzhjIS;?hfL&H-8IHQzkJ{zH!#@o~T_ z<3e&~39(JV0i)XhIQ}^}%nS56e`u|Z4YicM#b?VDqcw=`7`>e|@Z6esaT=KN)K}6Q z^Ad1i8f^{kY4xv}wTH_AGpkJNm`WkIq{KkZEHVu{4nbmnv%0WaDh(X@US=LmWH{a! zqoLpoN+{02i__qgUauU-rU4(g#_cIv%`8^;ROq$=dvHqmCybnf<7jgZPA^Oj&WCop z_DXo(!x0|yf`g0r4LQ(9stH19G^@i{WEOZeC!nE%>4yoBRR7iGED%S zFmq--VYO@R`_jOXuO6or0pIeDfEP_0hW!~qHt)3)2h6OJC-?gnJ+@PL%w6kd7?zQo zS(Y~E3HHLwne~L_zDivLPN7qe(@KC>!r+ZJO$2fQvsZ?iSw4}Ze}+w)kDH*JQ8mU> z6XLS6GNb3uY*89!oblBOb8ys#d2dOUTRHX|0IM}2@DWglvoI(_!!LMU^`cpXVgDD% zW{()}`4>_CG={Er@?;=q7MUgx&b_4m=7tt<bQjlc|kc*NF9uPNt zg>jw(5M}`Wg|bipGW+Ymjtyh250`33`X@gLJ)6$f|;9F)_eP~+u0Pxk!(t`U9-0s@pp#o7; zZ%@P;M>CqbzD&D^O}Qh~gJ_xO!U0J?E-R)7ve!rH$7pJ;#k`i44y#8hELfwdOfn5* z(6*bkv>pJxW4%h>w{YaE$7w~tx11y3^`*r+H0}XlteFMl;Nd&E zr0R4s99}~FRGN>aJa4nn;3Qt})$c_K-84sP6O+K%CI^Gb$-yJa zT8~(7or43HlTwerYrZRhBib5$pQcp2h zGrEw%0jIJh+?jcTMO_p{ts5I#~NDIte9pai98RW!^IpwBPEr<_z0am2YK)(Orammd30;HXjkvawNq!jea4P8FJ_ z*qkDjb7tl4)0qym3FB=?gyC&xXurD73a|o<@HFSBT&501U84j2$BVeNAAh$*;q`PA zg%M1JxZYgogs>b5Lyw2=&y%gytb-IFj9y7O_fxefC6BL^YLlba${)#FKm|Ywn{zO; zGOkdGob*&t)FJTk_xbRIe_;tWI4|W4GIovKjn7o5Qiv0PondBOnzvsEax^IXJn`;9Ks|n*|v&(9|tqKU5=Tg@-wH zmZk8gz(UmMj(F_t5=BnL#5%!o$S?TJGGOhH8V1ToZPKxt^l0;vOF5LN<4VkVrQ8r+ zy1Xx5t4rjk=vVXU;5*lYctb>(FLMsN8y$)d&`+(djvI`1Ka*bzAg`Bam2YK)(MJ0s-#vzNhRj2CaLWd`5>0wdH86Z$cCN&kR z0gn8X;e=ujW@a&x`l>%y>1LA&jYdbsA4gaX^CSzQpDYYG`E;MtGG|s;BC7{_GMD2_uIf*3_ke5z_2TGM#A9*$!qc37EU>L~!*EH!VXhEagJ zRkz^zxz*3TZA*yAp6AtS-uQ4vuEQL^ynjFZzzghJSak}4V}e>|&iDZ-kE^`gfhxb8 zgn{Al^bcdj5tAo4*yRZpjHE96vj~W9ACU?X>H`v=o`hM}3Vy!GvJrVyWL1^H`l_k~ zbM^u$nlr0lz99jrQu0B?P(Z~{!kEf9-dR1@F%^$|WG1#E*FZw(d53lz=Rezi_EJ3T zRF83fy$+1!*ueR5146hKAGiy;TFu(YWLSk*g9xZBrmpGtCX-N;F+zw0ClZNPCVi1Y zMo*KG%In~^VVi|-7oA9DZ;xzS!o^=As&>K)tMY2S!#|fP$1h)|a-c%&p0?m~1od6A zPruA%Grr8-dZIj7fazh~n2N%7U_n_BQvd~rqWtQ~oQzAQ^u)0N&cR6-P9XMhW)>r< zGijlz6akj_uIF_LJO`YZ?sMkZeQx`lS+35iNgY^#3GeR?!1pxtOs%XrC1Vc8`HH2V z&{c1BmAltEyfKSzX)K%_P*W_X z=u043@uc#}WP~x_iq?lI-)Dqj2I5GlF%gL(%7hs(WsncWg!0n5cx9zlBjv4;IG%%{ z29}=>ZCjEDFRuC(zjp0feyy?j@?pev6#`OVo9dG#EOS(OWW(0XmWN^BFww1_nc0{r zi7C#KnHuU!wBJ)}UB-Z#*xKBF`z4>LP^Aw?9J^kF6Q9)H>P*MbRI0kA$+CXi)0t~~ z4$hbg9{%3=grx%WGtUNp0Olv}dpCsh0mq0r=yu+DescDDJ!R;M7vh)-wB%5oIHuxE zQRciQJvk6sh(}+2Y-n1r3HqEAhr=TvHIyNkD1@oV$3R%icNn3Q&b5rFUU@SP{u)wV zzF8cNKtJdCPuX;tx76IWe}NH^ER^xEb;b0#sja$-PPmOemU zGp1s?QGCLZMsPy~OXzt3=>-UGSMqskbxFkWa>+0Uhmq8dN3KJHk{x#n1EFCm*Zc@= zpEIivc?13$)f+eD@Csy3Sa1vYM;%eS&7vV&bjW-}v_}XHhMkDokfXIbdtWgev99C; z-#0ik>`=}`kumV(rY^?!eMNaQ87!}~T{NI$b}c!!ZsMSG8-?FkffM;p!)qKaTg`?l zskU~lfJ{ln0OYTUkk1U6Dv{b!&iJfDYfPQ*DXJxlLXjDs0XQ6drb3lM9C_?-+)Imc zC^z&)QIZq>pRBGsE>54v{k;9XD|!mxs^UzO|W zCaeUNz=2$cefrP~VCV!rdw&MfdNw#)2}yX@4Ll}Mc1^#h#-w9U6w^F{5F-HNIK(SV zVGuc(%8fQJa9KQIs*%ez>bW|Iv9ZlSt8ThEG<7R3*(`<{1fEy%G9Jmua4PF(z2Gc{ z7m*+j-iMco4m}-+o_XQgYQjd*Bz~xuWrbu0_i9!Yf{Zd~agbZ3BL|-{S6_6@9i0ho zyJ2~eQT`%Q9$QuuGnrtMF%`^u9GNpjj6uO67Dwe0S*qnf6{=y7ievE%smZ}{RbV9b zV#kmdxXuof)NrfIx^Vtij^D#i?kqqoP`;lBLN=8AlIc)pR#xK(Tbd&9$@|`Cp6&Ye z=Wk?w=D1BTgwaO7Hl~cGQF1E^5TYgASQ4g!4&40WQkI`4Ck+oaD1okuJO0Xf$%X zViLv#?clmmMCxv{8buySbjZ-n5;!!BC<-efd3@nZL$Gh@uh6Lq*0!xhv;vlG0ZpKy zrg(-)RB;s)1F!P@PYh80V%-wX6DselqbQn&2{w74SfczYhb)s~P)KaWMT%pesZa^W zVIadNIqb()ouZT4v4HD;7KAO~Ew|q|yhyK3kQR_^cQgklgIEF-K7md@6i zb2JlAAqZ+GJ%!M4wPbTZ@Gq8_?4cRJ*0|35jlZ_a9aPjfc%fx%CQk3A7$NW@41 zI--%N1U)Vy^F0Y3s~hjFPU5)1#SrQ&w?Yw)P}ya(*@li9bf`LTDPG_)ya2u#!~M57 z@Cf^E#V4Qq>~W~jKb?9PJ(`s)uT74N5!eUgVw%Mdf8rzL+ z+i2X_wr$&d_j~XCKVzJ;_Fj9gxp3xYEl(f(e&HtHRG(k2K93X0qRxk+$1qO(7=|MB z(mhPB90m82CJzlG0)|#l3?T~aN4;YNfMaJm0;iXZoSYQ3{YByE_*i+!tzji79meU` zS&`ywmRDDv38SiOR=D_lbN;}AG?YEw#FW&`m!x{5h!`@Ez;kk_YWHP7gUzcv#OpQH z>sAcU=kZyt*1@gwt5b4nu_$Bqd>(4b>c|4e>jrUN z28Mzecv!*#%-RY`Lf*k)&qHr9O7^#kuqhWsX!ihU$tV7h4yA29^BG3x@tc8MvLLJs zrK2ldRDgUhYC|V2da(HFovf;8n$`^C)7Y-RU|Z825Z5h)o6qKi*gWhSuzVxt3`?ycW8j)HtRSxEt>< zc-?b$LudQTbNhQQ%lP%~(pC~w&ev8!amB1ldo;3kYI&M5US`=hn*$BHelsB25O>yc zZga{l&XrWd+cs&`K+@heM_qUw;#(TNE#g$a#1@>=H?@@_4}wqxj)r;I=}XiNXag8L@cx`INkdiPw3 zc8o#f#m&vybQj&2U2VZ=>z`FHq2}t1g{PRwCO@xVsK5yRsGGSxPmYgkt7+Gq31XFW zilssseB0`%x)s6?!Hu6ctk~GRd+luSeC|cUzj}Fp!{HRdsnKRpkR-2%87jxS&2BkZ zRtCQ>7c^aRtA<4rm|`G32$#icCN@e*7yXF18J`lKK<8@SvX|ZJx%tV-y}VPSd3e{> zW$@s-h7|U(;jv{@6&jjU-zUD8Nk~iJuQMh2y~r$`+3Ngha~NUr{ZZ$0-hfdVwt7@x zF!lS2wdda22ZoxGdGgIZf9)qIg$@wD8z(2@ed7J+rN#6OpWM<|8T3qv*&a`ZnV{+~ zzH-eOh1B~zdxt$uUVA&_z;k{>d)Fq)6U9VSA>mfX9kH9dyW8a%6v7P>9$IGo7RPMk zFX7gXU!n7@t}5Ep9$>_>v`Ar zFw}P39n}%={q(|EJ$`I8as2dZ_x3-&k1wu5LC>&J*7gn~v6O}A+qa%AKTbvhjop{C zN`$l)PbqjC>8t_NSbykHA?A~6LO5?VwJGACI7ogFJ6=8EjP+FM06$;L(Ri?j*i6lp z5oXx1;D6w#GSPSck@{usH(p`)$KeSkgVxefZXBR3hmV6pMnOR8q(*r)#WdqH*kypU zM_4pjNK6CX-aFL1R^oXVxNDSq76~k68+`5rCmv^g@+LqyNrFW0_CQmxW)tKLmITl9 zD-2pa*!ZHyzVh($IG01o7-D%2KA9p8boERZTeq(Y{g}5Rt;0i1soYE_u(mcnwdL2I zOzhnTHso(3uctLTJc;Jo_q5EF8sUbcV`ql_3zcXkbi%V$djlgltvM-5n;7UY0Q+J{ zN$1HsfKTQy(z_{E;|z%KtJ)r?NI0l)+(;}`yq9LpmGWvgh>Bou=$=WHGIH#Hi)108 zS|rIMuLkaqi`H)Ckm9L?!{SO!vkk4q>1ko6N}-H$l7cthg#O6+$gyOERV|q0^Ek_m z=PKfNdEak5RcKw06($#X8M8i3_c37RhY@E*QI%_qr%;jL*Cd(B#CM{PaVJYwli2|i zPRP8iDH%*9S1y#c<<(Xyps$%4jg)epJGL-D!rGZwe6{DedENGP0t%G2dNTPovuLwf zSQ){()5yDarfk$en0?q;}E|UFjLYRHF4|%GWV1iO!4C2 zVQBmd?kT4Yec_QfFF*AEMF?r)zc2a9oAUBNQ=Kag|*$E2F0O-2uV# zO%srB=^c~W*J%)Bi4ewWU-n&M#Ry|nAvXB;{sAl@vVzp5pUh%n^&33+sgIU?v23Df zsD$W&D*NCS(_2>C%xKj%H01XzXl&^nB&w&~NNQyjfDl%hDn-pcp}LZpJ2FE}%#fS3 z*hD8Y>OETXTDE-rS=Ppa&*(zW#re656AF>d>dVN>uAyf;`i3p^euW10lT8GFaAmn3erKN^*>4Akz{B0ejrTziR;%SCvku2 z85~)kS%XbdPl6-ed_I*cO_8Bi!60IAu(Lm<0$?G0L_`v< z0`)CBmxalWx`czDhzfX(2HT60zyowml}M5aU>RZ4vJjN` zOR39Y1hHvp@AlTx{7r0`QD!oknOg8w^ztvIn;#(NCFf)-7HC>sQ4+eI9Pj7#H>M*S zDeKFZtE|l8l~K%yKXs`#yH&oWxp@d9^$W~SO6Ze9thiU2fpLvnUL%SMHdHxmQtyu> zW$JlAlX@w!{GK0-CjsEF0LQ7Dj@U4I9LUy0L4C}IHEl8s>8q()Ex5MFkvo+ad7Fnr zObL~{wp}PZ{SgFKltS0QQVVaPE7m3f50T!AO*js35=cLdo~V?l0S@E2ag7Lieca&5 zo+RowbgZa`62V9)Q}Tmu|Lm0peoyVvuBM;pgEmxn z^Sp?4#ofVBfOSrNq83xWW`@uc6-HDvBrOvh+$S&}kuLUz>q?LVm>Qee%a)F<-M7+p}qO)+Cv<%X({TE3YPsJ`e#`yI7_k7=e)$ zz1h&vAU-Awn;SXiqO3h19G1(7p{DoCZ~u74O?u2KU|G-#Z|c47h(gO6S1ZvBqr_+w z^M=4^Cu02T^QnvWyDlH(9ck&!OFI+j5OJ=peLYk;$Xhy_?-YKPipEHgW8_NJA#(4y0y4T%{J!&|aJZ&}bXCTUv37rGTULXSvkTf_h46kIb-k@O z6`YF)xE+F$Q4w<-^>c6i^!k-*HTydUIczk_|CEX%CVS{+RQXEr4Nef0f2}FCHRZ zVXJX>a>k5wTOkBIbdWYL9+$~% zO2(emO8Q~h#obQ|3X;6uuZ;#?{G;Py9$GJbQSV!wzd6ovbws;v&%_%Yd_9F@GZ{Qj z&gaX}DIhWUWdN+4;%{YK3Sr0lvR+f~pN(Mazj(a~6b=(1lljZvgTSys8%AJxsLse5 zn&o?!A^G;$%fiGoY^^RPAKx3$RlCisIb%GHCT0LjrE}Ev*zRTXQH86G`XTH>PHH?I zc-4y|oTB8c@QcTrvxcQ>9iC6sS|gN3+FWYI-5hPGV_#m5cqiH8-&xiHije%01i%8P z2#r{L#k#R{g?2wk$;l@ofsJl-hn=os@CZV)^f|l4!=}d!z7{YGqrpRt^uWqrG z_TpsPz&D8_Ki`k38rF64#-DoMT`+1nXm`_cwpLfeF)dM0ewz*+#EqhII;RqyJ>PIf zGf#^Q^^B*vur9lGHlS+qh(Sh|F)}h9LrmF(9ZjOg6I);WJmet~Z}jV573>oB{p_%{ zP#D?ts;_s#N&IA~5VC$Y<19;`0tbDxOnn6stLjb8CjgAkj2unzXOu5OV(*NYwU@rJ z?-T}Y;}GW-x-_bci4pIR>F+;Be0{Vj>Dial|JjjSYth-@fkN^P{rx_jLmD^UFH%Fl zc5H)y2pg!XTJV~r8k}rd_1u3H_ily8R{k`VX9#NUdN{pqr{yT#MySN66+OJ)?O|eK z${>fTlo*y5mXcOluv*|qMmhrG*_u+ec?^fo{LkrZ$a{;4@%};YM~I8%bi&g=9ZIy{ z0KZbyNC$i^xm&*+5>}ji5|O5iLxUbJ>^f$W9KgnawOjD_^ooLf$0ne}G|VZZGxbVQ=Wltd$*3&95B66J~ba{+#FNJ1Yuoiz%vx z6r1f9*(5sUFB2hiZ%dF#ILD1M^0=u^Rz53nxFwkII`&{c4|{DNg{E~CUGHnMQhApMqd2)ot-vqpu&W^jFGFjYA@< z^_NUiS{j=BaG74J)rNQ_5%0_O@*EcEtX zH`vET_36dqtB0pxcSq7MJPDD7E1h0HzQdaZ2y4kR+%U1P{eb<^(b0fPF0*izLaN$w zwtGJ0!u-M%^W2-~kPs6EE7ad)?9NApNwlr?&T`Rh=Tgmid+;PHlS!mEmjWv2N8jvF z;?hDFc@L=_j4|v~dF@{=!;gB zX5&@QJc?h7+2QlCI{9?zbc!k5%ZrRYzp)w8;eki#D;fkrNRA@`v%`Q5(~4%=9QmZt zAF+sqY5iP;XE|_2*hKWk6cS8H@p~bD4@zdKT6tRFC#nFIy!-*c+MYptBGBSgx34lB zrzirPXs-Rizdy2iUEgNj|Ok1o~0fdE0tfV(YzF5@quF`OdI+SSrJvGNhRk zO+KW;&_(#p6D}kaJewQ8`r_bRE9>O~f9HY?JH3h?m_JWK5e{2t;j^W9jiC} z+coab>lW?LMQuL~d5{UXU0Z<9b9TdGo|zR%cV z4|)7md>7?kizH#g3Wqa!Sj;vXji-R@@|2~Wf0a!o1BeL0ryYi~5{bgK%Wf6=14Zpw zTwWGq;vu}fyD%Za8&Yy|`i|cuhd}k<&o~obZk>-d`if~VW0@h3@-R)gIhB=x8D{?j z(Pb`|qhz#EDWNMEG(};KlgaMQS;C8Zrnh_)zq3exT;FInJT&r*-36P{p5tZgL`LJ zvd?@iskP*UfP&+!xS3gEZaRMTSjT})3_y%}854~IfW&jWrJVaMwYQpa?t2KP?TssZ zard&v1wz46mLi?a2%M^JFTqaxn)ZuzAJ>Ce6|8w{f`-baGacc_H~akfP7`QniF;`C z=3UpbapEFqjvy+G!sTWMG$VmKLD(UK4}I?ox0l7VHJHzJ_BZ(Sh;P0`QzvE|ZXkC4 z`&R1J)zu-Ps(EEDRgdBPA^fqREvPC>)(Yq_WACJjhOuAl+H}=yH`m< zbH2PjA}TYd+7oD=Hbne_?dkmv!SqQ(UtA$VW!6Z!OL+Xp^;4dgjLefCuyrg8g~WPf zM&=sSgYr4LbN2rFge}Vaj?6<-YZm#Vk~Va>&>&^;_Z2Ve>XBdW#3Kg4oQcMdV*9K z*vS6$;hae0_{M=a;-pKats6Fj!^rhGATz}1S}=$SGiUG+C6_(#hLbwi5@i`krAziW zE{Zcp0N zQ{zcuh~s9P{0|L)@#o+Yk%`H;k>^kLu zQF8s8M0I$I1=>@el6Cr$R8a*z#**`gluK%=PLu5pJPGHl6L;i?rMxpmIxokoE5xCT zK(xXK=Om4-f;B6ACNHTj5k6!4z^z|3o|1m&ISIP+DO#G=E(NOhqlqmN)k*%a1_cn8 zs;=(@S0S=ILwso&O)LPsq_`Eh{HF}?mbdEypZ)rx`*R>qoQi|thwipu#IOhov4%QP zEpL=0foCTyJ!^aPQuPTYEwC0Gjm3P*EEeCf-qs=~OGD@5=rrZ#KF@KHqB6_A+WSCO z9&hYKqpKcm9r~0>&7(zV&8Q3NkB+jyQKmv&JLfp1P`f9jZ;{aNM%tah!Tnkh!A|NR z_l(4oUj(g@{jiaG*EOsm`dH~_{lqgl1Oz`3&JK!s#rBqU?~KDG1+Z&ks46X>!OtyI zZG%%W#$gV49AjVvOJS|T*TmPUVotfccva08$*+>V#(_pOPrre+l1vF0aWP}G#g>r* zWMlQ6-J{YLDBPQI&=U$JGZZoUSL`xa$ilIi`xAEnwosRhObO7 z5(UtM6c{hf0D0zH`%~gO=h8d{?(fe(qjhm~1O9+0FPG)_|FcEVFEQWXS31APpLm}vRc)%S=!HZK?0V@P^_DO+i&b6YX@Pv zze#|as z6%rCsn33ehVp&vEdq?4P<@~Nvj5$Mn^Q^3gYm#8X5#Pkv&HIC{8Qadz?yOV4uDtf{ z#xt@Ky87;5QOBV{=8x3l?~JNCP-**aX|em2$w^$?Ccbgs(J9EB#$$;gemnZk`yG1l z$%=+AEx+ss9?oIbVUpz-aaPe|`d%R&H`gO}@fbuM^s-_%>5U^HB^MwA2#w(0hzkH-n<$`uJEK@OtK{|3VLBb$*KxJa?KJBBj8paOSQdwAF z#2hWFmzP@m>*btTLKcFiVw=4x~s9Ld{5CgAP|5ot_(`b%afbW(4nTQc^a@InwD$dFIb>;zqA{ z;{g=1bp1n)&lL$%U0i%5;a*9nXDV`V-qd%fGO={~ot{43>n$gh{o+W2JW(UNHQT^xh&xDJ zmUMpWHLuahQ50WYV{7qc0z3|z1lCm2s(LEpJyn_He2@hD+tbyT&-|Ms+DKC_^#a7E zSHcj@nwTV|N_t^1!r^wU&l$OxmxYSsqG!6eIq}T>z~JB@2Ds)j*7vwm6gvIRcq%Ye zu%BnW*S|%QSvn7f4;DSvpxu1AKCB@)GtTz)f1FL=Oge0^y(DGdeEfs&*?zBjOn{a9 zod1+pRCI{9QIKUf&n07II8W--7W8?4MuXGCI1lw*In>%+duP0Xa!JXne>495ESq9@ z1USEnoqI-E8awbvLkBaVD#gNq`V>75HsObmy`YuWRkMisU5W3io!Me-FUGFQ_h`_; zLxr4Y(poSGBcDpJ;pXh=ovCjO=6GYRWh5UWi}YY8rVWx+AgW4@|HVE_oqAr@^#wn( zQpVZkZEtTcOdco8PKCUX{g{|qSE)<0@db3LNObtn54*CpHqtiyPJDDE8XljYuk5n8 zxL8fr`Qge6JY~y23R*c74!t})t*NvEErKZK1}#R&1eqmg#{D+EpJQ~gWJBx1B9ud# ztZXXLN}VpJR2=q6+-H9{qYKd3r0-C#=JhnY&{^ge;pZVYLhtd>VR}Xe=lRv?GgnQ1 z!+jzk3Pu89f`l3aCp>Se%I$bMKs%sZL00~b#VQA;^%i)o9*rvNe8-!Xjw+NYg@6f_ z38veT{BnWwbCMou=2gvx#XMCqTm|E6*WimID_|u3wdUCttm@_BQmhU(^V5;wCNx!- zCd(HwNw*u!)Vy_T5@EF2ho#$%>+f8dbftuoHp}xQ$tZf7%O<%{xHC ze{t{~+)gpP<>|G#x3@kn)%ySVj*V|~c=qHYss;@5)fH9ddW zpRS=rf4^pdDhJ31qRZA+!4WZ!Ft{~#K5wQ_mAc@cn@^nJN=mqXuFOBqS`H zW^Pl#<80|iSV?Q+V%)Xa*5$OyAiP1^?B`xACq`u77>U4yQwXk4j33vI)#@>x>VN9? zD4@o+G1yJH(yF3;_jo*?DUc#~bVD<;%@~0<>3XR$R;FNz!=ZY)*o{7x_Ya}cY6N+j z3^B+SZOH2tiwC3!L*DaFP;z&-rp0?0Vrj<*Ps8ucntx9qZyD;rtAux z2e$k-$D8^ivpVrcgXfZu2$+3LiJ8Xa!nwM7s_~E$4|AGM>|!;vV;VNmJw^K+s&U36 zc$i9HEYyQVU)Zum7`7sb4ow*a5J+tpm6oM9H8L`6=xE|PaW!F*H=>62r*hWnEhuP% z{#)4CFlL#^H6l%)A|R(_vZz zdwSXM72bN}+XYfBv9=%ftXrfrHDzZ^Zsv*nwej7- z^d#8NhfHllaax+0uC-+H^wc`0b;nmi=e5Qmk%MDw404tfBmB}tv@jN}DQs-)-~88I z4q^Pi%hL9#+1c56RsZSIG!-AP&3|KhQU76*HpwCzL*)>!1$Kxq%xO=Y|9+x`;s~8c zQ)99D#@vIK4;JC%aW$Qw|F(cVde7=A0VI(F5y9Ti-tl;F2xLRCTm}mGh51BEYYE3g zBAY;}Z)iW#KWXs_f8x-aJ=WiM{M*TdvTAgXTvt+Pb7boqCp&b(nKa~WyBs5Uq*jKGeOx_UgzYU;gs`Z@`S~xttX#mTU_(nF zm9q?#A(C1lGAMu2C#C}84f+1o4d9~A?O>!s7HKh-f%o={{PjAT#K1u%chZ<)DV&g% ztuF~jd)J>Rt(16f%-Me$PlB1mzj_hI%+%AQY)GaE+fY$erM9`XB1_okD`_M&e-yYu4jvxMTebxv8#fJ|{H@B8q&GP6Dt zWo1Ks1A=&C6Rd^dI3xbZEx@f2-DKp~6M5gsFXj{?p$==A)5d&wwM^O;(&fnCN616` z_QJK>ilJ@i8{^plH>e6 zR67uLo+P2i|5kN7_bF8xkZ)vs7aQA`%XBt0?k~{B|3vUr)YI zNeCSj(s8?fxs3Rc15J&TuYy?Bu%Oy!BLZYv0Z4i@YcZOD5MX4Tt(KjWLrT88yFk$! zF?MOzq*x2ti!-%>U~aC5%d9AqXvkPrO)la7Qa_K&qMlSZ8E0wiic`C_Qw1sREpD7U z`1W|wX9UM#W9s$wEWvmF{hV9Aub>Vci%?ZXr4XzjOepeskg$ge-zI!$|U8=_(wk}qZQPuO)0elA<1W2?iyjM zgt|&?TR9or?;SC`kId)~J;Ig8M(hjB_2e-sWHD0IM$^=E?Sym1XixykfjeEX2>v10J1u*A`a6(QX>+HA(9wQhon_!NZlWgT3HpEM&9FZ0_0?JVIdmaWSo*~aY+d{ zA|j$(4Kj!3h3_?4LLdjm;&)`c_jYMU%#+z7g#RT8P|yK_w151BDO*KlWCMT#SB5;) zR@T-ITVy)w$>M}Kh2!$`f*-${^Fs7Od^hEz@=J2&5z~WabQl)r9OQ~GgH$;q3q0Rj zbjLoKFIG@wkAc76ZoXH~{A4CE2PZKF|3T(QJ54bNQ-` zY*esz%28(QZ&Q$jaEMs(7UfJLOUv(v9Vw(UTJ&0kK2rS!p-I-U!oc3VctB@7BV!ny zegH6u?*(8OS;!FG0SFG_liV#Fmah8pKH*hnqA=CYVD4ZAss2GgfD2|IFnEvP&e_1E z1<=r3mL||si_gv#kf2+9oSzGrFTH0^a*-0eIydnZPC*-20rP*!RU$uP(naBksl#CK z0nw4`uaBd>Y022Id(y)ADONAL{UI~+Judzbs8#A!@W>qEI!WOl3gM6R6jGua_kY)d zDdNU69ih^q&!UB#X=sOOS}`s2->~I!Cg5~TAtv6n`CEw4Z4sykc)Hq3!N#p2S+zKL z=BxFT9v~q49a0r$d6=e=>VhOWr;U*tBO#}kiZ#Mmy{Z0K2b!>slLkWVEzQYkRCl*p z^hDW?rg5A|!Y?Wa%5(InShjq=hIVBm!gGwNVPH)+l=-0jQl62Fg~x;Yh29TK4TY_k z_fWfmWoF^(+LV^ZL6zyM2Xl*Kh~jG(Np!06`Il1?)BvN4{}Cf$M)sW2KNMp%(bVkF z^Z-Lp(hx*O#fqgl?Z4C)Uyljg+8~~*fNK4bDQO}^AsjgfpdYlq!m^}N@bH))udx~r zUo!bN+u~Bq{!~^QOSl@7I~CVw_>)HAr}*1YnF!fJ2BWt3L5ZnK34wTs_nQ+Y=TZL$ zxwXEEYkp0B9B55&P}LieQ%3iuY9E+uyr(K9jkJM)Bqn)-GEP^h&=BWo>YQsNh!S!HtKJKl-n0n_`hn zTqm!d;D;}67VP5-$P!iWZQ@(VWuXqD;d;Azlf&3Ey7v4t)uyLk&M zMR5oK4u(qPk71VW%YUY_f8Iew{o^Boh}w=DCJ|5>cu&U{x{z%l*(0InZDh#as_qZQq5RI zqz39mgCR1KZz+z&WY;+pp)+9*TP^uGkBrQ+$2m;0fWE_R8JC--c`_1J6_v3}fg!sr zAOCos9n}xU38wkvWT`h(KM{qpL>~Iz6C3%x3C&!`7`FmvN3@jo;^6#T2FQ`*S=r(*rUP|*sFj{ zxBG)PAhNyP42#^o)VZpo+R&OTN|N-hiAA z>hg0;Iq+Rwq$8-${D~?mEKf+Ya#T{+?eMV7fv(W&q|k~t)uK?JGXKGRK6vocUAjYG zA@Ic=(Og}&MS}XLut5qIJB|42QV$y&+s)wwVm~2zBJuG7huP!pMKh#8x=yKve%i#i zQx231i}RN>cMB_A#Ls0SDN>G@f*>1(!mRi$Z>S6$?%ToR@uhEv_u8#?fWu zcSUpnlz@Y@^bE6sfyj^vKyov3BZVepA8D&=F++Uon@e#lVsCT_(n9K$fSO$9MuSDd zR^aS7W89FaG(-5ZiX0l4HnX6jby|?&pOAV;7akRJhBOz(DNUyyP6_buI*6P_2E$%W<&kkPo!9o2+@;xL>1Dv@n9>`LRfYwsSHOddd8cUljTngJ8&gaA5hAXfNpmS#FIP!VkO4;!2T!LdqR zJZH^c6&)2NsKpXyZq7ERDjkI8-$czSW1&HAL<0 z%@1R+XNeHtw|cmk(e$gKCuYH-uP$g9xEJYX=VoWB;4-rqbncG;m58q6dUjZW>}h@g zXDLr0gd#7$f+m$C5xeC-mDY=wZ(>dIrr-q>~~C&FK%d8UVC7rc_qc=x1F1)TF?PSG7yGo?&{%ost7p!gyI+_8X}wB_Zs$gcx(N$!poUxCY&s zmT)kb;cQV*E?>#TAk^Bt!rl|k2LP$xUXYPzyfO6Bu)F*z_3@=4pWvf8yN8lwmf-;a zs8=|UeGpk9*chbfb}6xZe4{IXd-{3M6$HGByRa=sK%}Y$k=X~H?%Fyd4j02|rmZQ2 zleE7M9XI3GHWoe*=bs+6_RXue@|J4ijju6Q-3$y2{}pwj($Zh)04$L%5DQv*uUDN3 z{{=m+y&mh;sc~oZXl1fl>tuR@#wm4~#(16--wUzER6nLaJWh&C8s1pAxFs_4BZ&%f zta)t{qiPm|OBh5-~R|=_G>>{~x%mJ%twFga3JR&d+vp0$BavjyJ= z@N|B*LJ`1N_JyDeuw&5XLS2T#U6MBk;-sGl(QZaRvCG*ZK;vNH9WR6%4Nt`obEvfl zPN}S88fr9JAXkEG>m9@?W@(QQbH>LvKX~>cx8UR#>l=t_%RIj5cXR`@StPDqm438U zw*3BES{t#XqpK@n>=N>mOhPi@b+i9*#X69+ifZz}pdD>cM2@kQu^>8)b1L66D=Uiz z!=KD^9|JrQb2dW#65}7&pC+8s#l`!3xG7A4OG&A!4{AWux_TLBb6_vHR7|IONoD09 zXsE?AL=Xz-rI4GCLu`trC`PR>c_wkQMyJ0XjX|S`=lrP(D#&0aV~c=~jVg_rc8$B= z_=(gp;dTW@5U?X=#G~+s|J(8NO{#K2wexssXCAo$DN+VgbTnC}++8YIxoN&5u!|Ch zTwCuUsm7pd)8_g043vQJ9&81C7iYj%wS>S)(EI@>%|RExlJrCC=glb_9nx7e+<*8d zT}d=GWwD6lA4^a0NL0r|OGG~+Rvbqpe5w2S7tsjHI2U4jnv1JHabs+hFPRI2%*rN@ zCjE2Gj!(Vro6AUaNiJLi2gmnZJ~LJ6Mr1#Lv8Cu%OqQ>T`0azf)?WNBrK#myndD5i z0BtwkpKUojSH7X=`x8uux#dy1p01xi;c_J-LrnTx>hQc<3(OS`lsN#pQaH>%`rRkR z8ufb~caq3Lm?OE1)~AI+QAjmi!@i4>WTt#l;^pHO92# zNnWKh$GTj}FOB6yFU`uV_q|ZkeEvaPDqrxu2%#B12dsVZF7w0F#7|wreSd4psL4#1$E2V z*qni7sw@)3(~VEMYodW6kCj{tM5@}lhECyOLo8=JNdMo2Y3F{i@c%5JVGS3RzvA^0GN8KlbVl3t z1VuyE(fOGf@-$F%h`3p9zRu+#f48y^p1i`zcSE6BP)s22f4`1@6ZYifP zjjR%zm}F}7FO&Zh9BcpyGX{?XjutuHivdPiiw{}6@QmK-@u{1eo}L~jFxNsp(=%Q1 z(r0XPWN8H-Rrh+UCK|%u3 z2wut6P&*2QlFGh{Chk2V3?T~u{gk5)qApkuh?y9l-#tEkt?F4>lEJ$W zpsj?h!rNKoatEOz+?o)fgz~UdlvuEShcQWQmogt!_{Iu_hhb?;ed+DOhE(-Fd(rA_ zs)D)~bkK4KA!=n+7RaLe&;W*57jFix4$;V`S@%zRK9gVL3bMh)p&2p;rI}cPEKaEe z9LP}?uPT#ftB-@ra(tx+e{p7|?*?mFwLnx2i%NpE=OW!f#4oa&ZCVwB#nvOI{?M?ys0M3@h~qRk5)LjFN)BV ztx~jB&&G|k>urwG59$K)RR0fpV%aoLbke+MgX$MAMOlNXouP?S&3K)XelB$0J?5d4{TVF+dBm1T@HK09z=uAXkv@_D&LAxl) z*^OHNYqJE$JNW-mLKB@PXkceX*)n$c>gwU`BQSuO zRG#a14q;BR*e})X}liuI>gx(?s2Jx+`AfI8;p$q0cWX38tFz!5UMjN zWj(g~T}5xYXF^P_W4N$I1zA<+ZFg7r$^L%_w77Vu-@9RPQT@NbH$liS^sU?e88ZC; z@zmLoptmtTY=8URI3dS@Jrv6t$AtCR-qw_sW7eL5uy7Ei43aX)GTYFccqoNME2wzz zZK;!spJ8a+$r|c?yT?i?mh)(Gp#n6pZ6}U}ZG|{Obr|E2U8CO&UHGiuMyfvc&VLa7nB{9GAEk(b#2*{@cOZ_(6w>eHa@K1EHmfzradC)#j)RqKbC9_m;L1Kh;rUb~ZK-KfkNFS-{Ki>XCwCrXb7DCg0;qlh8ip`Z?R0 zQp<(5zdo(pqsKB08(r@MyRfH>Lpu*=6-##Yj_{T1+5w+-7K(494yA#C_J|VJiMRw& z67FB0A8fhFaA5h8P-d_+n(b6OyYh)vwGiz~KtHW4qyGYr=oC64wKfo{`YC}JH9KQ$ zwa-`Ry-Vo5Eh{bnJk>F`9d1Swz`>!SNXBy}x)Kh((c+J@x7WKvZO1g$yyWq1tjFuR8^asGO|mhLfU+lk&|j%I~DGHxaZ!+?zS17Mz9GsEo1OMsHT zzv}*CygY1*(j@~WWu?EXCwcJW%jh1$?mKO)cD5RnSH;D;xPMjY9bW`qFiH}I*r>jW z74tgRvgYhNZ*6caoipT%eo*jAjj0}u9TD=+ykJ+xDN+an{Nt)Xr``E+vUZnl7M^Ula)}V8Qswura#LvmzHrmv zLH?<6c2`<4+31PwT<+l=sNS)io8KM!P1(&V7QwOCvn28VJf9Ae9Pk!D^EN`%%Uy!y zAg5iGY@PDoOEncFKV7_p2slV~s0lHHO@DAvCC!r0JV)hbDgiei8wtur$T@HQ*#rPZ z$J7yG`8K|=;GiE&y#15*`ukp8f5j+rQ3dYf8TNVEE`;l1fJrAf>E>)d z)bs}$#;@90sZt&)0tD_cKi0}EF5z0GyA6|jI{^SomY`3^y{F;gmO;wibG*bp&(5!q zB(dJZ?O0g~*N>BN!)Vf@zt79Mo$D3Riicryn_`@1<~^6+u+>E~EuakHD~X!Lq<;g0 zB>w79zHCnaRnKb<#M39ViF1-iM6Dz4;{j_DpCF`*^HF8AAp7zF4~>D_Ay1np!U*Q> zu8v9~tAeuTTMQlSgvHqx2?=rtA%|Rsnz?QG{7mK=g0JAHR05oH5@LTF5oJUXKzNnz z-|xpGTKoNRxr~L&;>v#@As4=VzD264|$I22l z^qBthfD+Absw5sC9zwLjR0-+g`S&o(e`_JE{_R*Y5p&XfT!O^fIXDo=)5yi*Euz&w zmUB1~sf30`_V?Qe4eFvAzVemZN7z5sFHX(2a@|GyeE+!LCaRO56)t*i-pN@R%M|pR^BK9Jda> z<4gUh>fh>}!DkOOu?qbQ4K5~dbkq>`hPAjh_*B_GZFW;%Ph2t@hps=uo3dTPgt6e7qoonlk;2PZOU88y`Ky`|cfZA1WlT0K3Q|x#AYQ<^kpwk4C=GPP z(lhw_^dtC+Vr!RdRds=QfIrxC`E!N=L;@aDfAPk%!+xR3dLpVtrI{@`#7xZ36N2ZJ zh#N9^Nr1?t{;GID^-*|-$}uZl%SMR(r~{2J*ozwlDyVbZl{{sDu9xHge~wCw5%oV! zeRot-Pw+3jgLITCok%B?Pz3~$7OH{J>!pbVL_wrUktRi?1pc~2j`7XM}em|e{ zlDIEBsQN+3GW=01AfkF=s2O`&FAz-Yd^Okqo3pG#<|8V{I_FZ-mDIy+<|QUA7joJS+x=7r#IRlb)u9*Ony*{_O!c|H#F5_~j=t}(B> zU{3JpJRnXsIi|pGr zTK^miAZ=Wh$zJlcOYS;OKAq;Nza#QeJn@)Ab(l?xoe9!ML%G0XGp1?ybZIhhjj&p|lR8!~Tk zXf#H}8{Ph-KJiKC0iB*2G0vQy_r;(Y#}XK?A4nz2&BX4LW0%bLOVOoPCGV zX_hv0FQZKKY7zrF50aOAHNo`9e|P@!+*Hzq!^7y=y{tEP#R%IJimbfD=;@D4Pq+B~G(QE27>=8x$piy$Y ziqme2Y^w(`NU-0hV{xjM-84GT@Cv}`9udP2(ZA5ZmZ(#`O8dCMX2J)+M1l|+21(^u?e=ju8o;<8nr9^x=~KfkG|R%nbsFZkfv+4ZOL>PcsB7VL? z&w6Gxhp8DSAmOm6UaLUDgIPZlpG__3-&0@oA;rr(#-7`yp$ z)uw>yPZ0p@>iv-$Xvdb=;hjhGiW}OH4VPB(>uQ=HPHjcdRWc0PifZ#$+<6L*_*zTk z;gF{w@um|)AM{DH-NVhy+j-i|6l3-FAbv%^d=fmARxT3sW3OMEZJcdamVd|-&ReKt zQH12UPvbLF8yzASVQ}@cL+xdKQ<$m#^7UTj5Hai3rtmi=i_YZg1|j;5Tunfo1c`53_f7zq6#9?8*5((6FNrp7dmh!$6RgC*^~mL>Hlm6iGqnWAf#4dR4i z&q)5{R09=tUL5?5#q15-0(HE98LV{c5C2iW_bBd0JbgB$SO%S3$bxHWXwBeHcKIAN zEt!`f3NZZ(d{~#kX$W8`oCj}nP&?5a>W(|)6x!+Erm1Y?; zI4LLyR9gU0||N9(iqM4K6(9*>n}gOIiclyCBCW^ ziuehCZCplRU60*BS*nckQIHNl;-=Lz>W^FUOh8!W;;0e92jbbH{902(G`JeMV7|>% z5Y-(L*GDo-OW(EptW3?MAFSlsm1+DEh85oe(`diLftF*%t`HO1$ABJ zd;5w}07IBJ14ubpf;jZxW=!@8AHOW(pmH1u2@^^ch zzFSS-dxCN5`OJ8u{YO?G^Zyvbr!{3ji>pD%F&E~qoOvfB!q9tT);+ge5@N3h%v5D1 zCuggFMj`ufHzHd`Jy~>x3wW6qUYvWf_p;3^@T&g6_JEe%gr#nJW-VC{72KW7gMT}} z%&MmrKQCL&-5~q;nPdf#RyN-`Ke$lp)8J}ip%Bn=*PRJmy8|Icej@ zD4DAavtOY6=Y?-Oxf3*pvG&}MW8_SARh8}Un0u+(xS9(dDgl+!eg9`vVso++S(cz+ z0n;Qr^lZFT#fJ{G9Q`!ig}u1+LZlGCXxr55Q~3dx93uwjrgCe#_BJ0$@06YxE6j2n z9{9S|R&dE;fmO7>?!YiG1x2TAVQc2n0}vUThs}* zS1BAQy11~)L&m$kWCZ)E??~Z~whtaE&*Ex81riXKK7Afv3Q|pJf z<8B&AMSn|K;2!u$8u-0YW<%Lxily-nZ=(xz|5z#cCHYd#xc{3f;Ww+QZh~JiAgiT& z*@OI3I*r?nf{yiGR*LxldcwXcTkNb=sPLmGm>zm$`he(wC1tFKKZ;uj8pXfG>NFKSJriR_S!?pW$GRhn!cpVQJ8vcy_OOL1QBx01|60MXt}9z?JT;SJ#Yr_n4E_u#4!ujdp{fb7B31+- zA=$@C9sEcA;ySDMu*e-JMG}2S4%5FhN02RRW10}FI^uN)NJ*l-fTW=|th0&x_;3!3 zQEeVP_Jp?A|IIi6sbZKSV%E@{@DKj-kZU6EXH)YnI;WYti1?+R-?6- z2(7bueACO0`&36TYNGWQ$6{t_7O{rbuU?x{+CZ3`Rz`Hb()tp~$FF}VR1@e1u_+xo zj$-Qrk(Jw%Oe`k^iny20wRGOo)oJr~Xz@&Y#%OKlu6BINM~VupRdnaA-jTf`P3vic z<#nQeP0*x=`m-nNQT51C!qL3XMaR90T zVihB^`rG*#Nce6uy@e6Tju_pfIWMcXozJI$kz*X=0AS(J6M9ga4C{pJR)W*xQ5 z)v-%@#r?cS*z|rq`4ty|lgdr_9lZGRV6$Wt zy8+=nkF1v4S%7i@uwW8cu)I?!QFWkLw7{=>ni9QY;~8tIsb84wN1kagqmY!+ zlrGPBRCiBHKAv0f?<2!lt^m{0*JPm#?ro&d+_Z7Bc-fEs-TbaKfW>M$^Jxh;c!bpGOu;NC_pT_QF0MR@)C z0PYh=bQ*I_hLRxdo6LN~BSYYmLWlKawh z=E0GBRtBF)!G7_BINeoj@l|m3H^-e1>6J<%S~`r#y{X#y-P%``uE5BV#;7kIr+afj zQrZhBeziB{9gS2X`@_#Qk%Uxwzqh^7CuaMRm+<57JlFBDWq$00{B+edHE@ataXmmE z?W3d5laRMFY8iIR-k#63506`#39mOY))9Azc?yT#FLI$aXF$SN4hUKAvfq)?zr0Z} z!dei^_C$XowvY4Ay;AH2TNCTme)jLw+KfwI|7Ncn5vS3)^y2iwZM)&z%e1#-zfwwq zM$2}2dHr30i0yQqOLD|=l6^~@eN@ZIhbT|wOa8~-S}u2g4GO%vvA58beeyIqTw>2` z-e!Udm>xU~D>IF{k?ZN%{l4?y@Q>$KTc}0y$tG@6b3qag#=QRSV8#T%wxk{0gadM{ zv+tD_^FdijCbD7*7`7#ozjEn5j!D#jnB?zG{XWr%gl@uRcAbgYuzI_*VnRQtY0ck@ z;&#?cL+W!}VS3nGFUAnfdi1j}wuBv5Gn|A=k6M;Tx7zqhS8hg5w|}oT?kjB3vt!)L zxXUB|r@Vvb@;g(4E&Pm6x*&FzPvTGABWfdJuH~G$e7IFySUrqtf71nE6z}lAAePhtImsWN8urQmA;4|V66S1zqVgIKqHVK=+M(~)|V6nNC$ZJt;2irv^vDSIA3W! zm++dFUgR_qqH}Jtt<26{;cfe* zrAs8MaiV4d;SD1pXAMbC`v)cM99oW*G?XP>ddAIaV`D&0pm0OnrC()<6ga^Yx2s~M z?7rR5LjXHgp6Zo!DH=BiS>*B~Kj9SaQ%u*k)I=9_Y&x)|o{dXQeZuaEefe~SQ}Ewb zQf~{}=ug3U{z8kU;5wP%b&@>xaEHouq6&7R3d_~^9`G=PrOpS6Qes&s4y|Z*aqOet zA}(*Y=`I) z@uadvpJfu!JH5234UU*e$Fq<>eh5{OY517;ZZxgNf-naH{x<36fs?r&m9RAYarkjs zJ5I`N;0c*!1Gao3nwmu7l+23LeeJD7=XZ*KaxRsyUBk$7h`O3yv@nu!(Fo=3+H6CooYx;>??k%n14>)?<`Rsy%rwm z^tD2E%CeUC{KjfC873FWK?$91DprGjdD>N*d=}KWl*-)IKqS+rojtqb;2l!wpPg{F z>9P6AUa*NcsKeeDzfU@JKc>kDDK;Z_HbSeajJbtUh!*gLGzA`2H{@ptnXVR2oT?LP zHP=JJzmH1lR;hptnnJFPbm23F|IHW?JdQ4CXy;Fd(2A9w#7#BmG=B+c;Q-MqS?Ytn zT+r(3bs5#fw8pDh={o<&unhIcy)_Pn`-y)Sc#~ZwZT5qxsBUhL=RdgP)tHMEU4_cH zMZOEW^`JJ!!nqNS@5$wk3S-!o`lWyonInZ(L!-kV)SBN^L7Ej8>QDT3+Hi2Zi~G}| z8)I8{S8h}C^rE##`sjFVs!i~OAZPU0#aPJ8ytlHr4Ti0#cd6s}**W{gIhvK5yaf!^s*2kHc#`f!`0xkEI>S&{KKGS-x

k#mDGY+Ybv?|9|q?u5?b{?(izKZ_ny(7w%=Vg|ueAx%f0`-I-79sH{t0 zL@QO@)xbb(A1%P?n>7vF-8u|`DDESqINX3hId{QV z#%?m`=IrzK3qHGBG(%1FURfi523p^G0`ohO%1@sl=qLmOHH>@$i8t^@u|C%Xd50Y# z4ALTaQS2#&=q}bZddAqt|3{Zhl(bhgqK2S}TkgfV#ZprnLP9~cr$Gqj-bOOJJ6H`! zGt3KAJM#eH(%a};+w_aj8mXnnx;EBBGj!KT@-R%1X3-Waoz#R=*46IgG77tN*4-jr{9g7DJ z$s}=o=0+*+`BS5LQO_9CIKE3>td6+V zZguQBcG3m?b_s{YQV+RxP*dN6IHBJXI z>2*H5{T^m^M>C%=!QiOOH0S>$IIyPS>@&(BR)qI$7UyhY*xp_84!>i)$r4(vk#3Ar-kM9@)o= zT0S1=*F+hr_b}NRKc_EWOQPC6c+=D7k8Y$5JmhCgMC?13KNluiSWb&_V}Z-&zg~VY zJD$%<90#P8@nmfHGDM<#wt?{GpRXl;$LmVUW_+XD2#>v$WtZ43 z{`%zCHggjBza))>_(%2yChoI!+_oLVua%KLGhj)3In-XnC2DMLU6=4RjU{gY-HvIs za-&hneIr=Z#;(Iye)}4`k`^le`&F)?B5Qt>8vFqQGX9~IN z0zn2!5PQiNY3O7vQqU%U+O|y91)VArNoTyMMSMp^Oh&f4#CSRzq1a{KA$c&=7bw>8 zq1+DCe6ifr`nTHSpS3E_O+0|w#-FrxM#rB#Jb@Ft2kB9;bmOL1m$#}F(Wr2!Ff0njDXL#nMWX%mugH4pz+&z%Bf{7Oi1Ku1JO z(hx0vsT5mG0j?e#j=lA{wp{}4?a6#(aQd|xA}84hFp_>jQDV=GV)x#^r*`Rm=i2KF$FI( zZFB_WUkkaj7BPW?Y(`e&KMI)>g9KJehjT3^>03}AOA@LU{~T_~N?c6sUAA1DQ4aaD bqXo)dXVkuUB|ky`oI5BjDD{o963PDoeRNQ2 literal 0 HcmV?d00001 diff --git a/2d/platformer/screenshots/shoot.png b/2d/platformer/screenshots/shoot.png deleted file mode 100644 index 12d2660c9bb13abadc5591b37606400d370d3ea1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18478 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 literal 0 HcmV?d00001 diff --git a/2d/platformer/src/Actors/Actor.gd b/2d/platformer/src/Actors/Actor.gd deleted file mode 100644 index 990d9eb0..00000000 --- a/2d/platformer/src/Actors/Actor.gd +++ /dev/null @@ -1,17 +0,0 @@ -class_name Actor -extends CharacterBody2D - -# Both the Player and Enemy inherit this scene as they have shared behaviours -# such as speed and are affected by gravity. - - -@export var speed = Vector2(150.0, 350.0) -@onready var gravity = ProjectSettings.get("physics/2d/default_gravity") - -const FLOOR_NORMAL = Vector2.UP - -# _physics_process is called after the inherited _physics_process function. -# This allows the Player and Enemy scenes to be affected by gravity. -func _physics_process(delta): - velocity.y += gravity * delta - move_and_slide() diff --git a/2d/platformer/src/Actors/Enemy.gd b/2d/platformer/src/Actors/Enemy.gd deleted file mode 100644 index 7f57c1f9..00000000 --- a/2d/platformer/src/Actors/Enemy.gd +++ /dev/null @@ -1,77 +0,0 @@ -class_name Enemy -extends Actor - - -enum State { - WALKING, - DEAD, -} - -var _state = State.WALKING - -@onready var platform_detector = $PlatformDetector -@onready var floor_detector_left = $FloorDetectorLeft -@onready var floor_detector_right = $FloorDetectorRight -@onready var sprite = $Sprite2D -@onready var animation_player = $AnimationPlayer - -# This function is called when the scene enters the scene tree. -# We can initialize variables here. -func _ready(): - velocity.x = speed.x - -# Physics process is a built-in loop in Godot. -# If you define _physics_process on a node, Godot will call it every frame. - -# At a glance, you can see that the physics process loop: -# 1. Calculates the move velocity. -# 2. Moves the character. -# 3. Updates the sprite direction. -# 4. Updates the animation. - -# Splitting the physics process logic into functions not only makes it -# easier to read, it help to change or improve the code later on: -# - If you need to change a calculation, you can use Go To -> Function -# (Ctrl Alt F) to quickly jump to the corresponding function. -# - If you split the character into a state machine or more advanced pattern, -# you can easily move individual functions. -func _physics_process(_delta): - # If the enemy encounters a wall or an edge, the horizontal velocity is flipped. - if not floor_detector_left.is_colliding(): - velocity.x = speed.x - elif not floor_detector_right.is_colliding(): - velocity.x = -speed.x - - if is_on_wall(): - velocity.x *= -1 - - # We only update the y value of _velocity as we want to handle the horizontal movement ourselves. - # TODO: This information should be set to the CharacterBody properties instead of arguments. - move_and_slide() - - # We flip the Sprite2D depending on which way the enemy is moving. - if velocity.x > 0: - sprite.scale.x = 1 - else: - sprite.scale.x = -1 - - var animation = get_new_animation() - if animation != animation_player.current_animation: - animation_player.play(animation) - - -func destroy(): - _state = State.DEAD - velocity = Vector2.ZERO - - -func get_new_animation(): - var animation_new = "" - if _state == State.WALKING: - if velocity.x == 0: - animation_new = "idle" - else: - animation_new = "walk" - else: - animation_new = "destroy" - return animation_new diff --git a/2d/platformer/src/Actors/Gun.gd b/2d/platformer/src/Actors/Gun.gd deleted file mode 100644 index 5d3de5d6..00000000 --- a/2d/platformer/src/Actors/Gun.gd +++ /dev/null @@ -1,26 +0,0 @@ -class_name Gun -extends Marker2D -# Represents a weapon that spawns and shoots bullets. -# The Cooldown timer controls the cooldown duration between shots. - - -const BULLET_VELOCITY = 500.0 -const Bullet = preload("res://src/Objects/Bullet.tscn") - -@onready var sound_shoot = $Shoot -@onready var timer = $Cooldown - - -# This method is only called by Player.gd. -func shoot(direction = 1): - if not timer.is_stopped(): - return false - var bullet = Bullet.instantiate() - bullet.global_position = global_position - bullet.linear_velocity = Vector2(direction * BULLET_VELOCITY, 0) - - bullet.set_as_top_level(true) - add_child(bullet) - sound_shoot.play() - timer.start() - return true diff --git a/2d/platformer/src/Actors/Player.gd b/2d/platformer/src/Actors/Player.gd deleted file mode 100644 index ea358d18..00000000 --- a/2d/platformer/src/Actors/Player.gd +++ /dev/null @@ -1,133 +0,0 @@ -class_name Player -extends Actor - - -# warning-ignore:unused_signal -signal collect_coin() - -const FLOOR_DETECT_DISTANCE = 20.0 - -@export var action_suffix: String = "" - -@onready var platform_detector = $PlatformDetector -@onready var animation_player = $AnimationPlayer -@onready var shoot_timer = $ShootAnimation -@onready var sprite = $Sprite2D -@onready var sound_jump = $Jump -@onready var gun = sprite.get_node(^"Gun") - - -func _ready(): - # Static types are necessary here to avoid warnings. - var camera: Camera2D = $Camera3D - if action_suffix == "_p1": - camera.custom_viewport = $"../.." - await get_tree().process_frame - camera.make_current() - elif action_suffix == "_p2": - var viewport: SubViewport = $"../../../../ViewportContainer2/Viewport2" - viewport.world_2d = ($"../.." as SubViewport).world_2d - camera.custom_viewport = viewport - await get_tree().process_frame - camera.make_current() - - -# Physics process is a built-in loop in Godot. -# If you define _physics_process on a node, Godot will call it every frame. - -# We use separate functions to calculate the direction and velocity to make this one easier to read. -# At a glance, you can see that the physics process loop: -# 1. Calculates the move direction. -# 2. Calculates the move velocity. -# 3. Moves the character. -# 4. Updates the sprite direction. -# 5. Shoots bullets. -# 6. Updates the animation. - -# Splitting the physics process logic into functions not only makes it -# easier to read, it help to change or improve the code later on: -# - If you need to change a calculation, you can use Go To -> Function -# (Ctrl Alt F) to quickly jump to the corresponding function. -# - If you split the character into a state machine or more advanced pattern, -# you can easily move individual functions. -func _physics_process(_delta): - # Play jump sound - if Input.is_action_just_pressed("jump" + action_suffix) and is_on_floor(): - sound_jump.play() - - var direction = get_direction() - - var is_jump_interrupted = Input.is_action_just_released("jump" + action_suffix) and velocity.y < 0.0 - velocity = calculate_move_velocity(velocity, direction, speed, is_jump_interrupted) - - var snap_vector = Vector2.ZERO - if direction.y == 0.0: - snap_vector = Vector2.DOWN * FLOOR_DETECT_DISTANCE - var is_on_platform = platform_detector.is_colliding() - # TODO: This information should be set to the CharacterBody properties instead of arguments. - move_and_slide() - #velocity, snap_vector, FLOOR_NORMAL, not is_on_platform, 4, 0.9, false - - # When the character’s direction changes, we want to to scale the Sprite2D accordingly to flip it. - # This will make Robi face left or right depending on the direction you move. - if direction.x != 0: - if direction.x > 0: - sprite.scale.x = 1 - else: - sprite.scale.x = -1 - - # We use the sprite's scale to store Robi’s look direction which allows us to shoot - # bullets forward. - # There are many situations like these where you can reuse existing properties instead of - # creating new variables. - var is_shooting = false - if Input.is_action_just_pressed("shoot" + action_suffix): - is_shooting = gun.shoot(sprite.scale.x) - - var animation = get_new_animation(is_shooting) - if animation != animation_player.current_animation and shoot_timer.is_stopped(): - if is_shooting: - shoot_timer.start() - animation_player.play(animation) - - -func get_direction(): - return Vector2( - Input.get_action_strength("move_right" + action_suffix) - Input.get_action_strength("move_left" + action_suffix), - -1 if is_on_floor() and Input.is_action_just_pressed("jump" + action_suffix) else 0 - ) - - -# This function calculates a new velocity whenever you need it. -# It allows you to interrupt jumps. -func calculate_move_velocity( - linear_velocity, - direction, - speed, - is_jump_interrupted - ): - linear_velocity.x = speed.x * direction.x - if direction.y != 0.0: - linear_velocity.y = speed.y * direction.y - if is_jump_interrupted: - # Decrease the Y velocity by multiplying it, but don't set it to 0 - # as to not be too abrupt. - linear_velocity.y *= 0.6 - return linear_velocity - - -func get_new_animation(is_shooting = false): - var animation_new = "" - if is_on_floor(): - if abs(velocity.x) > 0.1: - animation_new = "run" - else: - animation_new = "idle" - else: - if velocity.y > 0: - animation_new = "falling" - else: - animation_new = "jumping" - if is_shooting: - animation_new += "_weapon" - return animation_new diff --git a/2d/platformer/src/Level/Level.gd b/2d/platformer/src/Level/Level.gd deleted file mode 100644 index 9d76c70b..00000000 --- a/2d/platformer/src/Level/Level.gd +++ /dev/null @@ -1,15 +0,0 @@ -extends Node2D - -const LIMIT_LEFT = -315 -const LIMIT_TOP = -250 -const LIMIT_RIGHT = 955 -const LIMIT_BOTTOM = 690 - -func _ready(): - for child in get_children(): - if child is Player: - var camera = child.get_node(^"Camera3D") - camera.limit_left = LIMIT_LEFT - camera.limit_top = LIMIT_TOP - camera.limit_right = LIMIT_RIGHT - camera.limit_bottom = LIMIT_BOTTOM diff --git a/2d/platformer/src/Level/Level.tscn b/2d/platformer/src/Level/Level.tscn deleted file mode 100644 index a479d842..00000000 --- a/2d/platformer/src/Level/Level.tscn +++ /dev/null @@ -1,267 +0,0 @@ -[gd_scene load_steps=12 format=2] - -[ext_resource path="res://assets/art/tileset/tileset.tres" type="TileSet" id=1] -[ext_resource path="res://src/Actors/Enemy.tscn" type="PackedScene" id=2] -[ext_resource path="res://src/Platforms/Platform.tscn" type="PackedScene" id=3] -[ext_resource path="res://src/Objects/Coin.tscn" type="PackedScene" id=4] -[ext_resource path="res://src/Level/Level.gd" type="Script" id=5] -[ext_resource path="res://assets/art/platforms/moving_platform.png" type="Texture2D" id=6] -[ext_resource path="res://src/Level/ParallaxBackground.tscn" type="PackedScene" id=7] -[ext_resource path="res://assets/audio/music/music.ogg" type="AudioStream" id=8] -[ext_resource path="res://src/Level/Music.gd" type="Script" id=9] - -[sub_resource type="Animation" id=1] -resource_name = "move" -length = 4.0 -loop = true -tracks/0/type = "value" -tracks/0/path = NodePath(".:position") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/keys = { -"times": PackedFloat32Array(0, 2), -"transitions": PackedFloat32Array(1, 1), -"update": 0, -"values": [Vector2(707, 400), Vector2(566, 303)] -} - -[sub_resource type="Animation" id=2] -length = 8.0 -loop = true -tracks/0/type = "value" -tracks/0/path = NodePath(".:position") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/keys = { -"times": PackedFloat32Array(0, 4), -"transitions": PackedFloat32Array(1, 1), -"update": 0, -"values": [Vector2(-47, 80), Vector2(-47, 407)] -} - -[node name="Level" type="Node2D"] -process_mode = 1 -script = ExtResource( 5 ) - -[node name="TileMap" type="TileMap" parent="."] -tile_set = ExtResource( 1 ) -cell_size = Vector2(32, 32) -collision_layer = 16 -collision_mask = 0 -format = 1 -tile_data = PackedInt32Array(-65546, 536870913, 0, -65545, 1, 0, -131044, 536870913, 0, -131043, 1, 0, -10, 536870915, 0, -9, 3, 0, -65508, 536870915, 0, -65507, 3, 0, 65526, 536870915, 0, 65527, 3, 0, 28, 536870915, 0, 29, 3, 0, 131062, 536870915, 0, 131063, 3, 0, 131069, 536870918, 0, 131070, 5, 0, 131071, 5, 0, 65536, 5, 0, 65537, 5, 0, 65538, 5, 0, 65539, 5, 0, 65540, 6, 0, 65564, 536870915, 0, 65565, 3, 0, 196598, 536870915, 0, 196599, 3, 0, 131080, 536870913, 0, 131081, 0, 0, 131082, 0, 0, 131083, 0, 0, 131084, 0, 0, 131085, 1, 0, 131100, 536870915, 0, 131101, 3, 0, 262134, 536870915, 0, 262135, 3, 0, 196616, 536870921, 0, 196617, 8, 0, 196618, 8, 0, 196619, 8, 0, 196620, 8, 0, 196621, 9, 0, 196626, 536870913, 0, 196627, 0, 0, 196628, 0, 0, 196629, 0, 0, 196630, 0, 0, 196631, 0, 0, 196632, 0, 0, 196633, 0, 0, 196634, 0, 0, 196635, 0, 0, 196636, 536870916, 0, 196637, 3, 0, 327670, 536870915, 0, 327671, 3, 0, 262149, 536870918, 0, 262150, 6, 0, 262162, 536870921, 0, 262163, 536870920, 0, 262164, 536870920, 0, 262165, 536870920, 0, 262166, 536870920, 0, 262167, 536870922, 0, 262168, 7, 0, 262169, 7, 0, 262170, 7, 0, 262171, 7, 0, 262172, 7, 0, 262173, 3, 0, 393206, 536870915, 0, 393207, 3, 0, 327682, 536870918, 0, 327683, 6, 0, 327703, 536870921, 0, 327704, 536870920, 0, 327705, 536870922, 0, 327706, 7, 0, 327707, 7, 0, 327708, 7, 0, 327709, 3, 0, 458742, 536870915, 0, 458743, 4, 0, 458744, 0, 0, 458745, 0, 0, 458746, 1, 0, 393241, 536870921, 0, 393242, 536870920, 0, 393243, 536870920, 0, 393244, 536870922, 0, 393245, 3, 0, 524278, 536870915, 0, 524279, 536870919, 0, 524280, 536870919, 0, 524281, 536870919, 0, 524282, 3, 0, 458754, 536870913, 0, 458755, 0, 0, 458756, 0, 0, 458757, 2, 0, 458764, 536870913, 0, 458765, 1, 0, 458780, 536870915, 0, 458781, 3, 0, 589814, 536870915, 0, 589815, 536870919, 0, 589816, 536870919, 0, 589817, 536870919, 0, 589818, 3, 0, 524290, 536870915, 0, 524291, 7, 0, 524292, 7, 0, 524294, 536870912, 0, 524295, 536870912, 0, 524296, 536870912, 0, 524297, 536870912, 0, 524298, 536870912, 0, 524299, 536870912, 0, 524300, 536870916, 0, 524301, 3, 0, 524316, 536870915, 0, 524317, 3, 0, 655350, 536870915, 0, 655351, 536870919, 0, 655352, 536870919, 0, 655353, 536870919, 0, 655354, 3, 0, 589826, 536870915, 0, 589827, 7, 0, 589828, 7, 0, 589829, 7, 0, 589830, 7, 0, 589831, 7, 0, 589832, 7, 0, 589833, 7, 0, 589834, 7, 0, 589835, 7, 0, 589836, 7, 0, 589837, 4, 0, 589838, 0, 0, 589839, 1, 0, 589852, 536870915, 0, 589853, 3, 0, 720886, 536870915, 0, 720887, 536870919, 0, 720888, 536870919, 0, 720889, 536870919, 0, 720890, 3, 0, 655362, 536870921, 0, 655363, 536870920, 0, 655364, 536870920, 0, 655365, 536870920, 0, 655366, 536870920, 0, 655367, 536870920, 0, 655368, 536870920, 0, 655369, 536870920, 0, 655370, 536870920, 0, 655371, 536870920, 0, 655372, 536870920, 0, 655373, 536870920, 0, 655374, 536870920, 0, 655375, 9, 0, 655388, 536870915, 0, 655389, 3, 0, 786422, 536870915, 0, 786423, 536870919, 0, 786424, 536870919, 0, 786425, 536870919, 0, 786426, 3, 0, 720924, 536870915, 0, 720925, 3, 0, 851958, 536870915, 0, 851959, 536870919, 0, 851960, 536870919, 0, 851961, 536870919, 0, 851962, 3, 0, 786456, 536870918, 0, 786457, 536870917, 0, 786458, 6, 0, 786460, 536870915, 0, 786461, 3, 0, 917494, 536870915, 0, 917495, 536870919, 0, 917496, 536870919, 0, 917497, 536870919, 0, 917498, 4, 0, 917499, 0, 0, 917500, 0, 0, 917501, 0, 0, 917502, 0, 0, 917503, 0, 0, 851968, 0, 0, 851969, 1, 0, 851996, 536870915, 0, 851997, 3, 0, 983030, 536870915, 0, 983031, 536870919, 0, 983032, 536870919, 0, 983033, 536870919, 0, 983034, 536870919, 0, 983035, 536870919, 0, 983036, 536870919, 0, 983037, 536870919, 0, 983038, 536870919, 0, 983039, 536870919, 0, 917504, 536870919, 0, 917505, 3, 0, 917526, 536870913, 0, 917527, 536870912, 0, 917528, 536870912, 0, 917529, 0, 0, 917530, 536870912, 0, 917531, 536870912, 0, 917532, 536870916, 0, 917533, 3, 0, 1048566, 536870915, 0, 1048567, 536870919, 0, 1048568, 536870919, 0, 1048569, 536870919, 0, 1048570, 536870919, 0, 1048571, 536870919, 0, 1048572, 536870919, 0, 1048573, 536870919, 0, 1048574, 536870919, 0, 1048575, 536870919, 0, 983040, 536870919, 0, 983041, 3, 0, 983057, 536870918, 0, 983058, 5, 0, 983059, 6, 0, 983062, 536870915, 0, 983063, 7, 0, 983064, 7, 0, 983065, 7, 0, 983066, 7, 0, 983067, 7, 0, 983068, 7, 0, 983069, 3, 0, 1114102, 536870915, 0, 1114103, 536870919, 0, 1114104, 536870919, 0, 1114105, 536870919, 0, 1114106, 536870919, 0, 1114107, 536870919, 0, 1114108, 536870919, 0, 1114109, 536870919, 0, 1114110, 536870919, 0, 1114111, 536870919, 0, 1048576, 536870919, 0, 1048577, 3, 0, 1048579, 536870926, 0, 1048598, 536870915, 0, 1048599, 7, 0, 1048600, 7, 0, 1048601, 7, 0, 1048602, 7, 0, 1048603, 7, 0, 1048604, 7, 0, 1048605, 3, 0, 1179638, 536870915, 0, 1179639, 536870919, 0, 1179640, 536870919, 0, 1179641, 536870919, 0, 1179642, 536870919, 0, 1179643, 536870919, 0, 1179644, 536870919, 0, 1179645, 536870919, 0, 1179646, 536870919, 0, 1179647, 536870919, 0, 1114112, 536870919, 0, 1114113, 4, 0, 1114114, 0, 0, 1114115, 536870925, 0, 1114116, 0, 0, 1114117, 2, 0, 1114123, 536870926, 0, 1114126, 536870918, 0, 1114127, 5, 0, 1114128, 6, 0, 1114133, 536870914, 0, 1114134, 536870916, 0, 1114135, 7, 0, 1114136, 7, 0, 1114137, 7, 0, 1114138, 7, 0, 1114139, 7, 0, 1114140, 7, 0, 1114141, 3, 0, 1245174, 536870915, 0, 1245175, 536870919, 0, 1245176, 536870919, 0, 1245177, 536870919, 0, 1245178, 536870919, 0, 1245179, 536870919, 0, 1245180, 536870919, 0, 1245181, 536870919, 0, 1245182, 536870919, 0, 1245183, 536870919, 0, 1179648, 536870919, 0, 1179649, 536870919, 0, 1179650, 536870919, 0, 1179651, 536870919, 0, 1179652, 7, 0, 1179654, 2, 0, 1179658, 536870913, 0, 1179659, 536870925, 0, 1179660, 1, 0, 1179668, 536870914, 0, 1179670, 7, 0, 1179671, 7, 0, 1179672, 7, 0, 1179673, 7, 0, 1179674, 7, 0, 1179675, 7, 0, 1179676, 7, 0, 1179677, 3, 0, 1310710, 536870915, 0, 1310711, 536870919, 0, 1310712, 536870919, 0, 1310713, 536870919, 0, 1310714, 536870919, 0, 1310715, 536870919, 0, 1310716, 536870919, 0, 1310717, 536870919, 0, 1310718, 536870919, 0, 1310719, 536870919, 0, 1245184, 536870919, 0, 1245185, 536870919, 0, 1245186, 536870919, 0, 1245187, 536870919, 0, 1245188, 536870919, 0, 1245189, 7, 0, 1245191, 2, 0, 1245194, 536870915, 0, 1245195, 7, 0, 1245196, 3, 0, 1245203, 536870914, 0, 1245205, 7, 0, 1245206, 7, 0, 1245207, 7, 0, 1245208, 7, 0, 1245209, 7, 0, 1245210, 7, 0, 1245211, 7, 0, 1245212, 7, 0, 1245213, 3, 0, 1376246, 536870915, 0, 1376247, 536870919, 0, 1376248, 536870919, 0, 1376249, 536870919, 0, 1376250, 536870919, 0, 1376251, 536870919, 0, 1376252, 536870919, 0, 1376253, 536870919, 0, 1376254, 536870919, 0, 1376255, 536870919, 0, 1310720, 536870919, 0, 1310721, 536870919, 0, 1310722, 536870919, 0, 1310723, 536870919, 0, 1310724, 536870919, 0, 1310725, 536870919, 0, 1310726, 7, 0, 1310728, 536870912, 0, 1310729, 536870912, 0, 1310730, 536870916, 0, 1310731, 7, 0, 1310732, 4, 0, 1310733, 0, 0, 1310734, 0, 0, 1310735, 0, 0, 1310736, 0, 0, 1310737, 0, 0, 1310738, 536870912, 0, 1310740, 7, 0, 1310741, 7, 0, 1310742, 7, 0, 1310743, 7, 0, 1310744, 7, 0, 1310745, 7, 0, 1310746, 7, 0, 1310747, 7, 0, 1310748, 7, 0, 1310749, 3, 0, 1441782, 536870921, 0, 1441783, 536870920, 0, 1441784, 536870920, 0, 1441785, 536870920, 0, 1441786, 536870920, 0, 1441787, 536870920, 0, 1441788, 536870920, 0, 1441789, 536870920, 0, 1441790, 536870920, 0, 1441791, 536870920, 0, 1376256, 536870920, 0, 1376257, 536870920, 0, 1376258, 536870920, 0, 1376259, 536870920, 0, 1376260, 536870920, 0, 1376261, 536870920, 0, 1376262, 536870920, 0, 1376263, 536870920, 0, 1376264, 536870920, 0, 1376265, 536870920, 0, 1376266, 536870920, 0, 1376267, 536870920, 0, 1376268, 536870920, 0, 1376269, 536870920, 0, 1376270, 536870920, 0, 1376271, 536870920, 0, 1376272, 536870920, 0, 1376273, 536870920, 0, 1376274, 536870920, 0, 1376275, 536870920, 0, 1376276, 536870920, 0, 1376277, 536870920, 0, 1376278, 536870920, 0, 1376279, 536870920, 0, 1376280, 536870920, 0, 1376281, 536870920, 0, 1376282, 536870920, 0, 1376283, 536870920, 0, 1376284, 8, 0, 1376285, 9, 0) - -[node name="Coins" type="Node" parent="."] - -[node name="CoinsArc" type="Node2D" parent="Coins"] -position = Vector2(269.878, 573.77) - -[node name="Coin" parent="Coins/CoinsArc" instance=ExtResource( 4 )] -position = Vector2(-14.7314, 29.9809) - -[node name="Coin2" parent="Coins/CoinsArc" instance=ExtResource( 4 )] -position = Vector2(0.0855715, 0.070923) - -[node name="Coin3" parent="Coins/CoinsArc" instance=ExtResource( 4 )] -position = Vector2(31.2736, -17.854) - -[node name="CoinsVertical" type="Node2D" parent="Coins"] -position = Vector2(366.022, 518.94) - -[node name="Coin" parent="Coins/CoinsVertical" instance=ExtResource( 4 )] -position = Vector2(-0.0551455, 15.9351) - -[node name="Coin2" parent="Coins/CoinsVertical" instance=ExtResource( 4 )] -position = Vector2(-0.0551455, -0.0649415) - -[node name="Coin3" parent="Coins/CoinsVertical" instance=ExtResource( 4 )] -position = Vector2(-0.0551455, -16.065) - -[node name="CoinsVertical2" type="Node2D" parent="Coins"] -position = Vector2(509.055, -8.98655) - -[node name="Coin" parent="Coins/CoinsVertical2" instance=ExtResource( 4 )] -position = Vector2(-0.0551455, 15.9351) - -[node name="Coin2" parent="Coins/CoinsVertical2" instance=ExtResource( 4 )] -position = Vector2(-0.0551455, -0.0649415) - -[node name="Coin3" parent="Coins/CoinsVertical2" instance=ExtResource( 4 )] -position = Vector2(-0.0551455, -16.065) - -[node name="CoinsSquare" type="Node2D" parent="Coins"] -position = Vector2(-214.835, 161.6) - -[node name="Coin" parent="Coins/CoinsSquare" instance=ExtResource( 4 )] -position = Vector2(-16, -16) - -[node name="Coin2" parent="Coins/CoinsSquare" instance=ExtResource( 4 )] -position = Vector2(16, -16) - -[node name="Coin3" parent="Coins/CoinsSquare" instance=ExtResource( 4 )] -position = Vector2(-16, 16) - -[node name="Coin4" parent="Coins/CoinsSquare" instance=ExtResource( 4 )] -position = Vector2(16, 16) - -[node name="CoinsSquare2" type="Node2D" parent="Coins"] -position = Vector2(347.552, 33.4742) - -[node name="Coin" parent="Coins/CoinsSquare2" instance=ExtResource( 4 )] -position = Vector2(-16, -16) - -[node name="Coin2" parent="Coins/CoinsSquare2" instance=ExtResource( 4 )] -position = Vector2(16, -16) - -[node name="Coin3" parent="Coins/CoinsSquare2" instance=ExtResource( 4 )] -position = Vector2(-16, 16) - -[node name="Coin4" parent="Coins/CoinsSquare2" instance=ExtResource( 4 )] -position = Vector2(16, 16) - -[node name="CoinsSquare3" type="Node2D" parent="Coins"] -position = Vector2(676.585, 58.6425) - -[node name="Coin" parent="Coins/CoinsSquare3" instance=ExtResource( 4 )] -position = Vector2(-16, -16) - -[node name="Coin2" parent="Coins/CoinsSquare3" instance=ExtResource( 4 )] -position = Vector2(16, -16) - -[node name="Coin3" parent="Coins/CoinsSquare3" instance=ExtResource( 4 )] -position = Vector2(-16, 16) - -[node name="Coin4" parent="Coins/CoinsSquare3" instance=ExtResource( 4 )] -position = Vector2(16, 16) - -[node name="CoinsSquare4" type="Node2D" parent="Coins"] -position = Vector2(796.29, 58.6425) - -[node name="Coin" parent="Coins/CoinsSquare4" instance=ExtResource( 4 )] -position = Vector2(-16, -16) - -[node name="Coin2" parent="Coins/CoinsSquare4" instance=ExtResource( 4 )] -position = Vector2(16, -16) - -[node name="Coin3" parent="Coins/CoinsSquare4" instance=ExtResource( 4 )] -position = Vector2(-16, 16) - -[node name="Coin4" parent="Coins/CoinsSquare4" instance=ExtResource( 4 )] -position = Vector2(16, 16) - -[node name="CoinsHorizontal" type="Node2D" parent="Coins"] -position = Vector2(36.6204, 402.991) - -[node name="Coin" parent="Coins/CoinsHorizontal" instance=ExtResource( 4 )] -position = Vector2(-16, 0) - -[node name="Coin2" parent="Coins/CoinsHorizontal" instance=ExtResource( 4 )] - -[node name="Coin3" parent="Coins/CoinsHorizontal" instance=ExtResource( 4 )] -position = Vector2(16, 0) - -[node name="CoinsHorizontal2" type="Node2D" parent="Coins"] -position = Vector2(668.605, 431.544) - -[node name="Coin" parent="Coins/CoinsHorizontal2" instance=ExtResource( 4 )] -position = Vector2(-16, 0) - -[node name="Coin2" parent="Coins/CoinsHorizontal2" instance=ExtResource( 4 )] - -[node name="Coin3" parent="Coins/CoinsHorizontal2" instance=ExtResource( 4 )] -position = Vector2(16, 0) - -[node name="CoinsHorizontal3" type="Node2D" parent="Coins"] -position = Vector2(335.585, 155.872) - -[node name="Coin" parent="Coins/CoinsHorizontal3" instance=ExtResource( 4 )] -position = Vector2(-16, 0) - -[node name="Coin2" parent="Coins/CoinsHorizontal3" instance=ExtResource( 4 )] - -[node name="Coin3" parent="Coins/CoinsHorizontal3" instance=ExtResource( 4 )] -position = Vector2(16, 0) - -[node name="CoinsHorizontal4" type="Node2D" parent="Coins"] -position = Vector2(-63.444, 20.5902) - -[node name="Coin" parent="Coins/CoinsHorizontal4" instance=ExtResource( 4 )] -position = Vector2(-16, 0) - -[node name="Coin2" parent="Coins/CoinsHorizontal4" instance=ExtResource( 4 )] - -[node name="Coin3" parent="Coins/CoinsHorizontal4" instance=ExtResource( 4 )] -position = Vector2(16, 0) - -[node name="CoinsHorizontal5" type="Node2D" parent="Coins"] -position = Vector2(127.607, 20.5902) - -[node name="Coin" parent="Coins/CoinsHorizontal5" instance=ExtResource( 4 )] -position = Vector2(-16, 0) - -[node name="Coin2" parent="Coins/CoinsHorizontal5" instance=ExtResource( 4 )] - -[node name="Coin3" parent="Coins/CoinsHorizontal5" instance=ExtResource( 4 )] -position = Vector2(16, 0) - -[node name="Platforms" type="Node" parent="."] - -[node name="Platform" parent="Platforms" instance=ExtResource( 3 )] -position = Vector2(707, 400) - -[node name="AnimationPlayer" type="AnimationPlayer" parent="Platforms/Platform"] -autoplay = "move" -playback_process_mode = 0 -anims/move = SubResource( 1 ) - -[node name="Platform2" parent="Platforms" instance=ExtResource( 3 )] -position = Vector2(-47, 80) - -[node name="AnimationPlayer" type="AnimationPlayer" parent="Platforms/Platform2"] -autoplay = "move" -playback_process_mode = 0 -anims/move = SubResource( 2 ) - -[node name="PlatformStatic" type="StaticBody2D" parent="Platforms"] -position = Vector2(569.935, 105.877) -rotation = 0.355618 -z_index = -1 -collision_layer = 16 -collision_mask = 0 - -[node name="Sprite2" type="Sprite2D" parent="Platforms/PlatformStatic"] -position = Vector2(-88.692, 10.5003) -rotation = -0.246293 -texture = ExtResource( 6 ) - -[node name="Sprite2D" type="Sprite2D" parent="Platforms/PlatformStatic"] -texture = ExtResource( 6 ) - -[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Platforms/PlatformStatic"] -position = Vector2(-0.0684814, 0.0254364) -polygon = PackedVector2Array(-129.699, 9.94633, -47, -10.5, 8, -7, 10, -1.5, -46.75, -4, -130, 15) - -[node name="Enemies" type="Node" parent="."] - -[node name="Enemy" parent="Enemies" instance=ExtResource( 2 )] -position = Vector2(271.04, 245.639) - -[node name="Enemy2" parent="Enemies" instance=ExtResource( 2 )] -position = Vector2(346.109, 48.5631) - -[node name="Enemy3" parent="Enemies" instance=ExtResource( 2 )] -position = Vector2(632.725, 78.5545) - -[node name="Enemy4" parent="Enemies" instance=ExtResource( 2 )] -position = Vector2(828.515, 77.262) - -[node name="ParallaxBackground" parent="." instance=ExtResource( 7 )] - -[node name="Music" type="AudioStreamPlayer" parent="."] -stream = ExtResource( 8 ) -autoplay = true -script = ExtResource( 9 ) diff --git a/2d/platformer/src/Level/Music.gd b/2d/platformer/src/Level/Music.gd deleted file mode 100644 index 10893213..00000000 --- a/2d/platformer/src/Level/Music.gd +++ /dev/null @@ -1,16 +0,0 @@ -extends AudioStreamPlayer - -const DOUBLE_VOLUME_DB = 6 # Do not change. Represents doubling of sound pressure. - -@export var base_volume_db: int = -14 - -func _ready(): - # To avoid AudioStreamPlayer2D sounds playing on top of each other and - # being very loud, let's decrease the volume for splitscreen mode, but - # increase the music volume to keep the music at the same volume. - if get_parent().get_owner().name == "Splitscreen": - AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), base_volume_db - DOUBLE_VOLUME_DB) - volume_db = DOUBLE_VOLUME_DB - else: - AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), base_volume_db) - volume_db = 0 diff --git a/2d/platformer/src/Main/Game.gd b/2d/platformer/src/Main/Game.gd deleted file mode 100644 index 49e580e6..00000000 --- a/2d/platformer/src/Main/Game.gd +++ /dev/null @@ -1,43 +0,0 @@ -extends Node -# This class contains controls that should always be accessible, like pausing -# the game or toggling the window full-screen. - - -# The "_" prefix is a convention to indicate that variables are private, -# that is to say, another node or script should not access them. -@onready var _pause_menu = $InterfaceLayer/PauseMenu - - -func _notification(what): - if what == NOTIFICATION_WM_CLOSE_REQUEST: - # We need to clean up a little bit first to avoid SubViewport errors. - if name == "Splitscreen": - $Black/SplitContainer/ViewportContainer1.free() - $Black.queue_free() - - -func _unhandled_input(event): - if event.is_action_pressed("toggle_fullscreen"): - OS.window_fullscreen = not OS.window_fullscreen - get_tree().set_input_as_handled() - # The GlobalControls node, in the Stage scene, is set to process even - # when the game is paused, so this code keeps running. - # To see that, select GlobalControls, and scroll down to the Pause category - # in the inspector. - elif event.is_action_pressed("toggle_pause"): - var tree = get_tree() - tree.paused = not tree.paused - if tree.paused: - _pause_menu.open() - else: - _pause_menu.close() - get_tree().set_input_as_handled() - - elif event.is_action_pressed("splitscreen"): - if name == "Splitscreen": - # We need to clean up a little bit first to avoid SubViewport errors. - $Black/SplitContainer/ViewportContainer1.free() - $Black.queue_free() - get_tree().change_scene("res://src/Main/Game.tscn") - else: - get_tree().change_scene("res://src/Main/Splitscreen.tscn") diff --git a/2d/platformer/src/Main/Game.tscn b/2d/platformer/src/Main/Game.tscn deleted file mode 100644 index 08deb37c..00000000 --- a/2d/platformer/src/Main/Game.tscn +++ /dev/null @@ -1,22 +0,0 @@ -[gd_scene load_steps=5 format=3 uid="uid://b0qd6b4ipb0iv"] - -[ext_resource type="PackedScene" path="res://src/UserInterface/PauseMenu.tscn" id="1"] -[ext_resource type="Script" path="res://src/Main/Game.gd" id="2"] -[ext_resource type="PackedScene" path="res://src/Level/Level.tscn" id="3"] -[ext_resource type="PackedScene" path="res://src/Actors/Player.tscn" id="4"] - -[node name="Game" type="Node"] -process_mode = 3 -script = ExtResource("2") - -[node name="Level" parent="." instance=ExtResource("3")] - -[node name="Player" parent="Level" instance=ExtResource("4")] -position = Vector2(90, 546) - -[node name="InterfaceLayer" type="CanvasLayer" parent="."] -layer = 100 - -[node name="PauseMenu" parent="InterfaceLayer" instance=ExtResource("1")] -layout_mode = 3 -anchors_preset = 15 diff --git a/2d/platformer/src/Main/Splitscreen.tscn b/2d/platformer/src/Main/Splitscreen.tscn deleted file mode 100644 index 839a8787..00000000 --- a/2d/platformer/src/Main/Splitscreen.tscn +++ /dev/null @@ -1,80 +0,0 @@ -[gd_scene load_steps=6 format=2] - -[ext_resource path="res://src/UserInterface/PauseMenu.tscn" type="PackedScene" id=1] -[ext_resource path="res://src/Main/Game.gd" type="Script" id=2] -[ext_resource path="res://src/Level/Level.tscn" type="PackedScene" id=3] -[ext_resource path="res://src/Actors/Player.tscn" type="PackedScene" id=4] -[ext_resource path="res://src/Level/ParallaxBackground.tscn" type="PackedScene" id=5] - -[node name="Splitscreen" type="Node"] -process_mode = 3 -script = ExtResource( 2 ) - -[node name="InterfaceLayer" type="CanvasLayer" parent="."] -layer = 100 - -[node name="PauseMenu" parent="InterfaceLayer" instance=ExtResource( 1 )] - -[node name="Black" type="ColorRect" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_right = 6.10352e-05 -offset_bottom = 3.05176e-05 -color = Color(0, 0, 0, 1) - -[node name="SplitContainer" type="HSplitContainer" parent="Black"] -anchor_right = 1.0 -anchor_bottom = 1.0 -dragger_visibility = 1 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="ViewportContainer1" type="SubViewportContainer" parent="Black/SplitContainer"] -offset_right = 394.0 -offset_bottom = 480.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 -stretch = true -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Viewport1" type="SubViewport" parent="Black/SplitContainer/ViewportContainer1"] -size = Vector2(394, 480) -size_override_stretch = true -handle_input_locally = false -usage = 0 -render_target_update_mode = 3 -audio_listener_enable_2d = true - -[node name="Level" parent="Black/SplitContainer/ViewportContainer1/Viewport1" instance=ExtResource( 3 )] - -[node name="Player1" parent="Black/SplitContainer/ViewportContainer1/Viewport1/Level" instance=ExtResource( 4 )] -position = Vector2(90, 546) -action_suffix = "_p1" - -[node name="Player2" parent="Black/SplitContainer/ViewportContainer1/Viewport1/Level" instance=ExtResource( 4 )] -position = Vector2(120, 546) -action_suffix = "_p2" - -[node name="ViewportContainer2" type="SubViewportContainer" parent="Black/SplitContainer"] -offset_left = 406.0 -offset_right = 800.0 -offset_bottom = 480.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 -stretch = true -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Viewport2" type="SubViewport" parent="Black/SplitContainer/ViewportContainer2"] -size = Vector2(394, 480) -size_override_stretch = true -handle_input_locally = false -usage = 0 -render_target_update_mode = 3 -audio_listener_enable_2d = true - -[node name="ParallaxBackground" parent="Black/SplitContainer/ViewportContainer2/Viewport2" instance=ExtResource( 5 )] diff --git a/2d/platformer/src/Objects/Bullet.gd b/2d/platformer/src/Objects/Bullet.gd deleted file mode 100644 index 7b35e9fe..00000000 --- a/2d/platformer/src/Objects/Bullet.gd +++ /dev/null @@ -1,14 +0,0 @@ -class_name Bullet -extends RigidBody2D - - -@onready var animation_player = $AnimationPlayer - - -func destroy(): - animation_player.play("destroy") - - -func _on_body_entered(body): - if body is Enemy: - body.destroy() diff --git a/2d/platformer/src/Objects/Coin.gd b/2d/platformer/src/Objects/Coin.gd deleted file mode 100644 index 1fe195f3..00000000 --- a/2d/platformer/src/Objects/Coin.gd +++ /dev/null @@ -1,16 +0,0 @@ -class_name Coin -extends Area2D -# Collectible that disappears when the player touches it. - -@onready var animation_player = $AnimationPlayer - -# The Coins only detects collisions with the Player thanks to its collision mask. -# This prevents other characters such as enemies from picking up coins. - -# When the player collides with a coin, the coin plays its "picked" animation. -# The animation takes cares of making the coin disappear, but also deactivates its -# collisions and frees it from memory, saving us from writing more complex code. -# Click the AnimationPlayer node to see the animation timeline. -func _on_body_entered(_body): - animation_player.play("picked") - _body.emit_signal("collect_coin") diff --git a/2d/platformer/src/Platforms/Platform.tscn b/2d/platformer/src/Platforms/Platform.tscn deleted file mode 100644 index e10ef13c..00000000 --- a/2d/platformer/src/Platforms/Platform.tscn +++ /dev/null @@ -1,21 +0,0 @@ -[gd_scene load_steps=3 format=2] - -[ext_resource path="res://assets/art/platforms/moving_platform.png" type="Texture2D" id=2] - -[sub_resource type="RectangleShape2D" id=1] -extents = Vector2(47, 6) - -[node name="Platform" type="CharacterBody2D"] -z_index = -1 -collision_layer = 8 -collision_mask = 0 -collision/safe_margin = 0.12 -motion/sync_to_physics = true - -[node name="Sprite2D" type="Sprite2D" parent="."] -texture = ExtResource( 2 ) - -[node name="CollisionShape2D" type="CollisionShape2D" parent="."] -position = Vector2(0, -4) -shape = SubResource( 1 ) -one_way_collision = true diff --git a/2d/platformer/src/UserInterface/CoinsCounter.gd b/2d/platformer/src/UserInterface/CoinsCounter.gd deleted file mode 100644 index 9ddcb41f..00000000 --- a/2d/platformer/src/UserInterface/CoinsCounter.gd +++ /dev/null @@ -1,25 +0,0 @@ -extends Panel - -var coins_collected = 0 - -@onready var coins_label = $Label - - -func _ready(): - coins_label.set_text(str(coins_collected)) - # Static types are necessary here to avoid warnings. - var anim_sprite: AnimatedSprite2D = $AnimatedSprite2D - anim_sprite.play() - # Check if the game is in splitscreen mode by checking the scene root name. - if get_tree().get_root().get_child(0).name == "Splitscreen": - var _level_node = get_node(^"../../../../Black/SplitContainer/ViewportContainer1/Viewport1/Level") - _level_node.get_node(^"Player1").collect_coin.connect(self._collect_coin) - _level_node.get_node(^"Player2").collect_coin.connect(self._collect_coin) - else: - var _player_path = get_node(^"../../../../Level/Player") - _player_path.collect_coin.connect(self._collect_coin) - - -func _collect_coin(): - coins_collected += 1 - coins_label.set_text(str(coins_collected)) diff --git a/2d/platformer/src/UserInterface/CoinsCounter.tscn b/2d/platformer/src/UserInterface/CoinsCounter.tscn deleted file mode 100644 index 1dd7364d..00000000 --- a/2d/platformer/src/UserInterface/CoinsCounter.tscn +++ /dev/null @@ -1,63 +0,0 @@ -[gd_scene load_steps=10 format=2] - -[ext_resource path="res://assets/theme/user_interface.tres" type="Theme" id=1] -[ext_resource path="res://assets/art/coin/coin.png" type="Texture2D" id=2] -[ext_resource path="res://src/UserInterface/CoinsCounter.gd" type="Script" id=3] - -[sub_resource type="StyleBoxFlat" id=1] -bg_color = Color(0, 0, 0, 0.5) - -[sub_resource type="AtlasTexture" id=2] -atlas = ExtResource( 2 ) -region = Rect2(0, 0, 8, 8) - -[sub_resource type="AtlasTexture" id=3] -atlas = ExtResource( 2 ) -region = Rect2(8, 0, 8, 8) - -[sub_resource type="AtlasTexture" id=4] -atlas = ExtResource( 2 ) -region = Rect2(16, 0, 8, 8) - -[sub_resource type="AtlasTexture" id=5] -atlas = ExtResource( 2 ) -region = Rect2(24, 0, 8, 8) - -[sub_resource type="SpriteFrames" id=6] -animations = [{ -"frames": [SubResource( 2 ), SubResource( 3 ), SubResource( 4 ), SubResource( 5 ), SubResource( 4 ), SubResource( 3 )], -"loop": true, -"name": "coin_spinning", -"speed": 6.5 -}] - -[node name="CoinsCounter" type="Panel"] -offset_left = 5.0 -offset_top = 5.0 -offset_right = 100.0 -offset_bottom = 45.0 -rect_min_size = Vector2(100, 45) -theme = ExtResource( 1 ) -custom_styles/panel = SubResource( 1 ) -script = ExtResource( 3 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Label" type="Label" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_right = -8.0 -text = "100" -align = 2 -valign = 1 -autowrap = true -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] -position = Vector2(21.5, 22.5) -scale = Vector2(4.375, 4.375) -frames = SubResource( 6 ) -animation = "coin_spinning" diff --git a/2d/platformer/src/UserInterface/PauseMenu.gd b/2d/platformer/src/UserInterface/PauseMenu.gd deleted file mode 100644 index e022c9b5..00000000 --- a/2d/platformer/src/UserInterface/PauseMenu.gd +++ /dev/null @@ -1,58 +0,0 @@ -extends Control - - -@export var _start_position: Vector2 = Vector2(0, -20) -@export var _end_position: Vector2 = Vector2.ZERO -@export var fade_in_duration: float = 0.3 -@export var fade_out_duration: float = 0.2 - -@onready var center_cont = $ColorRect/CenterContainer -@onready var resume_button = center_cont.get_node(^"VBoxContainer/ResumeButton") - -@onready var root = get_tree().get_root() -@onready var scene_root = root.get_child(root.get_child_count() - 1) -@onready var tween = $Tween - - -func _ready(): - hide() - - -func close(): - get_tree().paused = false - # Tween's interpolate_property has these arguments: - # (Target object, "Property:OptionalSubProperty", From value, To value, - # Tween duration, Transition type, Easing type, Optional delay) - tween.interpolate_property(self, "modulate:a", 1.0, 0.0, - fade_out_duration, Tween.TRANS_LINEAR, Tween.EASE_IN) - tween.interpolate_property(center_cont, "position", - _end_position, _start_position, fade_out_duration, - Tween.TRANS_CUBIC, Tween.EASE_OUT) - tween.start() - - -func open(): - show() - resume_button.grab_focus() - - tween.interpolate_property(self, "modulate:a", 0.0, 1.0, - fade_in_duration, Tween.TRANS_LINEAR, Tween.EASE_IN) - tween.interpolate_property(center_cont, "position", - _start_position, _end_position, fade_in_duration, - Tween.TRANS_CUBIC, Tween.EASE_OUT) - tween.start() - - -func _on_ResumeButton_pressed(): - if not tween.is_active(): - close() - - -func _on_QuitButton_pressed(): - scene_root.notification(NOTIFICATION_WM_CLOSE_REQUEST) - get_tree().quit() - - -func _on_Tween_all_completed(): - if modulate.a < 0.5: - hide()