├── .gitignore
├── LICENSE
├── concept-plain.svg
├── concept.svg
├── source
├── Actors
│ ├── Enemies
│ │ ├── CutoutCharacter.tscn
│ │ ├── Enemy.gd
│ │ ├── Enemy.tscn
│ │ ├── ToughEnemy.tscn
│ │ ├── particle.svg
│ │ └── particle.svg.import
│ └── Player
│ │ ├── Player.gd
│ │ └── Player.tscn
├── Areas
│ └── AsteroidSurface
│ │ ├── rocks-and-craters.svg
│ │ ├── rocks-and-craters.svg.import
│ │ ├── sand.svg
│ │ ├── sand.svg.import
│ │ ├── tileset.tres
│ │ ├── walkable-path.svg
│ │ └── walkable-path.svg.import
├── Game.gd
├── Game.tscn
├── Levels
│ ├── AStarGrid
│ │ ├── AStarGrid.gd
│ │ └── AStarGrid.tscn
│ ├── EventsPlayer.gd
│ ├── Level.gd
│ ├── Level.tscn
│ ├── Level1.tscn
│ ├── Level2.tscn
│ ├── TowerPlacer
│ │ ├── TowerPlacer.gd
│ │ ├── TowerPlacer.tscn
│ │ ├── grid-cell.svg
│ │ └── grid-cell.svg.import
│ └── Waves
│ │ ├── Wave.gd
│ │ ├── Wave1.tscn
│ │ ├── Wave2.tscn
│ │ ├── Wave3.tscn
│ │ └── Wave4.tscn
├── Objects
│ ├── EnemySpawn
│ │ ├── enemy-spawn.svg
│ │ └── enemy-spawn.svg.import
│ ├── HitBox
│ │ ├── HitBoxArea2D.gd
│ │ └── HitBoxArea2D.tscn
│ ├── HurtBox
│ │ ├── HurtBoxArea2D.gd
│ │ └── HurtBoxArea2D.tscn
│ ├── PlayerBase
│ │ ├── CutoutPlayerBase.tscn
│ │ ├── CutoutSprites.gd
│ │ ├── PlayerBase.gd
│ │ ├── PlayerBase.tscn
│ │ ├── player-base.svg
│ │ └── player-base.svg.import
│ ├── SelectableArea2D
│ │ ├── SelectableArea2D.gd
│ │ └── SelectableArea2D.tscn
│ ├── Towers
│ │ ├── BombTower.tscn
│ │ ├── RifleTower.tscn
│ │ ├── Tower.gd
│ │ ├── Tower.tscn
│ │ └── Upgrades
│ │ │ ├── FireRangeUpgrade.gd
│ │ │ └── Upgrade.gd
│ ├── WaveSpawner2D
│ │ ├── WaveSpawner2D.gd
│ │ └── WaveSpawner2D.tscn
│ └── Weapon2D
│ │ ├── Bullets
│ │ ├── BombBullet.tscn
│ │ ├── Bullet.gd
│ │ └── Bullet.tscn
│ │ ├── RangePreview
│ │ ├── RangePreview.gd
│ │ ├── RangePreview.tscn
│ │ ├── range-preview.svg
│ │ └── range-preview.svg.import
│ │ ├── Weapon2D.gd
│ │ └── Weapon2D.tscn
├── Screens
│ ├── EndScreen.gd
│ └── EndScreen.tscn
├── UI
│ ├── Theme
│ │ ├── Montserrat-ExtraBold.ttf
│ │ ├── background_stylebox.tres
│ │ ├── button_font.tres
│ │ ├── foreground_stylebox.tres
│ │ ├── main_font.tres
│ │ └── main_theme.tres
│ ├── UICooldownBar
│ │ ├── UICooldownBar.gd
│ │ ├── UICooldownBar.tscn
│ │ ├── clock-tic.png
│ │ ├── clock-tic.png.import
│ │ ├── clock.png
│ │ ├── clock.png.import
│ │ ├── cooldown-bar-over.png
│ │ ├── cooldown-bar-over.png.import
│ │ ├── cooldown-bar-progress.png
│ │ ├── cooldown-bar-progress.png.import
│ │ ├── cooldown-bar-under.png
│ │ └── cooldown-bar-under.png.import
│ ├── UIGoldPanel.gd
│ ├── UIGoldPanel.tscn
│ ├── UIHealthBar
│ │ ├── UIHealthBar.tscn
│ │ ├── UITimedHealthBar.gd
│ │ ├── UITimedHealthBar.tscn
│ │ ├── heart.svg
│ │ └── heart.svg.import
│ ├── UIScreenOverlay.gd
│ ├── UIScreenOverlay.tscn
│ ├── UITowerShop
│ │ ├── UITowerPurchaseButton.gd
│ │ ├── UITowerPurchaseButton.tscn
│ │ ├── UITowerShop.gd
│ │ ├── UITowerShop.tscn
│ │ ├── tower-icon-disabled.svg
│ │ ├── tower-icon-disabled.svg.import
│ │ ├── tower-icon-focused.svg
│ │ ├── tower-icon-focused.svg.import
│ │ ├── tower-icon-hover.svg
│ │ ├── tower-icon-hover.svg.import
│ │ ├── tower-icon-normal.svg
│ │ ├── tower-icon-normal.svg.import
│ │ ├── tower-icon-pressed.svg
│ │ └── tower-icon-pressed.svg.import
│ ├── UIUnit
│ │ ├── UIUnit.gd
│ │ └── UIUnit.tscn
│ └── UIUpgradeShop
│ │ ├── UIUpgradeButton.gd
│ │ ├── UIUpgradeButton.tscn
│ │ ├── UIUpgradeShop.gd
│ │ └── UIUpgradeShop.tscn
├── VFX
│ ├── Explosions
│ │ ├── Explosion.tscn
│ │ ├── SmallExplosion.tscn
│ │ ├── explosion_gradient.tres
│ │ ├── puff.png
│ │ ├── puff.png.import
│ │ ├── puff_smooth.png
│ │ ├── puff_smooth.png.import
│ │ ├── scraps_gradient.tres
│ │ ├── sparkle.png
│ │ ├── sparkle.png.import
│ │ ├── white_glowing_circle.png
│ │ └── white_glowing_circle.png.import
│ └── PathPreview.tscn
├── default_env.tres
├── icon.png
├── icon.png.import
├── project.godot
├── sprite-sheet.svg
└── sprite-sheet.svg.import
└── start-project
├── Actors
└── Enemies
│ ├── CutoutCharacter.tscn
│ ├── particle.svg
│ └── particle.svg.import
├── Areas
└── AsteroidSurface
│ ├── rocks-and-craters.svg
│ ├── rocks-and-craters.svg.import
│ ├── sand.svg
│ ├── sand.svg.import
│ ├── tileset.tres
│ ├── walkable-path.svg
│ └── walkable-path.svg.import
├── Objects
├── PlayerBase
│ ├── CutoutPlayerBase.tscn
│ └── CutoutSprites.gd
└── Weapon2D
│ └── RangePreview
│ ├── RangePreview.gd
│ ├── RangePreview.tscn
│ ├── range-preview.svg
│ └── range-preview.svg.import
├── Screens
├── EndScreen.gd
└── EndScreen.tscn
├── UI
├── Theme
│ ├── Montserrat-ExtraBold.ttf
│ ├── background_stylebox.tres
│ ├── button_font.tres
│ ├── foreground_stylebox.tres
│ ├── main_font.tres
│ └── main_theme.tres
├── UICooldownBar
│ ├── UICooldownBar.gd
│ ├── UICooldownBar.tscn
│ ├── clock-tic.png
│ ├── clock-tic.png.import
│ ├── clock.png
│ ├── clock.png.import
│ ├── cooldown-bar-over.png
│ ├── cooldown-bar-over.png.import
│ ├── cooldown-bar-progress.png
│ ├── cooldown-bar-progress.png.import
│ ├── cooldown-bar-under.png
│ └── cooldown-bar-under.png.import
├── UIGoldPanel
│ ├── UIGoldPanel.gd
│ └── UIGoldPanel.tscn
├── UIHealthBar
│ ├── UIHealthBar.tscn
│ ├── UITimedHealthBar.gd
│ ├── UITimedHealthBar.tscn
│ ├── heart.svg
│ └── heart.svg.import
├── UIScreenOverlay
│ ├── UIScreenOverlay.gd
│ └── UIScreenOverlay.tscn
├── UITowerShop
│ ├── tower-icon-disabled.svg
│ ├── tower-icon-disabled.svg.import
│ ├── tower-icon-focused.svg
│ ├── tower-icon-focused.svg.import
│ ├── tower-icon-hover.svg
│ ├── tower-icon-hover.svg.import
│ ├── tower-icon-normal.svg
│ ├── tower-icon-normal.svg.import
│ ├── tower-icon-pressed.svg
│ └── tower-icon-pressed.svg.import
└── UIUnit
│ ├── UIUnit.gd
│ └── UIUnit.tscn
├── VFX
├── Explosion
│ ├── Explosion.tscn
│ ├── SmallExplosion.tscn
│ ├── explosion_gradient.tres
│ ├── puff.png
│ ├── puff.png.import
│ ├── puff_smooth.png
│ ├── puff_smooth.png.import
│ ├── scraps_gradient.tres
│ ├── sparkle.png
│ ├── sparkle.png.import
│ ├── white_glowing_circle.png
│ └── white_glowing_circle.png.import
└── PathPreview.tscn
├── default_env.tres
├── grid-cell.svg
├── grid-cell.svg.import
├── icon.png
├── icon.png.import
├── project.godot
├── sprite-sheet.svg
└── sprite-sheet.svg.import
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Godot-specific ignores
3 | .import/
4 | export.cfg
5 | export_presets.cfg
6 |
7 | # Mono-specific ignores
8 | .mono/
9 | data_*/
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 GDQuest
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/source/Actors/Enemies/Enemy.gd:
--------------------------------------------------------------------------------
1 | class_name Enemy
2 | extends PathFollow2D
3 |
4 | signal died(gold_amount)
5 |
6 | # Movement speed in pixels per second.
7 | export var speed := 64.0
8 | # Amount of gold earned upon killing this enemy.
9 | export var gold_value := 50
10 |
11 | export var max_health := 15
12 | onready var health := max_health setget set_health
13 |
14 | onready var _ui_pivot := $UIPivot
15 | onready var _health_bar := $UIPivot/HealthBar
16 | onready var _anim_player := $AnimationPlayer
17 | onready var _cutout_anim_player := $CutoutCharacter/AnimationPlayer
18 |
19 |
20 | func _ready() -> void:
21 | set_physics_process(false)
22 |
23 | _ui_pivot.set_as_toplevel(true)
24 |
25 | _health_bar.max_value = max_health
26 | _health_bar.value = health
27 |
28 |
29 | func _physics_process(delta: float) -> void:
30 | offset += speed * delta
31 |
32 | if unit_offset >= 1.0:
33 | set_physics_process(false)
34 | disappear()
35 |
36 |
37 | func move() -> void:
38 | set_physics_process(true)
39 | _cutout_anim_player.play("move")
40 |
41 |
42 | func disappear() -> void:
43 | _anim_player.play("disappear")
44 |
45 |
46 | func die() -> void:
47 | emit_signal("died", gold_value)
48 | disappear()
49 |
50 |
51 | func set_health(value: int) -> void:
52 | health = clamp(value, 0, max_health)
53 | _health_bar.value = health
54 |
55 | if health < 1:
56 | die()
57 |
58 |
59 | func _on_HurtBoxArea2D_hit_landed(damage: int) -> void:
60 | set_health(health - damage)
61 |
--------------------------------------------------------------------------------
/source/Actors/Enemies/ToughEnemy.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=2]
2 |
3 | [ext_resource path="res://Actors/Enemies/Enemy.tscn" type="PackedScene" id=1]
4 |
5 | [sub_resource type="CircleShape2D" id=1]
6 | radius = 48.0
7 |
8 | [node name="Enemy" instance=ExtResource( 1 )]
9 | speed = 128.0
10 | gold_value = 75
11 | max_health = 12
12 |
13 | [node name="CutoutCharacter" parent="." index="0"]
14 | scale = Vector2( 1.2, 1.2 )
15 |
16 | [node name="Sprite" parent="CutoutCharacter" index="1"]
17 | region_rect = Rect2( 384, 64, 57, 57 )
18 |
19 | [node name="Sprite2" parent="CutoutCharacter" index="2"]
20 | region_rect = Rect2( 384, 64, 57, 57 )
21 |
22 | [node name="Sprite3" parent="CutoutCharacter" index="3"]
23 | region_rect = Rect2( 384, 64, 57, 57 )
24 |
25 | [node name="Sprite4" parent="CutoutCharacter" index="4"]
26 | region_rect = Rect2( 384, 64, 57, 57 )
27 |
28 | [node name="HurtBoxArea2D" parent="." index="1"]
29 | armor = 2
30 |
31 | [node name="CollisionShape2D" parent="HitBoxArea2D" index="0"]
32 | position = Vector2( 0, -28 )
33 |
34 | [node name="CollisionShape2D" parent="VisibleArea2D" index="0"]
35 | shape = SubResource( 1 )
36 |
37 | [editable path="CutoutCharacter"]
38 |
--------------------------------------------------------------------------------
/source/Actors/Enemies/particle.svg:
--------------------------------------------------------------------------------
1 |
2 |
63 |
--------------------------------------------------------------------------------
/source/Actors/Enemies/particle.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/particle.svg-6a2c10808518a648f8e5ec8f4688e443.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Actors/Enemies/particle.svg"
13 | dest_files=[ "res://.import/particle.svg-6a2c10808518a648f8e5ec8f4688e443.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/Actors/Player/Player.gd:
--------------------------------------------------------------------------------
1 | class_name Player
2 | extends Node
3 |
4 | signal gold_changed(gold_amount)
5 |
6 | export var gold := 100 setget set_gold
7 |
8 |
9 | func set_gold(new_amount: int) -> void:
10 | gold = max(0, new_amount)
11 | emit_signal("gold_changed", gold)
12 |
--------------------------------------------------------------------------------
/source/Actors/Player/Player.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://Actors/Player/Player.gd" type="Script" id=1]
4 |
5 |
6 | [node name="Player" type="Node"]
7 | script = ExtResource( 1 )
8 | gold = 1000
9 |
--------------------------------------------------------------------------------
/source/Areas/AsteroidSurface/rocks-and-craters.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/rocks-and-craters.svg-d039ad5957be00f78334d088af06d900.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Areas/AsteroidSurface/rocks-and-craters.svg"
13 | dest_files=[ "res://.import/rocks-and-craters.svg-d039ad5957be00f78334d088af06d900.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/Areas/AsteroidSurface/sand.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/sand.svg-8176aa2958b49ade8514e76ba5a92581.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Areas/AsteroidSurface/sand.svg"
13 | dest_files=[ "res://.import/sand.svg-8176aa2958b49ade8514e76ba5a92581.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/Areas/AsteroidSurface/tileset.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="TileSet" load_steps=5 format=2]
2 |
3 | [ext_resource path="res://Levels/TowerPlacer/grid-cell.svg" type="Texture" id=1]
4 | [ext_resource path="res://Areas/AsteroidSurface/rocks-and-craters.svg" type="Texture" id=2]
5 | [ext_resource path="res://Areas/AsteroidSurface/walkable-path.svg" type="Texture" id=3]
6 | [ext_resource path="res://Areas/AsteroidSurface/sand.svg" type="Texture" id=4]
7 |
8 | [resource]
9 | 0/name = "grid-cell.svg 0"
10 | 0/texture = ExtResource( 1 )
11 | 0/tex_offset = Vector2( 0, 0 )
12 | 0/modulate = Color( 1, 1, 1, 1 )
13 | 0/region = Rect2( 0, 0, 64, 64 )
14 | 0/tile_mode = 0
15 | 0/occluder_offset = Vector2( 0, 0 )
16 | 0/navigation_offset = Vector2( 0, 0 )
17 | 0/shape_offset = Vector2( 0, 0 )
18 | 0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
19 | 0/shape_one_way = false
20 | 0/shape_one_way_margin = 0.0
21 | 0/shapes = [ ]
22 | 0/z_index = 0
23 | 1/name = "Non Placeable Cells"
24 | 1/texture = ExtResource( 2 )
25 | 1/tex_offset = Vector2( 0, 0 )
26 | 1/modulate = Color( 1, 1, 1, 1 )
27 | 1/region = Rect2( 0, 0, 192, 192 )
28 | 1/tile_mode = 2
29 | 1/autotile/icon_coordinate = Vector2( 1, 1 )
30 | 1/autotile/tile_size = Vector2( 64, 64 )
31 | 1/autotile/spacing = 0
32 | 1/autotile/occluder_map = [ ]
33 | 1/autotile/navpoly_map = [ ]
34 | 1/autotile/priority_map = [ ]
35 | 1/autotile/z_index_map = [ ]
36 | 1/occluder_offset = Vector2( 0, 0 )
37 | 1/navigation_offset = Vector2( 0, 0 )
38 | 1/shape_offset = Vector2( 0, 0 )
39 | 1/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
40 | 1/shape_one_way = false
41 | 1/shape_one_way_margin = 0.0
42 | 1/shapes = [ ]
43 | 1/z_index = 0
44 | 2/name = "Enemy Walking Path"
45 | 2/texture = ExtResource( 3 )
46 | 2/tex_offset = Vector2( 0, 0 )
47 | 2/modulate = Color( 1, 1, 1, 1 )
48 | 2/region = Rect2( 0, 0, 384, 384 )
49 | 2/tile_mode = 1
50 | 2/autotile/bitmask_mode = 1
51 | 2/autotile/bitmask_flags = [ Vector2( 0, 1 ), 48, Vector2( 0, 2 ), 56, Vector2( 0, 3 ), 432, Vector2( 0, 4 ), 438, Vector2( 0, 5 ), 54, Vector2( 1, 0 ), 144, Vector2( 1, 1 ), 186, Vector2( 1, 2 ), 18, Vector2( 1, 3 ), 504, Vector2( 1, 4 ), 511, Vector2( 1, 5 ), 63, Vector2( 2, 1 ), 24, Vector2( 2, 2 ), 146, Vector2( 2, 3 ), 216, Vector2( 2, 4 ), 219, Vector2( 2, 5 ), 27, Vector2( 3, 0 ), 176, Vector2( 3, 1 ), 50, Vector2( 3, 2 ), 184, Vector2( 3, 3 ), 178, Vector2( 3, 4 ), 16, Vector2( 4, 0 ), 152, Vector2( 4, 1 ), 26, Vector2( 4, 2 ), 58, Vector2( 4, 3 ), 154 ]
52 | 2/autotile/icon_coordinate = Vector2( 3, 4 )
53 | 2/autotile/tile_size = Vector2( 64, 64 )
54 | 2/autotile/spacing = 0
55 | 2/autotile/occluder_map = [ ]
56 | 2/autotile/navpoly_map = [ ]
57 | 2/autotile/priority_map = [ ]
58 | 2/autotile/z_index_map = [ ]
59 | 2/occluder_offset = Vector2( 0, 0 )
60 | 2/navigation_offset = Vector2( 0, 0 )
61 | 2/shape_offset = Vector2( 0, 0 )
62 | 2/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
63 | 2/shape_one_way = false
64 | 2/shape_one_way_margin = 0.0
65 | 2/shapes = [ ]
66 | 2/z_index = 0
67 | 3/name = "Tower Placeable Cell"
68 | 3/texture = ExtResource( 4 )
69 | 3/tex_offset = Vector2( 0, 0 )
70 | 3/modulate = Color( 1, 1, 1, 1 )
71 | 3/region = Rect2( 0, 0, 64, 64 )
72 | 3/tile_mode = 0
73 | 3/occluder_offset = Vector2( 0, 0 )
74 | 3/navigation_offset = Vector2( 0, 0 )
75 | 3/shape_offset = Vector2( 0, 0 )
76 | 3/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
77 | 3/shape_one_way = false
78 | 3/shape_one_way_margin = 0.0
79 | 3/shapes = [ ]
80 | 3/z_index = 0
81 |
--------------------------------------------------------------------------------
/source/Areas/AsteroidSurface/walkable-path.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/walkable-path.svg-ecaa9a460c48ad8740e02db5f09971a1.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Areas/AsteroidSurface/walkable-path.svg"
13 | dest_files=[ "res://.import/walkable-path.svg-ecaa9a460c48ad8740e02db5f09971a1.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/Game.gd:
--------------------------------------------------------------------------------
1 | # Initializes the user interface, forwarding it the data it needs from the game world.
2 | extends Node
3 |
4 | export(String, FILE, "*tscn") var end_screen_path = "res://Screens/EndScreen.tscn"
5 |
6 | onready var _player := $Player
7 | onready var _level := $Level
8 | onready var _hud := $UILayer/UI/HUD
9 | onready var _tower_shop := $UILayer/UI/HUD/UITowerShop
10 | onready var _screen_overlay := $UILayer/UI/UIScreenOverlay
11 | onready var _mouse_barrier := $UILayer/UI/MouseBarrier
12 | onready var _retry_button := $UILayer/UI/HUD/RetryButton
13 | onready var _start_button := $UILayer/UI/HUD/StartWaveButton
14 | onready var _gold_panel := $UILayer/UI/HUD/UIGoldPanel
15 | onready var _upgrade_shop := $UILayer/UI/HUD/UIUpgradeShop
16 |
17 |
18 | func _ready() -> void:
19 | _tower_shop.player = _player
20 | _gold_panel.player = _player
21 | _upgrade_shop.player = _player
22 | _setup_level()
23 | _level.start()
24 |
25 |
26 | func _setup_level() -> void:
27 | _level.connect("base_destroyed", self, "_on_Level_base_destroyed")
28 | _level.connect("finished", self, "_on_Level_finished")
29 | _level.connect("gold_earned", self, "_on_Level_gold_earned")
30 | _level.connect("round_finished", self, "_on_Level_round_finished")
31 |
32 | _level.tower_placer.connect("tower_placed", _tower_shop, "_on_TowerPlacer_tower_placed")
33 | _level.tower_placer.connect("tower_placed", _upgrade_shop, "_on_TowerPlacer_tower_placed")
34 | _tower_shop.connect("tower_purchased", _level.tower_placer, "add_new_tower")
35 |
36 |
37 | func _load_next_level() -> void:
38 | var next_level: Node = load(_level.next_level_path).instance()
39 | _level.queue_free()
40 | _level = next_level
41 | add_child(_level)
42 | _setup_level()
43 | _level.start()
44 |
45 |
46 | func _toggle_interface() -> void:
47 | _hud.visible = not _hud.visible
48 | _toggle_mouse_barrier()
49 |
50 |
51 | # Prevents mouse interactions in play mode
52 | func _toggle_mouse_barrier() -> void:
53 | _mouse_barrier.visible = not _hud.visible
54 |
55 |
56 | func _on_StartWaveButton_pressed() -> void:
57 | # Enters in the "play mode". In play mode, players become passive to the
58 | # game's event. Interface becomes invisible and the Level starts.
59 | _toggle_interface()
60 | get_tree().call_group("selected", "set_selected", false)
61 | yield(_screen_overlay.play_wave_start(), "completed")
62 | _level.start()
63 |
64 |
65 | func _on_Level_round_finished() -> void:
66 | # Enters in the "plan mode". In plan mode, players can take actions and plan
67 | # their Tower Layout for the next wave. Interface becomes visible again.
68 | _toggle_interface()
69 | _level.show_walkable_path()
70 |
71 |
72 | # Lose condition
73 | func _on_Level_base_destroyed() -> void:
74 | _start_button.hide()
75 | _tower_shop.hide()
76 | _retry_button.show()
77 | yield(_screen_overlay.play_lost(), "completed")
78 | _toggle_interface()
79 |
80 |
81 | # Win condition
82 | func _on_Level_finished() -> void:
83 | yield(_screen_overlay.play_win(), "completed")
84 | if _level.next_level_path:
85 | _load_next_level()
86 | else:
87 | var end_screen: Node = load(end_screen_path).instance()
88 | end_screen.player_score = _player.gold
89 | var packed_scene := PackedScene.new()
90 | packed_scene.pack(end_screen)
91 | get_tree().change_scene_to(packed_scene)
92 |
93 |
94 | func _on_RetryButton_pressed() -> void:
95 | get_tree().reload_current_scene()
96 |
97 |
98 | func _on_Level_gold_earned(gold_amount) -> void:
99 | _player.gold += gold_amount
100 |
--------------------------------------------------------------------------------
/source/Game.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=8 format=2]
2 |
3 | [ext_resource path="res://UI/UITowerShop/UITowerShop.tscn" type="PackedScene" id=1]
4 | [ext_resource path="res://Levels/Level1.tscn" type="PackedScene" id=2]
5 | [ext_resource path="res://Game.gd" type="Script" id=3]
6 | [ext_resource path="res://UI/UIGoldPanel.tscn" type="PackedScene" id=4]
7 | [ext_resource path="res://UI/UIScreenOverlay.tscn" type="PackedScene" id=5]
8 | [ext_resource path="res://Actors/Player/Player.tscn" type="PackedScene" id=6]
9 | [ext_resource path="res://UI/UIUpgradeShop/UIUpgradeShop.tscn" type="PackedScene" id=7]
10 |
11 | [node name="Game" type="Node"]
12 | script = ExtResource( 3 )
13 |
14 | [node name="Player" parent="." instance=ExtResource( 6 )]
15 |
16 | [node name="UILayer" type="CanvasLayer" parent="."]
17 |
18 | [node name="UI" type="Control" parent="UILayer"]
19 | anchor_right = 1.0
20 | anchor_bottom = 1.0
21 | mouse_filter = 2
22 | __meta__ = {
23 | "_edit_use_anchors_": false
24 | }
25 |
26 | [node name="HUD" type="Control" parent="UILayer/UI"]
27 | visible = false
28 | anchor_right = 1.0
29 | anchor_bottom = 1.0
30 | mouse_filter = 2
31 | __meta__ = {
32 | "_edit_use_anchors_": false
33 | }
34 |
35 | [node name="StartWaveButton" type="Button" parent="UILayer/UI/HUD"]
36 | anchor_left = 0.5
37 | anchor_top = 1.0
38 | anchor_right = 0.5
39 | anchor_bottom = 1.0
40 | margin_left = 256.0
41 | margin_top = -184.0
42 | margin_right = 448.0
43 | margin_bottom = -120.0
44 | text = "Start!"
45 | __meta__ = {
46 | "_edit_use_anchors_": false
47 | }
48 |
49 | [node name="RetryButton" type="Button" parent="UILayer/UI/HUD"]
50 | visible = false
51 | anchor_left = 0.5
52 | anchor_top = 0.5
53 | anchor_right = 0.5
54 | anchor_bottom = 0.5
55 | margin_left = -96.0
56 | margin_top = -32.0
57 | margin_right = 96.0
58 | margin_bottom = 32.0
59 | text = "Retry"
60 | __meta__ = {
61 | "_edit_use_anchors_": false
62 | }
63 |
64 | [node name="UIGoldPanel" parent="UILayer/UI/HUD" instance=ExtResource( 4 )]
65 | anchor_left = 0.5
66 | anchor_top = 1.0
67 | anchor_right = 0.5
68 | anchor_bottom = 1.0
69 | margin_left = -108.0
70 | margin_top = -56.0
71 | margin_right = 108.0
72 | margin_bottom = 0.0
73 |
74 | [node name="UITowerShop" parent="UILayer/UI/HUD" instance=ExtResource( 1 )]
75 | margin_top = -248.0
76 | margin_bottom = -64.0
77 |
78 | [node name="UIUpgradeShop" parent="UILayer/UI/HUD" instance=ExtResource( 7 )]
79 |
80 | [node name="MouseBarrier" type="Control" parent="UILayer/UI"]
81 | visible = false
82 | anchor_right = 1.0
83 | anchor_bottom = 1.0
84 | __meta__ = {
85 | "_edit_use_anchors_": false
86 | }
87 |
88 | [node name="UIScreenOverlay" parent="UILayer/UI" instance=ExtResource( 5 )]
89 |
90 | [node name="Level" parent="." instance=ExtResource( 2 )]
91 |
92 | [connection signal="pressed" from="UILayer/UI/HUD/StartWaveButton" to="." method="_on_StartWaveButton_pressed"]
93 | [connection signal="pressed" from="UILayer/UI/HUD/RetryButton" to="." method="_on_RetryButton_pressed"]
94 |
--------------------------------------------------------------------------------
/source/Levels/AStarGrid/AStarGrid.gd:
--------------------------------------------------------------------------------
1 | # Calculates a set of walkable positions between the start_point and the goal_point
2 | extends TileMap
3 |
4 | const DIRECTIONS := [
5 | Vector2.UP,
6 | Vector2.LEFT,
7 | Vector2.RIGHT,
8 | Vector2.DOWN
9 | ]
10 |
11 | export var start_point := Vector2.ZERO
12 | export var goal_point := Vector2.ZERO
13 | export var offset := Vector2(32, 32)
14 |
15 | var walkable_cells: PoolVector2Array
16 |
17 | var _astar := AStar2D.new()
18 | var _start_id := 0
19 | var _goal_id := 0
20 |
21 |
22 | func get_walkable_path() -> PoolVector2Array:
23 | var walkable_path := PoolVector2Array()
24 |
25 | var astar_path = _get_astar_path()
26 | for cell in astar_path:
27 | var point := map_to_world(cell)
28 | walkable_path.append(to_global(point) + offset)
29 | return walkable_path
30 |
31 |
32 | func _get_astar_path() -> PoolVector2Array:
33 | var astar_path: PoolVector2Array
34 |
35 | _create_astar_points()
36 | _connect_neighbor_cells()
37 |
38 | # Creates a walkable path from the start_point to the goal_point
39 | astar_path = _astar.get_point_path(_start_id, _goal_id)
40 | return astar_path
41 |
42 |
43 | func _create_astar_points() -> void:
44 | # Sets cells ID by iteration order
45 | var cell_id := 0
46 | for cell in walkable_cells:
47 | _astar.add_point(cell_id, cell)
48 |
49 | # Store the start and goal point IDs
50 | if cell == world_to_map(start_point):
51 | _start_id = cell_id
52 | if cell == world_to_map(goal_point):
53 | _goal_id = cell_id
54 |
55 | cell_id += 1
56 |
57 |
58 | func _connect_neighbor_cells():
59 | # Turn the walkable_cells in an Array to find its elements indices
60 | var walkable_cells_array := Array(walkable_cells)
61 |
62 | for point in _astar.get_points():
63 | var cell = _astar.get_point_position(point)
64 | for direction in DIRECTIONS:
65 | var neighbor_cell_id = walkable_cells_array.find(cell + direction)
66 | # Skip cells that weren't found
67 | if neighbor_cell_id == -1:
68 | continue
69 | _astar.connect_points(point, neighbor_cell_id)
70 |
--------------------------------------------------------------------------------
/source/Levels/AStarGrid/AStarGrid.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://Levels/AStarGrid/AStarGrid.gd" type="Script" id=1]
4 |
5 | [node name="AStarGrid" type="TileMap"]
6 | position = Vector2( 32, 32 )
7 | format = 1
8 | script = ExtResource( 1 )
9 |
--------------------------------------------------------------------------------
/source/Levels/EventsPlayer.gd:
--------------------------------------------------------------------------------
1 | extends AnimationPlayer
2 |
3 | export var current_event = 0
4 |
5 | func play_event(event_index := current_event) -> void:
6 | var events_list: Array = get_animation_list()
7 | var animation_count := events_list.size()
8 | if event_index >= animation_count:
9 | return
10 | play(events_list[event_index])
11 |
12 |
13 | func play_current_event() -> void:
14 | play_event()
15 | current_event += 1
16 |
--------------------------------------------------------------------------------
/source/Levels/Level.gd:
--------------------------------------------------------------------------------
1 | # Controls Wave's flow and TowerPlacement
2 | extends Node2D
3 |
4 | signal finished
5 | signal round_finished
6 | signal base_destroyed
7 | signal gold_earned(gold_amount)
8 |
9 | const TOWER_PLACEABLE_CELLS_ID := 3
10 | const ENEMY_WALK_PATH_CELLS_ID := 2
11 |
12 | export(String, FILE, "*.tscn") var next_level_path
13 |
14 | onready var tower_placer := $TowerPlacer
15 | onready var _tilemap := $TileMap
16 | onready var _astar_grid := $AStarGrid
17 | onready var _wave_spawner := $WaveSpawner2D
18 | onready var _events_player := $EventsPlayer
19 | onready var _path_preview := $PathPreview
20 | onready var _player_base := $GoalPoint/PlayerBase
21 |
22 |
23 | func _ready() -> void:
24 | _setup()
25 |
26 |
27 | func start() -> void:
28 | _path_preview.fade_out()
29 | _events_player.play_current_event()
30 |
31 |
32 | func finish() -> void:
33 | if _player_base.health > 0:
34 | emit_signal("finished")
35 |
36 |
37 | func spawn_wave() -> void:
38 | var wave = _wave_spawner.spawn()
39 | wave.connect("finished", self, "_on_Wave_finished")
40 | _setup_wave_path(wave)
41 |
42 | for enemy in wave.get_children():
43 | enemy.connect("died", self, "_on_Enemy_died")
44 |
45 | wave.start()
46 |
47 |
48 | func start_round() -> void:
49 | if _events_player.current_event >= _events_player.get_animation_list().size():
50 | finish()
51 | return
52 | emit_signal("round_finished")
53 |
54 |
55 | func _setup() -> void:
56 | tower_placer.setup_available_cells(_tilemap.get_used_cells_by_id(TOWER_PLACEABLE_CELLS_ID))
57 | _astar_grid.walkable_cells = _tilemap.get_used_cells_by_id(ENEMY_WALK_PATH_CELLS_ID)
58 | _astar_grid.start_point = $StartPoint.position
59 | _astar_grid.goal_point = $GoalPoint.position
60 | show_walkable_path()
61 |
62 |
63 | func show_walkable_path(walking_path := _astar_grid.get_walkable_path()) -> void:
64 | _path_preview.clear_points()
65 | _path_preview.points = walking_path
66 | _path_preview.fade_in()
67 |
68 |
69 | func _setup_wave_path(wave: Wave) -> void:
70 | wave.set_movement_path(_astar_grid.get_walkable_path())
71 |
72 |
73 | func _on_Wave_finished() -> void:
74 | start_round()
75 |
76 |
77 | func _on_PlayerBase_destroyed():
78 | emit_signal("base_destroyed")
79 |
80 |
81 | func _on_Enemy_died(gold_earned: int) -> void:
82 | emit_signal("gold_earned", gold_earned)
83 |
84 |
85 | func _on_round_finished() -> void:
86 | start()
87 |
--------------------------------------------------------------------------------
/source/Levels/TowerPlacer/TowerPlacer.gd:
--------------------------------------------------------------------------------
1 | # Allows the player to interactively place a tower on the game grid.
2 | # Keeps track of free and occupied cells.
3 | class_name TowerPlacer
4 | extends TileMap
5 |
6 | signal tower_placed(tower)
7 |
8 | # The ID of the tiles where players can place a tower.
9 | const AVAILABLE_CELL_ID := 0
10 | const INVALID_CELL_ID := 1
11 |
12 | onready var _visual_grid := $VisualGrid
13 |
14 | var _current_cell := Vector2.ZERO
15 | var _current_tower: Tower
16 |
17 |
18 | func _ready() -> void:
19 | set_process_unhandled_input(false)
20 |
21 |
22 | func _unhandled_input(event: InputEvent) -> void:
23 | if event is InputEventMouseMotion:
24 | _snap_tower_to_grid()
25 | if event.is_action_pressed("tower_placement"):
26 | _place_tower()
27 |
28 |
29 | func setup_available_cells(cells_array: PoolVector2Array) -> void:
30 | for cell in cells_array:
31 | set_cell_placeable(cell)
32 |
33 |
34 | func add_new_tower(tower: Tower) -> void:
35 | if _current_tower:
36 | _current_tower.queue_free()
37 |
38 | add_child(tower)
39 | _current_tower = tower
40 |
41 | set_process_unhandled_input(true)
42 | _visual_grid.visible = true
43 |
44 | _snap_tower_to_grid()
45 |
46 |
47 | func set_cell_unplaceable(cell: Vector2) -> void:
48 | set_cellv(cell, INVALID_CELL_ID)
49 |
50 |
51 | func set_cell_placeable(cell: Vector2) -> void:
52 | set_cellv(cell, AVAILABLE_CELL_ID)
53 |
54 |
55 | func is_cell_placeable(cell: Vector2) -> bool:
56 | return get_cellv(cell) == AVAILABLE_CELL_ID
57 |
58 |
59 | func _place_tower() -> void:
60 | set_process_unhandled_input(false)
61 | _visual_grid.visible = false
62 |
63 | if not is_cell_placeable(_current_cell):
64 | _current_tower.queue_free()
65 | _current_tower = null
66 | return
67 | set_cell_unplaceable(_current_cell)
68 |
69 | emit_signal("tower_placed", _current_tower)
70 | _current_tower.connect("sold", self, "_on_Tower_sold")
71 | _current_tower = null
72 |
73 |
74 | func _snap_tower_to_grid() -> void:
75 | _current_cell = world_to_map(get_global_mouse_position())
76 | _current_tower.global_position = map_to_world(_current_cell)
77 | if not is_cell_placeable(_current_cell):
78 | _current_tower.modulate = Color(1, 0.375, 0.375)
79 | else:
80 | _current_tower.modulate = Color.white
81 |
82 |
83 | func _on_Tower_sold(_price: int, place: Vector2) -> void:
84 | set_cell_placeable(world_to_map(place))
85 |
--------------------------------------------------------------------------------
/source/Levels/TowerPlacer/grid-cell.svg:
--------------------------------------------------------------------------------
1 |
2 |
66 |
--------------------------------------------------------------------------------
/source/Levels/TowerPlacer/grid-cell.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/grid-cell.svg-44e798e11443aec844dd0cfbbb04cd83.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Levels/TowerPlacer/grid-cell.svg"
13 | dest_files=[ "res://.import/grid-cell.svg-44e798e11443aec844dd0cfbbb04cd83.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/Levels/Waves/Wave.gd:
--------------------------------------------------------------------------------
1 | class_name Wave
2 | extends Path2D
3 |
4 | signal starting
5 | signal started
6 | signal finished
7 |
8 | # The time interval between each BasicEnemy first movement, used to
9 | # create a gap between enemies by delaying the start of their movement
10 | export var enemy_time_interval := 0.5
11 |
12 |
13 | func _ready() -> void:
14 | enemy_time_interval = max(0.1, enemy_time_interval)
15 |
16 |
17 | func start() -> void:
18 | emit_signal("starting")
19 | setup_enemies()
20 | move_enemies()
21 |
22 |
23 | func setup_enemies() -> void:
24 | for enemy in get_children():
25 | enemy.unit_offset = 0.0
26 | enemy.connect("tree_exited", self, "_on_Enemy_tree_exited")
27 |
28 |
29 | func move_enemies() -> void:
30 | for enemy in get_children():
31 | yield(get_tree().create_timer(enemy_time_interval), "timeout")
32 | enemy.move()
33 | emit_signal("started")
34 |
35 |
36 | func set_movement_path(movement_path: PoolVector2Array) -> void:
37 | curve.clear_points()
38 | for point in movement_path:
39 | curve.add_point(point)
40 |
41 |
42 | func is_wave_finished() -> bool:
43 | return get_child_count() < 1
44 |
45 |
46 | func _on_Enemy_tree_exited() -> void:
47 | if is_wave_finished():
48 | emit_signal("finished")
49 | queue_free()
50 |
--------------------------------------------------------------------------------
/source/Levels/Waves/Wave1.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://Levels/Waves/Wave.gd" type="Script" id=1]
4 | [ext_resource path="res://Actors/Enemies/Enemy.tscn" type="PackedScene" id=2]
5 |
6 |
7 |
8 | [sub_resource type="Curve2D" id=1]
9 | _data = {
10 | "points": PoolVector2Array( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 0, 0, 512, 0 )
11 | }
12 |
13 | [node name="Wave" type="Path2D"]
14 | self_modulate = Color( 0.501961, 0.6, 1, 0.701961 )
15 | curve = SubResource( 1 )
16 | script = ExtResource( 1 )
17 |
18 | [node name="BasicEnemy" parent="." instance=ExtResource( 2 )]
19 |
20 | [node name="BasicEnemy2" parent="." instance=ExtResource( 2 )]
21 |
22 | [node name="BasicEnemy3" parent="." instance=ExtResource( 2 )]
23 |
--------------------------------------------------------------------------------
/source/Levels/Waves/Wave2.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://Levels/Waves/Wave.gd" type="Script" id=1]
4 | [ext_resource path="res://Actors/Enemies/Enemy.tscn" type="PackedScene" id=2]
5 |
6 | [sub_resource type="Curve2D" id=1]
7 | _data = {
8 | "points": PoolVector2Array( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 0 )
9 | }
10 |
11 | [node name="Wave" type="Path2D"]
12 | curve = SubResource( 1 )
13 | script = ExtResource( 1 )
14 |
15 | [node name="BasicEnemy" parent="." instance=ExtResource( 2 )]
16 |
17 | [node name="BasicEnemy2" parent="." instance=ExtResource( 2 )]
18 |
19 | [node name="BasicEnemy3" parent="." instance=ExtResource( 2 )]
20 |
21 | [node name="BasicEnemy4" parent="." instance=ExtResource( 2 )]
22 |
23 | [node name="BasicEnemy5" parent="." instance=ExtResource( 2 )]
24 |
--------------------------------------------------------------------------------
/source/Levels/Waves/Wave3.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=2]
2 |
3 | [ext_resource path="res://Levels/Waves/Wave.gd" type="Script" id=1]
4 | [ext_resource path="res://Actors/Enemies/Enemy.tscn" type="PackedScene" id=2]
5 | [ext_resource path="res://Actors/Enemies/ToughEnemy.tscn" type="PackedScene" id=3]
6 |
7 | [sub_resource type="Curve2D" id=1]
8 | _data = {
9 | "points": PoolVector2Array( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 0 )
10 | }
11 |
12 | [node name="Wave" type="Path2D"]
13 | curve = SubResource( 1 )
14 | script = ExtResource( 1 )
15 |
16 | [node name="BasicEnemy" parent="." instance=ExtResource( 2 )]
17 |
18 | [node name="ToughEnemy" parent="." instance=ExtResource( 3 )]
19 |
20 | [node name="BasicEnemy2" parent="." instance=ExtResource( 2 )]
21 |
22 | [node name="ToughEnemy2" parent="." instance=ExtResource( 3 )]
23 |
24 | [node name="BasicEnemy3" parent="." instance=ExtResource( 2 )]
25 |
--------------------------------------------------------------------------------
/source/Levels/Waves/Wave4.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=2]
2 |
3 | [ext_resource path="res://Levels/Waves/Wave.gd" type="Script" id=1]
4 | [ext_resource path="res://Actors/Enemies/Enemy.tscn" type="PackedScene" id=2]
5 | [ext_resource path="res://Actors/Enemies/ToughEnemy.tscn" type="PackedScene" id=3]
6 |
7 | [sub_resource type="Curve2D" id=1]
8 | _data = {
9 | "points": PoolVector2Array( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, 0 )
10 | }
11 |
12 | [node name="Wave" type="Path2D"]
13 | curve = SubResource( 1 )
14 | script = ExtResource( 1 )
15 |
16 | [node name="ToughEnemy" parent="." instance=ExtResource( 3 )]
17 |
18 | [node name="Enemy" parent="." instance=ExtResource( 2 )]
19 |
20 | [node name="ToughEnemy2" parent="." instance=ExtResource( 3 )]
21 |
22 | [node name="Enemy2" parent="." instance=ExtResource( 2 )]
23 |
24 | [node name="ToughEnemy3" parent="." instance=ExtResource( 3 )]
25 |
--------------------------------------------------------------------------------
/source/Objects/EnemySpawn/enemy-spawn.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/enemy-spawn.svg-8a0224ff5ee8c87ffcda5d22e0c2f2db.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Objects/EnemySpawn/enemy-spawn.svg"
13 | dest_files=[ "res://.import/enemy-spawn.svg-8a0224ff5ee8c87ffcda5d22e0c2f2db.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/Objects/HitBox/HitBoxArea2D.gd:
--------------------------------------------------------------------------------
1 | # Represents a Hit dealt from the attacker perspective
2 | class_name HitBoxArea2D
3 | extends Area2D
4 |
5 | enum Teams { PLAYER, ENEMY }
6 | export (Teams) var team := Teams.PLAYER
7 |
8 | export var damage := 1
9 | export var can_hit_multiple := false
10 |
11 |
12 | func apply_hit(hurt_box: HurtBoxArea2D) -> void:
13 | if team == hurt_box.team:
14 | return
15 | hurt_box.get_hurt(damage)
16 | set_deferred("monitoring", can_hit_multiple)
17 |
18 |
19 | func _on_area_entered(area: Area2D) -> void:
20 | apply_hit(area)
21 |
--------------------------------------------------------------------------------
/source/Objects/HitBox/HitBoxArea2D.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://Objects/HitBox/HitBoxArea2D.gd" type="Script" id=1]
4 |
5 | [node name="HitBoxArea2D" type="Area2D"]
6 | monitorable = false
7 | collision_layer = 0
8 | collision_mask = 2
9 | script = ExtResource( 1 )
10 | [connection signal="area_entered" from="." to="." method="_on_area_entered"]
11 |
--------------------------------------------------------------------------------
/source/Objects/HurtBox/HurtBoxArea2D.gd:
--------------------------------------------------------------------------------
1 | # Represents a Hit dealt from the target perspective
2 | class_name HurtBoxArea2D
3 | extends Area2D
4 |
5 | signal hit_landed(damage)
6 |
7 | enum Teams { PLAYER, ENEMY }
8 | export (Teams) var team := Teams.PLAYER
9 |
10 | export var armor := 0
11 |
12 |
13 | func get_hurt(damage: int) -> void:
14 | var final_damage := damage - armor
15 | emit_signal("hit_landed", final_damage)
16 |
--------------------------------------------------------------------------------
/source/Objects/HurtBox/HurtBoxArea2D.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://Objects/HurtBox/HurtBoxArea2D.gd" type="Script" id=1]
4 |
5 | [node name="HurtBoxArea2D" type="Area2D"]
6 | monitoring = false
7 | collision_layer = 2
8 | collision_mask = 0
9 | script = ExtResource( 1 )
10 |
--------------------------------------------------------------------------------
/source/Objects/PlayerBase/CutoutSprites.gd:
--------------------------------------------------------------------------------
1 | extends Node2D
2 |
3 |
4 | onready var _anim_player := $AnimationPlayer
5 |
6 | func play(animation: String) -> void:
7 | _anim_player.play(animation)
8 |
--------------------------------------------------------------------------------
/source/Objects/PlayerBase/PlayerBase.gd:
--------------------------------------------------------------------------------
1 | # The Player's main building.
2 | extends Node2D
3 |
4 | signal destroyed
5 |
6 | export var max_health := 10
7 | var health := max_health setget set_health
8 |
9 | onready var _sprites := $Sprites
10 | onready var _interface := $Interface
11 | onready var _ui_health_bar := $Interface/HealthBar
12 | onready var _health_bar := $HealthBar
13 | onready var _hurt_box := $HurtBoxArea2D
14 |
15 |
16 | func _ready() -> void:
17 | health = max_health
18 |
19 | # Share the Interface/HealthBar's values with the HealthBar
20 | # to keep them synced
21 | _ui_health_bar.share(_health_bar)
22 |
23 | _ui_health_bar.max_value = max_health
24 | _ui_health_bar.value = health
25 |
26 |
27 | func set_health(value: int) -> void:
28 | health = clamp(value, 0, max_health)
29 |
30 | _ui_health_bar.value = health
31 |
32 | if health < 1:
33 | _destroy()
34 |
35 |
36 | func _destroy() -> void:
37 | emit_signal("destroyed")
38 | _sprites.play("Explode")
39 |
40 | # Make a deferred call to prevent errors
41 | _hurt_box.set_deferred("monitorable", false)
42 |
43 |
44 | func _on_HurtBoxArea2D_hit_landed(damage: int) -> void:
45 | set_health(health - damage)
46 |
47 |
48 | func _on_SelectableArea2D_selection_changed(selected: bool) -> void:
49 | if selected:
50 | _interface.appear()
51 | else:
52 | _interface.disappear()
53 |
--------------------------------------------------------------------------------
/source/Objects/PlayerBase/PlayerBase.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=9 format=2]
2 |
3 | [ext_resource path="res://Objects/PlayerBase/CutoutPlayerBase.tscn" type="PackedScene" id=1]
4 | [ext_resource path="res://Objects/HurtBox/HurtBoxArea2D.tscn" type="PackedScene" id=2]
5 | [ext_resource path="res://Objects/SelectableArea2D/SelectableArea2D.tscn" type="PackedScene" id=3]
6 | [ext_resource path="res://Objects/PlayerBase/PlayerBase.gd" type="Script" id=4]
7 | [ext_resource path="res://UI/UIHealthBar/UIHealthBar.tscn" type="PackedScene" id=5]
8 | [ext_resource path="res://UI/UIUnit/UIUnit.tscn" type="PackedScene" id=6]
9 | [ext_resource path="res://UI/UIHealthBar/UITimedHealthBar.tscn" type="PackedScene" id=8]
10 |
11 | [sub_resource type="RectangleShape2D" id=1]
12 | extents = Vector2( 64, 34 )
13 |
14 | [node name="PlayerBase" type="Node2D"]
15 | script = ExtResource( 4 )
16 |
17 | [node name="Sprites" parent="." instance=ExtResource( 1 )]
18 |
19 | [node name="HurtBoxArea2D" parent="." instance=ExtResource( 2 )]
20 | position = Vector2( 0, 10 )
21 |
22 | [node name="CollisionShape2D" type="CollisionShape2D" parent="HurtBoxArea2D"]
23 | position = Vector2( 0, -8 )
24 | shape = SubResource( 1 )
25 |
26 | [node name="SelectableArea2D" parent="." instance=ExtResource( 3 )]
27 |
28 | [node name="CollisionShape2D" type="CollisionShape2D" parent="SelectableArea2D"]
29 | position = Vector2( 0, 2 )
30 | shape = SubResource( 1 )
31 |
32 | [node name="Interface" parent="." instance=ExtResource( 6 )]
33 |
34 | [node name="HealthBar" parent="Interface" instance=ExtResource( 5 )]
35 | margin_left = -88.0
36 | margin_top = -72.0
37 | margin_right = 84.0
38 | margin_bottom = -54.0
39 |
40 | [node name="HealthBar" parent="." instance=ExtResource( 8 )]
41 | margin_left = -88.0
42 | margin_top = -72.0
43 | margin_right = 84.0
44 | margin_bottom = -54.0
45 | step = 1.0
46 | [connection signal="hit_landed" from="HurtBoxArea2D" to="." method="_on_HurtBoxArea2D_hit_landed"]
47 | [connection signal="selection_changed" from="SelectableArea2D" to="." method="_on_SelectableArea2D_selection_changed"]
48 |
--------------------------------------------------------------------------------
/source/Objects/PlayerBase/player-base.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/player-base.svg-e6615df4603076c80a8bc8470eef80ce.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Objects/PlayerBase/player-base.svg"
13 | dest_files=[ "res://.import/player-base.svg-e6615df4603076c80a8bc8470eef80ce.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/Objects/SelectableArea2D/SelectableArea2D.gd:
--------------------------------------------------------------------------------
1 | # Communicates selection states at individual level.
2 | class_name SelectableArea2D
3 | extends Area2D
4 |
5 | signal selection_changed(selected)
6 |
7 | export var select_action := "select"
8 |
9 | var selected := false setget set_selected
10 |
11 |
12 | func _ready() -> void:
13 | set_process_unhandled_input(false)
14 |
15 |
16 | func _input_event(_viewport: Object, event: InputEvent, _shape_idx: int) -> void:
17 | if event.is_action_pressed(select_action):
18 | set_selected(not selected)
19 |
20 |
21 | func _unhandled_input(event: InputEvent) -> void:
22 | if event.is_action_pressed(select_action):
23 | set_selected(false)
24 | set_process_unhandled_input(false)
25 |
26 |
27 | func set_selected(select: bool) -> void:
28 | selected = select
29 | if selected:
30 | add_to_group("selected")
31 | else:
32 | remove_from_group("selected")
33 | emit_signal("selection_changed", selected)
34 |
35 |
36 | func _on_mouse_entered() -> void:
37 | set_process_unhandled_input(false)
38 |
39 |
40 | func _on_mouse_exited() -> void:
41 | set_process_unhandled_input(selected)
42 |
--------------------------------------------------------------------------------
/source/Objects/SelectableArea2D/SelectableArea2D.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://Objects/SelectableArea2D/SelectableArea2D.gd" type="Script" id=1]
4 |
5 | [node name="SelectableArea2D" type="Area2D"]
6 | monitoring = false
7 | collision_mask = 0
8 | script = ExtResource( 1 )
9 |
10 | [connection signal="mouse_entered" from="." to="." method="_on_mouse_entered"]
11 | [connection signal="mouse_exited" from="." to="." method="_on_mouse_exited"]
12 |
--------------------------------------------------------------------------------
/source/Objects/Towers/BombTower.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://Objects/Towers/Tower.tscn" type="PackedScene" id=1]
4 | [ext_resource path="res://Objects/Weapon2D/Bullets/BombBullet.tscn" type="PackedScene" id=2]
5 |
6 | [sub_resource type="CircleShape2D" id=1]
7 | resource_local_to_scene = true
8 | radius = 128.0
9 |
10 | [node name="Tower" instance=ExtResource( 1 )]
11 | cost = 500
12 |
13 | [node name="Weapon2D" parent="." index="1"]
14 | bullet_scene = ExtResource( 2 )
15 | fire_range = 128.0
16 | fire_cooldown = 3.0
17 |
18 | [node name="Sprite" parent="Weapon2D" index="0"]
19 | offset = Vector2( 36, 0 )
20 | region_rect = Rect2( 190, 217, 50, 28 )
21 |
22 | [node name="BulletSpawnPosition2D" parent="Weapon2D" index="1"]
23 | position = Vector2( 60, 0 )
24 |
25 | [node name="CollisionShape2D" parent="Weapon2D/RangeArea2D" index="0"]
26 | shape = SubResource( 1 )
27 |
28 | [editable path="Weapon2D"]
29 |
--------------------------------------------------------------------------------
/source/Objects/Towers/RifleTower.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=2]
2 |
3 | [ext_resource path="res://Objects/Towers/Tower.tscn" type="PackedScene" id=1]
4 | [ext_resource path="res://Objects/Towers/Upgrades/FireRangeUpgrade.gd" type="Script" id=3]
5 |
6 | [node name="Tower" instance=ExtResource( 1 )]
7 |
8 | [node name="FireRangeUpgrade" type="Node" parent="Upgrades" index="0"]
9 | script = ExtResource( 3 )
10 | display_name = "Fire Range"
11 | description = "Increases the tower's reach."
12 |
--------------------------------------------------------------------------------
/source/Objects/Towers/Tower.gd:
--------------------------------------------------------------------------------
1 | class_name Tower
2 | extends Node2D
3 |
4 | signal sold(price, place)
5 | signal selected(selected)
6 |
7 | export var cost := 100
8 |
9 | onready var _weapon := $Weapon2D
10 | onready var _interface := $Interface
11 | onready var _cooldown_bar := $UICooldownBar
12 | onready var _selection := $SelectableArea2D
13 | onready var _upgrades := $Upgrades
14 |
15 |
16 | func _ready() -> void:
17 | _weapon.show_range()
18 | for upgrade in _upgrades.get_children():
19 | upgrade.weapon = _weapon
20 | upgrade.connect("applied", self, "_on_Upgrade_applied")
21 |
22 |
23 | func show_interface() -> void:
24 | _weapon.show_range()
25 | _interface.appear()
26 |
27 |
28 | func hide_interface() -> void:
29 | _weapon.hide_range()
30 | _interface.disappear()
31 |
32 |
33 | func get_upgrades() -> Array:
34 | return _upgrades.get_children()
35 |
36 |
37 | func _on_SelectableArea2D_selection_changed(selected) -> void:
38 | if selected:
39 | show_interface()
40 | else:
41 | hide_interface()
42 | emit_signal("selected", selected)
43 |
44 |
45 | func _on_SellButton_pressed() -> void:
46 | emit_signal("sold", cost / 2, position)
47 | queue_free()
48 |
49 |
50 | func _on_Weapon2D_fired() -> void:
51 | _cooldown_bar.start(_weapon.fire_cooldown)
52 |
53 |
54 | func _on_Upgrade_applied(upgrade_cost: int) -> void:
55 | cost += upgrade_cost
56 |
--------------------------------------------------------------------------------
/source/Objects/Towers/Tower.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=9 format=2]
2 |
3 | [ext_resource path="res://Objects/Weapon2D/Weapon2D.tscn" type="PackedScene" id=1]
4 | [ext_resource path="res://Objects/SelectableArea2D/SelectableArea2D.tscn" type="PackedScene" id=2]
5 | [ext_resource path="res://Objects/Towers/Tower.gd" type="Script" id=3]
6 | [ext_resource path="res://sprite-sheet.svg" type="Texture" id=4]
7 | [ext_resource path="res://UI/UIUnit/UIUnit.tscn" type="PackedScene" id=5]
8 | [ext_resource path="res://UI/UICooldownBar/UICooldownBar.tscn" type="PackedScene" id=6]
9 |
10 | [sub_resource type="CircleShape2D" id=1]
11 | resource_local_to_scene = true
12 | radius = 128.0
13 |
14 | [sub_resource type="RectangleShape2D" id=2]
15 | extents = Vector2( 32, 32 )
16 |
17 | [node name="Tower" type="Node2D"]
18 | script = ExtResource( 3 )
19 |
20 | [node name="BaseSprite" type="Sprite" parent="."]
21 | texture = ExtResource( 4 )
22 | offset = Vector2( 32, 32 )
23 | region_enabled = true
24 | region_rect = Rect2( 192, 64, 73, 64 )
25 |
26 | [node name="Weapon2D" parent="." instance=ExtResource( 1 )]
27 | position = Vector2( 32, 36 )
28 | fire_range = 192.0
29 |
30 | [node name="CollisionShape2D" parent="Weapon2D/RangeArea2D" index="0"]
31 | shape = SubResource( 1 )
32 |
33 | [node name="GlassSprite" type="Sprite" parent="."]
34 | texture = ExtResource( 4 )
35 | offset = Vector2( 32, 38 )
36 | region_enabled = true
37 | region_rect = Rect2( 272, 89, 26, 27 )
38 |
39 | [node name="SelectableArea2D" parent="." instance=ExtResource( 2 )]
40 | position = Vector2( 32, 32 )
41 | z_index = -1
42 |
43 | [node name="CollisionShape2D" type="CollisionShape2D" parent="SelectableArea2D"]
44 | shape = SubResource( 2 )
45 |
46 | [node name="Interface" parent="." instance=ExtResource( 5 )]
47 | margin_left = 32.0
48 | margin_top = 40.0
49 | margin_right = 32.0
50 | margin_bottom = 40.0
51 |
52 | [node name="SellButton" type="Button" parent="Interface"]
53 | anchor_left = 0.5
54 | anchor_top = 1.0
55 | anchor_right = 0.5
56 | anchor_bottom = 1.0
57 | margin_left = -72.0
58 | margin_top = 32.0
59 | margin_right = 72.0
60 | margin_bottom = 70.0
61 | rect_pivot_offset = Vector2( 72, 16 )
62 | text = "Sell"
63 | __meta__ = {
64 | "_edit_use_anchors_": false
65 | }
66 |
67 | [node name="UICooldownBar" parent="." instance=ExtResource( 6 )]
68 | margin_left = -40.0
69 | margin_top = -40.0
70 | margin_right = 104.0
71 | margin_bottom = -16.0
72 |
73 | [node name="Upgrades" type="Node" parent="."]
74 |
75 | [connection signal="fired" from="Weapon2D" to="." method="_on_Weapon2D_fired"]
76 | [connection signal="selection_changed" from="SelectableArea2D" to="." method="_on_SelectableArea2D_selection_changed"]
77 | [connection signal="pressed" from="Interface/SellButton" to="." method="_on_SellButton_pressed"]
78 |
79 | [editable path="Weapon2D"]
80 |
--------------------------------------------------------------------------------
/source/Objects/Towers/Upgrades/FireRangeUpgrade.gd:
--------------------------------------------------------------------------------
1 | extends Upgrade
2 |
3 |
4 | func _apply() -> void:
5 | weapon.fire_range += value
6 | weapon.show_range()
7 |
--------------------------------------------------------------------------------
/source/Objects/Towers/Upgrades/Upgrade.gd:
--------------------------------------------------------------------------------
1 | class_name Upgrade
2 | extends Node
3 |
4 | signal applied(cost)
5 |
6 | export var display_name := "Upgrade name"
7 | export(String, MULTILINE) var description := "Upgrade description"
8 | export var cost := 100
9 | export var cost_multiplier := 1.2
10 | export var value := 100.0
11 |
12 | var weapon: Weapon2D
13 |
14 |
15 | func apply() -> void:
16 | _apply()
17 | cost *= cost_multiplier
18 | emit_signal("applied", cost)
19 |
20 |
21 | # Virtual method, override in children according to upgrade effect
22 | func _apply() -> void:
23 | pass
24 |
--------------------------------------------------------------------------------
/source/Objects/WaveSpawner2D/WaveSpawner2D.gd:
--------------------------------------------------------------------------------
1 | # Spawns enemy waves.
2 | class_name WaveSpawner2D
3 | extends Position2D
4 |
5 | signal spawned(spawn)
6 |
7 | export var spawn_scene: PackedScene
8 |
9 |
10 | func spawn() -> Node2D:
11 | var spawn: Node2D = spawn_scene.instance()
12 |
13 | add_child(spawn)
14 | spawn.set_as_toplevel(true)
15 | spawn.global_position = global_position
16 |
17 | emit_signal("spawned", spawn)
18 | return spawn
19 |
--------------------------------------------------------------------------------
/source/Objects/WaveSpawner2D/WaveSpawner2D.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://Objects/WaveSpawner2D/WaveSpawner2D.gd" type="Script" id=1]
4 |
5 | [node name="WaveSpawner2D" type="Position2D"]
6 | script = ExtResource( 1 )
7 |
--------------------------------------------------------------------------------
/source/Objects/Weapon2D/Bullets/BombBullet.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=6 format=2]
2 |
3 | [ext_resource path="res://Objects/Weapon2D/Bullets/Bullet.tscn" type="PackedScene" id=1]
4 | [ext_resource path="res://VFX/Explosions/Explosion.tscn" type="PackedScene" id=4]
5 |
6 | [sub_resource type="CircleShape2D" id=1]
7 | radius = 64.1249
8 |
9 | [sub_resource type="Animation" id=2]
10 | resource_name = "Explode"
11 | length = 3.0
12 | tracks/0/type = "animation"
13 | tracks/0/path = NodePath("Explosion/AnimationPlayer")
14 | tracks/0/interp = 1
15 | tracks/0/loop_wrap = true
16 | tracks/0/imported = false
17 | tracks/0/enabled = true
18 | tracks/0/keys = {
19 | "clips": PoolStringArray( "Explode" ),
20 | "times": PoolRealArray( 0 )
21 | }
22 | tracks/1/type = "value"
23 | tracks/1/path = NodePath("HitBoxArea2D/CollisionShape2D:disabled")
24 | tracks/1/interp = 1
25 | tracks/1/loop_wrap = true
26 | tracks/1/imported = false
27 | tracks/1/enabled = true
28 | tracks/1/keys = {
29 | "times": PoolRealArray( 0, 0.5 ),
30 | "transitions": PoolRealArray( 1, 1 ),
31 | "update": 1,
32 | "values": [ false, true ]
33 | }
34 | tracks/2/type = "method"
35 | tracks/2/path = NodePath(".")
36 | tracks/2/interp = 1
37 | tracks/2/loop_wrap = true
38 | tracks/2/imported = false
39 | tracks/2/enabled = true
40 | tracks/2/keys = {
41 | "times": PoolRealArray( 3 ),
42 | "transitions": PoolRealArray( 1 ),
43 | "values": [ {
44 | "args": [ ],
45 | "method": "queue_free"
46 | } ]
47 | }
48 |
49 | [sub_resource type="Animation" id=3]
50 | resource_name = "SETUP"
51 | tracks/0/type = "value"
52 | tracks/0/path = NodePath("HitBoxArea2D/CollisionShape2D:disabled")
53 | tracks/0/interp = 1
54 | tracks/0/loop_wrap = true
55 | tracks/0/imported = false
56 | tracks/0/enabled = true
57 | tracks/0/keys = {
58 | "times": PoolRealArray( 0 ),
59 | "transitions": PoolRealArray( 1 ),
60 | "update": 1,
61 | "values": [ true ]
62 | }
63 |
64 | [node name="Bullet" instance=ExtResource( 1 )]
65 |
66 | [node name="Sprite" parent="." index="0"]
67 | scale = Vector2( 1.3, 1.3 )
68 | region_rect = Rect2( 240, 144, 16, 16 )
69 |
70 | [node name="Sprite2" parent="Sprite" index="0"]
71 | visible = false
72 |
73 | [node name="HitBoxArea2D" parent="." index="1"]
74 | damage = 2
75 | can_hit_multiple = true
76 |
77 | [node name="CollisionShape2D" parent="HitBoxArea2D" index="0"]
78 | shape = SubResource( 1 )
79 |
80 | [node name="AnimationPlayer" parent="." index="3"]
81 | autoplay = "SETUP"
82 | anims/Explode = SubResource( 2 )
83 | anims/SETUP = SubResource( 3 )
84 |
85 | [node name="SmallExplosion" parent="." index="4"]
86 | visible = false
87 |
88 | [node name="Explosion" parent="." index="5" instance=ExtResource( 4 )]
89 |
--------------------------------------------------------------------------------
/source/Objects/Weapon2D/Bullets/Bullet.gd:
--------------------------------------------------------------------------------
1 | class_name Bullet
2 | extends Node2D
3 |
4 | export var speed := 500.0
5 |
6 | onready var _tween := $Tween
7 | onready var _anim_player := $AnimationPlayer
8 |
9 |
10 | func _init() -> void:
11 | set_as_toplevel(true)
12 |
13 |
14 | func fly_to(target_global_position: Vector2) -> void:
15 | var distance := global_position.distance_to(target_global_position)
16 | var duration := distance / speed
17 |
18 | _tween.interpolate_property(
19 | self, "global_position", global_position, target_global_position, duration
20 | )
21 | _tween.start()
22 | look_at(target_global_position)
23 | yield(_tween, "tween_all_completed")
24 | _anim_player.play("Explode")
25 |
--------------------------------------------------------------------------------
/source/Objects/Weapon2D/Bullets/Bullet.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=7 format=2]
2 |
3 | [ext_resource path="res://Objects/Weapon2D/Bullets/Bullet.gd" type="Script" id=1]
4 | [ext_resource path="res://sprite-sheet.svg" type="Texture" id=2]
5 | [ext_resource path="res://Objects/HitBox/HitBoxArea2D.tscn" type="PackedScene" id=3]
6 | [ext_resource path="res://VFX/Explosions/SmallExplosion.tscn" type="PackedScene" id=4]
7 |
8 | [sub_resource type="CapsuleShape2D" id=1]
9 | radius = 8.0
10 | height = 8.0
11 |
12 | [sub_resource type="Animation" id=2]
13 | resource_name = "Explode"
14 | length = 0.1
15 | tracks/0/type = "value"
16 | tracks/0/path = NodePath("SmallExplosion:emitting")
17 | tracks/0/interp = 1
18 | tracks/0/loop_wrap = true
19 | tracks/0/imported = false
20 | tracks/0/enabled = true
21 | tracks/0/keys = {
22 | "times": PoolRealArray( 0, 0.1 ),
23 | "transitions": PoolRealArray( 1, 1 ),
24 | "update": 1,
25 | "values": [ true, false ]
26 | }
27 | tracks/1/type = "method"
28 | tracks/1/path = NodePath(".")
29 | tracks/1/interp = 1
30 | tracks/1/loop_wrap = true
31 | tracks/1/imported = false
32 | tracks/1/enabled = true
33 | tracks/1/keys = {
34 | "times": PoolRealArray( 0.1 ),
35 | "transitions": PoolRealArray( 1 ),
36 | "values": [ {
37 | "args": [ ],
38 | "method": "queue_free"
39 | } ]
40 | }
41 |
42 | [node name="Bullet" type="Node2D"]
43 | script = ExtResource( 1 )
44 |
45 | [node name="Sprite" type="Sprite" parent="."]
46 | texture = ExtResource( 2 )
47 | region_enabled = true
48 | region_rect = Rect2( 192, 144, 21, 18 )
49 |
50 | [node name="Sprite2" type="Sprite" parent="Sprite"]
51 | show_behind_parent = true
52 | position = Vector2( -16, 0 )
53 | texture = ExtResource( 2 )
54 | region_enabled = true
55 | region_rect = Rect2( 129, 228, 27, 16 )
56 |
57 | [node name="HitBoxArea2D" parent="." instance=ExtResource( 3 )]
58 | damage = 3
59 |
60 | [node name="CollisionShape2D" type="CollisionShape2D" parent="HitBoxArea2D"]
61 | rotation = 1.57079
62 | shape = SubResource( 1 )
63 |
64 | [node name="Tween" type="Tween" parent="."]
65 | playback_process_mode = 0
66 |
67 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
68 | anims/Explode = SubResource( 2 )
69 |
70 | [node name="SmallExplosion" parent="." instance=ExtResource( 4 )]
71 |
--------------------------------------------------------------------------------
/source/Objects/Weapon2D/RangePreview/RangePreview.gd:
--------------------------------------------------------------------------------
1 | extends Sprite
2 |
3 | export var radius := 100.0
4 | export var tween_duration := 0.5
5 |
6 | onready var _tween := $Tween
7 |
8 |
9 | func appear() -> void:
10 | var ratio = radius / texture.get_width()
11 | var final_scale = Vector2(ratio, ratio) * 2.0
12 |
13 | _tween.stop_all()
14 |
15 | _tween.interpolate_property(
16 | self, "scale", scale, final_scale, tween_duration, Tween.TRANS_QUINT, Tween.EASE_OUT
17 | )
18 | _tween.interpolate_property(
19 | self, "modulate", modulate, Color(1, 1, 1, 1), tween_duration)
20 | _tween.start()
21 |
22 |
23 | func disappear() -> void:
24 | if _tween.is_active():
25 | _tween.stop_all()
26 |
27 | _tween.interpolate_property(
28 | self, "scale", scale, Vector2.ZERO, tween_duration, Tween.TRANS_BACK, Tween.EASE_IN
29 | )
30 | _tween.interpolate_property(
31 | self, "modulate", modulate, Color(1, 1, 1, 0), tween_duration * 2.0)
32 | _tween.start()
33 |
--------------------------------------------------------------------------------
/source/Objects/Weapon2D/RangePreview/RangePreview.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=2]
2 |
3 | [ext_resource path="res://Objects/Weapon2D/RangePreview/range-preview.svg" type="Texture" id=1]
4 | [ext_resource path="res://Objects/Weapon2D/RangePreview/RangePreview.gd" type="Script" id=2]
5 |
6 | [node name="RangePreview" type="Sprite"]
7 | modulate = Color( 1, 1, 1, 0 )
8 | texture = ExtResource( 1 )
9 | script = ExtResource( 2 )
10 | radius = 50.0
11 |
12 | [node name="Tween" type="Tween" parent="."]
13 |
--------------------------------------------------------------------------------
/source/Objects/Weapon2D/RangePreview/range-preview.svg:
--------------------------------------------------------------------------------
1 |
2 |
82 |
--------------------------------------------------------------------------------
/source/Objects/Weapon2D/RangePreview/range-preview.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/range-preview.svg-3ddcdc213d26cf3b747e41044dcee9ea.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Objects/Weapon2D/RangePreview/range-preview.svg"
13 | dest_files=[ "res://.import/range-preview.svg-3ddcdc213d26cf3b747e41044dcee9ea.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/Objects/Weapon2D/Weapon2D.gd:
--------------------------------------------------------------------------------
1 | class_name Weapon2D
2 | extends Node2D
3 |
4 | signal fired()
5 |
6 | export var bullet_scene: PackedScene
7 | # Range of the weapon in pixels.
8 | export var fire_range := 128.0 setget set_fire_range
9 | # Cooldown in seconds to fire again
10 | export var fire_cooldown := 1.0
11 |
12 | onready var _bullet_spawn_position := $BulletSpawnPosition2D
13 | onready var _cooldown_timer := $CooldownTimer
14 | onready var _range_area := $RangeArea2D
15 | onready var _animation_player := $AnimationPlayer
16 | onready var _range_shape: CircleShape2D = $RangeArea2D/CollisionShape2D.shape
17 | onready var _range_preview := $RangePreview
18 |
19 |
20 | func _ready() -> void:
21 | set_fire_range(fire_range)
22 | show_range()
23 |
24 |
25 | func _physics_process(_delta: float) -> void:
26 | if not _cooldown_timer.is_stopped():
27 | return
28 |
29 | var targets: Array = _range_area.get_overlapping_areas()
30 | if targets.empty():
31 | return
32 |
33 | var target: Node2D = targets[0]
34 | shoot_at(target.global_position)
35 |
36 |
37 | func set_fire_range(new_range: float) -> void:
38 | fire_range = new_range
39 | if not is_inside_tree():
40 | yield(self, "ready")
41 | _range_shape.radius = fire_range
42 |
43 |
44 | func shoot_at(target_position: Vector2) -> void:
45 | look_at(target_position)
46 | _animation_player.play("shoot")
47 |
48 | var bullet = bullet_scene.instance()
49 | add_child(bullet)
50 | bullet.global_position = _bullet_spawn_position.global_position
51 | bullet.fly_to(target_position)
52 |
53 | _cooldown_timer.start(fire_cooldown)
54 | emit_signal("fired")
55 |
56 |
57 | func show_range() -> void:
58 | _range_preview.radius = fire_range
59 | _range_preview.appear()
60 |
61 |
62 | func hide_range() -> void:
63 | _range_preview.disappear()
64 |
--------------------------------------------------------------------------------
/source/Objects/Weapon2D/Weapon2D.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=7 format=2]
2 |
3 | [ext_resource path="res://Objects/Weapon2D/Weapon2D.gd" type="Script" id=1]
4 | [ext_resource path="res://sprite-sheet.svg" type="Texture" id=2]
5 | [ext_resource path="res://Objects/Weapon2D/RangePreview/RangePreview.tscn" type="PackedScene" id=3]
6 | [ext_resource path="res://Objects/Weapon2D/Bullets/Bullet.tscn" type="PackedScene" id=4]
7 |
8 | [sub_resource type="CircleShape2D" id=1]
9 | resource_local_to_scene = true
10 | radius = 128.0
11 |
12 | [sub_resource type="Animation" id=2]
13 | resource_name = "shoot"
14 | length = 0.5
15 | tracks/0/type = "value"
16 | tracks/0/path = NodePath("Sprite:position")
17 | tracks/0/interp = 1
18 | tracks/0/loop_wrap = true
19 | tracks/0/imported = false
20 | tracks/0/enabled = true
21 | tracks/0/keys = {
22 | "times": PoolRealArray( 0, 0.2, 0.5 ),
23 | "transitions": PoolRealArray( 0.5, 1, 1 ),
24 | "update": 0,
25 | "values": [ Vector2( 0, 0 ), Vector2( -16, 0 ), Vector2( 0, 0 ) ]
26 | }
27 |
28 | [node name="Weapon2D" type="Node2D"]
29 | script = ExtResource( 1 )
30 | bullet_scene = ExtResource( 4 )
31 | fire_range = 256.0
32 |
33 | [node name="Sprite" type="Sprite" parent="."]
34 | texture = ExtResource( 2 )
35 | offset = Vector2( 40, 0 )
36 | region_enabled = true
37 | region_rect = Rect2( 192, 176, 54, 18 )
38 |
39 | [node name="BulletSpawnPosition2D" type="Position2D" parent="."]
40 | position = Vector2( 64, 0 )
41 |
42 | [node name="RangeArea2D" type="Area2D" parent="."]
43 | collision_layer = 0
44 | collision_mask = 4
45 |
46 | [node name="CollisionShape2D" type="CollisionShape2D" parent="RangeArea2D"]
47 | shape = SubResource( 1 )
48 |
49 | [node name="CooldownTimer" type="Timer" parent="."]
50 | process_mode = 0
51 | one_shot = true
52 |
53 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
54 | anims/shoot = SubResource( 2 )
55 |
56 | [node name="RangePreview" parent="." instance=ExtResource( 3 )]
57 |
--------------------------------------------------------------------------------
/source/Screens/EndScreen.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 | export var player_score := 0
4 |
5 | onready var _label := $Panel/Label
6 |
7 | func _ready() -> void:
8 | _label.text = _label.text % player_score
9 |
--------------------------------------------------------------------------------
/source/Screens/EndScreen.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=2]
2 |
3 | [ext_resource path="res://UI/Theme/Montserrat-ExtraBold.ttf" type="DynamicFontData" id=1]
4 | [ext_resource path="res://Screens/EndScreen.gd" type="Script" id=2]
5 |
6 | [sub_resource type="DynamicFont" id=1]
7 | size = 32
8 | font_data = ExtResource( 1 )
9 |
10 | [sub_resource type="Animation" id=2]
11 | resource_name = "Text"
12 | length = 2.5
13 | tracks/0/type = "value"
14 | tracks/0/path = NodePath("Panel:rect_scale")
15 | tracks/0/interp = 1
16 | tracks/0/loop_wrap = true
17 | tracks/0/imported = false
18 | tracks/0/enabled = true
19 | tracks/0/keys = {
20 | "times": PoolRealArray( 0, 0.2, 0.3 ),
21 | "transitions": PoolRealArray( 1, 0.5, 1 ),
22 | "update": 0,
23 | "values": [ Vector2( 0, 0 ), Vector2( 1.2, 1.2 ), Vector2( 1, 1 ) ]
24 | }
25 | tracks/1/type = "value"
26 | tracks/1/path = NodePath("Panel/Label:percent_visible")
27 | tracks/1/interp = 1
28 | tracks/1/loop_wrap = true
29 | tracks/1/imported = false
30 | tracks/1/enabled = true
31 | tracks/1/keys = {
32 | "times": PoolRealArray( 0, 0.4, 1.4, 2.5 ),
33 | "transitions": PoolRealArray( 1, 1, 1, 1 ),
34 | "update": 0,
35 | "values": [ 0.0, 0.0, 0.909091, 1.0 ]
36 | }
37 |
38 | [node name="EndScreen" type="Control"]
39 | anchor_right = 1.0
40 | anchor_bottom = 1.0
41 | script = ExtResource( 2 )
42 | __meta__ = {
43 | "_edit_use_anchors_": false
44 | }
45 |
46 | [node name="Panel" type="Panel" parent="."]
47 | anchor_left = 0.5
48 | anchor_top = 0.5
49 | anchor_right = 0.5
50 | anchor_bottom = 0.5
51 | margin_left = -618.0
52 | margin_top = -120.0
53 | margin_right = 618.0
54 | margin_bottom = 120.0
55 | rect_scale = Vector2( 1e-05, 1e-05 )
56 | rect_pivot_offset = Vector2( 618, 124 )
57 | __meta__ = {
58 | "_edit_use_anchors_": false
59 | }
60 |
61 | [node name="Label" type="Label" parent="Panel"]
62 | anchor_right = 1.0
63 | anchor_bottom = 1.0
64 | custom_fonts/font = SubResource( 1 )
65 | text = "Congratulations! We vanquished the Aster-570!
66 | As a good strategist you spent just the resources you need.
67 |
68 | Score: %s"
69 | align = 1
70 | valign = 1
71 | percent_visible = 0.0
72 | __meta__ = {
73 | "_edit_use_anchors_": false
74 | }
75 |
76 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
77 | autoplay = "Text"
78 | anims/Text = SubResource( 2 )
79 |
--------------------------------------------------------------------------------
/source/UI/Theme/Montserrat-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/UI/Theme/Montserrat-ExtraBold.ttf
--------------------------------------------------------------------------------
/source/UI/Theme/background_stylebox.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="StyleBoxFlat" format=2]
2 |
3 | [resource]
4 | bg_color = Color( 0.278431, 0.231373, 0.470588, 1 )
5 | border_width_left = 2
6 | border_width_top = 2
7 | border_width_right = 2
8 | border_width_bottom = 2
9 | border_color = Color( 1, 1, 1, 1 )
10 | corner_radius_top_left = 8
11 | corner_radius_top_right = 8
12 | corner_radius_bottom_right = 8
13 | corner_radius_bottom_left = 8
14 |
--------------------------------------------------------------------------------
/source/UI/Theme/button_font.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="DynamicFont" load_steps=2 format=2]
2 |
3 | [ext_resource path="res://UI/Theme/Montserrat-ExtraBold.ttf" type="DynamicFontData" id=1]
4 |
5 | [resource]
6 | size = 14
7 | font_data = ExtResource( 1 )
8 |
--------------------------------------------------------------------------------
/source/UI/Theme/foreground_stylebox.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="StyleBoxFlat" format=2]
2 |
3 | [resource]
4 | bg_color = Color( 0.235294, 0.639216, 0.439216, 1 )
5 | border_width_left = 2
6 | border_width_top = 2
7 | border_width_right = 2
8 | border_width_bottom = 2
9 | border_color = Color( 1, 1, 1, 1 )
10 | corner_radius_top_left = 8
11 | corner_radius_top_right = 8
12 | corner_radius_bottom_right = 8
13 | corner_radius_bottom_left = 8
14 |
--------------------------------------------------------------------------------
/source/UI/Theme/main_font.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="DynamicFont" load_steps=2 format=2]
2 |
3 | [ext_resource path="res://UI/Theme/Montserrat-ExtraBold.ttf" type="DynamicFontData" id=1]
4 |
5 | [resource]
6 | size = 20
7 | font_data = ExtResource( 1 )
8 |
--------------------------------------------------------------------------------
/source/UI/Theme/main_theme.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Theme" load_steps=10 format=2]
2 |
3 | [ext_resource path="res://UI/Theme/main_font.tres" type="DynamicFont" id=1]
4 | [ext_resource path="res://UI/Theme/button_font.tres" type="DynamicFont" id=2]
5 |
6 | [sub_resource type="StyleBoxFlat" id=1]
7 | bg_color = Color( 0.364706, 0.341176, 0.470588, 0.705882 )
8 | border_width_left = 4
9 | border_width_top = 4
10 | border_width_right = 4
11 | border_width_bottom = 4
12 |
13 | [sub_resource type="StyleBoxFlat" id=2]
14 | bg_color = Color( 0.278431, 0.231373, 0.470588, 0.705882 )
15 | border_width_left = 4
16 | border_width_top = 4
17 | border_width_right = 4
18 | border_width_bottom = 4
19 | border_color = Color( 1, 1, 1, 0.705882 )
20 |
21 | [sub_resource type="StyleBoxFlat" id=3]
22 | bg_color = Color( 0.37888, 0.3136, 0.64, 0.705882 )
23 | border_width_left = 4
24 | border_width_top = 4
25 | border_width_right = 4
26 | border_width_bottom = 4
27 | border_color = Color( 0.301961, 0.65098, 1, 0.705882 )
28 |
29 | [sub_resource type="StyleBoxFlat" id=4]
30 | bg_color = Color( 0.278431, 0.231373, 0.470588, 0.705882 )
31 | border_width_left = 4
32 | border_width_top = 4
33 | border_width_right = 4
34 | border_width_bottom = 4
35 | border_color = Color( 0.301961, 0.65098, 1, 0.705882 )
36 |
37 | [sub_resource type="StyleBoxFlat" id=5]
38 | bg_color = Color( 0.18944, 0.1568, 0.32, 0.486275 )
39 | border_width_left = 4
40 | border_width_top = 4
41 | border_width_right = 4
42 | border_width_bottom = 4
43 | border_color = Color( 0.301961, 0.65098, 1, 0.705882 )
44 |
45 | [sub_resource type="StyleBoxLine" id=6]
46 | color = Color( 1, 1, 1, 1 )
47 | thickness = 2
48 |
49 | [sub_resource type="StyleBoxFlat" id=7]
50 | bg_color = Color( 0.278431, 0.231373, 0.470588, 0.705882 )
51 | border_width_left = 4
52 | border_width_top = 4
53 | border_width_right = 4
54 | border_width_bottom = 4
55 | border_color = Color( 0.301961, 0.65098, 1, 0.705882 )
56 | corner_radius_top_left = 8
57 | corner_radius_top_right = 8
58 | corner_radius_bottom_right = 8
59 | corner_radius_bottom_left = 8
60 |
61 | [resource]
62 | default_font = ExtResource( 1 )
63 | Button/colors/font_color = Color( 1, 1, 1, 1 )
64 | Button/colors/font_color_disabled = Color( 0.607843, 0.607843, 0.607843, 1 )
65 | Button/colors/font_color_hover = Color( 1, 1, 1, 1 )
66 | Button/colors/font_color_pressed = Color( 1, 1, 1, 1 )
67 | Button/constants/hseparation = 2
68 | Button/fonts/font = ExtResource( 2 )
69 | Button/styles/disabled = SubResource( 1 )
70 | Button/styles/focus = SubResource( 2 )
71 | Button/styles/hover = SubResource( 3 )
72 | Button/styles/normal = SubResource( 4 )
73 | Button/styles/pressed = SubResource( 5 )
74 | HSeparator/constants/separation = 4
75 | HSeparator/styles/separator = SubResource( 6 )
76 | OptionButton/colors/font_color = Color( 0.88, 0.88, 0.88, 1 )
77 | OptionButton/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 )
78 | OptionButton/colors/font_color_hover = Color( 0.94, 0.94, 0.94, 1 )
79 | OptionButton/colors/font_color_pressed = Color( 1, 1, 1, 1 )
80 | OptionButton/constants/arrow_margin = 2
81 | OptionButton/constants/hseparation = 2
82 | OptionButton/fonts/font = null
83 | OptionButton/icons/arrow = null
84 | OptionButton/styles/disabled = null
85 | OptionButton/styles/focus = null
86 | OptionButton/styles/hover = null
87 | OptionButton/styles/normal = null
88 | OptionButton/styles/pressed = null
89 | Panel/styles/panel = SubResource( 7 )
90 | PanelContainer/styles/panel = SubResource( 7 )
91 |
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/UICooldownBar.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 |
4 | export var gradient: Gradient
5 |
6 | onready var _progress := $TextureProgress
7 | onready var _animator := $AnimationPlayer
8 | onready var _timer := $Timer
9 |
10 |
11 | func _ready() -> void:
12 | set_process(false)
13 | hide()
14 |
15 |
16 | func _process(delta: float) -> void:
17 | _progress.value = _timer.wait_time - _timer.time_left
18 | _progress.tint_progress = gradient.interpolate(_progress.ratio)
19 |
20 |
21 | func start(time: float) -> void:
22 | _timer.start(time)
23 | _progress.max_value = time
24 | _progress.value = 0.0
25 | _animator.playback_speed = 1.0/time
26 | _animator.play("Spin")
27 | set_process(true)
28 | show()
29 |
30 |
31 | func _on_Timer_timeout():
32 | _animator.play("Finish")
33 | set_process(false)
34 |
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/UICooldownBar.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=10 format=2]
2 |
3 | [ext_resource path="res://UI/UICooldownBar/cooldown-bar-progress.png" type="Texture" id=1]
4 | [ext_resource path="res://UI/UICooldownBar/cooldown-bar-over.png" type="Texture" id=2]
5 | [ext_resource path="res://UI/UICooldownBar/clock.png" type="Texture" id=3]
6 | [ext_resource path="res://UI/UICooldownBar/clock-tic.png" type="Texture" id=4]
7 | [ext_resource path="res://UI/UICooldownBar/cooldown-bar-under.png" type="Texture" id=5]
8 | [ext_resource path="res://UI/UICooldownBar/UICooldownBar.gd" type="Script" id=6]
9 |
10 | [sub_resource type="Gradient" id=1]
11 | offsets = PoolRealArray( 0.254682, 0.520599, 0.846442, 1 )
12 | colors = PoolColorArray( 0.921569, 0.337255, 0.294118, 1, 1, 0.568627, 0.4, 1, 1, 0.709804, 0.439216, 1, 1, 1, 1, 1 )
13 |
14 | [sub_resource type="Animation" id=2]
15 | resource_name = "Finish"
16 | length = 0.2
17 | tracks/0/type = "value"
18 | tracks/0/path = NodePath(".:visible")
19 | tracks/0/interp = 1
20 | tracks/0/loop_wrap = true
21 | tracks/0/imported = false
22 | tracks/0/enabled = true
23 | tracks/0/keys = {
24 | "times": PoolRealArray( 0.2 ),
25 | "transitions": PoolRealArray( 1 ),
26 | "update": 1,
27 | "values": [ false ]
28 | }
29 |
30 | [sub_resource type="Animation" id=3]
31 | tracks/0/type = "value"
32 | tracks/0/path = NodePath("Clock/Tic:rect_rotation")
33 | tracks/0/interp = 1
34 | tracks/0/loop_wrap = true
35 | tracks/0/imported = false
36 | tracks/0/enabled = true
37 | tracks/0/keys = {
38 | "times": PoolRealArray( 0, 1 ),
39 | "transitions": PoolRealArray( 1, 1 ),
40 | "update": 0,
41 | "values": [ 0.0, 360.0 ]
42 | }
43 |
44 | [node name="UICooldownBar" type="Control"]
45 | visible = false
46 | margin_right = 144.0
47 | margin_bottom = 24.0
48 | script = ExtResource( 6 )
49 | __meta__ = {
50 | "_edit_use_anchors_": false
51 | }
52 | gradient = SubResource( 1 )
53 |
54 | [node name="TextureProgress" type="TextureProgress" parent="."]
55 | anchor_left = 0.222
56 | anchor_right = 1.0
57 | anchor_bottom = 1.0
58 | margin_left = 0.0319977
59 | step = 0.01
60 | texture_under = ExtResource( 5 )
61 | texture_over = ExtResource( 2 )
62 | texture_progress = ExtResource( 1 )
63 | __meta__ = {
64 | "_edit_use_anchors_": false
65 | }
66 |
67 | [node name="Clock" type="TextureRect" parent="."]
68 | anchor_right = 0.167
69 | anchor_bottom = 1.0
70 | margin_right = -0.0480022
71 | texture = ExtResource( 3 )
72 | expand = true
73 | stretch_mode = 6
74 | __meta__ = {
75 | "_edit_use_anchors_": false
76 | }
77 |
78 | [node name="Tic" type="TextureRect" parent="Clock"]
79 | anchor_left = 0.5
80 | anchor_top = 0.5
81 | anchor_right = 0.5
82 | anchor_bottom = 0.5
83 | margin_left = -2.0
84 | margin_top = -8.0
85 | margin_right = 2.0
86 | rect_rotation = 252.0
87 | rect_pivot_offset = Vector2( 2, 8 )
88 | texture = ExtResource( 4 )
89 | expand = true
90 | stretch_mode = 1
91 | __meta__ = {
92 | "_edit_use_anchors_": false
93 | }
94 |
95 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
96 | anims/Finish = SubResource( 2 )
97 | anims/Spin = SubResource( 3 )
98 |
99 | [node name="Timer" type="Timer" parent="."]
100 |
101 | [connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
102 |
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/clock-tic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/UI/UICooldownBar/clock-tic.png
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/clock-tic.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/clock-tic.png-fcf004a0cb21e95bfb83688239d9146c.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UICooldownBar/clock-tic.png"
13 | dest_files=[ "res://.import/clock-tic.png-fcf004a0cb21e95bfb83688239d9146c.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/UI/UICooldownBar/clock.png
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/clock.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/clock.png-e646f709d1c473b8f555faca30d0b0fd.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UICooldownBar/clock.png"
13 | dest_files=[ "res://.import/clock.png-e646f709d1c473b8f555faca30d0b0fd.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/cooldown-bar-over.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/UI/UICooldownBar/cooldown-bar-over.png
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/cooldown-bar-over.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/cooldown-bar-over.png-139f0f8a8e088eb12a232c8fecc07bf6.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UICooldownBar/cooldown-bar-over.png"
13 | dest_files=[ "res://.import/cooldown-bar-over.png-139f0f8a8e088eb12a232c8fecc07bf6.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/cooldown-bar-progress.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/UI/UICooldownBar/cooldown-bar-progress.png
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/cooldown-bar-progress.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/cooldown-bar-progress.png-4efbbd0ea1e29dd11c8ddd7112fcbf44.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UICooldownBar/cooldown-bar-progress.png"
13 | dest_files=[ "res://.import/cooldown-bar-progress.png-4efbbd0ea1e29dd11c8ddd7112fcbf44.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/cooldown-bar-under.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/UI/UICooldownBar/cooldown-bar-under.png
--------------------------------------------------------------------------------
/source/UI/UICooldownBar/cooldown-bar-under.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/cooldown-bar-under.png-9693085f3ebee638ce0f793ec3efc232.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UICooldownBar/cooldown-bar-under.png"
13 | dest_files=[ "res://.import/cooldown-bar-under.png-9693085f3ebee638ce0f793ec3efc232.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UIGoldPanel.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 |
4 | onready var _label: Label = $Label
5 |
6 | var player: Player setget set_player
7 |
8 | func set_player(new_player: Player) -> void:
9 | player = new_player
10 | player.connect("gold_changed", self, "_update_gold_amount")
11 | _update_gold_amount(player.gold)
12 |
13 |
14 | func _update_gold_amount(new_amount: int) -> void:
15 | _label.text = "Gold: %s" % new_amount
16 |
--------------------------------------------------------------------------------
/source/UI/UIGoldPanel.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://UI/UIGoldPanel.gd" type="Script" id=2]
4 |
5 | [node name="UIGoldPanel" type="Panel"]
6 | margin_right = 224.0
7 | margin_bottom = 64.0
8 | mouse_filter = 2
9 | script = ExtResource( 2 )
10 | __meta__ = {
11 | "_edit_use_anchors_": false
12 | }
13 |
14 | [node name="Label" type="Label" parent="."]
15 | anchor_right = 1.0
16 | anchor_bottom = 1.0
17 | margin_left = 22.0
18 | margin_right = -22.0
19 | size_flags_horizontal = 3
20 | size_flags_vertical = 6
21 | text = "Gold: 1000"
22 | align = 1
23 | valign = 1
24 | __meta__ = {
25 | "_edit_use_anchors_": false
26 | }
27 |
--------------------------------------------------------------------------------
/source/UI/UIHealthBar/UIHealthBar.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://UI/UIHealthBar/heart.svg" type="Texture" id=1]
4 |
5 | [sub_resource type="StyleBoxFlat" id=1]
6 | bg_color = Color( 0.235294, 0.639216, 0.439216, 1 )
7 | border_width_left = 2
8 | border_width_top = 2
9 | border_width_right = 2
10 | border_width_bottom = 2
11 | border_color = Color( 1, 1, 1, 1 )
12 | corner_radius_top_left = 8
13 | corner_radius_top_right = 8
14 | corner_radius_bottom_right = 8
15 | corner_radius_bottom_left = 8
16 |
17 | [sub_resource type="StyleBoxFlat" id=2]
18 | bg_color = Color( 0.278431, 0.231373, 0.470588, 1 )
19 | border_width_left = 2
20 | border_width_top = 2
21 | border_width_right = 2
22 | border_width_bottom = 2
23 | border_color = Color( 1, 1, 1, 1 )
24 | corner_radius_top_left = 8
25 | corner_radius_top_right = 8
26 | corner_radius_bottom_right = 8
27 | corner_radius_bottom_left = 8
28 |
29 | [node name="HealthBar" type="ProgressBar"]
30 | margin_right = 172.0
31 | margin_bottom = 18.0
32 | custom_styles/fg = SubResource( 1 )
33 | custom_styles/bg = SubResource( 2 )
34 | step = 1.0
35 | value = 50.0
36 | percent_visible = false
37 | __meta__ = {
38 | "_edit_use_anchors_": false
39 | }
40 |
41 | [node name="TextureRect" type="TextureRect" parent="."]
42 | margin_left = -56.0
43 | margin_top = -14.0
44 | margin_right = -8.0
45 | margin_bottom = 34.0
46 | texture = ExtResource( 1 )
47 | expand = true
48 | stretch_mode = 6
49 | __meta__ = {
50 | "_edit_use_anchors_": false
51 | }
52 |
--------------------------------------------------------------------------------
/source/UI/UIHealthBar/UITimedHealthBar.gd:
--------------------------------------------------------------------------------
1 | extends ProgressBar
2 |
3 | onready var _timer := $Timer
4 |
5 |
6 | func _on_value_changed(_value: float) -> void:
7 | show()
8 | _timer.start()
9 |
10 |
11 | func _on_Timer_timeout() -> void:
12 | hide()
13 |
--------------------------------------------------------------------------------
/source/UI/UIHealthBar/UITimedHealthBar.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=2]
2 |
3 | [ext_resource path="res://UI/UIHealthBar/heart.svg" type="Texture" id=1]
4 | [ext_resource path="res://UI/UIHealthBar/UITimedHealthBar.gd" type="Script" id=2]
5 |
6 | [sub_resource type="StyleBoxFlat" id=1]
7 | bg_color = Color( 0.235294, 0.639216, 0.439216, 1 )
8 | border_width_left = 2
9 | border_width_top = 2
10 | border_width_right = 2
11 | border_width_bottom = 2
12 | border_color = Color( 1, 1, 1, 1 )
13 | corner_radius_top_left = 8
14 | corner_radius_top_right = 8
15 | corner_radius_bottom_right = 8
16 | corner_radius_bottom_left = 8
17 |
18 | [sub_resource type="StyleBoxFlat" id=2]
19 | bg_color = Color( 0.278431, 0.231373, 0.470588, 1 )
20 | border_width_left = 2
21 | border_width_top = 2
22 | border_width_right = 2
23 | border_width_bottom = 2
24 | border_color = Color( 1, 1, 1, 1 )
25 | corner_radius_top_left = 8
26 | corner_radius_top_right = 8
27 | corner_radius_bottom_right = 8
28 | corner_radius_bottom_left = 8
29 |
30 | [node name="UIHealthBar" type="ProgressBar"]
31 | margin_top = 6.0
32 | margin_right = 192.0
33 | margin_bottom = 24.0
34 | custom_styles/fg = SubResource( 1 )
35 | custom_styles/bg = SubResource( 2 )
36 | value = 50.0
37 | percent_visible = false
38 | script = ExtResource( 2 )
39 | __meta__ = {
40 | "_edit_use_anchors_": false
41 | }
42 |
43 | [node name="TextureRect" type="TextureRect" parent="."]
44 | margin_left = -56.0
45 | margin_top = -14.0
46 | margin_right = -8.0
47 | margin_bottom = 34.0
48 | texture = ExtResource( 1 )
49 | expand = true
50 | stretch_mode = 6
51 | __meta__ = {
52 | "_edit_use_anchors_": false
53 | }
54 |
55 | [node name="Timer" type="Timer" parent="."]
56 | wait_time = 0.5
57 |
58 | [connection signal="value_changed" from="." to="." method="_on_value_changed"]
59 | [connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
60 |
--------------------------------------------------------------------------------
/source/UI/UIHealthBar/heart.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/heart.svg-49f6cf64586eb6a039065531a8f12ab4.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UIHealthBar/heart.svg"
13 | dest_files=[ "res://.import/heart.svg-49f6cf64586eb6a039065531a8f12ab4.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UIScreenOverlay.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 | onready var _anim_player := $AnimationPlayer
4 |
5 |
6 | func play_win() -> void:
7 | _anim_player.play("PlayerWon")
8 | yield(_anim_player, "animation_finished")
9 |
10 |
11 | func play_lost() -> void:
12 | _anim_player.play("PlayerLost")
13 | yield(_anim_player, "animation_finished")
14 |
15 |
16 | func play_wave_start() -> void:
17 | _anim_player.play("WaveStarting")
18 | yield(_anim_player, "animation_finished")
19 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/UITowerPurchaseButton.gd:
--------------------------------------------------------------------------------
1 | extends TextureButton
2 |
3 | signal tower_purchased(tower_scene)
4 |
5 | export var tower_scene: PackedScene
6 |
7 | onready var _label := $Label
8 |
9 | var tower_cost = 0
10 |
11 |
12 | func _ready() -> void:
13 | setup_tower_data()
14 |
15 |
16 | # Instance the Tower to access its data, e.g. cost and description
17 | func setup_tower_data() -> void:
18 | var tower: Tower = tower_scene.instance()
19 | tower_cost = tower.cost
20 | _label.text = "Cost: %s" % tower_cost
21 | tower.queue_free()
22 |
23 |
24 | func _pressed() -> void:
25 | emit_signal("tower_purchased", tower_scene)
26 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/UITowerPurchaseButton.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=8 format=2]
2 |
3 | [ext_resource path="res://UI/UITowerShop/tower-icon-normal.svg" type="Texture" id=1]
4 | [ext_resource path="res://UI/UITowerShop/UITowerPurchaseButton.gd" type="Script" id=2]
5 | [ext_resource path="res://UI/UITowerShop/tower-icon-hover.svg" type="Texture" id=3]
6 | [ext_resource path="res://UI/UITowerShop/tower-icon-pressed.svg" type="Texture" id=4]
7 | [ext_resource path="res://Objects/Towers/Tower.tscn" type="PackedScene" id=5]
8 | [ext_resource path="res://UI/UITowerShop/tower-icon-disabled.svg" type="Texture" id=6]
9 | [ext_resource path="res://UI/UITowerShop/tower-icon-focused.svg" type="Texture" id=7]
10 |
11 | [node name="UITowerPurchaseButton" type="TextureButton"]
12 | margin_right = 64.0
13 | margin_bottom = 64.0
14 | rect_min_size = Vector2( 64, 64 )
15 | size_flags_horizontal = 3
16 | size_flags_vertical = 3
17 | action_mode = 0
18 | enabled_focus_mode = 0
19 | texture_normal = ExtResource( 1 )
20 | texture_pressed = ExtResource( 4 )
21 | texture_hover = ExtResource( 3 )
22 | texture_disabled = ExtResource( 6 )
23 | texture_focused = ExtResource( 7 )
24 | expand = true
25 | stretch_mode = 5
26 | script = ExtResource( 2 )
27 | __meta__ = {
28 | "_edit_use_anchors_": false
29 | }
30 | tower_scene = ExtResource( 5 )
31 |
32 | [node name="Label" type="Label" parent="."]
33 | anchor_top = 1.0
34 | anchor_right = 1.0
35 | anchor_bottom = 1.0
36 | margin_left = -40.0
37 | margin_top = 16.0
38 | margin_right = 40.0
39 | margin_bottom = 48.0
40 | text = "Cost: 100"
41 | align = 1
42 | valign = 1
43 | autowrap = true
44 | __meta__ = {
45 | "_edit_use_anchors_": false
46 | }
47 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/UITowerShop.gd:
--------------------------------------------------------------------------------
1 | class_name UITowerShop
2 | extends Panel
3 |
4 | signal tower_purchased(tower)
5 |
6 | onready var _buttons: Array = $HBoxContainer.get_children()
7 |
8 | var player: Player setget set_player
9 |
10 |
11 | func _ready() -> void:
12 | for button in _buttons:
13 | button.connect("tower_purchased", self, "_on_TowerPurchaseButton_tower_purchased")
14 |
15 |
16 | func set_player(new_player: Player) -> void:
17 | player = new_player
18 | player.connect("gold_changed", self, "_on_Player_gold_changed")
19 |
20 |
21 | func _on_TowerPurchaseButton_tower_purchased(tower_scene: PackedScene) -> void:
22 | var tower: Tower = tower_scene.instance()
23 |
24 | tower.connect("sold", self, "_on_Tower_sold")
25 | emit_signal("tower_purchased", tower)
26 |
27 |
28 | func _on_TowerPlacer_tower_placed(tower: Tower) -> void:
29 | player.gold -= tower.cost
30 |
31 |
32 | func _on_Tower_sold(price: int, _position: Vector2) -> void:
33 | player.gold += price
34 |
35 |
36 | func _on_Player_gold_changed(gold_amount: int) -> void:
37 | for button in _buttons:
38 | button.disabled = button.tower_cost > gold_amount
39 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/UITowerShop.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=2]
2 |
3 | [ext_resource path="res://Objects/Towers/BombTower.tscn" type="PackedScene" id=1]
4 | [ext_resource path="res://Objects/Towers/RifleTower.tscn" type="PackedScene" id=2]
5 | [ext_resource path="res://UI/UITowerShop/UITowerShop.gd" type="Script" id=3]
6 | [ext_resource path="res://UI/UITowerShop/UITowerPurchaseButton.tscn" type="PackedScene" id=6]
7 |
8 | [node name="UITowerShop" type="Panel"]
9 | anchor_left = 0.5
10 | anchor_top = 1.0
11 | anchor_right = 0.5
12 | anchor_bottom = 1.0
13 | margin_left = -160.0
14 | margin_top = -220.0
15 | margin_right = 160.0
16 | margin_bottom = -36.0
17 | rect_min_size = Vector2( 320, 184 )
18 | mouse_filter = 2
19 | script = ExtResource( 3 )
20 | __meta__ = {
21 | "_edit_use_anchors_": false
22 | }
23 |
24 | [node name="Label" type="Label" parent="."]
25 | anchor_left = 0.5
26 | anchor_top = 0.5
27 | anchor_right = 0.5
28 | anchor_bottom = 0.5
29 | margin_left = -128.0
30 | margin_top = -72.0
31 | margin_right = 128.0
32 | margin_bottom = -56.0
33 | text = "Purchase new towers"
34 | align = 1
35 | valign = 1
36 | __meta__ = {
37 | "_edit_use_anchors_": false
38 | }
39 |
40 | [node name="HBoxContainer" type="HBoxContainer" parent="."]
41 | anchor_left = 0.5
42 | anchor_top = 0.5
43 | anchor_right = 0.5
44 | anchor_bottom = 0.5
45 | margin_left = -128.0
46 | margin_top = -32.0
47 | margin_right = 128.0
48 | margin_bottom = 40.0
49 | custom_constants/separation = 16
50 | alignment = 1
51 | __meta__ = {
52 | "_edit_use_anchors_": false
53 | }
54 |
55 | [node name="UITowerPurchaseButton" parent="HBoxContainer" instance=ExtResource( 6 )]
56 | margin_right = 120.0
57 | margin_bottom = 72.0
58 | hint_tooltip = "Standard tower. Shoots bullets at a target direction.
59 | "
60 | focus_mode = 0
61 | mouse_filter = 1
62 | tower_scene = ExtResource( 2 )
63 |
64 | [node name="UITowerPurchaseButton2" parent="HBoxContainer" instance=ExtResource( 6 )]
65 | margin_left = 136.0
66 | margin_right = 256.0
67 | margin_bottom = 72.0
68 | hint_tooltip = "Bomb tower. Shoots a bomb at a target position that hits every enemy inside its explosion area.
69 | "
70 | focus_mode = 0
71 | mouse_filter = 1
72 | tower_scene = ExtResource( 1 )
73 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/tower-icon-disabled.svg:
--------------------------------------------------------------------------------
1 |
2 |
90 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/tower-icon-disabled.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tower-icon-disabled.svg-62c4df5afaef7403c38ea7613fee01a0.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UITowerShop/tower-icon-disabled.svg"
13 | dest_files=[ "res://.import/tower-icon-disabled.svg-62c4df5afaef7403c38ea7613fee01a0.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/tower-icon-focused.svg:
--------------------------------------------------------------------------------
1 |
2 |
90 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/tower-icon-focused.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tower-icon-focused.svg-e45f7d0f6fc6495dcb36beb0c612cd09.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UITowerShop/tower-icon-focused.svg"
13 | dest_files=[ "res://.import/tower-icon-focused.svg-e45f7d0f6fc6495dcb36beb0c612cd09.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/tower-icon-hover.svg:
--------------------------------------------------------------------------------
1 |
2 |
90 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/tower-icon-hover.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tower-icon-hover.svg-e3374d23a1e60195dc22da7d76b6bd7c.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UITowerShop/tower-icon-hover.svg"
13 | dest_files=[ "res://.import/tower-icon-hover.svg-e3374d23a1e60195dc22da7d76b6bd7c.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/tower-icon-normal.svg:
--------------------------------------------------------------------------------
1 |
2 |
90 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/tower-icon-normal.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tower-icon-normal.svg-54029b396714c9a0bc62fb03ce535dbe.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UITowerShop/tower-icon-normal.svg"
13 | dest_files=[ "res://.import/tower-icon-normal.svg-54029b396714c9a0bc62fb03ce535dbe.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/tower-icon-pressed.svg:
--------------------------------------------------------------------------------
1 |
2 |
90 |
--------------------------------------------------------------------------------
/source/UI/UITowerShop/tower-icon-pressed.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tower-icon-pressed.svg-b6c90a05f9abb921648be57d23811288.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UITowerShop/tower-icon-pressed.svg"
13 | dest_files=[ "res://.import/tower-icon-pressed.svg-b6c90a05f9abb921648be57d23811288.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/UI/UIUnit/UIUnit.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 |
4 | onready var _anim_player := $AnimationPlayer
5 |
6 | func appear() -> void:
7 | _anim_player.play("appear")
8 |
9 |
10 | func disappear() -> void:
11 | _anim_player.play("disappear")
12 |
--------------------------------------------------------------------------------
/source/UI/UIUnit/UIUnit.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://UI/UIUnit/UIUnit.gd" type="Script" id=1]
4 |
5 | [sub_resource type="Animation" id=3]
6 | resource_name = "appear"
7 | length = 0.3
8 | tracks/0/type = "value"
9 | tracks/0/path = NodePath(".:rect_scale")
10 | tracks/0/interp = 1
11 | tracks/0/loop_wrap = true
12 | tracks/0/imported = false
13 | tracks/0/enabled = true
14 | tracks/0/keys = {
15 | "times": PoolRealArray( 0, 0.2, 0.3 ),
16 | "transitions": PoolRealArray( 0.5, 1, 1 ),
17 | "update": 0,
18 | "values": [ Vector2( 0, 0 ), Vector2( 1.2, 1.2 ), Vector2( 1, 1 ) ]
19 | }
20 |
21 | [sub_resource type="Animation" id=2]
22 | resource_name = "disappear"
23 | length = 0.3
24 | tracks/0/type = "value"
25 | tracks/0/path = NodePath(".:rect_scale")
26 | tracks/0/interp = 1
27 | tracks/0/loop_wrap = true
28 | tracks/0/imported = false
29 | tracks/0/enabled = true
30 | tracks/0/keys = {
31 | "times": PoolRealArray( 0, 0.1, 0.3 ),
32 | "transitions": PoolRealArray( 0.5, 0.5, 0.5 ),
33 | "update": 0,
34 | "values": [ Vector2( 1, 1 ), Vector2( 1.2, 1.2 ), Vector2( 0, 0 ) ]
35 | }
36 |
37 | [node name="Interface" type="Control"]
38 | rect_scale = Vector2( 1e-05, 1e-05 )
39 | mouse_filter = 2
40 | script = ExtResource( 1 )
41 | __meta__ = {
42 | "_edit_use_anchors_": false
43 | }
44 |
45 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
46 | anims/appear = SubResource( 3 )
47 | anims/disappear = SubResource( 2 )
48 |
--------------------------------------------------------------------------------
/source/UI/UIUpgradeShop/UIUpgradeButton.gd:
--------------------------------------------------------------------------------
1 | class_name UIUpgradeButton
2 | extends Button
3 |
4 |
5 | func update_display(upgrade: Upgrade, player_gold: int) -> void:
6 | text = "%s: %sg" % [upgrade.display_name, upgrade.cost]
7 | hint_tooltip = upgrade.description
8 | disabled = player_gold < upgrade.cost
9 |
--------------------------------------------------------------------------------
/source/UI/UIUpgradeShop/UIUpgradeButton.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://UI/UIUpgradeShop/UIUpgradeButton.gd" type="Script" id=1]
4 |
5 | [node name="UIUpgradeButton" type="Button"]
6 | margin_right = 224.0
7 | margin_bottom = 34.0
8 | custom_constants/hseparation = 4
9 | text = "%s: %sg"
10 | script = ExtResource( 1 )
11 | __meta__ = {
12 | "_edit_use_anchors_": false
13 | }
14 |
--------------------------------------------------------------------------------
/source/UI/UIUpgradeShop/UIUpgradeShop.gd:
--------------------------------------------------------------------------------
1 | class_name UpgradeShop
2 | extends Control
3 |
4 | export var _upgrade_button_scene: PackedScene
5 |
6 | onready var _container := $Panel/VBoxContainer
7 | onready var _anim_player := $AnimationPlayer
8 | onready var _panel := $Panel
9 |
10 | var player: Player
11 |
12 |
13 | func appear() -> void:
14 | # Reset rotation to appear at tower's top portion
15 | rect_rotation = -90
16 | _panel.rect_rotation = 90
17 |
18 | # Rotate to always display the panel on screen. Fix cases where
19 | # players place towers near/at screen's edges
20 | if not get_viewport_rect().encloses(_panel.get_global_rect()):
21 | _fit_panel_in_view()
22 | _anim_player.play("Appear")
23 |
24 |
25 | func disappear() -> void:
26 | _anim_player.play("Disappear")
27 |
28 |
29 | func add_upgrade_button(upgrade: Upgrade) -> void:
30 | var button: UIUpgradeButton = _upgrade_button_scene.instance()
31 | button.connect("pressed", self, "_on_UIUpgradeButton_pressed", [button, upgrade])
32 | button.update_display(upgrade, player.gold)
33 |
34 | _container.add_child(button)
35 |
36 |
37 | func _update(tower: Tower) -> void:
38 | rect_global_position = tower.global_position
39 |
40 | for child in _container.get_children():
41 | child.queue_free()
42 |
43 | for upgrade in tower.get_upgrades():
44 | add_upgrade_button(upgrade)
45 |
46 |
47 | # Uses rotation to ensure the interface is always in the view.
48 | func _fit_panel_in_view() -> void:
49 | var center := get_viewport_rect().size * 0.5
50 | var angle := center.angle_to_point(rect_global_position - rect_pivot_offset)
51 | # Snap angle to 45 degrees increment
52 | angle = round(angle / (PI / 4)) * (PI / 4)
53 |
54 | rect_rotation = rad2deg(angle)
55 | _panel.rect_rotation = - rect_rotation
56 |
57 |
58 | func _on_TowerPlacer_tower_placed(tower: Tower) -> void:
59 | tower.connect("selected", self, "_on_Tower_selected", [tower])
60 | tower.connect("sold", self, "_on_Tower_sold")
61 |
62 |
63 | func _on_Tower_selected(selected: bool, tower: Tower) -> void:
64 | _update(tower)
65 |
66 | if selected:
67 | appear()
68 | else:
69 | disappear()
70 |
71 |
72 | func _on_Tower_sold(_price: int, place: Vector2) -> void:
73 | disappear()
74 |
75 |
76 | func _on_UIUpgradeButton_pressed(button: UIUpgradeButton, upgrade: Upgrade) -> void:
77 | if player.gold < upgrade.cost:
78 | return
79 | player.gold -= upgrade.cost
80 | upgrade.apply()
81 | button.update_display(upgrade, player.gold)
82 |
--------------------------------------------------------------------------------
/source/UI/UIUpgradeShop/UIUpgradeShop.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=2]
2 |
3 | [ext_resource path="res://UI/UIUpgradeShop/UIUpgradeShop.gd" type="Script" id=1]
4 | [ext_resource path="res://UI/UIUpgradeShop/UIUpgradeButton.tscn" type="PackedScene" id=2]
5 |
6 | [sub_resource type="Animation" id=1]
7 | resource_name = "Appear"
8 | length = 0.3
9 | step = 0.05
10 | tracks/0/type = "value"
11 | tracks/0/path = NodePath("Panel:rect_scale")
12 | tracks/0/interp = 1
13 | tracks/0/loop_wrap = true
14 | tracks/0/imported = false
15 | tracks/0/enabled = true
16 | tracks/0/keys = {
17 | "times": PoolRealArray( 0, 0.15, 0.3 ),
18 | "transitions": PoolRealArray( 0.5, 0.5, 1 ),
19 | "update": 0,
20 | "values": [ Vector2( 1e-05, 1e-05 ), Vector2( 0.05, 1 ), Vector2( 1, 1 ) ]
21 | }
22 |
23 | [sub_resource type="Animation" id=2]
24 | resource_name = "Disappear"
25 | length = 0.3
26 | step = 0.05
27 | tracks/0/type = "value"
28 | tracks/0/path = NodePath("Panel:rect_scale")
29 | tracks/0/interp = 1
30 | tracks/0/loop_wrap = true
31 | tracks/0/imported = false
32 | tracks/0/enabled = true
33 | tracks/0/keys = {
34 | "times": PoolRealArray( 0, 0.15, 0.3 ),
35 | "transitions": PoolRealArray( 0.5, 0.5, 0.5 ),
36 | "update": 0,
37 | "values": [ Vector2( 1, 1 ), Vector2( 0.05, 1 ), Vector2( 1e-05, 1e-05 ) ]
38 | }
39 |
40 | [node name="UIUpgradeShop" type="Control"]
41 | rect_pivot_offset = Vector2( 32, 32 )
42 | mouse_filter = 2
43 | script = ExtResource( 1 )
44 | __meta__ = {
45 | "_edit_use_anchors_": false
46 | }
47 | _upgrade_button_scene = ExtResource( 2 )
48 |
49 | [node name="Panel" type="Panel" parent="."]
50 | margin_left = -96.0
51 | margin_top = -350.0
52 | margin_right = 160.0
53 | margin_bottom = -30.0
54 | rect_pivot_offset = Vector2( 128, 160 )
55 | __meta__ = {
56 | "_edit_use_anchors_": false
57 | }
58 |
59 | [node name="Label" type="Label" parent="Panel"]
60 | anchor_right = 1.0
61 | margin_left = 16.0
62 | margin_top = 16.0
63 | margin_right = -16.0
64 | margin_bottom = 64.0
65 | text = "Upgrades"
66 | align = 1
67 | valign = 1
68 | __meta__ = {
69 | "_edit_use_anchors_": false
70 | }
71 |
72 | [node name="HSeparator" type="HSeparator" parent="Panel"]
73 | anchor_left = 0.5
74 | anchor_right = 0.5
75 | margin_left = -96.0
76 | margin_top = 64.0
77 | margin_right = 96.0
78 | margin_bottom = 72.0
79 | __meta__ = {
80 | "_edit_use_anchors_": false
81 | }
82 |
83 | [node name="VBoxContainer" type="VBoxContainer" parent="Panel"]
84 | anchor_top = 1.0
85 | anchor_right = 1.0
86 | anchor_bottom = 1.0
87 | margin_left = 16.0
88 | margin_top = -240.0
89 | margin_right = -16.0
90 | margin_bottom = -16.0
91 | size_flags_horizontal = 3
92 | size_flags_vertical = 3
93 | __meta__ = {
94 | "_edit_use_anchors_": false
95 | }
96 |
97 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
98 | anims/Appear = SubResource( 1 )
99 | anims/Disappear = SubResource( 2 )
100 |
--------------------------------------------------------------------------------
/source/VFX/Explosions/SmallExplosion.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=7 format=2]
2 |
3 | [ext_resource path="res://VFX/Explosions/white_glowing_circle.png" type="Texture" id=1]
4 |
5 | [sub_resource type="Gradient" id=1]
6 | offsets = PoolRealArray( 0.788043, 1 )
7 | colors = PoolColorArray( 1, 1, 1, 1, 1, 1, 1, 0 )
8 |
9 | [sub_resource type="GradientTexture" id=2]
10 | gradient = SubResource( 1 )
11 |
12 | [sub_resource type="Curve" id=3]
13 | _data = [ Vector2( 0, 0 ), 0.0, 0.0, 0, 0, Vector2( 1, 0.954545 ), 0.0, 0.0, 0, 0 ]
14 |
15 | [sub_resource type="CurveTexture" id=4]
16 | curve = SubResource( 3 )
17 |
18 | [sub_resource type="ParticlesMaterial" id=5]
19 | emission_shape = 1
20 | emission_sphere_radius = 20.0
21 | flag_disable_z = true
22 | spread = 180.0
23 | gravity = Vector3( 0, 0, 0 )
24 | initial_velocity = 800.0
25 | orbit_velocity = 0.0
26 | orbit_velocity_random = 0.0
27 | damping = 2000.0
28 | scale = 0.5
29 | scale_random = 0.3
30 | scale_curve = SubResource( 4 )
31 | color_ramp = SubResource( 2 )
32 |
33 | [node name="SmallExplosion" type="Particles2D"]
34 | modulate = Color( 1.5, 1.5, 1.5, 1 )
35 | self_modulate = Color( 0.34902, 0.67451, 1, 1 )
36 | emitting = false
37 | amount = 16
38 | lifetime = 0.1
39 | explosiveness = 0.9
40 | local_coords = false
41 | process_material = SubResource( 5 )
42 | texture = ExtResource( 1 )
43 |
--------------------------------------------------------------------------------
/source/VFX/Explosions/explosion_gradient.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="GradientTexture" load_steps=2 format=2]
2 |
3 | [sub_resource type="Gradient" id=1]
4 | offsets = PoolRealArray( 0, 0.185185, 0.533333, 0.82963, 1 )
5 | colors = PoolColorArray( 1, 1, 1, 1, 1, 0.788235, 0.309804, 1, 0.980392, 0.419608, 0.211765, 1, 0.831373, 0.219608, 0.219608, 1, 0.831373, 0.219608, 0.219608, 0 )
6 |
7 | [resource]
8 | gradient = SubResource( 1 )
9 |
--------------------------------------------------------------------------------
/source/VFX/Explosions/puff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/VFX/Explosions/puff.png
--------------------------------------------------------------------------------
/source/VFX/Explosions/puff.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/puff.png-a97a2dbe05e458d4ca98d34a9d7f4da4.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://VFX/Explosions/puff.png"
13 | dest_files=[ "res://.import/puff.png-a97a2dbe05e458d4ca98d34a9d7f4da4.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/VFX/Explosions/puff_smooth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/VFX/Explosions/puff_smooth.png
--------------------------------------------------------------------------------
/source/VFX/Explosions/puff_smooth.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/puff_smooth.png-3930a30f50be4c9c75043e5a80de9680.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://VFX/Explosions/puff_smooth.png"
13 | dest_files=[ "res://.import/puff_smooth.png-3930a30f50be4c9c75043e5a80de9680.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/VFX/Explosions/scraps_gradient.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="GradientTexture" load_steps=2 format=2]
2 |
3 | [sub_resource type="Gradient" id=1]
4 | offsets = PoolRealArray( 0, 0.155894, 0.505017, 0.8327, 1 )
5 | colors = PoolColorArray( 0.258824, 0.25098, 0.25098, 1, 0.722656, 0.118153, 0.118153, 1, 0.855469, 0.323879, 0.126857, 1, 1, 0.788235, 0.309804, 0.717647, 1, 1, 1, 0 )
6 |
7 | [resource]
8 | gradient = SubResource( 1 )
9 |
--------------------------------------------------------------------------------
/source/VFX/Explosions/sparkle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/VFX/Explosions/sparkle.png
--------------------------------------------------------------------------------
/source/VFX/Explosions/sparkle.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/sparkle.png-9b6c5a08d7289a4e0580cfb7b180137f.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://VFX/Explosions/sparkle.png"
13 | dest_files=[ "res://.import/sparkle.png-9b6c5a08d7289a4e0580cfb7b180137f.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/VFX/Explosions/white_glowing_circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/VFX/Explosions/white_glowing_circle.png
--------------------------------------------------------------------------------
/source/VFX/Explosions/white_glowing_circle.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/white_glowing_circle.png-18c903a04f43dc51f1b475c2128e7106.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://VFX/Explosions/white_glowing_circle.png"
13 | dest_files=[ "res://.import/white_glowing_circle.png-18c903a04f43dc51f1b475c2128e7106.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/VFX/PathPreview.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=2]
2 |
3 | [sub_resource type="GDScript" id=1]
4 | script/source = "extends Line2D
5 |
6 |
7 | onready var _tween := $Tween
8 | onready var _timer := $Timer
9 |
10 | func fade_out() -> void:
11 | var transparent := modulate
12 | transparent.a = 0.0
13 | _tween.interpolate_property(self, \"modulate\", modulate, transparent, 0.5)
14 | _tween.start()
15 | _timer.start(0.5 / (get_point_count() -1))
16 |
17 |
18 | func fade_in() -> void:
19 | var opaque := modulate
20 | opaque.a = 1.0
21 | _tween.interpolate_property(self, \"modulate\", modulate, opaque, 0.5)
22 | _tween.start()
23 |
24 |
25 | func _on_Timer_timeout() -> void:
26 | if get_point_count() > 0:
27 | remove_point(get_point_count() -1)
28 | else:
29 | _timer.stop()
30 | "
31 |
32 | [sub_resource type="Animation" id=2]
33 | resource_name = "glow"
34 | loop = true
35 | step = 0.05
36 | tracks/0/type = "value"
37 | tracks/0/path = NodePath(".:modulate")
38 | tracks/0/interp = 1
39 | tracks/0/loop_wrap = true
40 | tracks/0/imported = false
41 | tracks/0/enabled = true
42 | tracks/0/keys = {
43 | "times": PoolRealArray( 0, 0.5 ),
44 | "transitions": PoolRealArray( 1, 1 ),
45 | "update": 0,
46 | "values": [ Color( 1, 1, 1, 1 ), Color( 1, 0.72549, 0.72549, 1 ) ]
47 | }
48 |
49 | [node name="PathPreview" type="Line2D"]
50 | width = 20.0
51 | default_color = Color( 1, 0.415686, 0.160784, 1 )
52 | joint_mode = 2
53 | script = SubResource( 1 )
54 |
55 | [node name="Tween" type="Tween" parent="."]
56 |
57 | [node name="Timer" type="Timer" parent="."]
58 |
59 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
60 | autoplay = "glow"
61 | anims/glow = SubResource( 2 )
62 |
63 | [connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
64 |
--------------------------------------------------------------------------------
/source/default_env.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Environment" load_steps=2 format=2]
2 |
3 | [sub_resource type="ProceduralSky" id=1]
4 |
5 | [resource]
6 | background_mode = 2
7 | background_sky = SubResource( 1 )
8 |
--------------------------------------------------------------------------------
/source/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/source/icon.png
--------------------------------------------------------------------------------
/source/icon.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://icon.png"
13 | dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/source/sprite-sheet.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/sprite-sheet.svg-770a08d3ddf9b41899e4553fd12331ab.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://sprite-sheet.svg"
13 | dest_files=[ "res://.import/sprite-sheet.svg-770a08d3ddf9b41899e4553fd12331ab.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/Actors/Enemies/particle.svg:
--------------------------------------------------------------------------------
1 |
2 |
63 |
--------------------------------------------------------------------------------
/start-project/Actors/Enemies/particle.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/particle.svg-6a2c10808518a648f8e5ec8f4688e443.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Actors/Enemies/particle.svg"
13 | dest_files=[ "res://.import/particle.svg-6a2c10808518a648f8e5ec8f4688e443.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/Areas/AsteroidSurface/rocks-and-craters.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/rocks-and-craters.svg-d039ad5957be00f78334d088af06d900.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Areas/AsteroidSurface/rocks-and-craters.svg"
13 | dest_files=[ "res://.import/rocks-and-craters.svg-d039ad5957be00f78334d088af06d900.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/Areas/AsteroidSurface/sand.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/sand.svg-8176aa2958b49ade8514e76ba5a92581.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Areas/AsteroidSurface/sand.svg"
13 | dest_files=[ "res://.import/sand.svg-8176aa2958b49ade8514e76ba5a92581.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/Areas/AsteroidSurface/tileset.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="TileSet" load_steps=4 format=2]
2 |
3 | [ext_resource path="res://Areas/AsteroidSurface/rocks-and-craters.svg" type="Texture" id=2]
4 | [ext_resource path="res://Areas/AsteroidSurface/walkable-path.svg" type="Texture" id=3]
5 | [ext_resource path="res://Areas/AsteroidSurface/sand.svg" type="Texture" id=4]
6 |
7 | [resource]
8 | 1/name = "Non Placeable Cells"
9 | 1/texture = ExtResource( 2 )
10 | 1/tex_offset = Vector2( 0, 0 )
11 | 1/modulate = Color( 1, 1, 1, 1 )
12 | 1/region = Rect2( 0, 0, 192, 192 )
13 | 1/tile_mode = 2
14 | 1/autotile/icon_coordinate = Vector2( 1, 1 )
15 | 1/autotile/tile_size = Vector2( 64, 64 )
16 | 1/autotile/spacing = 0
17 | 1/autotile/occluder_map = [ ]
18 | 1/autotile/navpoly_map = [ ]
19 | 1/autotile/priority_map = [ ]
20 | 1/autotile/z_index_map = [ ]
21 | 1/occluder_offset = Vector2( 0, 0 )
22 | 1/navigation_offset = Vector2( 0, 0 )
23 | 1/shape_offset = Vector2( 0, 0 )
24 | 1/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
25 | 1/shape_one_way = false
26 | 1/shape_one_way_margin = 0.0
27 | 1/shapes = [ ]
28 | 1/z_index = 0
29 | 2/name = "Enemy Walking Path"
30 | 2/texture = ExtResource( 3 )
31 | 2/tex_offset = Vector2( 0, 0 )
32 | 2/modulate = Color( 1, 1, 1, 1 )
33 | 2/region = Rect2( 0, 0, 384, 384 )
34 | 2/tile_mode = 1
35 | 2/autotile/bitmask_mode = 1
36 | 2/autotile/bitmask_flags = [ Vector2( 0, 1 ), 48, Vector2( 0, 2 ), 56, Vector2( 0, 3 ), 432, Vector2( 0, 4 ), 438, Vector2( 0, 5 ), 54, Vector2( 1, 0 ), 144, Vector2( 1, 1 ), 186, Vector2( 1, 2 ), 18, Vector2( 1, 3 ), 504, Vector2( 1, 4 ), 511, Vector2( 1, 5 ), 63, Vector2( 2, 1 ), 24, Vector2( 2, 2 ), 146, Vector2( 2, 3 ), 216, Vector2( 2, 4 ), 219, Vector2( 2, 5 ), 27, Vector2( 3, 0 ), 176, Vector2( 3, 1 ), 50, Vector2( 3, 2 ), 184, Vector2( 3, 3 ), 178, Vector2( 3, 4 ), 16, Vector2( 4, 0 ), 152, Vector2( 4, 1 ), 26, Vector2( 4, 2 ), 58, Vector2( 4, 3 ), 154 ]
37 | 2/autotile/icon_coordinate = Vector2( 3, 4 )
38 | 2/autotile/tile_size = Vector2( 64, 64 )
39 | 2/autotile/spacing = 0
40 | 2/autotile/occluder_map = [ ]
41 | 2/autotile/navpoly_map = [ ]
42 | 2/autotile/priority_map = [ ]
43 | 2/autotile/z_index_map = [ ]
44 | 2/occluder_offset = Vector2( 0, 0 )
45 | 2/navigation_offset = Vector2( 0, 0 )
46 | 2/shape_offset = Vector2( 0, 0 )
47 | 2/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
48 | 2/shape_one_way = false
49 | 2/shape_one_way_margin = 0.0
50 | 2/shapes = [ ]
51 | 2/z_index = 0
52 | 3/name = "Tower Placeable Cell"
53 | 3/texture = ExtResource( 4 )
54 | 3/tex_offset = Vector2( 0, 0 )
55 | 3/modulate = Color( 1, 1, 1, 1 )
56 | 3/region = Rect2( 0, 0, 64, 64 )
57 | 3/tile_mode = 0
58 | 3/occluder_offset = Vector2( 0, 0 )
59 | 3/navigation_offset = Vector2( 0, 0 )
60 | 3/shape_offset = Vector2( 0, 0 )
61 | 3/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
62 | 3/shape_one_way = false
63 | 3/shape_one_way_margin = 0.0
64 | 3/shapes = [ ]
65 | 3/z_index = 0
66 |
--------------------------------------------------------------------------------
/start-project/Areas/AsteroidSurface/walkable-path.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/walkable-path.svg-ecaa9a460c48ad8740e02db5f09971a1.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Areas/AsteroidSurface/walkable-path.svg"
13 | dest_files=[ "res://.import/walkable-path.svg-ecaa9a460c48ad8740e02db5f09971a1.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/Objects/PlayerBase/CutoutSprites.gd:
--------------------------------------------------------------------------------
1 | extends Node2D
2 |
3 |
4 | onready var _anim_player := $AnimationPlayer
5 |
6 | func play(animation: String) -> void:
7 | _anim_player.play(animation)
8 |
--------------------------------------------------------------------------------
/start-project/Objects/Weapon2D/RangePreview/RangePreview.gd:
--------------------------------------------------------------------------------
1 | extends Sprite
2 |
3 | export var radius := 100.0
4 | export var tween_duration := 0.5
5 |
6 | onready var _tween := $Tween
7 |
8 |
9 | func appear() -> void:
10 | var ratio = radius / texture.get_width()
11 | var final_scale = Vector2(ratio, ratio) * 2.0
12 |
13 | _tween.stop_all()
14 |
15 | _tween.interpolate_property(
16 | self, "scale", scale, final_scale, tween_duration, Tween.TRANS_QUINT, Tween.EASE_OUT
17 | )
18 | _tween.interpolate_property(
19 | self, "modulate", modulate, Color(1, 1, 1, 1), tween_duration)
20 | _tween.start()
21 |
22 |
23 | func disappear() -> void:
24 | if _tween.is_active():
25 | _tween.stop_all()
26 |
27 | _tween.interpolate_property(
28 | self, "scale", scale, Vector2.ZERO, tween_duration, Tween.TRANS_BACK, Tween.EASE_IN
29 | )
30 | _tween.interpolate_property(
31 | self, "modulate", modulate, Color(1, 1, 1, 0), tween_duration * 2.0)
32 | _tween.start()
33 |
--------------------------------------------------------------------------------
/start-project/Objects/Weapon2D/RangePreview/RangePreview.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=2]
2 |
3 | [ext_resource path="res://Objects/Weapon2D/RangePreview/range-preview.svg" type="Texture" id=1]
4 | [ext_resource path="res://Objects/Weapon2D/RangePreview/RangePreview.gd" type="Script" id=2]
5 |
6 | [node name="RangePreview" type="Sprite"]
7 | modulate = Color( 1, 1, 1, 0 )
8 | texture = ExtResource( 1 )
9 | script = ExtResource( 2 )
10 | radius = 50.0
11 |
12 | [node name="Tween" type="Tween" parent="."]
13 |
--------------------------------------------------------------------------------
/start-project/Objects/Weapon2D/RangePreview/range-preview.svg:
--------------------------------------------------------------------------------
1 |
2 |
82 |
--------------------------------------------------------------------------------
/start-project/Objects/Weapon2D/RangePreview/range-preview.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/range-preview.svg-3ddcdc213d26cf3b747e41044dcee9ea.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Objects/Weapon2D/RangePreview/range-preview.svg"
13 | dest_files=[ "res://.import/range-preview.svg-3ddcdc213d26cf3b747e41044dcee9ea.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=4.0
35 |
--------------------------------------------------------------------------------
/start-project/Screens/EndScreen.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 | export var player_score := 0
4 |
5 | onready var _label := $Panel/Label
6 |
7 | func _ready() -> void:
8 | _label.text = _label.text % player_score
9 |
--------------------------------------------------------------------------------
/start-project/Screens/EndScreen.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=2]
2 |
3 | [ext_resource path="res://UI/Theme/Montserrat-ExtraBold.ttf" type="DynamicFontData" id=1]
4 | [ext_resource path="res://Screens/EndScreen.gd" type="Script" id=2]
5 |
6 | [sub_resource type="DynamicFont" id=1]
7 | size = 32
8 | font_data = ExtResource( 1 )
9 |
10 | [sub_resource type="Animation" id=2]
11 | resource_name = "Text"
12 | length = 2.5
13 | tracks/0/type = "value"
14 | tracks/0/path = NodePath("Panel:rect_scale")
15 | tracks/0/interp = 1
16 | tracks/0/loop_wrap = true
17 | tracks/0/imported = false
18 | tracks/0/enabled = true
19 | tracks/0/keys = {
20 | "times": PoolRealArray( 0, 0.2, 0.3 ),
21 | "transitions": PoolRealArray( 1, 0.5, 1 ),
22 | "update": 0,
23 | "values": [ Vector2( 0, 0 ), Vector2( 1.2, 1.2 ), Vector2( 1, 1 ) ]
24 | }
25 | tracks/1/type = "value"
26 | tracks/1/path = NodePath("Panel/Label:percent_visible")
27 | tracks/1/interp = 1
28 | tracks/1/loop_wrap = true
29 | tracks/1/imported = false
30 | tracks/1/enabled = true
31 | tracks/1/keys = {
32 | "times": PoolRealArray( 0, 0.4, 1.4, 2.5 ),
33 | "transitions": PoolRealArray( 1, 1, 1, 1 ),
34 | "update": 0,
35 | "values": [ 0.0, 0.0, 0.909091, 1.0 ]
36 | }
37 |
38 | [node name="EndScreen" type="Control"]
39 | anchor_right = 1.0
40 | anchor_bottom = 1.0
41 | script = ExtResource( 2 )
42 | __meta__ = {
43 | "_edit_use_anchors_": false
44 | }
45 |
46 | [node name="Panel" type="Panel" parent="."]
47 | anchor_left = 0.5
48 | anchor_top = 0.5
49 | anchor_right = 0.5
50 | anchor_bottom = 0.5
51 | margin_left = -618.0
52 | margin_top = -120.0
53 | margin_right = 618.0
54 | margin_bottom = 120.0
55 | rect_scale = Vector2( 1e-05, 1e-05 )
56 | rect_pivot_offset = Vector2( 618, 124 )
57 | __meta__ = {
58 | "_edit_use_anchors_": false
59 | }
60 |
61 | [node name="Label" type="Label" parent="Panel"]
62 | anchor_right = 1.0
63 | anchor_bottom = 1.0
64 | custom_fonts/font = SubResource( 1 )
65 | text = "Congratulations! We vanquished the Aster-570!
66 | As a good strategist you spent just the resources you need.
67 |
68 | Score: %s"
69 | align = 1
70 | valign = 1
71 | percent_visible = 0.0
72 | __meta__ = {
73 | "_edit_use_anchors_": false
74 | }
75 |
76 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
77 | autoplay = "Text"
78 | anims/Text = SubResource( 2 )
79 |
--------------------------------------------------------------------------------
/start-project/UI/Theme/Montserrat-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/UI/Theme/Montserrat-ExtraBold.ttf
--------------------------------------------------------------------------------
/start-project/UI/Theme/background_stylebox.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="StyleBoxFlat" format=2]
2 |
3 | [resource]
4 | bg_color = Color( 0.278431, 0.231373, 0.470588, 1 )
5 | border_width_left = 2
6 | border_width_top = 2
7 | border_width_right = 2
8 | border_width_bottom = 2
9 | border_color = Color( 1, 1, 1, 1 )
10 | corner_radius_top_left = 8
11 | corner_radius_top_right = 8
12 | corner_radius_bottom_right = 8
13 | corner_radius_bottom_left = 8
14 |
--------------------------------------------------------------------------------
/start-project/UI/Theme/button_font.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="DynamicFont" load_steps=2 format=2]
2 |
3 | [ext_resource path="res://UI/Theme/Montserrat-ExtraBold.ttf" type="DynamicFontData" id=1]
4 |
5 | [resource]
6 | size = 14
7 | font_data = ExtResource( 1 )
8 |
--------------------------------------------------------------------------------
/start-project/UI/Theme/foreground_stylebox.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="StyleBoxFlat" format=2]
2 |
3 | [resource]
4 | bg_color = Color( 0.235294, 0.639216, 0.439216, 1 )
5 | border_width_left = 2
6 | border_width_top = 2
7 | border_width_right = 2
8 | border_width_bottom = 2
9 | border_color = Color( 1, 1, 1, 1 )
10 | corner_radius_top_left = 8
11 | corner_radius_top_right = 8
12 | corner_radius_bottom_right = 8
13 | corner_radius_bottom_left = 8
14 |
--------------------------------------------------------------------------------
/start-project/UI/Theme/main_font.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="DynamicFont" load_steps=2 format=2]
2 |
3 | [ext_resource path="res://UI/Theme/Montserrat-ExtraBold.ttf" type="DynamicFontData" id=1]
4 |
5 | [resource]
6 | size = 20
7 | font_data = ExtResource( 1 )
8 |
--------------------------------------------------------------------------------
/start-project/UI/Theme/main_theme.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Theme" load_steps=10 format=2]
2 |
3 | [ext_resource path="res://UI/Theme/main_font.tres" type="DynamicFont" id=1]
4 | [ext_resource path="res://UI/Theme/button_font.tres" type="DynamicFont" id=2]
5 |
6 | [sub_resource type="StyleBoxFlat" id=1]
7 | bg_color = Color( 0.364706, 0.341176, 0.470588, 0.705882 )
8 | border_width_left = 4
9 | border_width_top = 4
10 | border_width_right = 4
11 | border_width_bottom = 4
12 |
13 | [sub_resource type="StyleBoxFlat" id=2]
14 | bg_color = Color( 0.278431, 0.231373, 0.470588, 0.705882 )
15 | border_width_left = 4
16 | border_width_top = 4
17 | border_width_right = 4
18 | border_width_bottom = 4
19 | border_color = Color( 1, 1, 1, 0.705882 )
20 |
21 | [sub_resource type="StyleBoxFlat" id=3]
22 | bg_color = Color( 0.37888, 0.3136, 0.64, 0.705882 )
23 | border_width_left = 4
24 | border_width_top = 4
25 | border_width_right = 4
26 | border_width_bottom = 4
27 | border_color = Color( 0.301961, 0.65098, 1, 0.705882 )
28 |
29 | [sub_resource type="StyleBoxFlat" id=4]
30 | bg_color = Color( 0.278431, 0.231373, 0.470588, 0.705882 )
31 | border_width_left = 4
32 | border_width_top = 4
33 | border_width_right = 4
34 | border_width_bottom = 4
35 | border_color = Color( 0.301961, 0.65098, 1, 0.705882 )
36 |
37 | [sub_resource type="StyleBoxFlat" id=5]
38 | bg_color = Color( 0.18944, 0.1568, 0.32, 0.486275 )
39 | border_width_left = 4
40 | border_width_top = 4
41 | border_width_right = 4
42 | border_width_bottom = 4
43 | border_color = Color( 0.301961, 0.65098, 1, 0.705882 )
44 |
45 | [sub_resource type="StyleBoxLine" id=6]
46 | color = Color( 1, 1, 1, 1 )
47 | thickness = 2
48 |
49 | [sub_resource type="StyleBoxFlat" id=7]
50 | bg_color = Color( 0.278431, 0.231373, 0.470588, 0.705882 )
51 | border_width_left = 4
52 | border_width_top = 4
53 | border_width_right = 4
54 | border_width_bottom = 4
55 | border_color = Color( 0.301961, 0.65098, 1, 0.705882 )
56 | corner_radius_top_left = 8
57 | corner_radius_top_right = 8
58 | corner_radius_bottom_right = 8
59 | corner_radius_bottom_left = 8
60 |
61 | [resource]
62 | default_font = ExtResource( 1 )
63 | Button/colors/font_color = Color( 1, 1, 1, 1 )
64 | Button/colors/font_color_disabled = Color( 0.607843, 0.607843, 0.607843, 1 )
65 | Button/colors/font_color_hover = Color( 1, 1, 1, 1 )
66 | Button/colors/font_color_pressed = Color( 1, 1, 1, 1 )
67 | Button/constants/hseparation = 2
68 | Button/fonts/font = ExtResource( 2 )
69 | Button/styles/disabled = SubResource( 1 )
70 | Button/styles/focus = SubResource( 2 )
71 | Button/styles/hover = SubResource( 3 )
72 | Button/styles/normal = SubResource( 4 )
73 | Button/styles/pressed = SubResource( 5 )
74 | HSeparator/constants/separation = 4
75 | HSeparator/styles/separator = SubResource( 6 )
76 | OptionButton/colors/font_color = Color( 0.88, 0.88, 0.88, 1 )
77 | OptionButton/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 )
78 | OptionButton/colors/font_color_hover = Color( 0.94, 0.94, 0.94, 1 )
79 | OptionButton/colors/font_color_pressed = Color( 1, 1, 1, 1 )
80 | OptionButton/constants/arrow_margin = 2
81 | OptionButton/constants/hseparation = 2
82 | OptionButton/fonts/font = null
83 | OptionButton/icons/arrow = null
84 | OptionButton/styles/disabled = null
85 | OptionButton/styles/focus = null
86 | OptionButton/styles/hover = null
87 | OptionButton/styles/normal = null
88 | OptionButton/styles/pressed = null
89 | Panel/styles/panel = SubResource( 7 )
90 | PanelContainer/styles/panel = SubResource( 7 )
91 |
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/UICooldownBar.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 |
4 | export var gradient: Gradient
5 |
6 | onready var _progress := $TextureProgress
7 | onready var _animator := $AnimationPlayer
8 | onready var _timer := $Timer
9 |
10 |
11 | func _ready() -> void:
12 | set_process(false)
13 | hide()
14 |
15 |
16 | func _process(delta: float) -> void:
17 | _progress.value = _timer.wait_time - _timer.time_left
18 | _progress.tint_progress = gradient.interpolate(_progress.ratio)
19 |
20 |
21 | func start(time: float) -> void:
22 | _timer.start(time)
23 | _progress.max_value = time
24 | _progress.value = 0.0
25 | _animator.playback_speed = 1.0/time
26 | _animator.play("Spin")
27 | set_process(true)
28 | show()
29 |
30 |
31 | func _on_Timer_timeout():
32 | _animator.play("Finish")
33 | set_process(false)
34 |
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/UICooldownBar.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=10 format=2]
2 |
3 | [ext_resource path="res://UI/UICooldownBar/cooldown-bar-progress.png" type="Texture" id=1]
4 | [ext_resource path="res://UI/UICooldownBar/cooldown-bar-over.png" type="Texture" id=2]
5 | [ext_resource path="res://UI/UICooldownBar/clock.png" type="Texture" id=3]
6 | [ext_resource path="res://UI/UICooldownBar/clock-tic.png" type="Texture" id=4]
7 | [ext_resource path="res://UI/UICooldownBar/cooldown-bar-under.png" type="Texture" id=5]
8 | [ext_resource path="res://UI/UICooldownBar/UICooldownBar.gd" type="Script" id=6]
9 |
10 | [sub_resource type="Gradient" id=1]
11 | offsets = PoolRealArray( 0.254682, 0.520599, 0.846442, 1 )
12 | colors = PoolColorArray( 0.921569, 0.337255, 0.294118, 1, 1, 0.568627, 0.4, 1, 1, 0.709804, 0.439216, 1, 1, 1, 1, 1 )
13 |
14 | [sub_resource type="Animation" id=2]
15 | resource_name = "Finish"
16 | length = 0.2
17 | tracks/0/type = "value"
18 | tracks/0/path = NodePath(".:visible")
19 | tracks/0/interp = 1
20 | tracks/0/loop_wrap = true
21 | tracks/0/imported = false
22 | tracks/0/enabled = true
23 | tracks/0/keys = {
24 | "times": PoolRealArray( 0.2 ),
25 | "transitions": PoolRealArray( 1 ),
26 | "update": 1,
27 | "values": [ false ]
28 | }
29 |
30 | [sub_resource type="Animation" id=3]
31 | tracks/0/type = "value"
32 | tracks/0/path = NodePath("Clock/Tic:rect_rotation")
33 | tracks/0/interp = 1
34 | tracks/0/loop_wrap = true
35 | tracks/0/imported = false
36 | tracks/0/enabled = true
37 | tracks/0/keys = {
38 | "times": PoolRealArray( 0, 1 ),
39 | "transitions": PoolRealArray( 1, 1 ),
40 | "update": 0,
41 | "values": [ 0.0, 360.0 ]
42 | }
43 |
44 | [node name="UICooldownBar" type="Control"]
45 | visible = false
46 | margin_right = 144.0
47 | margin_bottom = 24.0
48 | script = ExtResource( 6 )
49 | __meta__ = {
50 | "_edit_use_anchors_": false
51 | }
52 | gradient = SubResource( 1 )
53 |
54 | [node name="TextureProgress" type="TextureProgress" parent="."]
55 | anchor_left = 0.222
56 | anchor_right = 1.0
57 | anchor_bottom = 1.0
58 | margin_left = 0.0319977
59 | step = 0.01
60 | texture_under = ExtResource( 5 )
61 | texture_over = ExtResource( 2 )
62 | texture_progress = ExtResource( 1 )
63 | __meta__ = {
64 | "_edit_use_anchors_": false
65 | }
66 |
67 | [node name="Clock" type="TextureRect" parent="."]
68 | anchor_right = 0.167
69 | anchor_bottom = 1.0
70 | margin_right = -0.0480022
71 | texture = ExtResource( 3 )
72 | expand = true
73 | stretch_mode = 6
74 | __meta__ = {
75 | "_edit_use_anchors_": false
76 | }
77 |
78 | [node name="Tic" type="TextureRect" parent="Clock"]
79 | anchor_left = 0.5
80 | anchor_top = 0.5
81 | anchor_right = 0.5
82 | anchor_bottom = 0.5
83 | margin_left = -2.0
84 | margin_top = -8.0
85 | margin_right = 2.0
86 | rect_rotation = 252.0
87 | rect_pivot_offset = Vector2( 2, 8 )
88 | texture = ExtResource( 4 )
89 | expand = true
90 | stretch_mode = 1
91 | __meta__ = {
92 | "_edit_use_anchors_": false
93 | }
94 |
95 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
96 | anims/Finish = SubResource( 2 )
97 | anims/Spin = SubResource( 3 )
98 |
99 | [node name="Timer" type="Timer" parent="."]
100 |
101 | [connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
102 |
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/clock-tic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/UI/UICooldownBar/clock-tic.png
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/clock-tic.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/clock-tic.png-fcf004a0cb21e95bfb83688239d9146c.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UICooldownBar/clock-tic.png"
13 | dest_files=[ "res://.import/clock-tic.png-fcf004a0cb21e95bfb83688239d9146c.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/UI/UICooldownBar/clock.png
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/clock.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/clock.png-e646f709d1c473b8f555faca30d0b0fd.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UICooldownBar/clock.png"
13 | dest_files=[ "res://.import/clock.png-e646f709d1c473b8f555faca30d0b0fd.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/cooldown-bar-over.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/UI/UICooldownBar/cooldown-bar-over.png
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/cooldown-bar-over.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/cooldown-bar-over.png-139f0f8a8e088eb12a232c8fecc07bf6.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UICooldownBar/cooldown-bar-over.png"
13 | dest_files=[ "res://.import/cooldown-bar-over.png-139f0f8a8e088eb12a232c8fecc07bf6.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/cooldown-bar-progress.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/UI/UICooldownBar/cooldown-bar-progress.png
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/cooldown-bar-progress.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/cooldown-bar-progress.png-4efbbd0ea1e29dd11c8ddd7112fcbf44.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UICooldownBar/cooldown-bar-progress.png"
13 | dest_files=[ "res://.import/cooldown-bar-progress.png-4efbbd0ea1e29dd11c8ddd7112fcbf44.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/cooldown-bar-under.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/UI/UICooldownBar/cooldown-bar-under.png
--------------------------------------------------------------------------------
/start-project/UI/UICooldownBar/cooldown-bar-under.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/cooldown-bar-under.png-9693085f3ebee638ce0f793ec3efc232.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UICooldownBar/cooldown-bar-under.png"
13 | dest_files=[ "res://.import/cooldown-bar-under.png-9693085f3ebee638ce0f793ec3efc232.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UIGoldPanel/UIGoldPanel.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 |
4 | onready var _label: Label = $Label
5 |
6 | var player: Player setget set_player
7 |
8 | func set_player(new_player: Player) -> void:
9 | player = new_player
10 | player.connect("gold_changed", self, "_update_gold_amount")
11 | _update_gold_amount(player.gold)
12 |
13 |
14 | func _update_gold_amount(new_amount: int) -> void:
15 | _label.text = "Gold: %s" % new_amount
16 |
--------------------------------------------------------------------------------
/start-project/UI/UIGoldPanel/UIGoldPanel.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=2 format=2]
2 |
3 | [ext_resource path="res://UI/UIGoldPanel/UIGoldPanel.gd" type="Script" id=1]
4 |
5 | [node name="UIGoldPanel" type="Panel"]
6 | margin_right = 224.0
7 | margin_bottom = 64.0
8 | mouse_filter = 2
9 | script = ExtResource( 1 )
10 | __meta__ = {
11 | "_edit_use_anchors_": false
12 | }
13 |
14 | [node name="Label" type="Label" parent="."]
15 | anchor_right = 1.0
16 | anchor_bottom = 1.0
17 | margin_left = 22.0
18 | margin_right = -22.0
19 | size_flags_horizontal = 3
20 | size_flags_vertical = 6
21 | text = "Gold: 1000"
22 | align = 1
23 | valign = 1
24 | __meta__ = {
25 | "_edit_use_anchors_": false
26 | }
27 |
--------------------------------------------------------------------------------
/start-project/UI/UIHealthBar/UIHealthBar.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://UI/UIHealthBar/heart.svg" type="Texture" id=1]
4 |
5 | [sub_resource type="StyleBoxFlat" id=1]
6 | bg_color = Color( 0.235294, 0.639216, 0.439216, 1 )
7 | border_width_left = 2
8 | border_width_top = 2
9 | border_width_right = 2
10 | border_width_bottom = 2
11 | border_color = Color( 1, 1, 1, 1 )
12 | corner_radius_top_left = 8
13 | corner_radius_top_right = 8
14 | corner_radius_bottom_right = 8
15 | corner_radius_bottom_left = 8
16 |
17 | [sub_resource type="StyleBoxFlat" id=2]
18 | bg_color = Color( 0.278431, 0.231373, 0.470588, 1 )
19 | border_width_left = 2
20 | border_width_top = 2
21 | border_width_right = 2
22 | border_width_bottom = 2
23 | border_color = Color( 1, 1, 1, 1 )
24 | corner_radius_top_left = 8
25 | corner_radius_top_right = 8
26 | corner_radius_bottom_right = 8
27 | corner_radius_bottom_left = 8
28 |
29 | [node name="HealthBar" type="ProgressBar"]
30 | margin_right = 172.0
31 | margin_bottom = 18.0
32 | custom_styles/fg = SubResource( 1 )
33 | custom_styles/bg = SubResource( 2 )
34 | step = 1.0
35 | value = 50.0
36 | percent_visible = false
37 | __meta__ = {
38 | "_edit_use_anchors_": false
39 | }
40 |
41 | [node name="TextureRect" type="TextureRect" parent="."]
42 | margin_left = -56.0
43 | margin_top = -14.0
44 | margin_right = -8.0
45 | margin_bottom = 34.0
46 | texture = ExtResource( 1 )
47 | expand = true
48 | stretch_mode = 6
49 | __meta__ = {
50 | "_edit_use_anchors_": false
51 | }
52 |
--------------------------------------------------------------------------------
/start-project/UI/UIHealthBar/UITimedHealthBar.gd:
--------------------------------------------------------------------------------
1 | extends ProgressBar
2 |
3 | onready var _timer := $Timer
4 |
5 |
6 | func _on_value_changed(value: float) -> void:
7 | show()
8 | _timer.start()
9 |
10 |
11 | func _on_Timer_timeout() -> void:
12 | hide()
13 |
--------------------------------------------------------------------------------
/start-project/UI/UIHealthBar/UITimedHealthBar.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=2]
2 |
3 | [ext_resource path="res://UI/UIHealthBar/heart.svg" type="Texture" id=1]
4 | [ext_resource path="res://UI/UIHealthBar/UITimedHealthBar.gd" type="Script" id=2]
5 |
6 | [sub_resource type="StyleBoxFlat" id=1]
7 | bg_color = Color( 0.235294, 0.639216, 0.439216, 1 )
8 | border_width_left = 2
9 | border_width_top = 2
10 | border_width_right = 2
11 | border_width_bottom = 2
12 | border_color = Color( 1, 1, 1, 1 )
13 | corner_radius_top_left = 8
14 | corner_radius_top_right = 8
15 | corner_radius_bottom_right = 8
16 | corner_radius_bottom_left = 8
17 |
18 | [sub_resource type="StyleBoxFlat" id=2]
19 | bg_color = Color( 0.278431, 0.231373, 0.470588, 1 )
20 | border_width_left = 2
21 | border_width_top = 2
22 | border_width_right = 2
23 | border_width_bottom = 2
24 | border_color = Color( 1, 1, 1, 1 )
25 | corner_radius_top_left = 8
26 | corner_radius_top_right = 8
27 | corner_radius_bottom_right = 8
28 | corner_radius_bottom_left = 8
29 |
30 | [node name="HealthBar" type="ProgressBar"]
31 | margin_right = 192.0
32 | margin_bottom = 18.0
33 | custom_styles/fg = SubResource( 1 )
34 | custom_styles/bg = SubResource( 2 )
35 | value = 50.0
36 | percent_visible = false
37 | script = ExtResource( 2 )
38 | __meta__ = {
39 | "_edit_use_anchors_": false
40 | }
41 |
42 | [node name="TextureRect" type="TextureRect" parent="."]
43 | margin_left = -56.0
44 | margin_top = -14.0
45 | margin_right = -8.0
46 | margin_bottom = 34.0
47 | texture = ExtResource( 1 )
48 | expand = true
49 | stretch_mode = 6
50 | __meta__ = {
51 | "_edit_use_anchors_": false
52 | }
53 |
54 | [node name="Timer" type="Timer" parent="."]
55 | wait_time = 0.5
56 |
57 | [connection signal="value_changed" from="." to="." method="_on_value_changed"]
58 | [connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
59 |
--------------------------------------------------------------------------------
/start-project/UI/UIHealthBar/heart.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/heart.svg-49f6cf64586eb6a039065531a8f12ab4.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UIHealthBar/heart.svg"
13 | dest_files=[ "res://.import/heart.svg-49f6cf64586eb6a039065531a8f12ab4.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UIScreenOverlay/UIScreenOverlay.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 | onready var _anim_player := $AnimationPlayer
4 |
5 |
6 | func play_win() -> void:
7 | _anim_player.play("PlayerWon")
8 | yield(_anim_player, "animation_finished")
9 |
10 |
11 | func play_lost() -> void:
12 | _anim_player.play("PlayerLost")
13 | yield(_anim_player, "animation_finished")
14 |
15 |
16 | func play_wave_start_async() -> void:
17 | _anim_player.play("WaveStarting")
18 | yield(_anim_player, "animation_finished")
19 |
--------------------------------------------------------------------------------
/start-project/UI/UITowerShop/tower-icon-disabled.svg:
--------------------------------------------------------------------------------
1 |
2 |
90 |
--------------------------------------------------------------------------------
/start-project/UI/UITowerShop/tower-icon-disabled.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tower-icon-disabled.svg-62c4df5afaef7403c38ea7613fee01a0.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UITowerShop/tower-icon-disabled.svg"
13 | dest_files=[ "res://.import/tower-icon-disabled.svg-62c4df5afaef7403c38ea7613fee01a0.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UITowerShop/tower-icon-focused.svg:
--------------------------------------------------------------------------------
1 |
2 |
90 |
--------------------------------------------------------------------------------
/start-project/UI/UITowerShop/tower-icon-focused.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tower-icon-focused.svg-e45f7d0f6fc6495dcb36beb0c612cd09.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UITowerShop/tower-icon-focused.svg"
13 | dest_files=[ "res://.import/tower-icon-focused.svg-e45f7d0f6fc6495dcb36beb0c612cd09.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UITowerShop/tower-icon-hover.svg:
--------------------------------------------------------------------------------
1 |
2 |
90 |
--------------------------------------------------------------------------------
/start-project/UI/UITowerShop/tower-icon-hover.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tower-icon-hover.svg-e3374d23a1e60195dc22da7d76b6bd7c.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UITowerShop/tower-icon-hover.svg"
13 | dest_files=[ "res://.import/tower-icon-hover.svg-e3374d23a1e60195dc22da7d76b6bd7c.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UITowerShop/tower-icon-normal.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tower-icon-normal.svg-54029b396714c9a0bc62fb03ce535dbe.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UITowerShop/tower-icon-normal.svg"
13 | dest_files=[ "res://.import/tower-icon-normal.svg-54029b396714c9a0bc62fb03ce535dbe.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UITowerShop/tower-icon-pressed.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tower-icon-pressed.svg-b6c90a05f9abb921648be57d23811288.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://UI/UITowerShop/tower-icon-pressed.svg"
13 | dest_files=[ "res://.import/tower-icon-pressed.svg-b6c90a05f9abb921648be57d23811288.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/UI/UIUnit/UIUnit.gd:
--------------------------------------------------------------------------------
1 | extends Control
2 |
3 |
4 | onready var _anim_player := $AnimationPlayer
5 |
6 | func appear() -> void:
7 | _anim_player.play("appear")
8 |
9 |
10 | func disappear() -> void:
11 | _anim_player.play("disappear")
12 |
--------------------------------------------------------------------------------
/start-project/UI/UIUnit/UIUnit.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=4 format=2]
2 |
3 | [ext_resource path="res://UI/UIUnit/UIUnit.gd" type="Script" id=1]
4 |
5 | [sub_resource type="Animation" id=1]
6 | resource_name = "appear"
7 | length = 0.3
8 | tracks/0/type = "value"
9 | tracks/0/path = NodePath(".:rect_scale")
10 | tracks/0/interp = 1
11 | tracks/0/loop_wrap = true
12 | tracks/0/imported = false
13 | tracks/0/enabled = true
14 | tracks/0/keys = {
15 | "times": PoolRealArray( 0, 0.2, 0.3 ),
16 | "transitions": PoolRealArray( 0.5, 1, 1 ),
17 | "update": 0,
18 | "values": [ Vector2( 0, 0 ), Vector2( 1.2, 1.2 ), Vector2( 1, 1 ) ]
19 | }
20 |
21 | [sub_resource type="Animation" id=2]
22 | resource_name = "disappear"
23 | length = 0.3
24 | tracks/0/type = "value"
25 | tracks/0/path = NodePath(".:rect_scale")
26 | tracks/0/interp = 1
27 | tracks/0/loop_wrap = true
28 | tracks/0/imported = false
29 | tracks/0/enabled = true
30 | tracks/0/keys = {
31 | "times": PoolRealArray( 0, 0.1, 0.3 ),
32 | "transitions": PoolRealArray( 0.5, 0.5, 0.5 ),
33 | "update": 0,
34 | "values": [ Vector2( 1, 1 ), Vector2( 1.2, 1.2 ), Vector2( 0, 0 ) ]
35 | }
36 |
37 | [node name="Interface" type="Control"]
38 | mouse_filter = 2
39 | script = ExtResource( 1 )
40 | __meta__ = {
41 | "_edit_use_anchors_": false
42 | }
43 |
44 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
45 | anims/appear = SubResource( 1 )
46 | anims/disappear = SubResource( 2 )
47 |
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/SmallExplosion.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=7 format=2]
2 |
3 | [ext_resource path="res://VFX/Explosion/white_glowing_circle.png" type="Texture" id=1]
4 |
5 | [sub_resource type="Gradient" id=1]
6 | offsets = PoolRealArray( 0.788043, 1 )
7 | colors = PoolColorArray( 1, 1, 1, 1, 1, 1, 1, 0 )
8 |
9 | [sub_resource type="GradientTexture" id=2]
10 | gradient = SubResource( 1 )
11 |
12 | [sub_resource type="Curve" id=3]
13 | _data = [ Vector2( 0, 0 ), 0.0, 0.0, 0, 0, Vector2( 1, 0.954545 ), 0.0, 0.0, 0, 0 ]
14 |
15 | [sub_resource type="CurveTexture" id=4]
16 | curve = SubResource( 3 )
17 |
18 | [sub_resource type="ParticlesMaterial" id=5]
19 | emission_shape = 1
20 | emission_sphere_radius = 20.0
21 | flag_disable_z = true
22 | spread = 180.0
23 | gravity = Vector3( 0, 0, 0 )
24 | initial_velocity = 800.0
25 | orbit_velocity = 0.0
26 | orbit_velocity_random = 0.0
27 | damping = 2000.0
28 | scale = 0.5
29 | scale_random = 0.3
30 | scale_curve = SubResource( 4 )
31 | color_ramp = SubResource( 2 )
32 |
33 | [node name="SmallExplosion" type="Particles2D"]
34 | modulate = Color( 1.5, 1.5, 1.5, 1 )
35 | self_modulate = Color( 0.34902, 0.67451, 1, 1 )
36 | emitting = false
37 | amount = 16
38 | lifetime = 0.1
39 | explosiveness = 0.9
40 | local_coords = false
41 | process_material = SubResource( 5 )
42 | texture = ExtResource( 1 )
43 |
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/explosion_gradient.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="GradientTexture" load_steps=2 format=2]
2 |
3 | [sub_resource type="Gradient" id=1]
4 | offsets = PoolRealArray( 0, 0.185185, 0.533333, 0.82963, 1 )
5 | colors = PoolColorArray( 1, 1, 1, 1, 1, 0.788235, 0.309804, 1, 0.980392, 0.419608, 0.211765, 1, 0.831373, 0.219608, 0.219608, 1, 0.831373, 0.219608, 0.219608, 0 )
6 |
7 | [resource]
8 | gradient = SubResource( 1 )
9 |
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/puff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/VFX/Explosion/puff.png
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/puff.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/puff.png-17343d3079ec2b5a1c4066139325ca90.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://VFX/Explosion/puff.png"
13 | dest_files=[ "res://.import/puff.png-17343d3079ec2b5a1c4066139325ca90.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/puff_smooth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/VFX/Explosion/puff_smooth.png
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/puff_smooth.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/puff_smooth.png-54099f8c14d24d7cf3bc581ad220923b.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://VFX/Explosion/puff_smooth.png"
13 | dest_files=[ "res://.import/puff_smooth.png-54099f8c14d24d7cf3bc581ad220923b.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/scraps_gradient.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="GradientTexture" load_steps=2 format=2]
2 |
3 | [sub_resource type="Gradient" id=1]
4 | offsets = PoolRealArray( 0, 0.155894, 0.505017, 0.8327, 1 )
5 | colors = PoolColorArray( 0.258824, 0.25098, 0.25098, 1, 0.722656, 0.118153, 0.118153, 1, 0.855469, 0.323879, 0.126857, 1, 1, 0.788235, 0.309804, 0.717647, 1, 1, 1, 0 )
6 |
7 | [resource]
8 | gradient = SubResource( 1 )
9 |
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/sparkle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/VFX/Explosion/sparkle.png
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/sparkle.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/sparkle.png-67cbc2cee3a6c5aeb5699820face8639.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://VFX/Explosion/sparkle.png"
13 | dest_files=[ "res://.import/sparkle.png-67cbc2cee3a6c5aeb5699820face8639.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/white_glowing_circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/VFX/Explosion/white_glowing_circle.png
--------------------------------------------------------------------------------
/start-project/VFX/Explosion/white_glowing_circle.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/white_glowing_circle.png-ec45a8abc7514e57582731cd4b5ff0a7.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://VFX/Explosion/white_glowing_circle.png"
13 | dest_files=[ "res://.import/white_glowing_circle.png-ec45a8abc7514e57582731cd4b5ff0a7.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/VFX/PathPreview.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=3 format=2]
2 |
3 | [sub_resource type="GDScript" id=1]
4 | script/source = "extends Line2D
5 |
6 |
7 | onready var _tween := $Tween
8 | onready var _timer := $Timer
9 |
10 | func fade_out() -> void:
11 | var transparent := modulate
12 | transparent.a = 0.0
13 | _tween.interpolate_property(self, \"modulate\", modulate, transparent, 0.5)
14 | _tween.start()
15 | _timer.start(0.5 / (get_point_count() -1))
16 |
17 |
18 | func fade_in() -> void:
19 | var opaque := modulate
20 | opaque.a = 1.0
21 | _tween.interpolate_property(self, \"modulate\", modulate, opaque, 0.5)
22 | _tween.start()
23 |
24 |
25 | func _on_Timer_timeout() -> void:
26 | if get_point_count() > 0:
27 | remove_point(get_point_count() -1)
28 | else:
29 | _timer.stop()
30 | "
31 |
32 | [sub_resource type="Animation" id=5]
33 | resource_name = "glow"
34 | loop = true
35 | step = 0.05
36 | tracks/0/type = "value"
37 | tracks/0/path = NodePath(".:modulate")
38 | tracks/0/interp = 1
39 | tracks/0/loop_wrap = true
40 | tracks/0/imported = false
41 | tracks/0/enabled = true
42 | tracks/0/keys = {
43 | "times": PoolRealArray( 0, 0.5 ),
44 | "transitions": PoolRealArray( 1, 1 ),
45 | "update": 0,
46 | "values": [ Color( 1, 1, 1, 1 ), Color( 1, 0.72549, 0.72549, 1 ) ]
47 | }
48 |
49 | [node name="PathPreview" type="Line2D"]
50 | width = 20.0
51 | default_color = Color( 1, 0.415686, 0.160784, 1 )
52 | joint_mode = 2
53 | script = SubResource( 1 )
54 |
55 | [node name="Tween" type="Tween" parent="."]
56 |
57 | [node name="Timer" type="Timer" parent="."]
58 |
59 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
60 | autoplay = "glow"
61 | anims/glow = SubResource( 5 )
62 | [connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
63 |
--------------------------------------------------------------------------------
/start-project/default_env.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Environment" load_steps=2 format=2]
2 |
3 | [sub_resource type="ProceduralSky" id=1]
4 |
5 | [resource]
6 | background_mode = 2
7 | background_sky = SubResource( 1 )
8 |
--------------------------------------------------------------------------------
/start-project/grid-cell.svg:
--------------------------------------------------------------------------------
1 |
2 |
66 |
--------------------------------------------------------------------------------
/start-project/grid-cell.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/grid-cell.svg-6dc3d08e9807150ffe3b0752d9dacc85.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://grid-cell.svg"
13 | dest_files=[ "res://.import/grid-cell.svg-6dc3d08e9807150ffe3b0752d9dacc85.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-2d-tower-defense/8d4e408cba9e9f31c06e54478bbe04943bb8b746/start-project/icon.png
--------------------------------------------------------------------------------
/start-project/icon.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://icon.png"
13 | dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/start-project/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=4
10 |
11 | _global_script_classes=[ ]
12 | _global_script_class_icons={
13 | }
14 |
15 | [application]
16 |
17 | config/name="Tower Defense - Start"
18 | config/description="The initial version of 2D Secrets topdown tower defense game project."
19 | config/icon="res://icon.png"
20 |
21 | [debug]
22 |
23 | gdscript/warnings/return_value_discarded=false
24 |
25 | [display]
26 |
27 | window/size/width=1920
28 | window/size/height=1080
29 | window/size/test_width=1280
30 | window/size/test_height=720
31 | window/stretch/mode="2d"
32 | window/stretch/aspect="keep_width"
33 |
34 | [gui]
35 |
36 | theme/custom="res://UI/Theme/main_theme.tres"
37 | theme/custom_font="res://UI/Theme/main_font.tres"
38 |
39 | [input]
40 |
41 | select={
42 | "deadzone": 0.5,
43 | "events": [ 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)
44 | ]
45 | }
46 | tower_placement={
47 | "deadzone": 0.5,
48 | "events": [ 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)
49 | ]
50 | }
51 |
52 | [input_devices]
53 |
54 | pointing/emulate_touch_from_mouse=true
55 |
56 | [layer_names]
57 |
58 | 2d_physics/layer_1="selection"
59 | 2d_physics/layer_2="combat"
60 | 2d_physics/layer_3="enemies"
61 |
62 | [rendering]
63 |
64 | 2d/snapping/use_gpu_pixel_snap=true
65 | environment/default_clear_color=Color( 0.196078, 0.160784, 0.278431, 1 )
66 | environment/default_environment="res://default_env.tres"
67 | quality/2d/use_pixel_snap=true
68 |
--------------------------------------------------------------------------------
/start-project/sprite-sheet.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/sprite-sheet.svg-770a08d3ddf9b41899e4553fd12331ab.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://sprite-sheet.svg"
13 | dest_files=[ "res://.import/sprite-sheet.svg-770a08d3ddf9b41899e4553fd12331ab.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------