diff --git a/assets/PunchVFX.aseprite b/assets/PunchVFX.aseprite new file mode 100644 index 0000000..6419fb6 Binary files /dev/null and b/assets/PunchVFX.aseprite differ diff --git a/assets/PunchVFX.aseprite.import b/assets/PunchVFX.aseprite.import new file mode 100644 index 0000000..825549c --- /dev/null +++ b/assets/PunchVFX.aseprite.import @@ -0,0 +1,14 @@ +[remap] + +importer="aseprite_wizard.plugin.noop" +type="PackedDataContainer" +uid="uid://sg2ms6cssj01" +path="res://.godot/imported/PunchVFX.aseprite-b06de0b1aa18d48e800d94ff6cf92f62.res" + +[deps] + +source_file="res://assets/PunchVFX.aseprite" +dest_files=["res://.godot/imported/PunchVFX.aseprite-b06de0b1aa18d48e800d94ff6cf92f62.res"] + +[params] + diff --git a/assets/export/punch-.png b/assets/export/punch-.png new file mode 100644 index 0000000..1848045 Binary files /dev/null and b/assets/export/punch-.png differ diff --git a/assets/export/punch-.png.import b/assets/export/punch-.png.import new file mode 100644 index 0000000..644873f --- /dev/null +++ b/assets/export/punch-.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cv731yjx5v71a" +path="res://.godot/imported/punch-.png-0d4c585a346b088b7f81847a43a045e4.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/export/punch-.png" +dest_files=["res://.godot/imported/punch-.png-0d4c585a346b088b7f81847a43a045e4.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/assets/weegee.aseprite b/assets/weegee.aseprite new file mode 100644 index 0000000..38ccd05 Binary files /dev/null and b/assets/weegee.aseprite differ diff --git a/assets/weegee.aseprite.import b/assets/weegee.aseprite.import new file mode 100644 index 0000000..b1c3ab9 --- /dev/null +++ b/assets/weegee.aseprite.import @@ -0,0 +1,14 @@ +[remap] + +importer="aseprite_wizard.plugin.noop" +type="PackedDataContainer" +uid="uid://boc2fqbk18m6" +path="res://.godot/imported/weegee.aseprite-3b2165eb9806715fac46d106c4ddf9ee.res" + +[deps] + +source_file="res://assets/weegee.aseprite" +dest_files=["res://.godot/imported/weegee.aseprite-3b2165eb9806715fac46d106c4ddf9ee.res"] + +[params] + diff --git a/components/Crawler.tscn b/components/Crawler.tscn index 89d4958..5de7c43 100644 --- a/components/Crawler.tscn +++ b/components/Crawler.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=35 format=3 uid="uid://n65kl0jalqdt"] +[gd_scene load_steps=36 format=3 uid="uid://n65kl0jalqdt"] [ext_resource type="Texture2D" uid="uid://b447sysxt4rhp" path="res://assets/export/crawler-.png" id="1_bdup0"] [ext_resource type="Script" path="res://scripts/crawler.gd" id="1_dcux3"] +[ext_resource type="AudioStream" uid="uid://dfrc2luquqqlw" path="res://assets/Explode.wav" id="3_qvljj"] [sub_resource type="AtlasTexture" id="AtlasTexture_6iqis"] atlas = ExtResource("1_bdup0") @@ -263,7 +264,7 @@ script = ExtResource("1_dcux3") texture_filter = 1 position = Vector2(-34, 0) sprite_frames = SubResource("SpriteFrames_e3bx4") -animation = &"jump away" +animation = &"Whip" metadata/_aseprite_wizard_config_ = { "layer": "", "o_ex_p": "", @@ -288,3 +289,24 @@ shape = SubResource("RectangleShape2D_k4vrw") position = Vector2(-42, 1) shape = SubResource("RectangleShape2D_s2a15") debug_color = Color(0.949698, 0.110143, 0.492661, 0.42) + +[node name="ExplosionSFX" type="AudioStreamPlayer2D" parent="."] +position = Vector2(-34, 0) +stream = ExtResource("3_qvljj") +volume_db = 10.0 + +[node name="DeathTimer" type="Timer" parent="."] +wait_time = 1.1 +one_shot = true + +[node name="HurtTimer" type="Timer" parent="."] +wait_time = 0.6 +one_shot = true + +[node name="AttackTimer" type="Timer" parent="."] +wait_time = 0.5 +one_shot = true + +[node name="Recharge" type="Timer" parent="."] +wait_time = 0.5 +one_shot = true diff --git a/components/Player.tscn b/components/Player.tscn index 9100115..a09103a 100644 --- a/components/Player.tscn +++ b/components/Player.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=79 format=3 uid="uid://cjiuycwqqxaxn"] +[gd_scene load_steps=88 format=3 uid="uid://cjiuycwqqxaxn"] [ext_resource type="Script" path="res://scripts/player.gd" id="1_oy25y"] [ext_resource type="Texture2D" uid="uid://d4mjdwhmho5vs" path="res://assets/export/player-Layer 5.png" id="2_g0lnn"] [ext_resource type="AudioStream" uid="uid://cir5d1qi0hcev" path="res://assets/PlayerHurt.wav" id="3_ggoam"] +[ext_resource type="Texture2D" uid="uid://cv731yjx5v71a" path="res://assets/export/punch-.png" id="3_jp05m"] [ext_resource type="AudioStream" uid="uid://du0f57xgcxuxf" path="res://assets/PlayerDeathSound.wav" id="4_8skcp"] [ext_resource type="Texture2D" uid="uid://cliy3s4yykb3k" path="res://assets/export/health-.png" id="5_1x6di"] @@ -612,6 +613,63 @@ size = Vector2(28, 64) [sub_resource type="RectangleShape2D" id="RectangleShape2D_mst3b"] size = Vector2(27, 41) +[sub_resource type="AtlasTexture" id="AtlasTexture_1n7yn"] +atlas = ExtResource("3_jp05m") +region = Rect2(0, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_dtbdr"] +atlas = ExtResource("3_jp05m") +region = Rect2(32, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_dhtio"] +atlas = ExtResource("3_jp05m") +region = Rect2(64, 0, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_t4yk0"] +atlas = ExtResource("3_jp05m") +region = Rect2(0, 32, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_1emd7"] +atlas = ExtResource("3_jp05m") +region = Rect2(32, 32, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ccqcb"] +atlas = ExtResource("3_jp05m") +region = Rect2(64, 32, 32, 32) + +[sub_resource type="AtlasTexture" id="AtlasTexture_g0kbm"] +atlas = ExtResource("3_jp05m") +region = Rect2(0, 64, 32, 32) + +[sub_resource type="SpriteFrames" id="SpriteFrames_sbboq"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_1n7yn") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_dtbdr") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_dhtio") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_t4yk0") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_1emd7") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ccqcb") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_g0kbm") +}], +"loop": true, +"name": &"default", +"speed": 10.0 +}] + [sub_resource type="AtlasTexture" id="AtlasTexture_5bnwc"] atlas = ExtResource("5_1x6di") region = Rect2(128, 16, 64, 16) @@ -723,6 +781,24 @@ position = Vector2(29, -3) shape = SubResource("RectangleShape2D_mst3b") debug_color = Color(2.11775e-06, 0.631094, 0.465774, 0.42) +[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="PunchHitbox"] +texture_filter = 1 +position = Vector2(26, -6) +sprite_frames = SubResource("SpriteFrames_sbboq") +metadata/_aseprite_wizard_config_ = { +"layer": "", +"o_ex_p": "", +"o_folder": "res://assets/export", +"o_name": "punch-", +"only_visible": true, +"slice": "", +"source": "res://assets/PunchVFX.aseprite" +} +metadata/_aseprite_wizard_interface_config_ = { +"output_section": true +} +metadata/_aseprite_wizard_source_file_hash_ = "4c71a20217ed605bc54873905f5606e3" + [node name="AttackTimer" type="Timer" parent="."] editor_description = " diff --git a/levels/level1/stage2.tscn b/levels/level1/stage2.tscn index bd43f2e..bba84d8 100644 --- a/levels/level1/stage2.tscn +++ b/levels/level1/stage2.tscn @@ -37,7 +37,7 @@ scale = Vector2(1.01667, 1) texture = ExtResource("4_d2h5p") [node name="Player" parent="." instance=ExtResource("5_kc5l1")] -position = Vector2(-40, -49) +position = Vector2(-154, -43) [node name="Borders" parent="." instance=ExtResource("6_47554")] position = Vector2(-272, -240) @@ -71,10 +71,10 @@ one_shot = true script = ExtResource("9_2n06p") [node name="Crawler2" parent="Level2Spawner" instance=ExtResource("9_sqnor")] -position = Vector2(-200, -41) +position = Vector2(-306, -39) [node name="Crawler" parent="Level2Spawner" instance=ExtResource("9_sqnor")] -position = Vector2(168, -41) +position = Vector2(307, -42) [node name="Floor" type="StaticBody2D" parent="."] diff --git a/scripts/crawler.gd b/scripts/crawler.gd index 6f79568..1958b2c 100644 --- a/scripts/crawler.gd +++ b/scripts/crawler.gd @@ -4,18 +4,29 @@ class_name Crawler extends Entity @onready var sprite = $AnimatedSprite2D @onready var main_collider = $CollisionShape2D @onready var whip = $WhipArea +@onready var speed_mult = 0 +@onready var is_dying = false +@onready var explosion_sfx = $ExplosionSFX +@onready var death_timer = $DeathTimer +@onready var hurting = false +@onready var hurt_timer = $HurtTimer +@onready var attack_timer = $AttackTimer +@onready var recharge_timer = $Recharge ## Crawl towards the player but stay within striking distance and not super close -const HEALTH = 40 +const HEALTH = 45 const SPEED_MULTIPLIER = 50 const ATTACK_DAMAGE = 20 +var death_timer_started = false +var attacking = true + func _init() -> void: super._init(HEALTH, SPEED_MULTIPLIER, ATTACK_DAMAGE) -#func _ready() -> void: - #whip.visible = false +func _ready() -> void: + whip.visible = false func face_player(): var player_position = player.global_position @@ -36,21 +47,65 @@ func _physics_process(delta: float) -> void: var distanceToPlayer = global_position.distance_to(player.global_position) var desiredDistance = 70 - if sprite.flip_h: - desiredDistance -= 69 - face_player() - print(distanceToPlayer) + if health <= 0 and !death_timer_started: + is_dying = true + death_timer_started = true + death_timer.start() - if distanceToPlayer > desiredDistance: - velocity.x = speed - face_player() + if !is_dying: + if !hurting: + if sprite.flip_h: + desiredDistance -= 69 + face_player() + + if distanceToPlayer > desiredDistance: + velocity.x = speed * speed_mult + face_player() + + if not sprite.flip_h: + velocity.x *= -1 + + sprite.play("walk") + else: + if recharge_timer.is_stopped(): + attacking = true + whip.visible = true + whip.connect("body_entered", whip_hit) + attack_timer.start() + + if attacking and !attack_timer.is_stopped(): + velocity.x = 0 + sprite.play("Whip") + elif attacking and attack_timer.is_stopped(): + recharge_timer.start() + whip.visible = false + whip.disconnect("body_entered", whip_hit) + attacking = false + - if not sprite.flip_h: - velocity.x *= -1 - - sprite.play("walk") + if hurt_timer.is_stopped(): + hurting = false + else: + sprite.play("jump back") + + move_and_slide() else: - velocity.x = 0 - sprite.play("Whip") + sprite.play("death") + explosion_sfx.play() + speed_mult = 0 + if death_timer.is_stopped(): + queue_free() - move_and_slide() +func charge() -> void: + speed_mult = 1 + +func hurt_anim(): + hurting = true + hurt_timer.start() + +func whip_hit(node: Node) -> void: + if node is Player: + node.health -= ATTACK_DAMAGE + node.take_knockback(50) + if node.has_method("hurt_anim"): + node.call("hurt_anim") diff --git a/scripts/player.gd b/scripts/player.gd index aa6e67c..95cb79e 100644 --- a/scripts/player.gd +++ b/scripts/player.gd @@ -12,6 +12,7 @@ class_name Player extends Entity @onready var player_death_sfx = $PlayerDeathSfx @onready var hurt_timer = $HurtTimer @onready var health_bar = $HealthBar +@onready var punch_vfx = $PunchHitbox/AnimatedSprite2D var jumping = false var facing_right = true @@ -20,7 +21,7 @@ var hurting = false var is_dying = false var is_death_sfx = false -const ATTACK_DAMAGE = 25 +const ATTACK_DAMAGE = 20 const INITIAL_HEALTH = 50 const SPEED_MULTIPLIER = 300 const ATTACK_KNOCKBACK = 5000 @@ -103,6 +104,7 @@ func _process(delta: float) -> void: if attack_timer.is_stopped() and Input.is_action_just_pressed("attack"): attack_timer.start() + punch_vfx.play("default") if is_on_floor(): animated_sprite.play("Right" if right_punch else "Left") diff --git a/scripts/stage_2_spawner.gd b/scripts/stage_2_spawner.gd index f1ed8f0..632c3a5 100644 --- a/scripts/stage_2_spawner.gd +++ b/scripts/stage_2_spawner.gd @@ -1,15 +1,21 @@ extends Node2D @onready var complete = false +@onready var wave_1 = [$Crawler, $Crawler2] # Called when the node enters the scene tree for the first time. func _ready() -> void: - pass # Replace with function body. - + for crawler in wave_1: + crawler.charge() # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: - pass + for crawler in wave_1: + if crawler.is_dying: + wave_1.erase(crawler) + + if wave_1 == []: + complete = true func is_complete() -> bool: return complete