Ebb and flow

This commit is contained in:
LittleSheep 2024-02-16 23:35:39 +08:00
parent 7cc86d8546
commit cc562a4950
31 changed files with 330 additions and 65 deletions

Binary file not shown.

View File

@ -0,0 +1,33 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://cjga4eijrww18"
path="res://.godot/imported/ibm-plex-sans-regular.otf-03ba595ab5fa8897c955d71d581c61dd.fontdata"
[deps]
source_file="res://assets/fonts/ibm-plex-sans-regular.otf"
dest_files=["res://.godot/imported/ibm-plex-sans-regular.otf-03ba595ab5fa8897c955d71d581c61dd.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

View File

Before

Width:  |  Height:  |  Size: 249 B

After

Width:  |  Height:  |  Size: 249 B

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://p3urintydjlo"
path="res://.godot/imported/attacker.svg-150f6909959cc42ad50b11689a4301db.ctex"
path="res://.godot/imported/attacker.svg-2be6a89ac945048dfab7b97c46f99d5f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/attacker.svg"
dest_files=["res://.godot/imported/attacker.svg-150f6909959cc42ad50b11689a4301db.ctex"]
source_file="res://assets/images/attacker.svg"
dest_files=["res://.godot/imported/attacker.svg-2be6a89ac945048dfab7b97c46f99d5f.ctex"]
[params]

View File

Before

Width:  |  Height:  |  Size: 226 B

After

Width:  |  Height:  |  Size: 226 B

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://voltvmrkr73s"
path="res://.godot/imported/bullet.svg-63ca26e6536cc1d6a6067a48f66d9b99.ctex"
path="res://.godot/imported/bullet.svg-3164417db6ddc18184d97c37d20e19f8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/bullet.svg"
dest_files=["res://.godot/imported/bullet.svg-63ca26e6536cc1d6a6067a48f66d9b99.ctex"]
source_file="res://assets/images/bullet.svg"
dest_files=["res://.godot/imported/bullet.svg-3164417db6ddc18184d97c37d20e19f8.ctex"]
[params]

View File

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 350 B

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://b4daomndc1ag"
path="res://.godot/imported/player.svg-e72d10ccf9c1b331af0b406534563f6c.ctex"
path="res://.godot/imported/player.svg-351bec044cd47e73eb6ecd3eb5a3b51d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/player.svg"
dest_files=["res://.godot/imported/player.svg-e72d10ccf9c1b331af0b406534563f6c.ctex"]
source_file="res://assets/images/player.svg"
dest_files=["res://.godot/imported/player.svg-351bec044cd47e73eb6ecd3eb5a3b51d.ctex"]
[params]

View File

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

View File

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://jxub8lma4oud"
path="res://.godot/imported/tower_background.svg-e77d209753f33c422eeb2695c1195112.ctex"
path="res://.godot/imported/tower.svg-0a634f4f37eb4a65b03541f661999487.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/tower_background.svg"
dest_files=["res://.godot/imported/tower_background.svg-e77d209753f33c422eeb2695c1195112.ctex"]
source_file="res://assets/images/tower.svg"
dest_files=["res://.godot/imported/tower.svg-0a634f4f37eb4a65b03541f661999487.ctex"]
[params]

View File

@ -1,7 +0,0 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1024" height="1024">
<title>Tower</title>
<style>
.s0 { fill: none;stroke: #4750a3;stroke-miterlimit:100;stroke-width: 64 }
</style>
<path id="Background" class="s0" d="m512 992c-265.4 0-480-214.6-480-480 0-265.4 214.6-480 480-480 265.4 0 480 214.6 480 480 0 265.4-214.6 480-480 480z"/>
</svg>

Before

Width:  |  Height:  |  Size: 385 B

View File

@ -1,37 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b4a5wo7y6orr0"
path="res://.godot/imported/tower_forceground.svg-9f6d44720ea623d40c26c9524e3dd5b1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/tower_forceground.svg"
dest_files=["res://.godot/imported/tower_forceground.svg-9f6d44720ea623d40c26c9524e3dd5b1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

6
codingland.tres Normal file
View File

@ -0,0 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=3 uid="uid://gh5a3no0ojkl"]
[ext_resource type="FontFile" uid="uid://cjga4eijrww18" path="res://assets/fonts/ibm-plex-sans-regular.otf" id="1_5jc7o"]
[resource]
default_font = ExtResource("1_5jc7o")

View File

@ -51,7 +51,8 @@ skill_dash={
}
weapon_fire={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(163, 27),"global_position":Vector2(171, 107),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":256,"position":Vector2(234, 24),"global_position":Vector2(242, 104),"factor":1.0,"button_index":9,"canceled":false,"pressed":true,"double_click":false,"script":null)
, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(185, 16),"global_position":Vector2(193, 96),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}

View File

@ -2,9 +2,10 @@
[ext_resource type="Script" path="res://scripts/enemy_farm.gd" id="1_66qev"]
[node name="EnemyFarm" type="Node2D" node_paths=PackedStringArray("common_parent")]
[node name="EnemyFarm" type="Node2D" node_paths=PackedStringArray("common_parent", "respawn_timer")]
script = ExtResource("1_66qev")
common_parent = NodePath(".")
respawn_timer = NodePath("RespawnTimer")
[node name="RespawnTimer" type="Timer" parent="."]
autostart = true

View File

@ -1,9 +1,12 @@
[gd_scene load_steps=6 format=3 uid="uid://l4mybb2dw107"]
[gd_scene load_steps=9 format=3 uid="uid://l4mybb2dw107"]
[ext_resource type="PackedScene" uid="uid://cwkcf8h5rspoh" path="res://scenes/objects/player.tscn" id="1_nq1ke"]
[ext_resource type="PackedScene" uid="uid://cxlgt8h33u7os" path="res://scenes/objects/tower.tscn" id="2_betjv"]
[ext_resource type="PackedScene" uid="uid://cppmks4ln28yd" path="res://scenes/objects/attacker.tscn" id="3_jg22m"]
[ext_resource type="PackedScene" uid="uid://cy2xpilh8v7vx" path="res://scenes/farms/enemy_farm.tscn" id="3_ogjsq"]
[ext_resource type="PackedScene" uid="uid://2tqfm73cc4id" path="res://scenes/manager/statistics.tscn" id="5_qd3ww"]
[ext_resource type="PackedScene" uid="uid://cjam63kp5sg2o" path="res://scenes/ui/stats_overlay.tscn" id="5_rymed"]
[ext_resource type="PackedScene" uid="uid://dy51uqtr2ng32" path="res://scenes/ui/finish_screen.tscn" id="6_b264x"]
[sub_resource type="Curve2D" id="Curve2D_gwd20"]
_data = {
@ -20,8 +23,9 @@ common_target = NodePath("../Player")
[node name="BulletFarm" type="Node2D" parent="."]
[node name="Player" parent="." node_paths=PackedStringArray("weapon_bullet_parent") instance=ExtResource("1_nq1ke")]
[node name="Player" parent="." node_paths=PackedStringArray("weapon_bullet_parent", "statistics") instance=ExtResource("1_nq1ke")]
weapon_bullet_parent = NodePath("../BulletFarm")
statistics = NodePath("../Statistics")
[node name="Tower" parent="." instance=ExtResource("2_betjv")]
@ -31,3 +35,17 @@ curve = SubResource("Curve2D_gwd20")
[node name="EnemySpawnPoint" type="PathFollow2D" parent="EnemySpawnPath"]
position = Vector2(-309, -271)
rotation = 1.5708
[node name="StatsOverlay" parent="." node_paths=PackedStringArray("stats") instance=ExtResource("5_rymed")]
stats = NodePath("../Statistics")
[node name="FinishScreen" parent="." node_paths=PackedStringArray("stats") instance=ExtResource("6_b264x")]
visible = false
stats = NodePath("../Statistics")
[node name="Statistics" parent="." instance=ExtResource("5_qd3ww")]
[connection signal="enemy_defeat" from="EnemyFarm" to="Statistics" method="_on_enemy_defeated"]
[connection signal="tower_broken" from="Tower" to="FinishScreen" method="_show"]
[connection signal="wave_finished" from="Statistics" to="EnemyFarm" method="_on_wave_finished"]
[connection signal="wave_started" from="Statistics" to="EnemyFarm" method="_on_wave_started"]

View File

@ -0,0 +1,18 @@
[gd_scene load_steps=2 format=3 uid="uid://2tqfm73cc4id"]
[ext_resource type="Script" path="res://scripts/statistics.gd" id="1_4fj6w"]
[node name="Statistics" type="Node" node_paths=PackedStringArray("wave_timer", "wave_gap_timer")]
script = ExtResource("1_4fj6w")
wave_timer = NodePath("WaveTimer")
wave_gap_timer = NodePath("WaveGapTimer")
[node name="WaveTimer" type="Timer" parent="."]
wait_time = 10.0
one_shot = true
[node name="WaveGapTimer" type="Timer" parent="."]
one_shot = true
[connection signal="timeout" from="WaveTimer" to="." method="_on_wave_passed"]
[connection signal="timeout" from="WaveGapTimer" to="." method="_on_wave_gap_passed"]

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=3 format=3 uid="uid://cppmks4ln28yd"]
[ext_resource type="Texture2D" uid="uid://p3urintydjlo" path="res://assets/attacker.svg" id="1_56wxx"]
[ext_resource type="Texture2D" uid="uid://p3urintydjlo" path="res://assets/images/attacker.svg" id="1_56wxx"]
[ext_resource type="Script" path="res://scripts/attacker.gd" id="1_d7hg4"]
[node name="Attacker" type="CharacterBody2D"]

View File

@ -1,7 +1,7 @@
[gd_scene load_steps=4 format=3 uid="uid://h4fxpxqc6bpt"]
[ext_resource type="Script" path="res://scripts/bullet.gd" id="1_7ic61"]
[ext_resource type="Texture2D" uid="uid://voltvmrkr73s" path="res://assets/bullet.svg" id="1_tytsj"]
[ext_resource type="Texture2D" uid="uid://voltvmrkr73s" path="res://assets/images/bullet.svg" id="1_tytsj"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_r7dy5"]
size = Vector2(8, 24)
@ -22,6 +22,7 @@ rotation = 1.5708
shape = SubResource("RectangleShape2D_r7dy5")
[node name="DisposeTimer" type="Timer" parent="."]
one_shot = true
autostart = true
[connection signal="timeout" from="DisposeTimer" to="." method="_on_timed_out"]

View File

@ -1,7 +1,7 @@
[gd_scene load_steps=5 format=3 uid="uid://cwkcf8h5rspoh"]
[ext_resource type="Script" path="res://scripts/player.gd" id="1_sa7t7"]
[ext_resource type="Texture2D" uid="uid://b4daomndc1ag" path="res://assets/player.svg" id="2_3pad2"]
[ext_resource type="Texture2D" uid="uid://b4daomndc1ag" path="res://assets/images/player.svg" id="2_3pad2"]
[ext_resource type="PackedScene" uid="uid://h4fxpxqc6bpt" path="res://scenes/objects/bullet.tscn" id="2_v83ov"]
[sub_resource type="CircleShape2D" id="CircleShape2D_k56cq"]

View File

@ -1,7 +1,7 @@
[gd_scene load_steps=5 format=3 uid="uid://cxlgt8h33u7os"]
[ext_resource type="Script" path="res://scripts/tower.gd" id="1_d5o8q"]
[ext_resource type="Texture2D" uid="uid://jxub8lma4oud" path="res://assets/tower_background.svg" id="2_ynj1l"]
[ext_resource type="Texture2D" uid="uid://jxub8lma4oud" path="res://assets/images/tower.svg" id="2_ynj1l"]
[ext_resource type="Script" path="res://scripts/tower_health_display.gd" id="3_ijb8h"]
[sub_resource type="CircleShape2D" id="CircleShape2D_7mogk"]

View File

@ -0,0 +1,28 @@
[gd_scene load_steps=3 format=3 uid="uid://dy51uqtr2ng32"]
[ext_resource type="Script" path="res://scripts/ui/finish_screen.gd" id="1_c1emt"]
[ext_resource type="Theme" uid="uid://gh5a3no0ojkl" path="res://codingland.tres" id="1_l6ven"]
[node name="FinishScreen" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("1_l6ven")
script = ExtResource("1_c1emt")
[node name="Panel" type="Panel" parent="."]
layout_mode = 0
offset_right = 1152.0
offset_bottom = 648.0
[node name="Title" type="Label" parent="Panel"]
layout_mode = 0
offset_top = 280.0
offset_right = 1152.0
offset_bottom = 364.0
theme_override_font_sizes/font_size = 64
text = "Game Over"
horizontal_alignment = 1

View File

@ -0,0 +1,78 @@
[gd_scene load_steps=5 format=3 uid="uid://cjam63kp5sg2o"]
[ext_resource type="Script" path="res://scripts/ui/stats_overlay.gd" id="1_iejg3"]
[ext_resource type="Theme" uid="uid://gh5a3no0ojkl" path="res://codingland.tres" id="1_ne3m3"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bs475"]
bg_color = Color(0.996078, 0.996078, 0.996078, 0.588235)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rfnxc"]
bg_color = Color(0.517647, 0.729412, 0.478431, 1)
[node name="StatsOverlay" type="Control" node_paths=PackedStringArray("survived_indicator", "wave_indicator", "wave_progress")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("1_ne3m3")
script = ExtResource("1_iejg3")
survived_indicator = NodePath("SurvivedControl/SurvivedTime")
wave_indicator = NodePath("WaveControl/WaveCount")
wave_progress = NodePath("WaveControl/WaveProgress")
[node name="SurvivedControl" type="Control" parent="."]
anchors_preset = 0
offset_top = 570.0
offset_right = 1152.0
offset_bottom = 648.0
[node name="SurvivedCaption" type="Label" parent="SurvivedControl"]
layout_mode = 0
offset_right = 1152.0
offset_bottom = 26.0
theme_override_font_sizes/font_size = 18
text = "You survived"
horizontal_alignment = 1
[node name="SurvivedTime" type="Label" parent="SurvivedControl"]
layout_mode = 0
offset_top = 20.0
offset_right = 1152.0
offset_bottom = 65.0
theme_override_font_sizes/font_size = 32
text = "0.0s"
horizontal_alignment = 1
[node name="WaveControl" type="Control" parent="."]
anchors_preset = 0
offset_right = 1152.0
offset_bottom = 648.0
[node name="WaveCaption" type="Label" parent="WaveControl"]
layout_mode = 0
offset_top = 14.0
offset_right = 1152.0
offset_bottom = 40.0
theme_override_font_sizes/font_size = 18
text = "Wave"
horizontal_alignment = 1
[node name="WaveCount" type="Label" parent="WaveControl"]
layout_mode = 0
offset_top = 34.0
offset_right = 1152.0
offset_bottom = 79.0
theme_override_font_sizes/font_size = 32
text = "1"
horizontal_alignment = 1
[node name="WaveProgress" type="ProgressBar" parent="WaveControl"]
custom_minimum_size = Vector2(2.08165e-12, 10)
layout_mode = 0
offset_right = 1152.0
offset_bottom = 8.0
theme_override_styles/background = SubResource("StyleBoxFlat_bs475")
theme_override_styles/fill = SubResource("StyleBoxFlat_rfnxc")
show_percentage = false

View File

@ -1,6 +1,7 @@
extends CharacterBody2D
@export var damage = 12.0
@export var knockback = 4
func _physics_process(delta):
var collision = move_and_collide(velocity * delta)
@ -8,6 +9,8 @@ func _physics_process(delta):
if collision:
var collider = collision.get_collider()
if collider is Enemy:
var normal = collision.get_normal()
collider.velocity = collider.velocity.bounce(normal) * knockback
collider.take_damage(damage)
queue_free()

View File

@ -2,6 +2,8 @@ class_name Enemy
extends CharacterBody2D
signal enemy_defeat
@export var damage = 8.0
@export var max_health = 20
@ -13,4 +15,5 @@ func _ready():
func take_damage(amount: float):
health -= amount
if health <= 0:
enemy_defeat.emit()
queue_free()

View File

@ -1,11 +1,15 @@
extends Node2D
signal enemy_defeat
@export var common_parent: Node2D
@export var path_follow: PathFollow2D
@export var target: PackedScene
@export var common_target: Node2D
@export var respawn_timer: Timer
func spawn():
var instance = target.instantiate()
@ -18,6 +22,16 @@ func spawn():
instance.speed = randi_range(800, 1400)
instance.target = common_target
instance.connect("enemy_defeat", _on_enemy_defeat)
# Add into common parent
common_parent.add_child(instance)
func _on_wave_finished():
respawn_timer.stop()
func _on_wave_started():
respawn_timer.start()
func _on_enemy_defeat():
enemy_defeat.emit()

View File

@ -14,6 +14,8 @@ extends CharacterBody2D
@export var fire_cooldown_duration = 0.2
@export var fire_cooldown_timer: Timer
@export var statistics: Statistics
func deal_move(delta):
var input_direction = Input.get_vector("move_left", "move_right", "move_up", "move_down")
velocity = velocity.move_toward(input_direction * speed, speed * delta)
@ -36,6 +38,7 @@ func deal_weapon_shoot():
bullet.global_position = global_position
bullet.velocity = direction * weapon_bullet_speed
statistics.bullet_shoot += 1
fire_cooldown_timer.start(fire_cooldown_duration)
func _on_dash_cooled_down():

71
scripts/statistics.gd Normal file
View File

@ -0,0 +1,71 @@
class_name Statistics
extends Node
signal wave_finished
signal wave_started
var time_started
var time_survived
var wave_passed: int
var in_wave_gap: bool
var enemies_defeated: int
var bullet_shoot: int
@export var wave_gap_duration = 10
@export var wave_duration = 10
@export var wave_multiplier = 1.5
@export var wave_timer: Timer
@export var wave_gap_timer: Timer
func _ready():
time_started = Time.get_ticks_msec()
time_survived = null
wave_passed = 0
enemies_defeated = 0
bullet_shoot = 0
_on_wave_gap_passed()
func _on_game_over():
time_survived = get_time_survived()
func get_current_wave():
return wave_passed + 1
func get_current_wave_time():
if in_wave_gap:
return get_current_wave_duration() - $WaveGapTimer.time_left
else:
return get_current_wave_duration() - $WaveTimer.time_left
func get_current_wave_duration():
if in_wave_gap:
return wave_gap_duration
else:
return wave_duration + wave_multiplier * wave_passed
func get_time_survived():
if time_survived == null:
return Time.get_ticks_msec() - time_started
else:
return time_survived
func _on_enemy_defeated():
enemies_defeated += 1
func _on_wave_passed():
wave_passed += 1
in_wave_gap = true
wave_finished.emit()
wave_gap_timer.start(wave_gap_duration)
func _on_wave_gap_passed():
in_wave_gap = false
wave_started.emit()
wave_timer.wait_time = get_current_wave_duration()
wave_timer.start()

View File

@ -2,6 +2,6 @@ extends Sprite2D
@export var regeneration_progress = 0.5
func _process(delta):
func _process(_wdelta):
set_modulate(Color(1, 1, 1, regeneration_progress))
rotation_degrees += 1

View File

@ -0,0 +1,6 @@
extends Control
@export var stats: Statistics
func _show():
visible = true

View File

@ -0,0 +1,25 @@
extends Control
@export var stats: Statistics
@export var survived_indicator: Label
@export var wave_indicator: Label
@export var wave_progress: ProgressBar
var wave_stylebox = StyleBoxFlat.new()
var wave_gap_stylebox = StyleBoxFlat.new()
func _ready():
wave_stylebox.bg_color = Color("84ba7a")
wave_gap_stylebox.bg_color = Color("89a1e5")
func _process(_delta):
survived_indicator.text = "%.2fs" % (stats.get_time_survived() / 1000.0)
wave_indicator.text = "%d" % stats.get_current_wave()
if stats.in_wave_gap:
wave_progress.add_theme_stylebox_override("fill", wave_gap_stylebox)
else:
wave_progress.add_theme_stylebox_override("fill", wave_stylebox)
wave_progress.value = stats.get_current_wave_time() / stats.get_current_wave_duration() * 100