diff --git a/components/Abstracts/EntityBase.tscn b/components/Abstracts/EntityBase.tscn index 17003d2..e6f47ea 100644 --- a/components/Abstracts/EntityBase.tscn +++ b/components/Abstracts/EntityBase.tscn @@ -23,6 +23,21 @@ animations = [{ [sub_resource type="CircleShape2D" id="CircleShape2D_buhm1"] radius = 40.0 +[sub_resource type="Animation" id="Animation_sxh2u"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:scale") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(-1, 1)] +} + [sub_resource type="Animation" id="Animation_vxanw"] resource_name = "left" tracks/0/type = "value" @@ -53,21 +68,6 @@ tracks/0/keys = { "values": [Vector2(1, 1)] } -[sub_resource type="Animation" id="Animation_sxh2u"] -length = 0.001 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath(".:scale") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector2(-1, 1)] -} - [sub_resource type="AnimationLibrary" id="AnimationLibrary_daot2"] _data = { "RESET": SubResource("Animation_sxh2u"), @@ -178,6 +178,8 @@ unique_name_in_owner = true [node name="sprint" type="AudioStreamPlayer2D" parent="sounds"] +[node name="heal" type="AudioStreamPlayer2D" parent="sounds"] + [node name="miss" type="AudioStreamPlayer2D" parent="sounds"] [node name="hurt" type="AudioStreamPlayer2D" parent="sounds"] diff --git a/components/Abstracts/FeedCardBase.tscn b/components/Abstracts/FeedCardBase.tscn index e448f5e..ef615e2 100644 --- a/components/Abstracts/FeedCardBase.tscn +++ b/components/Abstracts/FeedCardBase.tscn @@ -65,6 +65,7 @@ layout_mode = 2 [node name="costs" type="GridContainer" parent="container"] unique_name_in_owner = true layout_mode = 2 +size_flags_vertical = 10 theme_override_constants/h_separation = 10 theme_override_constants/v_separation = 10 columns = 2 diff --git a/components/Bullets/FireScan.tscn b/components/Bullets/FireScan.tscn index 0e7dfcf..45fd73c 100644 --- a/components/Bullets/FireScan.tscn +++ b/components/Bullets/FireScan.tscn @@ -9,8 +9,8 @@ a = Vector2(0, -10) [node name="FireScan" instance=ExtResource("1_cqre5")] script = ExtResource("2_qprdp") fields = { -0: 10, -1: 30, +0: 20, +1: 40, 2: 0 } lifeDistance = 200.0 diff --git a/components/Characters/Chick.tscn b/components/Characters/Chick.tscn index 9eb8eaa..92a52fe 100644 --- a/components/Characters/Chick.tscn +++ b/components/Characters/Chick.tscn @@ -36,8 +36,9 @@ cooldownUnit = 2000.0 displayName = "小鸡" drops = Array[int]([0, 1]) dropCounts = Array[Vector2]([Vector2(10, 20), Vector2(7, 14)]) +appleCount = Vector2i(2, 6) -[node name="hurt" parent="sounds" index="2"] +[node name="hurt" parent="sounds" index="3"] stream = ExtResource("3_ik1xf") [node name="attack1" type="AudioStreamPlayer2D" parent="sounds" index="4"] diff --git a/components/Characters/Rooster.tscn b/components/Characters/Rooster.tscn index 99a5acb..d99a8a2 100644 --- a/components/Characters/Rooster.tscn +++ b/components/Characters/Rooster.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://bm7ymrri6pykb"] +[gd_scene load_steps=12 format=3 uid="uid://bm7ymrri6pykb"] [ext_resource type="PackedScene" uid="uid://cvogxi7mktumf" path="res://components/Abstracts/EntityBase.tscn" id="1_e5pl8"] [ext_resource type="Script" path="res://scripts/Contents/Characters/Rooster.gd" id="2_oqdqd"] @@ -6,6 +6,7 @@ [ext_resource type="AudioStream" uid="uid://dclinyhu256xi" path="res://resources/sounds/effect/Low Whoosh.mp3" id="3_4syso"] [ext_resource type="Texture2D" uid="uid://ci2ik43ce82uy" path="res://resources/characters/cock/rooster-b.svg" id="3_b0fgx"] [ext_resource type="AudioStream" uid="uid://cdrevrq7n6yqa" path="res://resources/sounds/effect/Boing.mp3" id="4_66s6c"] +[ext_resource type="AudioStream" uid="uid://benyec5bqni0b" path="res://resources/sounds/effect/Chomp.wav" id="4_k0yme"] [ext_resource type="AudioStream" uid="uid://dmxh3bpk8vyy5" path="res://resources/sounds/effect/Coin.mp3" id="5_xnbhq"] [ext_resource type="AudioStream" uid="uid://des7x0l4f3ijc" path="res://resources/sounds/effect/Low Boing.mp3" id="6_nmmw2"] @@ -37,21 +38,20 @@ radius = 41.0122 [node name="Rooster" instance=ExtResource("1_e5pl8")] script = ExtResource("2_oqdqd") cooldownUnit = 200.0 -inventory = { -0: 100, -1: 100 -} [node name="sprint" parent="sounds" index="0"] stream = ExtResource("4_66s6c") -[node name="miss" parent="sounds" index="1"] +[node name="heal" parent="sounds" index="1"] +stream = ExtResource("4_k0yme") + +[node name="miss" parent="sounds" index="2"] stream = ExtResource("5_xnbhq") -[node name="hurt" parent="sounds" index="2"] +[node name="hurt" parent="sounds" index="3"] stream = ExtResource("6_nmmw2") -[node name="attack0" parent="sounds" index="3"] +[node name="attack0" parent="sounds" index="4"] stream = ExtResource("3_4syso") [node name="texture" parent="." index="1"] diff --git a/components/Feeds/Banana.tscn b/components/Feeds/Banana.tscn index 0f7f726..8bf7626 100644 --- a/components/Feeds/Banana.tscn +++ b/components/Feeds/Banana.tscn @@ -6,10 +6,10 @@ [node name="Banana" instance=ExtResource("1_vapev")] avatarTexture = ExtResource("2_2mlfi") displayName = "香蕉" -fields = Array[int]([0, 3, 1]) -fieldValues = Array[float]([10.0, 0.1, 0.1]) +fields = Array[int]([0, 3]) +fieldValues = Array[float]([10.0, 0.12]) costs = Array[int]([0, 1]) -costCounts = Array[int]([10, 5]) +costCounts = Array[int]([100, 55]) [node name="avatar" parent="container/info" index="0"] texture = ExtResource("2_2mlfi") diff --git a/components/Feeds/Cake.tscn b/components/Feeds/Cake.tscn new file mode 100644 index 0000000..9622af6 --- /dev/null +++ b/components/Feeds/Cake.tscn @@ -0,0 +1,19 @@ +[gd_scene load_steps=4 format=3 uid="uid://dl34e70hpckp0"] + +[ext_resource type="PackedScene" uid="uid://bykwevnv7keeh" path="res://components/Abstracts/FeedCardBase.tscn" id="1_f2mv8"] +[ext_resource type="Texture2D" uid="uid://b7vxserbhskol" path="res://resources/feeds/banana.svg" id="2_1wmlm"] +[ext_resource type="Texture2D" uid="uid://bfioxi3ehf4kv" path="res://resources/feeds/cake-a.svg" id="2_ijk6h"] + +[node name="Cake" instance=ExtResource("1_f2mv8")] +avatarTexture = ExtResource("2_ijk6h") +displayName = "生日蛋糕" +fields = Array[int]([4, 8]) +fieldValues = Array[float]([0.06, 0.075]) +costs = Array[int]([1]) +costCounts = Array[int]([70]) + +[node name="avatar" parent="container/info" index="0"] +texture = ExtResource("2_1wmlm") + +[node name="name" parent="container/info" index="1"] +text = "[b]香蕉[/b]" diff --git a/components/Feeds/Puffs.tscn b/components/Feeds/Puffs.tscn new file mode 100644 index 0000000..81e209c --- /dev/null +++ b/components/Feeds/Puffs.tscn @@ -0,0 +1,19 @@ +[gd_scene load_steps=3 format=3 uid="uid://dvl7u4jkugkhk"] + +[ext_resource type="PackedScene" uid="uid://bykwevnv7keeh" path="res://components/Abstracts/FeedCardBase.tscn" id="1_1jl1i"] +[ext_resource type="Texture2D" uid="uid://d3op67s1hysla" path="res://resources/feeds/cheesy puffs.png" id="2_p35iw"] + +[node name="Puffs" instance=ExtResource("1_1jl1i")] +avatarTexture = ExtResource("2_p35iw") +displayName = "奶酪泡芙" +fields = Array[int]([10, 5, 13]) +fieldValues = Array[float]([0.06, 0.12, 0.3]) +costs = Array[int]([0, 1]) +costCounts = Array[int]([250, 100]) +metadata/_edit_lock_ = true + +[node name="avatar" parent="container/info" index="0"] +texture = ExtResource("2_p35iw") + +[node name="name" parent="container/info" index="1"] +text = "[b]奶酪泡芙[/b]" diff --git a/components/Scenes/FullscreenPanels/MakeFeed.tscn b/components/Scenes/FullscreenPanels/MakeFeed.tscn index de501e1..4ec1a58 100644 --- a/components/Scenes/FullscreenPanels/MakeFeed.tscn +++ b/components/Scenes/FullscreenPanels/MakeFeed.tscn @@ -1,8 +1,10 @@ -[gd_scene load_steps=4 format=3 uid="uid://1n28ji5sl6bx"] +[gd_scene load_steps=6 format=3 uid="uid://1n28ji5sl6bx"] [ext_resource type="PackedScene" uid="uid://d3qojeqa3difn" path="res://components/Abstracts/FullscreenPanelBase.tscn" id="1_1wmro"] [ext_resource type="Script" path="res://scripts/Contents/Panels/MakeFeed.gd" id="2_pr610"] [ext_resource type="PackedScene" uid="uid://btisbc7ehj4fo" path="res://components/Feeds/Banana.tscn" id="3_f2lyw"] +[ext_resource type="PackedScene" uid="uid://dl34e70hpckp0" path="res://components/Feeds/Cake.tscn" id="4_lykfv"] +[ext_resource type="PackedScene" uid="uid://dvl7u4jkugkhk" path="res://components/Feeds/Puffs.tscn" id="5_qnkr0"] [node name="MakeFeed" instance=ExtResource("1_1wmro")] script = ExtResource("2_pr610") @@ -64,10 +66,7 @@ alignment = 1 unique_name_in_owner = true [node name="Banana" parent="content/wrapper/avaliableFeeds" index="0" instance=ExtResource("3_f2lyw")] -visible = false -[node name="Banana2" parent="content/wrapper/avaliableFeeds" index="1" instance=ExtResource("3_f2lyw")] -visible = false +[node name="Cake" parent="content/wrapper/avaliableFeeds" index="1" instance=ExtResource("4_lykfv")] -[node name="Banana3" parent="content/wrapper/avaliableFeeds" index="2" instance=ExtResource("3_f2lyw")] -visible = false +[node name="Puffs" parent="content/wrapper/avaliableFeeds" index="2" instance=ExtResource("5_qnkr0")] diff --git a/components/Scenes/UI.tscn b/components/Scenes/UI.tscn index c028a9b..19a7968 100644 --- a/components/Scenes/UI.tscn +++ b/components/Scenes/UI.tscn @@ -60,6 +60,11 @@ unique_name_in_owner = true layout_mode = 2 type = 1 +[node name="apple" parent="root/items/container" instance=ExtResource("3_o2oi4")] +unique_name_in_owner = true +layout_mode = 2 +type = 2 + [node name="panels" type="Control" parent="root"] unique_name_in_owner = true layout_mode = 1 diff --git a/project.godot b/project.godot index 963ea96..f83cf21 100644 --- a/project.godot +++ b/project.godot @@ -56,6 +56,11 @@ sprint={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) ] } +heal={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"key_label":0,"unicode":114,"location":0,"echo":false,"script":null) +] +} [physics] diff --git a/resources/feeds/cake-a.svg b/resources/feeds/cake-a.svg new file mode 100644 index 0000000..927315a --- /dev/null +++ b/resources/feeds/cake-a.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/feeds/cake-a.svg.import b/resources/feeds/cake-a.svg.import new file mode 100644 index 0000000..d886e91 --- /dev/null +++ b/resources/feeds/cake-a.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bfioxi3ehf4kv" +path="res://.godot/imported/cake-a.svg-137d30f32205bef7a30432592ccdd5bd.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resources/feeds/cake-a.svg" +dest_files=["res://.godot/imported/cake-a.svg-137d30f32205bef7a30432592ccdd5bd.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 diff --git a/resources/feeds/cheesy puffs.png b/resources/feeds/cheesy puffs.png new file mode 100644 index 0000000..50c6d70 Binary files /dev/null and b/resources/feeds/cheesy puffs.png differ diff --git a/resources/feeds/cheesy puffs.png.import b/resources/feeds/cheesy puffs.png.import new file mode 100644 index 0000000..9cdea83 --- /dev/null +++ b/resources/feeds/cheesy puffs.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d3op67s1hysla" +path="res://.godot/imported/cheesy puffs.png-fa02975696d66e66cc98f13ef025fb66.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resources/feeds/cheesy puffs.png" +dest_files=["res://.godot/imported/cheesy puffs.png-fa02975696d66e66cc98f13ef025fb66.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 diff --git a/resources/items/apple.svg b/resources/items/apple.svg index 0a6efaa..67975b0 100644 --- a/resources/items/apple.svg +++ b/resources/items/apple.svg @@ -1,16 +1 @@ - - - - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/resources/items/apple.svg.import b/resources/items/apple.svg.import new file mode 100644 index 0000000..96c713e --- /dev/null +++ b/resources/items/apple.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://iu5i8ullbhf6" +path="res://.godot/imported/apple.svg-d6f4bd0685ab049c5d0bf7bb28035304.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resources/items/apple.svg" +dest_files=["res://.godot/imported/apple.svg-d6f4bd0685ab049c5d0bf7bb28035304.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 diff --git a/resources/sounds/effect/Chomp.wav b/resources/sounds/effect/Chomp.wav new file mode 100644 index 0000000..fde1183 Binary files /dev/null and b/resources/sounds/effect/Chomp.wav differ diff --git a/resources/sounds/effect/Chomp.wav.import b/resources/sounds/effect/Chomp.wav.import new file mode 100644 index 0000000..69d959e --- /dev/null +++ b/resources/sounds/effect/Chomp.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://benyec5bqni0b" +path="res://.godot/imported/Chomp.wav-b0cbf4d62eaef8ab4e52f661a0680a56.sample" + +[deps] + +source_file="res://resources/sounds/effect/Chomp.wav" +dest_files=["res://.godot/imported/Chomp.wav-b0cbf4d62eaef8ab4e52f661a0680a56.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=0 diff --git a/scripts/Contents/Characters/Rooster.gd b/scripts/Contents/Characters/Rooster.gd index 1c811ef..8dbccd4 100644 --- a/scripts/Contents/Characters/Rooster.gd +++ b/scripts/Contents/Characters/Rooster.gd @@ -17,6 +17,8 @@ func ai(): tryAttack(0) if Input.is_action_just_pressed("sprint"): trySprint() + if Input.is_action_just_pressed("heal"): + tryHeal(20) func attack(type): if type == 0: var weaponPos = findWeaponAnchor("normal") @@ -26,3 +28,6 @@ func sprint(): Input.get_axis("m_left", "m_right"), Input.get_axis("m_up", "m_down") ) * sprintMultiplier, true) +func heal(count: float): + health += count + DamageLabel.create(-count, false, damageAnchor.global_position + MathTool.randv2_range(GameRule.damageLabelSpawnOffset)) diff --git a/scripts/Statemachine/DamageLabel.gd b/scripts/Statemachine/DamageLabel.gd index fe3e2c0..5d7f46b 100644 --- a/scripts/Statemachine/DamageLabel.gd +++ b/scripts/Statemachine/DamageLabel.gd @@ -3,15 +3,25 @@ class_name DamageLabel @export var damage: float = 0 @export var crit: bool = false +@export var color1: Color = Color(1, 0, 0, 1) +@export var color2: Color = Color(0, 1, 0, 1) +@export var color3: Color = Color(0.5, 0.5, 0.5, 1) @onready var label: Label = $"%label" @onready var animator: AnimationPlayer = $"%animator" func _ready(): - if damage == 0: - label.text = "MISS" + var damageValue = round(abs(damage)) + var damageSign = sign(damage) + if damageSign > 0: + label.label_settings.font_color = color1 + label.text = "%s%s" % [damageValue, "!!!" if crit else ""] + elif damageSign < 0: + label.label_settings.font_color = color2 + label.text = "+%s%s" % [damageValue, "!!!" if crit else ""] else: - label.text = str(round(damage)) + ("!!!" if crit else "") + label.label_settings.font_color = color3 + label.text = "MISS" animator.play("show") await animator.animation_finished queue_free() diff --git a/scripts/Statemachine/EntityBase.gd b/scripts/Statemachine/EntityBase.gd index d9e9dd8..e600afb 100644 --- a/scripts/Statemachine/EntityBase.gd +++ b/scripts/Statemachine/EntityBase.gd @@ -9,19 +9,33 @@ var fields = { FieldStore.Entity.CRIT_RATE: 0.05, FieldStore.Entity.CRIT_DAMAGE: 1, FieldStore.Entity.PENERATE: 0, - FieldStore.Entity.OFFSET_SHOOT: 3 + FieldStore.Entity.OFFSET_SHOOT: 3, + FieldStore.Entity.HEAL_ABILITY: 1, + FieldStore.Entity.EXTRA_APPLE_MAX: 0, + FieldStore.Entity.ENERGY_MULTIPILER: 1, + FieldStore.Entity.PENARATION_RESISTANCE: 0, + FieldStore.Entity.PRICE_REDUCTION: 0, + FieldStore.Entity.EXTRA_BULLET_COUNT: 0, + FieldStore.Entity.DROP_APPLE_RATE: 0 +} +var inventory = { + ItemStore.ItemType.BASEBALL: 100, + ItemStore.ItemType.BASKETBALL: 100, + ItemStore.ItemType.APPLE: 3, +} +var inventoryMax = { + ItemStore.ItemType.BASEBALL: INF, # 无限 + ItemStore.ItemType.BASKETBALL: INF, + ItemStore.ItemType.APPLE: 20, # 最多20个苹果 } @export var cooldownUnit: float = 100 # 100毫秒每次攻击 @export var isBoss: bool = false @export var displayName: String = "未知实体" @export var sprintMultiplier: float = 7 -@export var inventory = { - ItemStore.ItemType.BASEBALL: 0, - ItemStore.ItemType.BASKETBALL: 0 -} @export var drops: Array[ItemStore.ItemType] = [] @export var dropCounts: Array[Vector2] = [] +@export var appleCount: Vector2i = Vector2(0, 1) # 死亡后掉落的苹果数量 @onready var animatree: AnimationTree = $"%animatree" @onready var texture: AnimatedSprite2D = $"%texture" @@ -29,6 +43,7 @@ var fields = { @onready var statebar: EntityStateBar = $"%statebar" @onready var sounds: Node2D = $"%sounds" @onready var hurtAnimator: AnimationPlayer = $"%hurtAnimator" +@onready var damageAnchor: Node2D = $"%damageAnchor" var health: float = 0 @@ -53,6 +68,8 @@ func _ready(): func _process(_delta): health = clamp(health, 0, fields.get(FieldStore.Entity.MAX_HEALTH)) animatree.set("parameters/blend_position", lerpf(animatree.get("parameters/blend_position"), lastDirection, 0.1)) + for i in inventory: + inventory[i] = clamp(inventory[i], 0, inventoryMax[i]) func _physics_process(_delta: float) -> void: if sprinting: velocity *= 0.9 @@ -82,13 +99,13 @@ func takeDamage(bullet: BulletBase, crit: bool): else: playSound("hurt") health -= damage - DamageLabel.create(damage, crit, $"%damageAnchor".global_position + MathTool.randv2_range(GameRule.damageLabelSpawnOffset)) + DamageLabel.create(damage, crit, damageAnchor.global_position + MathTool.randv2_range(GameRule.damageLabelSpawnOffset)) if isBoss and bullet.launcher.isPlayer(): bullet.launcher.setBoss(self) if health <= 0: if isBoss: bullet.launcher.setBoss(null) - tryDie() + tryDie(bullet) func isCooldowned(): return Time.get_ticks_msec() - lastAttack >= cooldownUnit / fields.get(FieldStore.Entity.ATTACK_SPEED) func startCooldown(): @@ -106,13 +123,21 @@ func trySprint(): playSound("sprint") sprint() sprinting = true -func tryDie(): +func tryDie(by: BulletBase): for drop in range(min(len(drops), len(dropCounts))): var item = drops[drop] var count = ceil(randf_range(dropCounts[drop].x, dropCounts[drop].y)) for i in range(count): ItemDropped.generate(item, count, position + MathTool.randv2_range(GameRule.itemDroppedSpawnOffset)) + if MathTool.rate(GameRule.appleDropRate + by.launcher.fields.get(FieldStore.Entity.DROP_APPLE_RATE)) or isBoss: + for i in randi_range(appleCount.x, appleCount.y): + ItemDropped.generate(ItemStore.ItemType.APPLE, 1, position + MathTool.randv2_range(GameRule.itemDroppedSpawnOffset)) die() +func tryHeal(count: float): + if inventory[ItemStore.ItemType.APPLE] > 0 and health < fields.get(FieldStore.Entity.MAX_HEALTH): + inventory[ItemStore.ItemType.APPLE] -= 1 + playSound("heal") + heal(count) func findWeaponAnchor(weaponName: String): var anchor = $"%weapons".get_node(weaponName) if anchor is Node2D: @@ -145,6 +170,8 @@ func die(): queue_free() func sprint(): pass +func heal(_count: float): + pass static func generate( entity: PackedScene, diff --git a/scripts/Statemachine/UIState.gd b/scripts/Statemachine/UIState.gd index 9062057..86b1a16 100644 --- a/scripts/Statemachine/UIState.gd +++ b/scripts/Statemachine/UIState.gd @@ -3,6 +3,7 @@ class_name UIState @onready var baseball = $"%baseball" @onready var basketball = $"%basketball" +@onready var apple = $"%apple" static var player: EntityBase = null static var bossbar: EntityStateBar @@ -18,6 +19,7 @@ func _physics_process(_delta): if is_instance_valid(player): baseball.count = player.inventory[ItemStore.ItemType.BASEBALL] basketball.count = player.inventory[ItemStore.ItemType.BASKETBALL] + apple.count = player.inventory[ItemStore.ItemType.APPLE] if currentPanel: WorldManager.rootNode.process_mode = Node.PROCESS_MODE_DISABLED else: diff --git a/scripts/Structs/Feed.gd b/scripts/Structs/Feed.gd index a175834..d25a8fc 100644 --- a/scripts/Structs/Feed.gd +++ b/scripts/Structs/Feed.gd @@ -64,8 +64,7 @@ func apply(entity: EntityBase): for i in range(min(fields.size(), fieldValues.size())): var field = fields[i] var value = fieldValues[i] - entity.fields[field] += value - if field == FieldStore.Entity.MAX_HEALTH: - entity.health += value - print(entity.fields) + var applier = FieldStore.entityApplier.get(field, null) + if !applier or applier.call(entity, value): + entity.fields[field] += value return allHave diff --git a/scripts/Tools/FieldStore.gd b/scripts/Tools/FieldStore.gd index 4640aa1..8eef897 100644 --- a/scripts/Tools/FieldStore.gd +++ b/scripts/Tools/FieldStore.gd @@ -14,7 +14,14 @@ enum Entity { CRIT_RATE, CRIT_DAMAGE, PENERATE, - OFFSET_SHOOT + OFFSET_SHOOT, + HEAL_ABILITY, + EXTRA_APPLE_MAX, + ENERGY_MULTIPILER, + PENARATION_RESISTANCE, + PRICE_REDUCTION, + EXTRA_BULLET_COUNT, + DROP_APPLE_RATE } static var entityMap = { Entity.MAX_HEALTH: "最大生命值", @@ -24,7 +31,14 @@ static var entityMap = { Entity.CRIT_RATE: "暴击率", Entity.CRIT_DAMAGE: "暴击伤害", Entity.PENERATE: "穿透", - Entity.OFFSET_SHOOT: "散射角" + Entity.OFFSET_SHOOT: "散射角", + Entity.HEAL_ABILITY: "治疗量", + Entity.EXTRA_APPLE_MAX: "苹果上限", + Entity.ENERGY_MULTIPILER: "能量倍率", + Entity.PENARATION_RESISTANCE: "穿透抗性", + Entity.PRICE_REDUCTION: "饲料降价", + Entity.EXTRA_BULLET_COUNT: "额外子弹", + Entity.DROP_APPLE_RATE: "苹果掉落率" } static var entityMapType = { Entity.MAX_HEALTH: DataType.VALUE, @@ -34,7 +48,22 @@ static var entityMapType = { Entity.CRIT_RATE: DataType.PERCENT, Entity.CRIT_DAMAGE: DataType.PERCENT, Entity.PENERATE: DataType.PERCENT, - Entity.OFFSET_SHOOT: DataType.ANGLE + Entity.OFFSET_SHOOT: DataType.ANGLE, + Entity.HEAL_ABILITY: DataType.PERCENT, + Entity.EXTRA_APPLE_MAX: DataType.VALUE, + Entity.ENERGY_MULTIPILER: DataType.PERCENT, + Entity.PENARATION_RESISTANCE: DataType.PERCENT, + Entity.PRICE_REDUCTION: DataType.PERCENT, + Entity.EXTRA_BULLET_COUNT: DataType.VALUE, + Entity.DROP_APPLE_RATE: DataType.PERCENT +} +static var entityApplier = { + Entity.MAX_HEALTH: func(entity, value): + entity.health += value + , + Entity.EXTRA_APPLE_MAX: func(entity, value): + entity.inventoryMax[ItemStore.ItemType.APPLE] += value + , } enum Bullet { diff --git a/scripts/Tools/GameRule.gd b/scripts/Tools/GameRule.gd index f6867fe..d7322ff 100644 --- a/scripts/Tools/GameRule.gd +++ b/scripts/Tools/GameRule.gd @@ -5,3 +5,4 @@ static var bulletSpeedMultiplier: float = 1 # 子弹速度倍率 static var damageOffset: float = 0.2 # 伤害随机浮动比例,默认20%,即10的基础伤害会应用为8~12 static var damageLabelSpawnOffset: float = 10 # 伤害标签生成位置的随机偏移 static var itemDroppedSpawnOffset: float = 30 # 掉落物生成位置的随机偏移 +static var appleDropRate: float = 0.1 # 苹果掉落概率 \ No newline at end of file diff --git a/scripts/Tools/ItemStore.gd b/scripts/Tools/ItemStore.gd index 0448f7f..06417ca 100644 --- a/scripts/Tools/ItemStore.gd +++ b/scripts/Tools/ItemStore.gd @@ -3,15 +3,18 @@ class_name ItemStore enum ItemType { BASEBALL, - BASKETBALL + BASKETBALL, + APPLE } static var nameMap = { ItemType.BASEBALL: "棒球", - ItemType.BASKETBALL: "篮球" + ItemType.BASKETBALL: "篮球", + ItemType.APPLE: "苹果" } static var idMap = { ItemType.BASEBALL: "baseball", - ItemType.BASKETBALL: "basketball" + ItemType.BASKETBALL: "basketball", + ItemType.APPLE: "apple" } static func getTexture(type: ItemType) -> Texture2D: - return load("res://resources/items/%s.svg" % idMap[type]) \ No newline at end of file + return load("res://resources/items/%s.svg" % idMap[type])