Эх сурвалжийг харах

Remake the 2d/platformer demo from scratch

This Godot project is a complete rewrite of the official Platformer 2D demo. This is part of a proposal to improve and harmonize the official demo projects. We want to:

- Teach good programming practices with Godot.
- Bring demos to a higher quality standard.
- Unify the code in the demos.

See the [open issue](https://github.com/godotengine/godot-demo-projects/issues/390) for more information.

This new demo showcases features from the original, and works with Godot 3.2.

Co-authored-by: Johnny Goss <[email protected]>
Nathan Lovato 5 жил өмнө
parent
commit
e323bead2e
88 өөрчлөгдсөн 1410 нэмэгдсэн , 1319 устгасан
  1. 0 17
      2d/platformer/Stage.tscn
  2. 0 243
      2d/platformer/TileSet.tres
  3. 0 324
      2d/platformer/TilesetEdit.tscn
  4. 0 0
      2d/platformer/assets/art/background/cloud_1.png
  5. 3 3
      2d/platformer/assets/art/background/cloud_1.png.import
  6. 0 0
      2d/platformer/assets/art/background/cloud_2.png
  7. 34 0
      2d/platformer/assets/art/background/cloud_2.png.import
  8. 0 0
      2d/platformer/assets/art/background/cloud_3.png
  9. 34 0
      2d/platformer/assets/art/background/cloud_3.png.import
  10. BIN
      2d/platformer/assets/art/background/distant_platforms_1.png
  11. 34 0
      2d/platformer/assets/art/background/distant_platforms_1.png.import
  12. BIN
      2d/platformer/assets/art/background/distant_platforms_2.png
  13. 34 0
      2d/platformer/assets/art/background/distant_platforms_2.png.import
  14. 0 0
      2d/platformer/assets/art/background/sky.png
  15. 3 3
      2d/platformer/assets/art/background/sky.png.import
  16. 0 0
      2d/platformer/assets/art/coin/coin.png
  17. 3 3
      2d/platformer/assets/art/coin/coin.png.import
  18. 0 0
      2d/platformer/assets/art/enemy/enemy.png
  19. 3 3
      2d/platformer/assets/art/enemy/enemy.png.import
  20. BIN
      2d/platformer/assets/art/platforms/moving_platform.png
  21. 3 3
      2d/platformer/assets/art/platforms/moving_platform.png.import
  22. 0 0
      2d/platformer/assets/art/platforms/one_way_platform.png
  23. 3 3
      2d/platformer/assets/art/platforms/one_way_platform.png.import
  24. 0 0
      2d/platformer/assets/art/player/bullet/bullet.png
  25. 3 3
      2d/platformer/assets/art/player/bullet/bullet.png.import
  26. 0 0
      2d/platformer/assets/art/player/robot_demo.png
  27. 3 3
      2d/platformer/assets/art/player/robot_demo.png.import
  28. BIN
      2d/platformer/assets/art/tileset/tiles_demo.png
  29. 3 3
      2d/platformer/assets/art/tileset/tiles_demo.png.import
  30. 263 0
      2d/platformer/assets/art/tileset/tileset.tres
  31. 0 0
      2d/platformer/assets/art/ui/touch_button_fire.png
  32. 3 3
      2d/platformer/assets/art/ui/touch_button_fire.png.import
  33. 0 0
      2d/platformer/assets/art/ui/touch_button_jump.png
  34. 3 3
      2d/platformer/assets/art/ui/touch_button_jump.png.import
  35. 0 0
      2d/platformer/assets/art/ui/touch_button_left.png
  36. 3 3
      2d/platformer/assets/art/ui/touch_button_left.png.import
  37. 0 0
      2d/platformer/assets/art/ui/touch_button_right.png
  38. 3 3
      2d/platformer/assets/art/ui/touch_button_right.png.import
  39. 0 0
      2d/platformer/assets/audio/music/music.ogg
  40. 15 0
      2d/platformer/assets/audio/music/music.ogg.import
  41. 0 0
      2d/platformer/assets/audio/sfx/coin_pickup.wav
  42. 21 0
      2d/platformer/assets/audio/sfx/coin_pickup.wav.import
  43. 0 0
      2d/platformer/assets/audio/sfx/explode.wav
  44. 3 3
      2d/platformer/assets/audio/sfx/explode.wav.import
  45. 0 0
      2d/platformer/assets/audio/sfx/hit.wav
  46. 3 3
      2d/platformer/assets/audio/sfx/hit.wav.import
  47. 0 0
      2d/platformer/assets/audio/sfx/jump.wav
  48. 3 3
      2d/platformer/assets/audio/sfx/jump.wav.import
  49. 0 0
      2d/platformer/assets/audio/sfx/shoot.wav
  50. 3 3
      2d/platformer/assets/audio/sfx/shoot.wav.import
  51. BIN
      2d/platformer/assets/theme/fonts/kenney_mini_square.ttf
  52. 82 0
      2d/platformer/assets/theme/user_interface.tres
  53. 0 15
      2d/platformer/audio/music.ogg.import
  54. 0 21
      2d/platformer/audio/sound_explode.wav.import
  55. BIN
      2d/platformer/background/scroll_bg_fg_1.png
  56. 0 34
      2d/platformer/background/scroll_bg_fg_1.png.import
  57. BIN
      2d/platformer/background/scroll_bg_fg_2.png
  58. 0 34
      2d/platformer/background/scroll_bg_fg_2.png.import
  59. 0 140
      2d/platformer/coin/Coin.tscn
  60. 0 11
      2d/platformer/coin/coin.gd
  61. 0 50
      2d/platformer/enemy/enemy.gd
  62. 0 16
      2d/platformer/platform/MovingPlatform.tscn
  63. 0 17
      2d/platformer/platform/OneWayPlatform.tscn
  64. 0 17
      2d/platformer/platform/moving_platform.gd
  65. BIN
      2d/platformer/platform/moving_platform.png
  66. 0 11
      2d/platformer/player/bullet.gd
  67. 0 34
      2d/platformer/player/osb_left.png.import
  68. 0 34
      2d/platformer/player/osb_right.png.import
  69. 0 97
      2d/platformer/player/player.gd
  70. 45 13
      2d/platformer/project.godot
  71. 18 0
      2d/platformer/src/Actors/Actor.gd
  72. 78 0
      2d/platformer/src/Actors/Enemy.gd
  73. 110 73
      2d/platformer/src/Actors/Enemy.tscn
  74. 24 0
      2d/platformer/src/Actors/Gun.gd
  75. 96 0
      2d/platformer/src/Actors/Player.gd
  76. 48 37
      2d/platformer/src/Actors/Player.tscn
  77. 52 0
      2d/platformer/src/Level/Level.tscn
  78. 20 16
      2d/platformer/src/Level/ParallaxBackground.tscn
  79. 26 0
      2d/platformer/src/Main/Game.gd
  80. 16 0
      2d/platformer/src/Main/Game.tscn
  81. 14 0
      2d/platformer/src/Objects/Bullet.gd
  82. 16 14
      2d/platformer/src/Objects/Bullet.tscn
  83. 15 0
      2d/platformer/src/Objects/Coin.gd
  84. 161 0
      2d/platformer/src/Objects/Coin.tscn
  85. 21 0
      2d/platformer/src/Platforms/Platform.tscn
  86. 26 0
      2d/platformer/src/UserInterface/PauseMenu.gd
  87. 56 0
      2d/platformer/src/UserInterface/PauseMenu.tscn
  88. BIN
      2d/platformer/tiles_demo.png

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 17
2d/platformer/Stage.tscn


+ 0 - 243
2d/platformer/TileSet.tres

@@ -1,243 +0,0 @@
-[gd_resource type="TileSet" load_steps=14 format=2]
-
-[ext_resource path="res://tiles_demo.png" type="Texture" id=1]
-
-[sub_resource type="ConvexPolygonShape2D" id=1]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( 32, -24, 32, 32, -32, 32, -32, -24 )
-
-[sub_resource type="ConvexPolygonShape2D" id=2]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( -32, -24, 24, -24, 24, 32, -32, 32 )
-
-[sub_resource type="ConvexPolygonShape2D" id=3]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( 32, -32, 32, 32, -32, 32, -32, -32 )
-
-[sub_resource type="ConvexPolygonShape2D" id=4]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( -32, -56, 32, 8, 32, 64, -32, 64 )
-
-[sub_resource type="ConvexPolygonShape2D" id=5]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( -32, -32, 24, -32, 24, 32, -32, 32 )
-
-[sub_resource type="ConvexPolygonShape2D" id=6]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( 32, -24, 32, 24, -32, 24, -32, -24 )
-
-[sub_resource type="ConvexPolygonShape2D" id=7]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( 24, -24, 24, 24, -32, 24, -32, -24 )
-
-[sub_resource type="ConvexPolygonShape2D" id=8]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( -32, -32, 24, -32, 24, 32, -32, 32 )
-
-[sub_resource type="ConvexPolygonShape2D" id=9]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( -64, -32, -8, -32, -8, 32, -64, 32 )
-
-[sub_resource type="ConvexPolygonShape2D" id=10]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( -32, -32, 24, -32, 32, -24, 32, 32, -32, 32 )
-
-[sub_resource type="ConvexPolygonShape2D" id=11]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( -32, -24, 32, -24, 32, 32, -32, 32 )
-
-[sub_resource type="ConvexPolygonShape2D" id=12]
-
-custom_solver_bias = 0.0
-points = PoolVector2Array( -32, -24, 32, -24, 32, 32, -32, 32 )
-
-[resource]
-
-0/name = "floor"
-0/texture = ExtResource( 1 )
-0/tex_offset = Vector2( 0, 0 )
-0/modulate = Color( 1, 1, 1, 1 )
-0/region = Rect2( 0, 0, 64, 64 )
-0/occluder_offset = Vector2( 32, 32 )
-0/navigation_offset = Vector2( 32, 32 )
-0/shapes = [ {
-"one_way": false,
-"shape": SubResource( 1 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 32 )
-} ]
-1/name = "edge"
-1/texture = ExtResource( 1 )
-1/tex_offset = Vector2( 0, 0 )
-1/modulate = Color( 1, 1, 1, 1 )
-1/region = Rect2( 64, 0, 64, 64 )
-1/occluder_offset = Vector2( 32, 32 )
-1/navigation_offset = Vector2( 32, 32 )
-1/shapes = [ {
-"one_way": false,
-"shape": SubResource( 2 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 32 )
-} ]
-2/name = "wall"
-2/texture = ExtResource( 1 )
-2/tex_offset = Vector2( 0, 0 )
-2/modulate = Color( 1, 1, 1, 1 )
-2/region = Rect2( 64, 64, 64, 64 )
-2/occluder_offset = Vector2( 32, 32 )
-2/navigation_offset = Vector2( 32, 32 )
-2/shapes = [ {
-"one_way": false,
-"shape": SubResource( 8 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 32 )
-} ]
-3/name = "wall_deco"
-3/texture = ExtResource( 1 )
-3/tex_offset = Vector2( 0, 0 )
-3/modulate = Color( 1, 1, 1, 1 )
-3/region = Rect2( 320, 128, 128, 64 )
-3/occluder_offset = Vector2( 64, 32 )
-3/navigation_offset = Vector2( 64, 32 )
-3/shapes = [ {
-"one_way": false,
-"shape": SubResource( 9 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 64, 32 )
-} ]
-4/name = "corner"
-4/texture = ExtResource( 1 )
-4/tex_offset = Vector2( 0, 0 )
-4/modulate = Color( 1, 1, 1, 1 )
-4/region = Rect2( 64, 128, 64, 64 )
-4/occluder_offset = Vector2( 32, 32 )
-4/navigation_offset = Vector2( 32, 32 )
-4/shapes = [ {
-"one_way": false,
-"shape": SubResource( 10 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 32 )
-} ]
-5/name = "flowers"
-5/texture = ExtResource( 1 )
-5/tex_offset = Vector2( 0, 0 )
-5/modulate = Color( 1, 1, 1, 1 )
-5/region = Rect2( 192, 192, 64, 64 )
-5/occluder_offset = Vector2( 32, 32 )
-5/navigation_offset = Vector2( 32, 32 )
-5/shapes = [ {
-"one_way": false,
-"shape": SubResource( 11 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 32 )
-} ]
-6/name = "tree_base"
-6/texture = ExtResource( 1 )
-6/tex_offset = Vector2( 0, 0 )
-6/modulate = Color( 1, 1, 1, 1 )
-6/region = Rect2( 256, 192, 64, 64 )
-6/occluder_offset = Vector2( 32, 32 )
-6/navigation_offset = Vector2( 32, 32 )
-6/shapes = [ {
-"one_way": false,
-"shape": SubResource( 12 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 32 )
-} ]
-7/name = "tree_mid"
-7/texture = ExtResource( 1 )
-7/tex_offset = Vector2( 0, 0 )
-7/modulate = Color( 1, 1, 1, 1 )
-7/region = Rect2( 256, 128, 64, 64 )
-7/occluder_offset = Vector2( 32, 32 )
-7/navigation_offset = Vector2( 32, 32 )
-7/shapes = [  ]
-8/name = "tree_mid 2"
-8/texture = ExtResource( 1 )
-8/tex_offset = Vector2( 0, 0 )
-8/modulate = Color( 1, 1, 1, 1 )
-8/region = Rect2( 256, 64, 64, 64 )
-8/occluder_offset = Vector2( 32, 32 )
-8/navigation_offset = Vector2( 32, 32 )
-8/shapes = [  ]
-9/name = "tree_top"
-9/texture = ExtResource( 1 )
-9/tex_offset = Vector2( 0, 0 )
-9/modulate = Color( 1, 1, 1, 1 )
-9/region = Rect2( 256, 0, 64, 64 )
-9/occluder_offset = Vector2( 32, 32 )
-9/navigation_offset = Vector2( 32, 32 )
-9/shapes = [  ]
-10/name = "solid"
-10/texture = ExtResource( 1 )
-10/tex_offset = Vector2( 0, 0 )
-10/modulate = Color( 1, 1, 1, 1 )
-10/region = Rect2( 0, 64, 64, 64 )
-10/occluder_offset = Vector2( 32, 32 )
-10/navigation_offset = Vector2( 32, 32 )
-10/shapes = [  ]
-11/name = "ceiling"
-11/texture = ExtResource( 1 )
-11/tex_offset = Vector2( 0, 0 )
-11/modulate = Color( 1, 1, 1, 1 )
-11/region = Rect2( 384, 64, 64, 64 )
-11/occluder_offset = Vector2( 32, 32 )
-11/navigation_offset = Vector2( 32, 32 )
-11/shapes = [ {
-"one_way": false,
-"shape": SubResource( 3 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 32 )
-} ]
-12/name = "ramp"
-12/texture = ExtResource( 1 )
-12/tex_offset = Vector2( 0, 0 )
-12/modulate = Color( 1, 1, 1, 1 )
-12/region = Rect2( 128, 128, 64, 128 )
-12/occluder_offset = Vector2( 32, 64 )
-12/navigation_offset = Vector2( 32, 64 )
-12/shapes = [ {
-"one_way": false,
-"shape": SubResource( 4 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 64 )
-} ]
-13/name = "ceiling2wall"
-13/texture = ExtResource( 1 )
-13/tex_offset = Vector2( 0, 0 )
-13/modulate = Color( 1, 1, 1, 1 )
-13/region = Rect2( 448, 64, 64, 64 )
-13/occluder_offset = Vector2( 32, 32 )
-13/navigation_offset = Vector2( 32, 32 )
-13/shapes = [ {
-"one_way": false,
-"shape": SubResource( 5 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 32 )
-} ]
-14/name = "platform_floor"
-14/texture = ExtResource( 1 )
-14/tex_offset = Vector2( 0, 0 )
-14/modulate = Color( 1, 1, 1, 1 )
-14/region = Rect2( 128, 0, 64, 64 )
-14/occluder_offset = Vector2( 32, 32 )
-14/navigation_offset = Vector2( 32, 32 )
-14/shapes = [ {
-"one_way": false,
-"shape": SubResource( 6 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 32 )
-} ]
-15/name = "platform_edge"
-15/texture = ExtResource( 1 )
-15/tex_offset = Vector2( 0, 0 )
-15/modulate = Color( 1, 1, 1, 1 )
-15/region = Rect2( 192, 0, 64, 64 )
-15/occluder_offset = Vector2( 32, 32 )
-15/navigation_offset = Vector2( 32, 32 )
-15/shapes = [ {
-"one_way": false,
-"shape": SubResource( 7 ),
-"shape_transform": Transform2D( 1, 0, 0, 1, 32, 32 )
-} ]
-

+ 0 - 324
2d/platformer/TilesetEdit.tscn

@@ -1,324 +0,0 @@
-[gd_scene load_steps=2 format=2]
-
-[ext_resource path="res://tiles_demo.png" type="Texture" id=1]
-
-[node name="Node" type="Node"]
-
-[node name="floor" type="Sprite" parent="."]
-
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 0, 0, 64, 64 )
-
-[node name="collision" type="StaticBody2D" parent="floor"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="floor/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( 32, -24, 32, 32, -32, 32, -32, -24 )
-
-[node name="edge" type="Sprite" parent="."]
-
-position = Vector2( 64, 0 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 64, 0, 64, 64 )
-
-[node name="collision" type="StaticBody2D" parent="edge"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="edge/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( -32, -24, 24, -24, 24, 32, -32, 32 )
-
-[node name="wall" type="Sprite" parent="."]
-
-position = Vector2( 64, 64 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 64, 64, 64, 64 )
-
-[node name="collision" type="StaticBody2D" parent="wall"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="wall/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( -32, -32, 24, -32, 24, 32, -32, 32 )
-
-[node name="wall_deco" type="Sprite" parent="."]
-
-position = Vector2( 96, 128 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 320, 128, 128, 64 )
-
-[node name="collision" type="StaticBody2D" parent="wall_deco"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="wall_deco/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( -64, -32, -8, -32, -8, 32, -64, 32 )
-
-[node name="corner" type="Sprite" parent="."]
-
-position = Vector2( 64, 192 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 64, 128, 64, 64 )
-
-[node name="collision" type="StaticBody2D" parent="corner"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="corner/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( -32, -32, 24, -32, 32, -24, 32, 32, -32, 32 )
-
-[node name="flowers" type="Sprite" parent="."]
-
-position = Vector2( 128, 192 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 192, 192, 64, 64 )
-
-[node name="collision" type="StaticBody2D" parent="flowers"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="flowers/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( -32, 32, 32, 32, 32, -24, -32, -24 )
-
-[node name="tree_base" type="Sprite" parent="."]
-
-position = Vector2( 192, 192 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 256, 192, 64, 64 )
-
-[node name="collision" type="StaticBody2D" parent="tree_base"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="tree_base/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( -32, 32, 32, 32, 32, -24, -32, -24 )
-
-[node name="tree_mid" type="Sprite" parent="."]
-
-position = Vector2( 192, 128 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 256, 128, 64, 64 )
-
-[node name="tree_mid 2" type="Sprite" parent="."]
-
-position = Vector2( 192, 64 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 256, 64, 64, 64 )
-
-[node name="tree_top" type="Sprite" parent="."]
-
-position = Vector2( 192, 0 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 256, 0, 64, 64 )
-
-[node name="solid" type="Sprite" parent="."]
-
-position = Vector2( 0, 64 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 0, 64, 64, 64 )
-
-[node name="ceiling" type="Sprite" parent="."]
-
-position = Vector2( 0, 128 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 384, 64, 64, 64 )
-
-[node name="collision" type="StaticBody2D" parent="ceiling"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="ceiling/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( 32, -32, 32, 32, -32, 32, -32, -32 )
-
-[node name="ramp" type="Sprite" parent="."]
-
-position = Vector2( 256, 224 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 128, 128, 64, 128 )
-
-[node name="collision" type="StaticBody2D" parent="ramp"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="ramp/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( -32, -56, 32, 8, 32, 64, -32, 64 )
-
-[node name="ceiling2wall" type="Sprite" parent="."]
-
-position = Vector2( 0, 192 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 448, 64, 64, 64 )
-
-[node name="collision" type="StaticBody2D" parent="ceiling2wall"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="ceiling2wall/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( -32, -32, 24, -32, 24, 32, -32, 32 )
-
-[node name="platform_floor" type="Sprite" parent="."]
-
-position = Vector2( 0, 256 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 128, 0, 64, 64 )
-
-[node name="collision" type="StaticBody2D" parent="platform_floor"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="platform_floor/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( 32, -24, 32, 24, -32, 24, -32, -24 )
-
-[node name="platform_edge" type="Sprite" parent="."]
-
-position = Vector2( 64, 256 )
-texture = ExtResource( 1 )
-region_enabled = true
-region_rect = Rect2( 192, 0, 64, 64 )
-
-[node name="collision" type="StaticBody2D" parent="platform_edge"]
-
-input_pickable = false
-collision_layer = 1
-collision_mask = 1
-constant_linear_velocity = Vector2( 0, 0 )
-constant_angular_velocity = 0.0
-friction = 1.0
-bounce = 0.0
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="platform_edge/collision"]
-
-build_mode = 0
-polygon = PoolVector2Array( 24, -24, 24, 24, -32, 24, -32, -24 )
-
-[node name="help" type="Label" parent="."]
-
-anchor_left = 0.0
-anchor_top = 0.0
-anchor_right = 0.0
-anchor_bottom = 0.0
-margin_left = 1.0
-margin_top = 331.0
-margin_right = 727.0
-margin_bottom = 422.0
-rect_pivot_offset = Vector2( 0, 0 )
-rect_clip_content = false
-mouse_filter = 2
-size_flags_horizontal = 2
-size_flags_vertical = 0
-text = "This scene serves as a tool for editing the tileset.
-Nodes (sprites) and their respective collisionsare edited here.
-
-To create a tileset from this, a \"TileSet\" resoucre must be created. Use the helper in: Scene -> Convert To -> TileSet.
-This will save a tileset. Saving over it will merge your changes.
-
-Finally, the saved tileset resource (tileset.tres in this case), can be opened to be used into a TileMap node for editing a tile map."
-percent_visible = 1.0
-lines_skipped = 0
-max_lines_visible = -1
-
-

+ 0 - 0
2d/platformer/background/scroll_bg_cloud_1.png → 2d/platformer/assets/art/background/cloud_1.png


+ 3 - 3
2d/platformer/player/osb_jump.png.import → 2d/platformer/assets/art/background/cloud_1.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/osb_jump.png-0d4d2b2d1a7d2c11e3e4fd800b8589ed.stex"
+path="res://.import/cloud_1.png-03c0ad8be397b731df0dd38fa3c87727.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://player/osb_jump.png"
-dest_files=[ "res://.import/osb_jump.png-0d4d2b2d1a7d2c11e3e4fd800b8589ed.stex" ]
+source_file="res://assets/art/background/cloud_1.png"
+dest_files=[ "res://.import/cloud_1.png-03c0ad8be397b731df0dd38fa3c87727.stex" ]
 
 [params]
 

+ 0 - 0
2d/platformer/background/scroll_bg_cloud_2.png → 2d/platformer/assets/art/background/cloud_2.png


+ 34 - 0
2d/platformer/assets/art/background/cloud_2.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/cloud_2.png-4ddf8c5bceca4aa07a8bc86d7d788e02.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/art/background/cloud_2.png"
+dest_files=[ "res://.import/cloud_2.png-4ddf8c5bceca4aa07a8bc86d7d788e02.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=false
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=false
+svg/scale=1.0

+ 0 - 0
2d/platformer/background/scroll_bg_cloud_3.png → 2d/platformer/assets/art/background/cloud_3.png


+ 34 - 0
2d/platformer/assets/art/background/cloud_3.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/cloud_3.png-a1b7dc71aa84bea9cb4f78f585dcc65d.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/art/background/cloud_3.png"
+dest_files=[ "res://.import/cloud_3.png-a1b7dc71aa84bea9cb4f78f585dcc65d.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=false
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=false
+svg/scale=1.0

BIN
2d/platformer/assets/art/background/distant_platforms_1.png


+ 34 - 0
2d/platformer/assets/art/background/distant_platforms_1.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/distant_platforms_1.png-7286fe6c8587b96abbbe0bc4a8cbc510.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/art/background/distant_platforms_1.png"
+dest_files=[ "res://.import/distant_platforms_1.png-7286fe6c8587b96abbbe0bc4a8cbc510.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=false
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=false
+svg/scale=1.0

BIN
2d/platformer/assets/art/background/distant_platforms_2.png


+ 34 - 0
2d/platformer/assets/art/background/distant_platforms_2.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/distant_platforms_2.png-ba010b30987da6d74062ce964ab450ef.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/art/background/distant_platforms_2.png"
+dest_files=[ "res://.import/distant_platforms_2.png-ba010b30987da6d74062ce964ab450ef.stex" ]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_mode=0
+compress/bptc_ldr=0
+compress/normal_map=0
+flags/repeat=0
+flags/filter=false
+flags/mipmaps=false
+flags/anisotropic=false
+flags/srgb=2
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/HDR_as_SRGB=false
+process/invert_color=false
+stream=false
+size_limit=0
+detect_3d=false
+svg/scale=1.0

+ 0 - 0
2d/platformer/background/scroll_bg_sky.png → 2d/platformer/assets/art/background/sky.png


+ 3 - 3
2d/platformer/player/osb_fire.png.import → 2d/platformer/assets/art/background/sky.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/osb_fire.png-67a49910acd764fd7c67429af0ad5cb8.stex"
+path="res://.import/sky.png-c175b712c46edc17f2b5fc55b9de3c49.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://player/osb_fire.png"
-dest_files=[ "res://.import/osb_fire.png-67a49910acd764fd7c67429af0ad5cb8.stex" ]
+source_file="res://assets/art/background/sky.png"
+dest_files=[ "res://.import/sky.png-c175b712c46edc17f2b5fc55b9de3c49.stex" ]
 
 [params]
 

+ 0 - 0
2d/platformer/coin/coin.png → 2d/platformer/assets/art/coin/coin.png


+ 3 - 3
2d/platformer/coin/coin.png.import → 2d/platformer/assets/art/coin/coin.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/coin.png-c9e5c2f51b2a10beb2d794afbbee004f.stex"
+path="res://.import/coin.png-87689993f83db6056500d4fa153313d8.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://coin/coin.png"
-dest_files=[ "res://.import/coin.png-c9e5c2f51b2a10beb2d794afbbee004f.stex" ]
+source_file="res://assets/art/coin/coin.png"
+dest_files=[ "res://.import/coin.png-87689993f83db6056500d4fa153313d8.stex" ]
 
 [params]
 

+ 0 - 0
2d/platformer/enemy/enemy.png → 2d/platformer/assets/art/enemy/enemy.png


+ 3 - 3
2d/platformer/enemy/enemy.png.import → 2d/platformer/assets/art/enemy/enemy.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/enemy.png-1891d9038eeed672a2459bc4e7db5910.stex"
+path="res://.import/enemy.png-c2f48b2558d3b68a547452306041a310.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://enemy/enemy.png"
-dest_files=[ "res://.import/enemy.png-1891d9038eeed672a2459bc4e7db5910.stex" ]
+source_file="res://assets/art/enemy/enemy.png"
+dest_files=[ "res://.import/enemy.png-c2f48b2558d3b68a547452306041a310.stex" ]
 
 [params]
 

BIN
2d/platformer/assets/art/platforms/moving_platform.png


+ 3 - 3
2d/platformer/platform/moving_platform.png.import → 2d/platformer/assets/art/platforms/moving_platform.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/moving_platform.png-7e92061cd93e8b0235df711d3782cd8c.stex"
+path="res://.import/moving_platform.png-479aa8f802d1a4964b138893ada8d372.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://platform/moving_platform.png"
-dest_files=[ "res://.import/moving_platform.png-7e92061cd93e8b0235df711d3782cd8c.stex" ]
+source_file="res://assets/art/platforms/moving_platform.png"
+dest_files=[ "res://.import/moving_platform.png-479aa8f802d1a4964b138893ada8d372.stex" ]
 
 [params]
 

+ 0 - 0
2d/platformer/platform/one_way_platform.png → 2d/platformer/assets/art/platforms/one_way_platform.png


+ 3 - 3
2d/platformer/platform/one_way_platform.png.import → 2d/platformer/assets/art/platforms/one_way_platform.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/one_way_platform.png-2865772e209813c1636a14aee8d019a3.stex"
+path="res://.import/one_way_platform.png-aaf0179c7171228f27cb489e99e339bd.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://platform/one_way_platform.png"
-dest_files=[ "res://.import/one_way_platform.png-2865772e209813c1636a14aee8d019a3.stex" ]
+source_file="res://assets/art/platforms/one_way_platform.png"
+dest_files=[ "res://.import/one_way_platform.png-aaf0179c7171228f27cb489e99e339bd.stex" ]
 
 [params]
 

+ 0 - 0
2d/platformer/player/bullet.png → 2d/platformer/assets/art/player/bullet/bullet.png


+ 3 - 3
2d/platformer/player/bullet.png.import → 2d/platformer/assets/art/player/bullet/bullet.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/bullet.png-5615cb9904aab8db60fe6f48e996475f.stex"
+path="res://.import/bullet.png-a148438922f3743d5615622ef8134c9f.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://player/bullet.png"
-dest_files=[ "res://.import/bullet.png-5615cb9904aab8db60fe6f48e996475f.stex" ]
+source_file="res://assets/art/player/bullet/bullet.png"
+dest_files=[ "res://.import/bullet.png-a148438922f3743d5615622ef8134c9f.stex" ]
 
 [params]
 

+ 0 - 0
2d/platformer/player/robot_demo.png → 2d/platformer/assets/art/player/robot_demo.png


+ 3 - 3
2d/platformer/player/robot_demo.png.import → 2d/platformer/assets/art/player/robot_demo.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/robot_demo.png-7165a8ae8f36b01883df6b585a93f592.stex"
+path="res://.import/robot_demo.png-cd7cbcf6d0c47d4a233ea7ce93b142c2.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://player/robot_demo.png"
-dest_files=[ "res://.import/robot_demo.png-7165a8ae8f36b01883df6b585a93f592.stex" ]
+source_file="res://assets/art/player/robot_demo.png"
+dest_files=[ "res://.import/robot_demo.png-cd7cbcf6d0c47d4a233ea7ce93b142c2.stex" ]
 
 [params]
 

BIN
2d/platformer/assets/art/tileset/tiles_demo.png


+ 3 - 3
2d/platformer/tiles_demo.png.import → 2d/platformer/assets/art/tileset/tiles_demo.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/tiles_demo.png-7ca5c7c5c02ab8abe0d585a6a8f086bd.stex"
+path="res://.import/tiles_demo.png-f720a7de2b60b01f690cfa3cb881996b.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://tiles_demo.png"
-dest_files=[ "res://.import/tiles_demo.png-7ca5c7c5c02ab8abe0d585a6a8f086bd.stex" ]
+source_file="res://assets/art/tileset/tiles_demo.png"
+dest_files=[ "res://.import/tiles_demo.png-f720a7de2b60b01f690cfa3cb881996b.stex" ]
 
 [params]
 

+ 263 - 0
2d/platformer/assets/art/tileset/tileset.tres

@@ -0,0 +1,263 @@
+[gd_resource type="TileSet" load_steps=14 format=2]
+
+[ext_resource path="res://assets/art/tileset/tiles_demo.png" type="Texture" id=1]
+
+[sub_resource type="ConvexPolygonShape2D" id=1]
+points = PoolVector2Array( 0, 12, 64, 12, 64, 64, 0, 64 )
+
+[sub_resource type="ConvexPolygonShape2D" id=2]
+points = PoolVector2Array( 0, 12, 56, 12, 56, 64, 0, 64 )
+
+[sub_resource type="ConvexPolygonShape2D" id=3]
+points = PoolVector2Array( 0, 0, 64, 0, 64, 64, 0, 64 )
+
+[sub_resource type="ConvexPolygonShape2D" id=4]
+points = PoolVector2Array( 0, 12, 64, 12, 64, 64, 0, 64 )
+
+[sub_resource type="ConvexPolygonShape2D" id=5]
+points = PoolVector2Array( 64, 76, 64, 128, 0, 128, 0, 12 )
+
+[sub_resource type="ConvexPolygonShape2D" id=6]
+points = PoolVector2Array( 0, 0, 56, 0, 56, 64, 0, 64 )
+
+[sub_resource type="ConvexPolygonShape2D" id=7]
+points = PoolVector2Array( 56, 12, 64, 12, 64, 64, 0, 64, 0, 0, 56, 0 )
+
+[sub_resource type="ConvexPolygonShape2D" id=8]
+points = PoolVector2Array( 0, 12, 64, 12, 64, 64, 0, 64 )
+
+[sub_resource type="ConvexPolygonShape2D" id=9]
+points = PoolVector2Array( 0, 12, 56, 12, 56, 64, 0, 64 )
+
+[sub_resource type="ConvexPolygonShape2D" id=10]
+points = PoolVector2Array( 0, 0, 64, 0, 64, 64, 0, 64 )
+
+[sub_resource type="ConvexPolygonShape2D" id=11]
+points = PoolVector2Array( 0, 0, 64, 0, 64, 48, 0, 48 )
+
+[sub_resource type="ConvexPolygonShape2D" id=12]
+points = PoolVector2Array( 0, 0, 56, 0, 56, 48, 0, 48 )
+
+[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, 64, 64 )
+0/tile_mode = 0
+0/occluder_offset = Vector2( 0, 0 )
+0/navigation_offset = Vector2( 0, 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( 64, 0, 64, 64 )
+1/tile_mode = 0
+1/occluder_offset = Vector2( 0, 0 )
+1/navigation_offset = Vector2( 0, 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( 128, 128, 64, 128 )
+2/tile_mode = 0
+2/occluder_offset = Vector2( 0, 0 )
+2/navigation_offset = Vector2( 0, 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( 64, 64, 64, 64 )
+3/tile_mode = 0
+3/occluder_offset = Vector2( 0, 0 )
+3/navigation_offset = Vector2( 0, 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( 64, 128, 64, 64 )
+4/tile_mode = 0
+4/occluder_offset = Vector2( 0, 0 )
+4/navigation_offset = Vector2( 0, 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( 128, 0, 64, 64 )
+5/tile_mode = 0
+5/occluder_offset = Vector2( 0, 0 )
+5/navigation_offset = Vector2( 0, 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( 192, 0, 64, 64 )
+6/tile_mode = 0
+6/occluder_offset = Vector2( 0, 0 )
+6/navigation_offset = Vector2( 0, 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, 64, 64, 64 )
+7/tile_mode = 0
+7/occluder_offset = Vector2( 0, 0 )
+7/navigation_offset = Vector2( 0, 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( 384, 64, 64, 64 )
+8/tile_mode = 0
+8/occluder_offset = Vector2( 0, 0 )
+8/navigation_offset = Vector2( 0, 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( 448, 64, 64, 64 )
+9/tile_mode = 0
+9/occluder_offset = Vector2( 0, 0 )
+9/navigation_offset = Vector2( 0, 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( 320, 64, 64, 64 )
+10/tile_mode = 0
+10/occluder_offset = Vector2( 0, 0 )
+10/navigation_offset = Vector2( 0, 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( 256, 128, 64, 64 )
+11/tile_mode = 0
+11/occluder_offset = Vector2( 0, 0 )
+11/navigation_offset = Vector2( 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( 256, 64, 64, 64 )
+12/tile_mode = 0
+12/occluder_offset = Vector2( 0, 0 )
+12/navigation_offset = Vector2( 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( 256, 192, 64, 64 )
+13/tile_mode = 0
+13/occluder_offset = Vector2( 0, 0 )
+13/navigation_offset = Vector2( 0, 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( 256, 0, 64, 64 )
+14/tile_mode = 0
+14/occluder_offset = Vector2( 0, 0 )
+14/navigation_offset = Vector2( 0, 0 )
+14/shapes = [  ]
+14/z_index = 0

+ 0 - 0
2d/platformer/player/osb_fire.png → 2d/platformer/assets/art/ui/touch_button_fire.png


+ 3 - 3
2d/platformer/background/scroll_bg_cloud_1.png.import → 2d/platformer/assets/art/ui/touch_button_fire.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/scroll_bg_cloud_1.png-19f55c25a7e1985c92542faa0106888e.stex"
+path="res://.import/touch_button_fire.png-8b72c42a8cb252207ce8948d4b623690.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://background/scroll_bg_cloud_1.png"
-dest_files=[ "res://.import/scroll_bg_cloud_1.png-19f55c25a7e1985c92542faa0106888e.stex" ]
+source_file="res://assets/art/ui/touch_button_fire.png"
+dest_files=[ "res://.import/touch_button_fire.png-8b72c42a8cb252207ce8948d4b623690.stex" ]
 
 [params]
 

+ 0 - 0
2d/platformer/player/osb_jump.png → 2d/platformer/assets/art/ui/touch_button_jump.png


+ 3 - 3
2d/platformer/background/scroll_bg_cloud_2.png.import → 2d/platformer/assets/art/ui/touch_button_jump.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/scroll_bg_cloud_2.png-869806dcc546591f3d754e3b845c61c9.stex"
+path="res://.import/touch_button_jump.png-f72afeb370538aa951853dbc52052250.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://background/scroll_bg_cloud_2.png"
-dest_files=[ "res://.import/scroll_bg_cloud_2.png-869806dcc546591f3d754e3b845c61c9.stex" ]
+source_file="res://assets/art/ui/touch_button_jump.png"
+dest_files=[ "res://.import/touch_button_jump.png-f72afeb370538aa951853dbc52052250.stex" ]
 
 [params]
 

+ 0 - 0
2d/platformer/player/osb_left.png → 2d/platformer/assets/art/ui/touch_button_left.png


+ 3 - 3
2d/platformer/background/scroll_bg_cloud_3.png.import → 2d/platformer/assets/art/ui/touch_button_left.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/scroll_bg_cloud_3.png-831c6ed9fa8b4070081428a936bcc2f7.stex"
+path="res://.import/touch_button_left.png-e48f16cfdaae98fdc92a21f20c157c53.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://background/scroll_bg_cloud_3.png"
-dest_files=[ "res://.import/scroll_bg_cloud_3.png-831c6ed9fa8b4070081428a936bcc2f7.stex" ]
+source_file="res://assets/art/ui/touch_button_left.png"
+dest_files=[ "res://.import/touch_button_left.png-e48f16cfdaae98fdc92a21f20c157c53.stex" ]
 
 [params]
 

+ 0 - 0
2d/platformer/player/osb_right.png → 2d/platformer/assets/art/ui/touch_button_right.png


+ 3 - 3
2d/platformer/background/scroll_bg_sky.png.import → 2d/platformer/assets/art/ui/touch_button_right.png.import

@@ -2,15 +2,15 @@
 
 importer="texture"
 type="StreamTexture"
-path="res://.import/scroll_bg_sky.png-377ea542199b2e23d7a822ed940ea99e.stex"
+path="res://.import/touch_button_right.png-74bf87a3a0fa663fbb3574844de31372.stex"
 metadata={
 "vram_texture": false
 }
 
 [deps]
 
-source_file="res://background/scroll_bg_sky.png"
-dest_files=[ "res://.import/scroll_bg_sky.png-377ea542199b2e23d7a822ed940ea99e.stex" ]
+source_file="res://assets/art/ui/touch_button_right.png"
+dest_files=[ "res://.import/touch_button_right.png-74bf87a3a0fa663fbb3574844de31372.stex" ]
 
 [params]
 

+ 0 - 0
2d/platformer/audio/music.ogg → 2d/platformer/assets/audio/music/music.ogg


+ 15 - 0
2d/platformer/assets/audio/music/music.ogg.import

@@ -0,0 +1,15 @@
+[remap]
+
+importer="ogg_vorbis"
+type="AudioStreamOGGVorbis"
+path="res://.import/music.ogg-e27216112531ea490cdad574860a53a5.oggstr"
+
+[deps]
+
+source_file="res://assets/audio/music/music.ogg"
+dest_files=[ "res://.import/music.ogg-e27216112531ea490cdad574860a53a5.oggstr" ]
+
+[params]
+
+loop=true
+loop_offset=0

+ 0 - 0
2d/platformer/audio/sound_coin.wav → 2d/platformer/assets/audio/sfx/coin_pickup.wav


+ 21 - 0
2d/platformer/assets/audio/sfx/coin_pickup.wav.import

@@ -0,0 +1,21 @@
+[remap]
+
+importer="wav"
+type="AudioStreamSample"
+path="res://.import/coin_pickup.wav-69d455f3063e30fd994846647c281aea.sample"
+
+[deps]
+
+source_file="res://assets/audio/sfx/coin_pickup.wav"
+dest_files=[ "res://.import/coin_pickup.wav-69d455f3063e30fd994846647c281aea.sample" ]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=true
+edit/normalize=true
+edit/loop=false
+compress/mode=0

+ 0 - 0
2d/platformer/audio/sound_explode.wav → 2d/platformer/assets/audio/sfx/explode.wav


+ 3 - 3
2d/platformer/audio/sound_shoot.wav.import → 2d/platformer/assets/audio/sfx/explode.wav.import

@@ -2,12 +2,12 @@
 
 importer="wav"
 type="AudioStreamSample"
-path="res://.import/sound_shoot.wav-a37772efd1dbcd76c4fe35742f502bb7.sample"
+path="res://.import/explode.wav-302a3de6d016432bf47477d337a4d553.sample"
 
 [deps]
 
-source_file="res://audio/sound_shoot.wav"
-dest_files=[ "res://.import/sound_shoot.wav-a37772efd1dbcd76c4fe35742f502bb7.sample" ]
+source_file="res://assets/audio/sfx/explode.wav"
+dest_files=[ "res://.import/explode.wav-302a3de6d016432bf47477d337a4d553.sample" ]
 
 [params]
 

+ 0 - 0
2d/platformer/audio/sound_hit.wav → 2d/platformer/assets/audio/sfx/hit.wav


+ 3 - 3
2d/platformer/audio/sound_hit.wav.import → 2d/platformer/assets/audio/sfx/hit.wav.import

@@ -2,12 +2,12 @@
 
 importer="wav"
 type="AudioStreamSample"
-path="res://.import/sound_hit.wav-6c98c4eeb2c6ac3fc45dc4a7ebd8602f.sample"
+path="res://.import/hit.wav-27e178036f6cee6545e9f025a3865a36.sample"
 
 [deps]
 
-source_file="res://audio/sound_hit.wav"
-dest_files=[ "res://.import/sound_hit.wav-6c98c4eeb2c6ac3fc45dc4a7ebd8602f.sample" ]
+source_file="res://assets/audio/sfx/hit.wav"
+dest_files=[ "res://.import/hit.wav-27e178036f6cee6545e9f025a3865a36.sample" ]
 
 [params]
 

+ 0 - 0
2d/platformer/audio/sound_jump.wav → 2d/platformer/assets/audio/sfx/jump.wav


+ 3 - 3
2d/platformer/audio/sound_coin.wav.import → 2d/platformer/assets/audio/sfx/jump.wav.import

@@ -2,12 +2,12 @@
 
 importer="wav"
 type="AudioStreamSample"
-path="res://.import/sound_coin.wav-e18cceeba8b7dc02bbb940b85bcad99a.sample"
+path="res://.import/jump.wav-127418ac4fc0b61a7fed0684053202c7.sample"
 
 [deps]
 
-source_file="res://audio/sound_coin.wav"
-dest_files=[ "res://.import/sound_coin.wav-e18cceeba8b7dc02bbb940b85bcad99a.sample" ]
+source_file="res://assets/audio/sfx/jump.wav"
+dest_files=[ "res://.import/jump.wav-127418ac4fc0b61a7fed0684053202c7.sample" ]
 
 [params]
 

+ 0 - 0
2d/platformer/audio/sound_shoot.wav → 2d/platformer/assets/audio/sfx/shoot.wav


+ 3 - 3
2d/platformer/audio/sound_jump.wav.import → 2d/platformer/assets/audio/sfx/shoot.wav.import

@@ -2,12 +2,12 @@
 
 importer="wav"
 type="AudioStreamSample"
-path="res://.import/sound_jump.wav-7e05b84e4426c7461dd15838765e210b.sample"
+path="res://.import/shoot.wav-f3ce9b4ae60220ecd3cf78df7278a10f.sample"
 
 [deps]
 
-source_file="res://audio/sound_jump.wav"
-dest_files=[ "res://.import/sound_jump.wav-7e05b84e4426c7461dd15838765e210b.sample" ]
+source_file="res://assets/audio/sfx/shoot.wav"
+dest_files=[ "res://.import/shoot.wav-f3ce9b4ae60220ecd3cf78df7278a10f.sample" ]
 
 [params]
 

BIN
2d/platformer/assets/theme/fonts/kenney_mini_square.ttf


+ 82 - 0
2d/platformer/assets/theme/user_interface.tres

@@ -0,0 +1,82 @@
+[gd_resource type="Theme" load_steps=8 format=2]
+
+[ext_resource path="res://assets/theme/fonts/kenney_mini_square.ttf" type="DynamicFontData" id=1]
+
+[sub_resource type="StyleBoxFlat" id=1]
+content_margin_left = 6.0
+content_margin_right = 6.0
+content_margin_top = 4.0
+content_margin_bottom = 4.0
+bg_color = Color( 0.18, 0.207, 0.279, 1 )
+border_width_left = 1
+border_width_top = 1
+border_width_right = 1
+border_width_bottom = 1
+border_color = Color( 0.14, 0.161, 0.217, 1 )
+
+[sub_resource type="StyleBoxFlat" id=2]
+content_margin_left = 6.0
+content_margin_right = 6.0
+content_margin_top = 4.0
+content_margin_bottom = 4.0
+bg_color = Color( 0.15, 0.1725, 0.2325, 1 )
+border_width_left = 1
+border_width_top = 1
+border_width_right = 1
+border_width_bottom = 1
+border_color = Color( 0.41, 0.61, 0.91, 1 )
+
+[sub_resource type="StyleBoxFlat" id=3]
+content_margin_left = 6.0
+content_margin_right = 6.0
+content_margin_top = 4.0
+content_margin_bottom = 4.0
+bg_color = Color( 0.15, 0.1725, 0.2325, 1 )
+border_width_left = 1
+border_width_top = 1
+border_width_right = 1
+border_width_bottom = 1
+border_color = Color( 0.4, 0.4225, 0.4825, 1 )
+
+[sub_resource type="StyleBoxFlat" id=4]
+content_margin_left = 6.0
+content_margin_right = 6.0
+content_margin_top = 4.0
+content_margin_bottom = 4.0
+bg_color = Color( 0.15, 0.1725, 0.2325, 1 )
+border_width_left = 1
+border_width_top = 1
+border_width_right = 1
+border_width_bottom = 1
+border_color = Color( 0.125, 0.14375, 0.19375, 1 )
+
+[sub_resource type="StyleBoxFlat" id=5]
+content_margin_left = 6.0
+content_margin_right = 6.0
+content_margin_top = 4.0
+content_margin_bottom = 4.0
+bg_color = Color( 0.15, 0.1725, 0.2325, 1 )
+border_width_left = 1
+border_width_top = 1
+border_width_right = 1
+border_width_bottom = 1
+border_color = Color( 0.41, 0.61, 0.91, 1 )
+
+[sub_resource type="DynamicFont" id=6]
+font_data = ExtResource( 1 )
+
+[resource]
+default_font = SubResource( 6 )
+Button/colors/font_color = Color( 0.8, 0.8075, 0.8275, 1 )
+Button/colors/font_color_disabled = Color( 1, 1, 1, 0.3 )
+Button/colors/font_color_hover = Color( 0.88, 0.8845, 0.8965, 1 )
+Button/colors/font_color_pressed = Color( 0.41, 0.61, 0.91, 1 )
+Button/colors/icon_color_hover = Color( 1.15, 1.15, 1.15, 1 )
+Button/colors/icon_color_pressed = Color( 0.4715, 0.7015, 1.0465, 1 )
+Button/constants/hseparation = 2
+Button/fonts/font = null
+Button/styles/disabled = SubResource( 1 )
+Button/styles/focus = SubResource( 2 )
+Button/styles/hover = SubResource( 3 )
+Button/styles/normal = SubResource( 4 )
+Button/styles/pressed = SubResource( 5 )

+ 0 - 15
2d/platformer/audio/music.ogg.import

@@ -1,15 +0,0 @@
-[remap]
-
-importer="ogg_vorbis"
-type="AudioStreamOGGVorbis"
-path="res://.import/music.ogg-552a37c4bfe46d894cb8004cf1c345ad.oggstr"
-
-[deps]
-
-source_file="res://audio/music.ogg"
-dest_files=[ "res://.import/music.ogg-552a37c4bfe46d894cb8004cf1c345ad.oggstr" ]
-
-[params]
-
-loop=true
-loop_offset=0

+ 0 - 21
2d/platformer/audio/sound_explode.wav.import

@@ -1,21 +0,0 @@
-[remap]
-
-importer="wav"
-type="AudioStreamSample"
-path="res://.import/sound_explode.wav-536668d880bfb277b9e5253774598e9e.sample"
-
-[deps]
-
-source_file="res://audio/sound_explode.wav"
-dest_files=[ "res://.import/sound_explode.wav-536668d880bfb277b9e5253774598e9e.sample" ]
-
-[params]
-
-force/8_bit=false
-force/mono=false
-force/max_rate=false
-force/max_rate_hz=44100
-edit/trim=true
-edit/normalize=true
-edit/loop=false
-compress/mode=0

BIN
2d/platformer/background/scroll_bg_fg_1.png


+ 0 - 34
2d/platformer/background/scroll_bg_fg_1.png.import

@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/scroll_bg_fg_1.png-20c90ebded5095c6863cdf6b1b82882d.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://background/scroll_bg_fg_1.png"
-dest_files=[ "res://.import/scroll_bg_fg_1.png-20c90ebded5095c6863cdf6b1b82882d.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=1
-flags/filter=false
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=false
-svg/scale=1.0

BIN
2d/platformer/background/scroll_bg_fg_2.png


+ 0 - 34
2d/platformer/background/scroll_bg_fg_2.png.import

@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/scroll_bg_fg_2.png-2b54decd69e8aff2caa33640a336d1e9.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://background/scroll_bg_fg_2.png"
-dest_files=[ "res://.import/scroll_bg_fg_2.png-2b54decd69e8aff2caa33640a336d1e9.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=1
-flags/filter=false
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=false
-svg/scale=1.0

+ 0 - 140
2d/platformer/coin/Coin.tscn

@@ -1,140 +0,0 @@
-[gd_scene load_steps=11 format=2]
-
-[ext_resource path="res://coin/coin.gd" type="Script" id=1]
-[ext_resource path="res://coin/coin.png" type="Texture" id=2]
-[ext_resource path="res://audio/sound_coin.wav" type="AudioStream" id=3]
-[ext_resource path="res://player/bullet.png" type="Texture" id=4]
-
-[sub_resource type="Animation" id=1]
-resource_name = "spin"
-length = 1.5
-loop = true
-step = 0.25
-tracks/0/type = "value"
-tracks/0/path = NodePath("Sprite:frame")
-tracks/0/interp = 1
-tracks/0/loop_wrap = true
-tracks/0/imported = false
-tracks/0/enabled = true
-tracks/0/keys = {
-"times": PoolRealArray( 0, 0.25, 0.5, 0.75, 1, 1.25, 1.5 ),
-"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1 ),
-"update": 1,
-"values": [ 0, 1, 2, 3, 2, 1, 0 ]
-}
-
-[sub_resource type="Animation" id=2]
-length = 8.0
-step = 0.0
-tracks/0/type = "value"
-tracks/0/path = NodePath("Sprite:frame")
-tracks/0/interp = 1
-tracks/0/loop_wrap = true
-tracks/0/imported = false
-tracks/0/enabled = true
-tracks/0/keys = {
-"times": PoolRealArray( 0 ),
-"transitions": PoolRealArray( 1 ),
-"update": 0,
-"values": [ 0 ]
-}
-tracks/1/type = "method"
-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": PoolRealArray( 2.7 ),
-"transitions": PoolRealArray( 1 ),
-"values": [ {
-"args": [  ],
-"method": "queue_free"
-} ]
-}
-tracks/2/type = "value"
-tracks/2/path = NodePath("Particles:emitting")
-tracks/2/interp = 1
-tracks/2/loop_wrap = true
-tracks/2/imported = false
-tracks/2/enabled = true
-tracks/2/keys = {
-"times": PoolRealArray( 0, 0.98 ),
-"transitions": PoolRealArray( 1, 1 ),
-"update": 1,
-"values": [ true, false ]
-}
-tracks/3/type = "value"
-tracks/3/path = NodePath("Sprite:self_modulate")
-tracks/3/interp = 1
-tracks/3/loop_wrap = true
-tracks/3/imported = false
-tracks/3/enabled = true
-tracks/3/keys = {
-"times": PoolRealArray( 0, 0.33 ),
-"transitions": PoolRealArray( 1, 1 ),
-"update": 0,
-"values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
-}
-tracks/4/type = "value"
-tracks/4/path = NodePath("Sound:playing")
-tracks/4/interp = 1
-tracks/4/loop_wrap = true
-tracks/4/imported = false
-tracks/4/enabled = true
-tracks/4/keys = {
-"times": PoolRealArray( 0.01 ),
-"transitions": PoolRealArray( 1 ),
-"update": 1,
-"values": [ true ]
-}
-
-[sub_resource type="CircleShape2D" id=3]
-
-[sub_resource type="CanvasItemMaterial" id=4]
-blend_mode = 1
-
-[sub_resource type="GradientTexture" id=5]
-
-[sub_resource type="ParticlesMaterial" id=6]
-emission_shape = 1
-emission_sphere_radius = 10.0
-flag_disable_z = true
-gravity = Vector3( 0, 90, 0 )
-initial_velocity = 121.98
-angular_velocity = -2.49891e+38
-orbit_velocity = 0.0
-orbit_velocity_random = 0.0
-scale = 0.2
-color_ramp = SubResource( 5 )
-
-[node name="Coin" type="Area2D"]
-script = ExtResource( 1 )
-
-[node name="Sprite" type="Sprite" parent="."]
-texture = ExtResource( 2 )
-hframes = 4
-
-[node name="Anim" type="AnimationPlayer" parent="."]
-autoplay = "spin"
-anims/spin = SubResource( 1 )
-anims/taken = SubResource( 2 )
-
-[node name="Collision" type="CollisionShape2D" parent="."]
-shape = SubResource( 3 )
-
-[node name="Sound" type="AudioStreamPlayer2D" parent="."]
-stream = ExtResource( 3 )
-
-[node name="Particles" type="Particles2D" parent="."]
-material = SubResource( 4 )
-emitting = false
-lifetime = 2.0
-explosiveness = 1.0
-process_material = SubResource( 6 )
-texture = ExtResource( 4 )
-
-[node name="Enabler" type="VisibilityEnabler2D" parent="."]
-pause_particles = false
-
-[connection signal="body_entered" from="." to="." method="_on_coin_body_enter"]

+ 0 - 11
2d/platformer/coin/coin.gd

@@ -1,11 +0,0 @@
-extends Area2D
-
-class_name Coin
-
-
-var taken = false
-
-func _on_coin_body_enter(body):
-	if not taken and body is Player:
-		($Anim as AnimationPlayer).play("taken")
-		taken = true

+ 0 - 50
2d/platformer/enemy/enemy.gd

@@ -1,50 +0,0 @@
-extends KinematicBody2D
-
-class_name Enemy
-
-
-const GRAVITY_VEC = Vector2(0, 900)
-const FLOOR_NORMAL = Vector2(0, -1)
-
-const STATE_WALKING = 0
-const STATE_KILLED = 1
-const WALK_SPEED = 70 
-
-var linear_velocity = Vector2()
-var direction = -1
-var anim = ""
-
-# state machine
-var state = STATE_WALKING
-
-onready var DetectFloorLeft = $DetectFloorLeft
-onready var DetectWallLeft = $DetectWallLeft
-onready var DetectFloorRight = $DetectFloorRight
-onready var DetectWallRight = $DetectWallRight
-onready var sprite = $Sprite
-
-func _physics_process(delta):
-	var new_anim = "idle"
-
-	if state == STATE_WALKING:
-		linear_velocity += GRAVITY_VEC * delta
-		linear_velocity.x = direction * WALK_SPEED
-		linear_velocity = move_and_slide(linear_velocity, FLOOR_NORMAL)
-
-		if not DetectFloorLeft.is_colliding() or DetectWallLeft.is_colliding():
-			direction = 1.0
-
-		if not DetectFloorRight.is_colliding() or DetectWallRight.is_colliding():
-			direction = -1.0
-
-		sprite.scale = Vector2(direction, 1.0)
-		new_anim = "walk"
-	else:
-		new_anim = "explode"
-
-	if anim != new_anim:
-		anim = new_anim
-		($Anim as AnimationPlayer).play(anim)
-
-func hit_by_bullet():
-	state = STATE_KILLED

+ 0 - 16
2d/platformer/platform/MovingPlatform.tscn

@@ -1,16 +0,0 @@
-[gd_scene load_steps=3 format=2]
-
-[ext_resource path="res://platform/moving_platform.gd" type="Script" id=1]
-[ext_resource path="res://platform/moving_platform.png" type="Texture" id=2]
-
-[node name="MovingPlatform" type="Node2D"]
-script = ExtResource( 1 )
-
-[node name="Platform" type="KinematicBody2D" parent="."]
-
-[node name="Sprite" type="Sprite" parent="Platform"]
-texture = ExtResource( 2 )
-
-[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Platform"]
-polygon = PoolVector2Array( -88, -24, 88, -24, 88, 24, -88, 24 )
-

+ 0 - 17
2d/platformer/platform/OneWayPlatform.tscn

@@ -1,17 +0,0 @@
-[gd_scene load_steps=3 format=2]
-
-[ext_resource path="res://platform/one_way_platform.png" type="Texture" id=1]
-
-[sub_resource type="RectangleShape2D" id=1]
-extents = Vector2( 100, 10 )
-
-[node name="OneWayPlatform" type="StaticBody2D"]
-
-[node name="Sprite" type="Sprite" parent="."]
-texture = ExtResource( 1 )
-
-[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
-position = Vector2( 1.46304, -13.1672 )
-shape = SubResource( 1 )
-one_way_collision = true
-

+ 0 - 17
2d/platformer/platform/moving_platform.gd

@@ -1,17 +0,0 @@
-extends Node2D
-
-class_name MovingPlatform
-
-
-# Member variables
-export var motion = Vector2()
-export var cycle = 1.0
-var accum = 0.0
-
-func _physics_process(delta):
-	accum += delta * (1.0 / cycle) * PI * 2.0
-	accum = fmod(accum, PI * 2.0)
-	var d = sin(accum)
-	var xf = Transform2D()
-	xf[2] = motion * d
-	($Platform as KinematicBody2D).transform = xf

BIN
2d/platformer/platform/moving_platform.png


+ 0 - 11
2d/platformer/player/bullet.gd

@@ -1,11 +0,0 @@
-extends RigidBody2D
-
-class_name Bullet
-
-
-func _on_bullet_body_enter(body):
-	if body.has_method("hit_by_bullet"):
-		body.call("hit_by_bullet")
-
-func _on_Timer_timeout():
-	($Anim as AnimationPlayer).play("shutdown")

+ 0 - 34
2d/platformer/player/osb_left.png.import

@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/osb_left.png-95ec3a371455889d592aa8cae0a755bc.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://player/osb_left.png"
-dest_files=[ "res://.import/osb_left.png-95ec3a371455889d592aa8cae0a755bc.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=false
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=false
-svg/scale=1.0

+ 0 - 34
2d/platformer/player/osb_right.png.import

@@ -1,34 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path="res://.import/osb_right.png-db9bb4651315f3d42b87bd17a86cce76.stex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://player/osb_right.png"
-dest_files=[ "res://.import/osb_right.png-db9bb4651315f3d42b87bd17a86cce76.stex" ]
-
-[params]
-
-compress/mode=0
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=0
-flags/filter=false
-flags/mipmaps=false
-flags/anisotropic=false
-flags/srgb=2
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-stream=false
-size_limit=0
-detect_3d=false
-svg/scale=1.0

+ 0 - 97
2d/platformer/player/player.gd

@@ -1,97 +0,0 @@
-extends KinematicBody2D
-
-class_name Player
-
-
-const GRAVITY_VEC = Vector2(0, 900)
-const FLOOR_NORMAL = Vector2(0, -1)
-const SLOPE_SLIDE_STOP = 25.0
-const WALK_SPEED = 250 # pixels/sec
-const JUMP_SPEED = 480
-const SIDING_CHANGE_SPEED = 10
-const BULLET_VELOCITY = 1000
-const SHOOT_TIME_SHOW_WEAPON = 0.2
-
-var linear_vel = Vector2()
-var shoot_time = 99999 # time since last shot
-
-var anim = ""
-
-# cache the sprite here for fast access (we will set scale to flip it often)
-onready var sprite = $Sprite
-# cache bullet for fast access
-var Bullet = preload("res://player/Bullet.tscn")
-
-
-func _physics_process(delta):
-	# Increment counters
-	shoot_time += delta
-
-	### MOVEMENT ###
-
-	# Apply gravity
-	linear_vel += delta * GRAVITY_VEC
-	# Move and slide
-	linear_vel = move_and_slide(linear_vel, FLOOR_NORMAL, SLOPE_SLIDE_STOP)
-	# Detect if we are on floor - only works if called *after* move_and_slide
-	var on_floor = is_on_floor()
-
-	### CONTROL ###
-
-	# Horizontal movement
-	var target_speed = 0
-	if Input.is_action_pressed("move_left"):
-		target_speed -= 1
-	if Input.is_action_pressed("move_right"):
-		target_speed += 1
-
-	target_speed *= WALK_SPEED
-	linear_vel.x = lerp(linear_vel.x, target_speed, 0.1)
-
-	# Jumping
-	if on_floor and Input.is_action_just_pressed("jump"):
-		linear_vel.y = -JUMP_SPEED
-		($SoundJump as AudioStreamPlayer2D).play()
-
-	# Shooting
-	if Input.is_action_just_pressed("shoot"):
-		var bullet = Bullet.instance()
-		bullet.position = ($Sprite/BulletShoot as Position2D).global_position # use node for shoot position
-		bullet.linear_velocity = Vector2(sprite.scale.x * BULLET_VELOCITY, 0)
-		bullet.add_collision_exception_with(self) # don't want player to collide with bullet
-		get_parent().add_child(bullet) # don't want bullet to move with me, so add it as child of parent
-		($SoundShoot as AudioStreamPlayer2D).play()
-		shoot_time = 0
-
-	### ANIMATION ###
-
-	var new_anim = "idle"
-
-	if on_floor:
-		if linear_vel.x < -SIDING_CHANGE_SPEED:
-			sprite.scale.x = -1
-			new_anim = "run"
-
-		if linear_vel.x > SIDING_CHANGE_SPEED:
-			sprite.scale.x = 1
-			new_anim = "run"
-	else:
-		# We want the character to immediately change facing side when the player
-		# tries to change direction, during air control.
-		# This allows for example the player to shoot quickly left then right.
-		if Input.is_action_pressed("move_left") and not Input.is_action_pressed("move_right"):
-			sprite.scale.x = -1
-		if Input.is_action_pressed("move_right") and not Input.is_action_pressed("move_left"):
-			sprite.scale.x = 1
-
-		if linear_vel.y < 0:
-			new_anim = "jumping"
-		else:
-			new_anim = "falling"
-
-	if shoot_time < SHOOT_TIME_SHOW_WEAPON:
-		new_anim += "_weapon"
-
-	if new_anim != anim:
-		anim = new_anim
-		($Anim as AnimationPlayer).play(anim)

+ 45 - 13
2d/platformer/project.godot

@@ -9,43 +9,49 @@
 config_version=4
 
 _global_script_classes=[ {
+"base": "KinematicBody2D",
+"class": "Actor",
+"language": "GDScript",
+"path": "res://src/Actors/Actor.gd"
+}, {
 "base": "RigidBody2D",
 "class": "Bullet",
 "language": "GDScript",
-"path": "res://player/bullet.gd"
+"path": "res://src/Objects/Bullet.gd"
 }, {
 "base": "Area2D",
 "class": "Coin",
 "language": "GDScript",
-"path": "res://coin/coin.gd"
+"path": "res://src/Objects/Coin.gd"
 }, {
-"base": "KinematicBody2D",
+"base": "Actor",
 "class": "Enemy",
 "language": "GDScript",
-"path": "res://enemy/enemy.gd"
+"path": "res://src/Actors/Enemy.gd"
 }, {
-"base": "Node2D",
-"class": "MovingPlatform",
+"base": "Position2D",
+"class": "Gun",
 "language": "GDScript",
-"path": "res://platform/moving_platform.gd"
+"path": "res://src/Actors/Gun.gd"
 }, {
-"base": "KinematicBody2D",
+"base": "Actor",
 "class": "Player",
 "language": "GDScript",
-"path": "res://player/player.gd"
+"path": "res://src/Actors/Player.gd"
 } ]
 _global_script_class_icons={
+"Actor": "",
 "Bullet": "",
 "Coin": "",
 "Enemy": "",
-"MovingPlatform": "",
+"Gun": "",
 "Player": ""
 }
 
 [application]
 
 config/name="Platformer 2D"
-run/main_scene="res://Stage.tscn"
+run/main_scene="res://src/Main/Game.tscn"
 config/icon="res://icon.png"
 target_fps="60"
 
@@ -61,8 +67,11 @@ gdscript/warnings/unsafe_call_argument=true
 
 window/size/width=800
 window/size/height=480
+window/size/test_width=1600
+window/size/test_height=960
+window/dpi/allow_hidpi=true
 window/stretch/mode="2d"
-window/stretch/aspect="keep_height"
+window/stretch/aspect="expand"
 stretch/aspect="keep_height"
 stretch/mode="2d"
 
@@ -80,18 +89,21 @@ jump={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
 , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
  ]
 }
 move_left={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
 , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
  ]
 }
 move_right={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
 , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
  ]
 }
 shoot={
@@ -99,6 +111,7 @@ shoot={
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
 , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
 , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"unicode":0,"echo":false,"script":null)
+, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
  ]
 }
 spawn={
@@ -107,6 +120,25 @@ spawn={
 , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
  ]
 }
+toggle_fullscreen={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777254,"unicode":0,"echo":false,"script":null)
+ ]
+}
+toggle_pause={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
+ ]
+}
+
+[layer_names]
+
+2d_physics/layer_1="player"
+2d_physics/layer_2="enemies"
+2d_physics/layer_3="coins"
+2d_physics/layer_4="platforms"
+2d_physics/layer_5="ground"
 
 [physics]
 
@@ -124,9 +156,9 @@ mipmap_policy=1
 
 quality/intended_usage/framebuffer_allocation=0
 quality/intended_usage/framebuffer_allocation.mobile=1
+quality/2d/use_pixel_snap=true
 quality/filters/anisotropic_filter_level=2
 quality/filters/use_nearest_mipmap_filter=true
-quality/voxel_cone_tracing/high_quality=false
 quality/depth/hdr=false
 
 [texture_import]

+ 18 - 0
2d/platformer/src/Actors/Actor.gd

@@ -0,0 +1,18 @@
+extends KinematicBody2D
+class_name Actor
+
+# 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(400.0, 500.0)
+export var gravity = 3500.0
+
+const FLOOR_NORMAL = Vector2.UP
+
+var _velocity = Vector2.ZERO
+
+# _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

+ 78 - 0
2d/platformer/src/Actors/Enemy.gd

@@ -0,0 +1,78 @@
+extends Actor
+class_name Enemy
+
+
+onready var platform_detector = $PlatformDetector
+onready var floor_detector_left = $FloorDetectorLeft
+onready var floor_detector_right = $FloorDetectorRight
+onready var sprite = $Sprite
+onready var animation_player = $AnimationPlayer
+
+enum State {WALKING, DEAD}
+
+var _state = State.WALKING
+
+# 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):
+	_velocity = calculate_move_velocity(_velocity)
+
+	# We only update the y value of _velocity as we want to handle the horizontal movement ourselves.
+	_velocity.y = move_and_slide(_velocity, FLOOR_NORMAL).y
+
+	# We flip the Sprite depending on which way the enemy is moving.
+	sprite.scale.x = 1 if _velocity.x > 0 else -1
+
+	var animation = get_new_animation()
+	if animation != animation_player.current_animation:
+		animation_player.play(animation)
+
+
+func destroy():
+	_state = State.DEAD
+	_velocity = Vector2.ZERO
+
+
+# This function calculates a new velocity whenever you need it.
+# If the enemy encounters a wall or an edge, the horizontal velocity is flipped.
+func calculate_move_velocity(
+		linear_velocity
+	):
+	var velocity = linear_velocity
+
+	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
+
+	return velocity
+
+
+func get_new_animation():
+	var animation_new = ""
+	if _state == State.WALKING:
+		animation_new = "walk" if abs(_velocity.x) > 0 else "idle"
+	else:
+		animation_new = "destroy"
+	return animation_new

+ 110 - 73
2d/platformer/enemy/Enemy.tscn → 2d/platformer/src/Actors/Enemy.tscn

@@ -1,15 +1,16 @@
-[gd_scene load_steps=13 format=2]
-
-[ext_resource path="res://enemy/enemy.gd" type="Script" id=1]
-[ext_resource path="res://enemy/enemy.png" type="Texture" id=2]
-[ext_resource path="res://player/bullet.png" type="Texture" id=3]
-[ext_resource path="res://audio/sound_hit.wav" type="AudioStream" id=4]
-[ext_resource path="res://audio/sound_explode.wav" type="AudioStream" id=5]
-
-[sub_resource type="Animation" id=1]
-resource_name = "explode"
-length = 5.0
-step = 0.0
+[gd_scene load_steps=15 format=2]
+
+[ext_resource path="res://assets/art/player/bullet/bullet.png" type="Texture" 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="Texture" id=4]
+[ext_resource path="res://src/Actors/Enemy.gd" type="Script" id=5]
+
+[sub_resource type="CanvasItemMaterial" id=1]
+
+[sub_resource type="Animation" id=2]
+resource_name = "destroy"
+length = 1.5
 tracks/0/type = "value"
 tracks/0/path = NodePath("Sprite:frame")
 tracks/0/interp = 1
@@ -20,7 +21,7 @@ tracks/0/keys = {
 "times": PoolRealArray( 0 ),
 "transitions": PoolRealArray( 1 ),
 "update": 0,
-"values": [ 0 ]
+"values": [ 7 ]
 }
 tracks/1/type = "value"
 tracks/1/path = NodePath("Sprite:rotation_degrees")
@@ -29,8 +30,8 @@ tracks/1/loop_wrap = true
 tracks/1/imported = false
 tracks/1/enabled = true
 tracks/1/keys = {
-"times": PoolRealArray( 0, 3.2 ),
-"transitions": PoolRealArray( 0.5, 1 ),
+"times": PoolRealArray( 0, 0.8 ),
+"transitions": PoolRealArray( 0.0796601, 1 ),
 "update": 0,
 "values": [ 0.0, 180.0 ]
 }
@@ -41,10 +42,10 @@ tracks/2/loop_wrap = true
 tracks/2/imported = false
 tracks/2/enabled = true
 tracks/2/keys = {
-"times": PoolRealArray( 2.6, 3.4 ),
-"transitions": PoolRealArray( 1, 1 ),
+"times": PoolRealArray( 0, 0.3, 0.9 ),
+"transitions": PoolRealArray( 1, 1, 1 ),
 "update": 0,
-"values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
+"values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
 }
 tracks/3/type = "value"
 tracks/3/path = NodePath("Explosion:emitting")
@@ -53,7 +54,7 @@ tracks/3/loop_wrap = true
 tracks/3/imported = false
 tracks/3/enabled = true
 tracks/3/keys = {
-"times": PoolRealArray( 0, 2.8 ),
+"times": PoolRealArray( 0, 0.8 ),
 "transitions": PoolRealArray( 1, 1 ),
 "update": 1,
 "values": [ false, true ]
@@ -65,13 +66,13 @@ tracks/4/loop_wrap = true
 tracks/4/imported = false
 tracks/4/enabled = true
 tracks/4/keys = {
-"times": PoolRealArray( 2.8, 3.4 ),
+"times": PoolRealArray( 0.4, 0.8 ),
 "transitions": PoolRealArray( 1, 1 ),
 "update": 0,
 "values": [ 1.0, 4.0 ]
 }
 tracks/5/type = "value"
-tracks/5/path = NodePath("SoundHit:playing")
+tracks/5/path = NodePath("Hit:playing")
 tracks/5/interp = 1
 tracks/5/loop_wrap = true
 tracks/5/imported = false
@@ -83,13 +84,13 @@ tracks/5/keys = {
 "values": [ true ]
 }
 tracks/6/type = "value"
-tracks/6/path = NodePath("SoundExplode:playing")
+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 = {
-"times": PoolRealArray( 2.9 ),
+"times": PoolRealArray( 0.6 ),
 "transitions": PoolRealArray( 1 ),
 "update": 1,
 "values": [ true ]
@@ -101,15 +102,39 @@ tracks/7/loop_wrap = true
 tracks/7/imported = false
 tracks/7/enabled = true
 tracks/7/keys = {
-"times": PoolRealArray( 4.2 ),
+"times": PoolRealArray( 1.5 ),
 "transitions": PoolRealArray( 1 ),
 "values": [ {
 "args": [  ],
 "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 = {
+"times": PoolRealArray( 0 ),
+"transitions": PoolRealArray( 1 ),
+"update": 1,
+"values": [ 0 ]
+}
+tracks/9/type = "value"
+tracks/9/path = NodePath("Sprite:position")
+tracks/9/interp = 1
+tracks/9/loop_wrap = true
+tracks/9/imported = false
+tracks/9/enabled = true
+tracks/9/keys = {
+"times": PoolRealArray( 0, 0.2, 0.4 ),
+"transitions": PoolRealArray( 2.2974, 0.183011, 1 ),
+"update": 0,
+"values": [ Vector2( 0, 0 ), Vector2( 0, -32 ), Vector2( 0, 0 ) ]
+}
 
-[sub_resource type="Animation" id=2]
+[sub_resource type="Animation" id=3]
 length = 6.75
 loop = true
 step = 0.25
@@ -126,8 +151,7 @@ tracks/0/keys = {
 "values": [ 5, 6, 5, 6, 5, 6, 7, 6, 7, 5 ]
 }
 
-[sub_resource type="Animation" id=3]
-resource_name = "walk"
+[sub_resource type="Animation" id=4]
 length = 1.25
 loop = true
 step = 0.25
@@ -144,8 +168,6 @@ tracks/0/keys = {
 "values": [ 0, 1, 2, 3, 4, 0 ]
 }
 
-[sub_resource type="CanvasItemMaterial" id=4]
-
 [sub_resource type="CapsuleShape2D" id=5]
 radius = 13.4556
 height = 14.2002
@@ -153,58 +175,73 @@ height = 14.2002
 [sub_resource type="CanvasItemMaterial" id=6]
 blend_mode = 1
 
-[sub_resource type="ParticlesMaterial" id=7]
+[sub_resource type="Gradient" id=7]
+offsets = PoolRealArray( 0.562963, 1 )
+colors = PoolColorArray( 1, 1, 1, 1, 0, 0, 0, 1 )
+
+[sub_resource type="GradientTexture" id=8]
+gradient = SubResource( 7 )
+width = 256
+
+[sub_resource type="ParticlesMaterial" id=9]
+emission_shape = 1
+emission_sphere_radius = 8.0
 flag_disable_z = true
-gravity = Vector3( 0, 98, 0 )
+spread = 180.0
+gravity = Vector3( 0, 250, 0 )
+initial_velocity = 120.0
+initial_velocity_random = 0.5
 orbit_velocity = 0.0
 orbit_velocity_random = 0.0
+angle = 720.0
+angle_random = 1.0
+scale = 0.4
+scale_random = 1.0
+color_ramp = SubResource( 8 )
+hue_variation = 0.05
+hue_variation_random = 0.46
 
 [node name="Enemy" type="KinematicBody2D"]
-script = ExtResource( 1 )
+collision_layer = 2
+collision_mask = 24
+script = ExtResource( 5 )
+speed = Vector2( 150, 500 )
+gravity = 1800.0
 
-[node name="Enabler" type="VisibilityEnabler2D" parent="."]
-position = Vector2( 16.2569, 11.0034 )
-scale = Vector2( 23.5056, 10.8629 )
-pause_particles = false
+[node name="PlatformDetector" type="RayCast2D" parent="."]
+position = Vector2( 0, 12 )
+enabled = true
+cast_to = Vector2( 0, 8 )
+collision_mask = 8
 
-[node name="Anim" type="AnimationPlayer" parent="."]
-anims/explode = SubResource( 1 )
-anims/idle = SubResource( 2 )
-anims/walk = SubResource( 3 )
+[node name="FloorDetectorLeft" type="RayCast2D" parent="."]
+position = Vector2( -30, -8 )
+enabled = true
+cast_to = Vector2( 0, 70 )
+collision_mask = 24
+
+[node name="FloorDetectorRight" type="RayCast2D" parent="."]
+position = Vector2( 31.16, -8 )
+enabled = true
+cast_to = Vector2( 0, 70 )
+collision_mask = 24
 
 [node name="Sprite" type="Sprite" parent="."]
-material = SubResource( 4 )
-texture = ExtResource( 2 )
+material = SubResource( 1 )
+texture = ExtResource( 4 )
 flip_h = true
 hframes = 8
+frame = 5
+
+[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
+anims/destroy = SubResource( 2 )
+anims/idle = SubResource( 3 )
+anims/walk = SubResource( 4 )
 
 [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
-position = Vector2( -0.00525069, -0.727495 )
 rotation = -1.5708
 shape = SubResource( 5 )
 
-[node name="DetectFloorLeft" type="RayCast2D" parent="."]
-position = Vector2( -33.2868, -9.34363 )
-enabled = true
-cast_to = Vector2( 0, 45 )
-
-[node name="DetectWallLeft" type="RayCast2D" parent="."]
-position = Vector2( -12.1361, -0.739977 )
-rotation = 1.5708
-enabled = true
-cast_to = Vector2( 0, 20 )
-
-[node name="DetectWallRight" type="RayCast2D" parent="."]
-position = Vector2( 3.2788, -0.381488 )
-rotation = -1.5708
-enabled = true
-cast_to = Vector2( 0, 20 )
-
-[node name="DetectFloorRight" type="RayCast2D" parent="."]
-position = Vector2( 29.1987, -9.34363 )
-enabled = true
-cast_to = Vector2( 0, 45 )
-
 [node name="Explosion" type="Particles2D" parent="."]
 self_modulate = Color( 1, 1, 1, 0.12 )
 material = SubResource( 6 )
@@ -213,13 +250,13 @@ amount = 32
 lifetime = 0.5
 one_shot = true
 speed_scale = 1.2
-explosiveness = 0.1
-process_material = SubResource( 7 )
-texture = ExtResource( 3 )
-
-[node name="SoundHit" type="AudioStreamPlayer2D" parent="."]
-stream = ExtResource( 4 )
+explosiveness = 0.76
+draw_order = 215832976
+process_material = SubResource( 9 )
+texture = ExtResource( 1 )
 
-[node name="SoundExplode" type="AudioStreamPlayer2D" parent="."]
-stream = ExtResource( 5 )
+[node name="Hit" type="AudioStreamPlayer2D" parent="."]
+stream = ExtResource( 3 )
 
+[node name="Explode" type="AudioStreamPlayer2D" parent="."]
+stream = ExtResource( 2 )

+ 24 - 0
2d/platformer/src/Actors/Gun.gd

@@ -0,0 +1,24 @@
+extends Position2D
+class_name Gun
+# Represents a weapon that spawns and shoots bullets.
+# The Cooldown timer controls the cooldown duration between shots.
+
+
+onready var sound_shoot = $Shoot
+onready var timer = $Cooldown
+
+const Bullet = preload("res://src/Objects/Bullet.tscn")
+const BULLET_VELOCITY = 1000.0
+
+
+func shoot(direction = 1):
+	if not timer.is_stopped():
+		return false
+	var bullet = Bullet.instance()
+	bullet.global_position = global_position
+	bullet.linear_velocity = Vector2(direction * BULLET_VELOCITY, 0)
+
+	bullet.set_as_toplevel(true)
+	add_child(bullet)
+	sound_shoot.play()
+	return true

+ 96 - 0
2d/platformer/src/Actors/Player.gd

@@ -0,0 +1,96 @@
+extends Actor
+class_name Player
+
+
+const FLOOR_DETECT_DISTANCE = 40.0
+
+onready var platform_detector = $PlatformDetector
+onready var sprite = $Sprite
+onready var animation_player = $AnimationPlayer
+onready var shoot_timer = $ShootAnimation
+onready var gun = $Sprite/Gun
+
+
+# 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):
+	var direction = get_direction()
+
+	var is_jump_interrupted = Input.is_action_just_released("jump") and _velocity.y < 0.0
+	_velocity = calculate_move_velocity(_velocity, direction, speed, is_jump_interrupted)
+
+	var snap_vector = Vector2.DOWN * FLOOR_DETECT_DISTANCE if direction.y == 0.0 else Vector2.ZERO
+	var is_on_platform = platform_detector.is_colliding()
+	_velocity = move_and_slide_with_snap(
+		_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 Sprite accordingly to flip it.
+	# This will make Robi face left or right depending on the direction you move.
+	if direction.x != 0:
+		sprite.scale.x = direction.x
+
+	# 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"):
+		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") - Input.get_action_strength("move_left"),
+		-Input.get_action_strength("jump") if is_on_floor() and Input.is_action_just_pressed("jump") else 0.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
+	):
+	var velocity = linear_velocity
+	velocity.x = speed.x * direction.x
+	if direction.y != 0.0:
+		velocity.y = speed.y * direction.y
+	if is_jump_interrupted:
+		velocity.y = 0.0
+	return velocity
+
+
+func get_new_animation(is_shooting = false):
+	var animation_new = ""
+	if is_on_floor():
+		animation_new = "run" if abs(_velocity.x) > 0.1 else "idle"
+	else:
+		animation_new = "falling" if _velocity.y > 0 else "jumping"
+	if is_shooting:
+		animation_new += "_weapon"
+	return animation_new

+ 48 - 37
2d/platformer/player/Player.tscn → 2d/platformer/src/Actors/Player.tscn

@@ -1,13 +1,14 @@
-[gd_scene load_steps=20 format=2]
+[gd_scene load_steps=21 format=2]
 
-[ext_resource path="res://player/player.gd" type="Script" id=1]
-[ext_resource path="res://player/robot_demo.png" type="Texture" id=2]
-[ext_resource path="res://audio/sound_jump.wav" type="AudioStream" id=3]
-[ext_resource path="res://audio/sound_shoot.wav" type="AudioStream" id=4]
-[ext_resource path="res://player/osb_left.png" type="Texture" id=5]
-[ext_resource path="res://player/osb_right.png" type="Texture" id=6]
-[ext_resource path="res://player/osb_jump.png" type="Texture" id=7]
-[ext_resource path="res://player/osb_fire.png" type="Texture" id=8]
+[ext_resource path="res://src/Actors/Player.gd" type="Script" id=1]
+[ext_resource path="res://assets/art/player/robot_demo.png" type="Texture" 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="Texture" id=5]
+[ext_resource path="res://assets/art/ui/touch_button_right.png" type="Texture" id=6]
+[ext_resource path="res://assets/art/ui/touch_button_jump.png" type="Texture" id=7]
+[ext_resource path="res://assets/art/ui/touch_button_fire.png" type="Texture" id=8]
+[ext_resource path="res://src/Actors/Gun.gd" type="Script" id=9]
 
 [sub_resource type="Animation" id=1]
 resource_name = "crouch"
@@ -182,26 +183,47 @@ tracks/0/keys = {
 "values": [ 10, 11, 12, 13, 14, 5 ]
 }
 
-[sub_resource type="CapsuleShape2D" id=11]
-height = 44.4787
+[sub_resource type="RectangleShape2D" id=11]
+extents = Vector2( 10, 27 )
 
 [node name="Player" type="KinematicBody2D"]
+collision_mask = 30
 script = ExtResource( 1 )
+speed = Vector2( 300, 700 )
+gravity = 1800.0
+
+[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="Sprite" type="Sprite" parent="."]
+position = Vector2( 0, -28 )
 texture = ExtResource( 2 )
 vframes = 2
 hframes = 16
-frame = 22
-
-[node name="Smoke" type="Node2D" parent="Sprite"]
-position = Vector2( 20.7312, 3.21187 )
-rotation = -1.45648
+frame = 16
 
-[node name="BulletShoot" type="Position2D" parent="Sprite"]
+[node name="Gun" type="Position2D" parent="Sprite"]
 position = Vector2( 30.6589, 6.13176 )
+script = ExtResource( 9 )
+
+[node name="Shoot" type="AudioStreamPlayer2D" parent="Sprite/Gun"]
+position = Vector2( -30.6589, -6.13176 )
+stream = ExtResource( 4 )
 
-[node name="Anim" type="AnimationPlayer" parent="."]
+[node name="Cooldown" type="Timer" parent="Sprite/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 )
@@ -214,20 +236,17 @@ anims/run_weapon = SubResource( 9 )
 anims/standing_weapon_ready = SubResource( 10 )
 
 [node name="Camera" type="Camera2D" parent="."]
+position = Vector2( 0, -28 )
 current = true
-limit_left = 0
-limit_top = 0
+process_mode = 0
 
 [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
-position = Vector2( 0.291992, -0.835023 )
+position = Vector2( 0, -27 )
 shape = SubResource( 11 )
 
-[node name="SoundJump" type="AudioStreamPlayer2D" parent="."]
+[node name="Jump" type="AudioStreamPlayer2D" parent="."]
 stream = ExtResource( 3 )
 
-[node name="SoundShoot" type="AudioStreamPlayer2D" parent="."]
-stream = ExtResource( 4 )
-
 [node name="UI" type="CanvasLayer" parent="."]
 layer = 0
 
@@ -247,23 +266,15 @@ passby_press = true
 action = "move_right"
 visibility_mode = 1
 
-[node name="BottomRightAnchor" type="Control" parent="UI"]
-anchor_left = 1.0
-anchor_top = 1.0
-anchor_right = 1.0
-anchor_bottom = 1.0
-margin_left = -40.0
-margin_top = -40.0
-
-[node name="Jump" type="TouchScreenButton" parent="UI/BottomRightAnchor"]
-position = Vector2( -98.151, -83.768 )
+[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/BottomRightAnchor"]
-position = Vector2( -96.302, -180 )
+[node name="Fire" type="TouchScreenButton" parent="UI"]
+position = Vector2( 668.073, 262.788 )
 scale = Vector2( 1.49157, 1.46265 )
 normal = ExtResource( 8 )
 action = "shoot"

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 52 - 0
2d/platformer/src/Level/Level.tscn


+ 20 - 16
2d/platformer/background/ParallaxBg.tscn → 2d/platformer/src/Level/ParallaxBackground.tscn

@@ -1,20 +1,20 @@
 [gd_scene load_steps=7 format=2]
 
-[ext_resource path="res://background/scroll_bg_sky.png" type="Texture" id=1]
-[ext_resource path="res://background/scroll_bg_cloud_1.png" type="Texture" id=2]
-[ext_resource path="res://background/scroll_bg_cloud_2.png" type="Texture" id=3]
-[ext_resource path="res://background/scroll_bg_cloud_3.png" type="Texture" id=4]
-[ext_resource path="res://background/scroll_bg_fg_2.png" type="Texture" id=5]
-[ext_resource path="res://background/scroll_bg_fg_1.png" type="Texture" id=6]
+[ext_resource path="res://assets/art/background/sky.png" type="Texture" id=1]
+[ext_resource path="res://assets/art/background/cloud_1.png" type="Texture" id=2]
+[ext_resource path="res://assets/art/background/cloud_2.png" type="Texture" id=3]
+[ext_resource path="res://assets/art/background/cloud_3.png" type="Texture" id=4]
+[ext_resource path="res://assets/art/background/distant_platforms_2.png" type="Texture" id=5]
+[ext_resource path="res://assets/art/background/distant_platforms_1.png" type="Texture" id=6]
 
-[node name="ParallaxBg" type="ParallaxBackground"]
+[node name="ParallaxBackground" type="ParallaxBackground"]
 scroll_base_scale = Vector2( 0.7, 0 )
 
 [node name="Sky" type="ParallaxLayer" parent="."]
 motion_mirroring = Vector2( 800, 0 )
 
 [node name="Sprite" type="Sprite" parent="Sky"]
-scale = Vector2( 128, 0.94 )
+scale = Vector2( 32, 0.94 )
 texture = ExtResource( 1 )
 centered = false
 
@@ -52,20 +52,24 @@ position = Vector2( 674, 70 )
 texture = ExtResource( 4 )
 centered = false
 
-[node name="Mount2" type="ParallaxLayer" parent="."]
+[node name="MountainsFar" type="ParallaxLayer" parent="."]
 motion_scale = Vector2( 0.2, 1 )
+motion_mirroring = Vector2( 800, 0 )
 
-[node name="Sprite" type="Sprite" parent="Mount2"]
-position = Vector2( 0, 353 )
+[node name="Sprite" type="Sprite" parent="MountainsFar"]
+position = Vector2( 0, 225 )
 texture = ExtResource( 5 )
+centered = false
 region_enabled = true
-region_rect = Rect2( 0, 0, 4096, 256 )
+region_rect = Rect2( 0, 0, 800, 256 )
 
-[node name="Mount1" type="ParallaxLayer" parent="."]
+[node name="MountainsClose" type="ParallaxLayer" parent="."]
 motion_scale = Vector2( 0.4, 1 )
+motion_mirroring = Vector2( 800, 0 )
 
-[node name="Sprite" type="Sprite" parent="Mount1"]
-position = Vector2( 0, 353 )
+[node name="Sprite" type="Sprite" parent="MountainsClose"]
+position = Vector2( 0, 225 )
 texture = ExtResource( 6 )
+centered = false
 region_enabled = true
-region_rect = Rect2( 0, 0, 4096, 256 )
+region_rect = Rect2( 0, 0, 800, 256 )

+ 26 - 0
2d/platformer/src/Main/Game.gd

@@ -0,0 +1,26 @@
+# This class contains controls that should always be accessible, like pausing
+# the game or toggling the window full-screen.
+extends Node
+
+
+# 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 _input(event: InputEvent) -> void:
+	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()

+ 16 - 0
2d/platformer/src/Main/Game.tscn

@@ -0,0 +1,16 @@
+[gd_scene load_steps=4 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]
+
+[node name="Game" type="Node"]
+pause_mode = 2
+script = ExtResource( 2 )
+
+[node name="Level" parent="." instance=ExtResource( 3 )]
+
+[node name="InterfaceLayer" type="CanvasLayer" parent="."]
+layer = 100
+
+[node name="PauseMenu" parent="InterfaceLayer" instance=ExtResource( 1 )]

+ 14 - 0
2d/platformer/src/Objects/Bullet.gd

@@ -0,0 +1,14 @@
+extends RigidBody2D
+class_name Bullet
+
+
+onready var animation_player = $AnimationPlayer
+
+
+func destroy():
+	animation_player.play("destroy")
+
+
+func _on_body_entered(body):
+	if body is Enemy:
+		body.destroy()

+ 16 - 14
2d/platformer/player/Bullet.tscn → 2d/platformer/src/Objects/Bullet.tscn

@@ -1,7 +1,7 @@
 [gd_scene load_steps=9 format=2]
 
-[ext_resource path="res://player/bullet.gd" type="Script" id=1]
-[ext_resource path="res://player/bullet.png" type="Texture" id=2]
+[ext_resource path="res://assets/art/player/bullet/bullet.png" type="Texture" id=1]
+[ext_resource path="res://src/Objects/Bullet.gd" type="Script" id=2]
 
 [sub_resource type="CanvasItemMaterial" id=1]
 
@@ -22,7 +22,8 @@ color = Color( 1, 1, 1, 0.705882 )
 [sub_resource type="CircleShape2D" id=5]
 
 [sub_resource type="Animation" id=6]
-length = 1.5
+resource_name = "destroy"
+length = 0.3
 tracks/0/type = "method"
 tracks/0/path = NodePath(".")
 tracks/0/interp = 1
@@ -30,7 +31,7 @@ tracks/0/loop_wrap = true
 tracks/0/imported = false
 tracks/0/enabled = true
 tracks/0/keys = {
-"times": PoolRealArray( 1.31 ),
+"times": PoolRealArray( 0.3 ),
 "transitions": PoolRealArray( 1 ),
 "values": [ {
 "args": [  ],
@@ -44,7 +45,7 @@ tracks/1/loop_wrap = true
 tracks/1/imported = false
 tracks/1/enabled = true
 tracks/1/keys = {
-"times": PoolRealArray( 0, 1 ),
+"times": PoolRealArray( 0, 0.3 ),
 "transitions": PoolRealArray( 1, 1 ),
 "update": 0,
 "values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
@@ -56,7 +57,7 @@ tracks/2/loop_wrap = true
 tracks/2/imported = false
 tracks/2/enabled = true
 tracks/2/keys = {
-"times": PoolRealArray( 0, 0.5 ),
+"times": PoolRealArray( 0, 0.3 ),
 "transitions": PoolRealArray( 1, 1 ),
 "update": 0,
 "values": [ Color( 1, 1, 1, 1 ), Color( 1, 1, 1, 0 ) ]
@@ -64,10 +65,12 @@ tracks/2/keys = {
 
 [node name="Bullet" type="RigidBody2D"]
 material = SubResource( 1 )
+collision_layer = 0
+collision_mask = 26
 continuous_cd = 2
 contacts_reported = 1
 contact_monitor = true
-script = ExtResource( 1 )
+script = ExtResource( 2 )
 
 [node name="Particles2D" type="Particles2D" parent="."]
 material = SubResource( 2 )
@@ -75,11 +78,11 @@ lifetime = 0.3
 speed_scale = 3.0
 local_coords = false
 process_material = SubResource( 3 )
-texture = ExtResource( 2 )
+texture = ExtResource( 1 )
 
 [node name="Sprite" type="Sprite" parent="."]
 material = SubResource( 4 )
-texture = ExtResource( 2 )
+texture = ExtResource( 1 )
 
 [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
 shape = SubResource( 5 )
@@ -88,8 +91,7 @@ shape = SubResource( 5 )
 one_shot = true
 autostart = true
 
-[node name="Anim" type="AnimationPlayer" parent="."]
-anims/shutdown = SubResource( 6 )
-
-[connection signal="body_entered" from="." to="." method="_on_bullet_body_enter"]
-[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
+[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
+anims/destroy = SubResource( 6 )
+[connection signal="body_entered" from="." to="." method="_on_body_entered"]
+[connection signal="timeout" from="Timer" to="." method="destroy"]

+ 15 - 0
2d/platformer/src/Objects/Coin.gd

@@ -0,0 +1,15 @@
+extends Area2D
+class_name Coin
+# 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")

+ 161 - 0
2d/platformer/src/Objects/Coin.tscn

@@ -0,0 +1,161 @@
+[gd_scene load_steps=7 format=2]
+
+[ext_resource path="res://assets/art/coin/coin.png" type="Texture" 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]
+
+[sub_resource type="Animation" id=1]
+resource_name = "picked"
+length = 1.5
+step = 0.25
+tracks/0/type = "value"
+tracks/0/path = NodePath("Sprite:frame")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/keys = {
+"times": PoolRealArray( 0 ),
+"transitions": PoolRealArray( 1 ),
+"update": 0,
+"values": [ 0 ]
+}
+tracks/1/type = "method"
+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": PoolRealArray( 1 ),
+"transitions": PoolRealArray( 1 ),
+"values": [ {
+"args": [  ],
+"method": "queue_free"
+} ]
+}
+tracks/2/type = "value"
+tracks/2/path = NodePath("Sprite:self_modulate")
+tracks/2/interp = 1
+tracks/2/loop_wrap = true
+tracks/2/imported = false
+tracks/2/enabled = true
+tracks/2/keys = {
+"times": PoolRealArray( 0.25, 1.25 ),
+"transitions": PoolRealArray( 1, 1 ),
+"update": 0,
+"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/keys = {
+"times": PoolRealArray( 0 ),
+"transitions": PoolRealArray( 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": PoolRealArray( 0 ),
+"transitions": PoolRealArray( 1 ),
+"update": 1,
+"values": [ false ]
+}
+tracks/5/type = "value"
+tracks/5/path = NodePath("Sprite:position")
+tracks/5/interp = 1
+tracks/5/loop_wrap = true
+tracks/5/imported = false
+tracks/5/enabled = true
+tracks/5/keys = {
+"times": PoolRealArray( 0, 1.5 ),
+"transitions": PoolRealArray( 1, 1 ),
+"update": 0,
+"values": [ Vector2( 0, 0 ), Vector2( 0, -42 ) ]
+}
+
+[sub_resource type="Animation" id=2]
+length = 1.5
+loop = true
+step = 0.25
+tracks/0/type = "value"
+tracks/0/path = NodePath("Sprite:frame")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/keys = {
+"times": PoolRealArray( 0, 0.25, 0.5, 0.75, 1, 1.25, 1.5 ),
+"transitions": PoolRealArray( 1, 1, 1, 1, 1, 1, 1 ),
+"update": 1,
+"values": [ 0, 1, 2, 3, 2, 1, 0 ]
+}
+tracks/1/type = "value"
+tracks/1/path = NodePath("Sprite:position")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/keys = {
+"times": PoolRealArray( 0 ),
+"transitions": PoolRealArray( 1 ),
+"update": 2,
+"values": [ Vector2( 0, 0 ) ]
+}
+tracks/2/type = "value"
+tracks/2/path = NodePath("Sprite:self_modulate")
+tracks/2/interp = 1
+tracks/2/loop_wrap = true
+tracks/2/imported = false
+tracks/2/enabled = true
+tracks/2/keys = {
+"times": PoolRealArray( 0 ),
+"transitions": PoolRealArray( 1 ),
+"update": 2,
+"values": [ Color( 1, 1, 1, 1 ) ]
+}
+tracks/3/type = "value"
+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": PoolRealArray( 0 ),
+"transitions": PoolRealArray( 1 ),
+"update": 2,
+"values": [ true ]
+}
+
+[sub_resource type="CircleShape2D" id=3]
+
+[node name="Coin" type="Area2D"]
+monitorable = false
+collision_layer = 0
+script = ExtResource( 4 )
+
+[node name="Sprite" type="Sprite" parent="."]
+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 )
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
+shape = SubResource( 3 )
+
+[node name="Pickup" type="AudioStreamPlayer2D" parent="."]
+stream = ExtResource( 3 )
+[connection signal="body_entered" from="." to="." method="_on_body_entered"]

+ 21 - 0
2d/platformer/src/Platforms/Platform.tscn

@@ -0,0 +1,21 @@
+[gd_scene load_steps=3 format=2]
+
+[ext_resource path="res://assets/art/platforms/moving_platform.png" type="Texture" id=2]
+
+[sub_resource type="RectangleShape2D" id=1]
+extents = Vector2( 94, 12 )
+
+[node name="Platform" type="KinematicBody2D"]
+z_index = -1
+collision_layer = 8
+collision_mask = 0
+collision/safe_margin = 0.12
+motion/sync_to_physics = true
+
+[node name="Sprite" type="Sprite" parent="."]
+texture = ExtResource( 2 )
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
+position = Vector2( 0, -8 )
+shape = SubResource( 1 )
+one_way_collision = true

+ 26 - 0
2d/platformer/src/UserInterface/PauseMenu.gd

@@ -0,0 +1,26 @@
+extends Control
+
+
+onready var resume_button = $VBoxContainer/ResumeButton
+
+
+func _ready():
+	visible = false
+
+
+func open():
+	visible = true
+	resume_button.grab_focus()
+
+
+func close():
+	visible = false
+
+
+func _on_ResumeButton_pressed() -> void:
+	get_tree().paused = false
+	visible = false
+
+
+func _on_QuitButton_pressed() -> void:
+	get_tree().quit()

+ 56 - 0
2d/platformer/src/UserInterface/PauseMenu.tscn

@@ -0,0 +1,56 @@
+[gd_scene load_steps=3 format=2]
+
+[ext_resource path="res://assets/theme/user_interface.tres" type="Theme" id=1]
+[ext_resource path="res://src/UserInterface/PauseMenu.gd" type="Script" id=2]
+
+[node name="PauseMenu" type="Control"]
+pause_mode = 2
+anchor_right = 1.0
+anchor_bottom = 1.0
+theme = ExtResource( 1 )
+script = ExtResource( 2 )
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="ColorRect" type="ColorRect" parent="."]
+anchor_right = 1.0
+anchor_bottom = 1.0
+color = Color( 0, 0, 0, 0.211765 )
+
+[node name="VBoxContainer" type="VBoxContainer" parent="."]
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+margin_left = -87.0
+margin_top = -125.0
+margin_right = 87.0
+margin_bottom = 126.0
+alignment = 1
+__meta__ = {
+"_edit_use_anchors_": false
+}
+
+[node name="Label" type="Label" parent="VBoxContainer"]
+margin_top = 71.0
+margin_right = 174.0
+margin_bottom = 91.0
+text = "Game Paused"
+align = 1
+
+[node name="ResumeButton" type="Button" parent="VBoxContainer"]
+margin_top = 95.0
+margin_right = 174.0
+margin_bottom = 135.0
+rect_min_size = Vector2( 0, 40 )
+text = "Resume"
+
+[node name="QuitButton" type="Button" parent="VBoxContainer"]
+margin_top = 139.0
+margin_right = 174.0
+margin_bottom = 179.0
+rect_min_size = Vector2( 0, 40 )
+text = "Quit"
+[connection signal="pressed" from="VBoxContainer/ResumeButton" to="." method="_on_ResumeButton_pressed"]
+[connection signal="pressed" from="VBoxContainer/QuitButton" to="." method="_on_QuitButton_pressed"]

BIN
2d/platformer/tiles_demo.png


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно