diff --git a/assets/graphics/player/dead/Player Death 64x64.png b/assets/graphics/player/dead/Player Death 64x64.png new file mode 100644 index 0000000..2e6a1ae Binary files /dev/null and b/assets/graphics/player/dead/Player Death 64x64.png differ diff --git a/assets/graphics/player/dead/Player Death 64x64.png.import b/assets/graphics/player/dead/Player Death 64x64.png.import new file mode 100644 index 0000000..303f5d4 --- /dev/null +++ b/assets/graphics/player/dead/Player Death 64x64.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b0kep0pa3fgop" +path="res://.godot/imported/Player Death 64x64.png-a1335d3f0d31c2c547d022fdb8875398.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/graphics/player/dead/Player Death 64x64.png" +dest_files=["res://.godot/imported/Player Death 64x64.png-a1335d3f0d31c2c547d022fdb8875398.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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/graphics/player/hurt/Player Hurt 48x48.png b/assets/graphics/player/hurt/Player Hurt 48x48.png new file mode 100644 index 0000000..57d8783 Binary files /dev/null and b/assets/graphics/player/hurt/Player Hurt 48x48.png differ diff --git a/assets/graphics/player/hurt/Player Hurt 48x48.png.import b/assets/graphics/player/hurt/Player Hurt 48x48.png.import new file mode 100644 index 0000000..76888e5 --- /dev/null +++ b/assets/graphics/player/hurt/Player Hurt 48x48.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cw3itaxh0fjob" +path="res://.godot/imported/Player Hurt 48x48.png-a720e51cb19103e76b22ab6c1b81302d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/graphics/player/hurt/Player Hurt 48x48.png" +dest_files=["res://.godot/imported/Player Hurt 48x48.png-a720e51cb19103e76b22ab6c1b81302d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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/project.godot b/project.godot index 83914df..987f30e 100644 --- a/project.godot +++ b/project.godot @@ -27,12 +27,6 @@ window/size/window_width_override=960 window/size/window_height_override=540 window/stretch/mode="viewport" -[file_customization] - -folder_colors={ -"res://scripts/": "red" -} - [input] shove={ diff --git a/scenes/player.tscn b/scenes/player.tscn index 3ce7f81..60507fd 100644 --- a/scenes/player.tscn +++ b/scenes/player.tscn @@ -4,6 +4,8 @@ [ext_resource type="Texture2D" uid="uid://d2e455oxjbsf5" path="res://assets/graphics/player/jump/player jump 48x48.png" id="2_dqkch"] [ext_resource type="Texture2D" uid="uid://dio2ufnpnihce" path="res://assets/graphics/player/idle/Player Idle 48x48.png" id="2_g2els"] [ext_resource type="Texture2D" uid="uid://bl7p2n2kgw2qx" path="res://assets/graphics/player/idle/player run 48x48.png" id="3_qhqgy"] +[ext_resource type="Texture2D" uid="uid://cw3itaxh0fjob" path="res://assets/graphics/player/hurt/Player Hurt 48x48.png" id="3_qlg0r"] +[ext_resource type="Texture2D" uid="uid://b0kep0pa3fgop" path="res://assets/graphics/player/dead/Player Death 64x64.png" id="3_tuyoq"] [sub_resource type="CapsuleShape2D" id="CapsuleShape2D_elsnr"] @@ -11,10 +13,66 @@ atlas = ExtResource("2_dqkch") region = Rect2(48, 0, 48, 48) +[sub_resource type="AtlasTexture" id="AtlasTexture_pf23h"] +atlas = ExtResource("3_tuyoq") +region = Rect2(0, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_dt7fs"] +atlas = ExtResource("3_tuyoq") +region = Rect2(48, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_wqfne"] +atlas = ExtResource("3_tuyoq") +region = Rect2(96, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_wnwbv"] +atlas = ExtResource("3_tuyoq") +region = Rect2(144, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_gl8cc"] +atlas = ExtResource("3_tuyoq") +region = Rect2(192, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_487ah"] +atlas = ExtResource("3_tuyoq") +region = Rect2(240, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_md1ol"] +atlas = ExtResource("3_tuyoq") +region = Rect2(288, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_bj30b"] +atlas = ExtResource("3_tuyoq") +region = Rect2(336, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_jc3p3"] +atlas = ExtResource("3_tuyoq") +region = Rect2(384, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_hax0n"] +atlas = ExtResource("3_tuyoq") +region = Rect2(432, 0, 48, 48) + [sub_resource type="AtlasTexture" id="AtlasTexture_i4ail"] atlas = ExtResource("2_dqkch") region = Rect2(96, 0, 48, 48) +[sub_resource type="AtlasTexture" id="AtlasTexture_l71n6"] +atlas = ExtResource("3_qlg0r") +region = Rect2(0, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ke2ow"] +atlas = ExtResource("3_qlg0r") +region = Rect2(48, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ujl30"] +atlas = ExtResource("3_qlg0r") +region = Rect2(96, 0, 48, 48) + +[sub_resource type="AtlasTexture" id="AtlasTexture_31cv2"] +atlas = ExtResource("3_qlg0r") +region = Rect2(144, 0, 48, 48) + [sub_resource type="AtlasTexture" id="AtlasTexture_qhqgy"] atlas = ExtResource("2_g2els") region = Rect2(0, 0, 48, 48) @@ -103,6 +161,41 @@ animations = [{ }, { "frames": [{ "duration": 1.0, +"texture": SubResource("AtlasTexture_pf23h") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_dt7fs") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_wqfne") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_wnwbv") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_gl8cc") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_487ah") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_md1ol") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_bj30b") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_jc3p3") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_hax0n") +}], +"loop": false, +"name": &"dead", +"speed": 12.0 +}, { +"frames": [{ +"duration": 1.0, "texture": SubResource("AtlasTexture_i4ail") }], "loop": false, @@ -111,6 +204,23 @@ animations = [{ }, { "frames": [{ "duration": 1.0, +"texture": SubResource("AtlasTexture_l71n6") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ke2ow") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ujl30") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_31cv2") +}], +"loop": false, +"name": &"hurt", +"speed": 12.0 +}, { +"frames": [{ +"duration": 1.0, "texture": SubResource("AtlasTexture_qhqgy") }, { "duration": 1.0, @@ -206,7 +316,7 @@ position = Vector2(-10, -12) texture_filter = 1 position = Vector2(0, -1) sprite_frames = SubResource("SpriteFrames_jej6c") -animation = &"apex" +animation = &"dead" autoplay = "idle" [node name="Camera2D" type="Camera2D" parent="." unique_id=1215632070] diff --git a/scripts/game_controller.gd b/scripts/game_controller.gd index 6b6eab7..c222e44 100644 --- a/scripts/game_controller.gd +++ b/scripts/game_controller.gd @@ -2,6 +2,7 @@ extends Node2D signal destroy(body) signal level_change_signal(level) +signal damage_player_signal(damage, player_health) var levels = ["res://scenes/level1.tscn","res://scenes/level2.tscn","res://scenes/level3.tscn"] var current_level_index = 0 @@ -12,8 +13,13 @@ var timer = Timer.new() var player:Player; var enemies = {} +var enemy_stats:CharacterStats +var player_stats:CharacterStats + func _ready(): - get_window().grab_focus() # Replace with function body. + get_window().grab_focus() + enemy_stats = load("res://scripts/resources/slime_stats.tres") + player_stats = load("res://scripts/resources/player_stats.tres") reset() add_child(timer) timer.wait_time = 1 @@ -31,7 +37,7 @@ func timer_tick(): func reset(): time_available = level_times[current_level_index] if player: - player.health = 5 + player.health = player_stats.starting_health func stop(): timer.stop() @@ -47,7 +53,6 @@ func _on_area_2d_trigger_active_signal(body, intentMessage): var crate_num : int = 0 func set_crate_num(count: int): crate_num = count - # print("number of crates: " + str(crate_num)) if crate_num <= 0: current_level_index += 1 if current_level_index == levels.size(): @@ -58,18 +63,18 @@ func set_crate_num(count: int): reset() func _on_slime_damage(body, slime): - print("game controller sees slime damage") - player.health -= enemies[slime]["damage"] - if player.health <= 0: - print("dead") - level_change_signal.emit(levels[current_level_index]) + damage_player_signal.emit(enemies[slime]["damage"]) func add_enemy(slime): var enemy_stat = { - "health": 5, - "damage": 3 + "health": enemy_stats.starting_health, + "damage": enemy_stats.melee_damage } enemies[slime] = enemy_stat func _on_slime_struck(body, slime): print("game controller sees slime struck") + +func _on_player_dead(player): + print("game controller sees dead player") + level_change_signal.emit(levels[current_level_index]) diff --git a/scripts/player.gd b/scripts/player.gd index 09032d5..44bdedf 100644 --- a/scripts/player.gd +++ b/scripts/player.gd @@ -7,6 +7,7 @@ class_name Player extends CharacterBody2D @onready var graphic: AnimatedSprite2D = $graphic signal new_player(player) +signal player_dead(player) const SPEED = 300.0 const JUMP_VELOCITY = -400.0 @@ -14,7 +15,7 @@ var direction : float = 0 enum FaceDirection { LEFT, RIGHT } var facing: FaceDirection = FaceDirection.LEFT var shove_target: RigidBody2D -enum State { IDLE, RUN, JUMP, APEX, FALL } +enum State { IDLE, RUN, JUMP, APEX, FALL, HURT, DYING, DEAD } var state: State = State.IDLE var up_jump:bool = false var health:int = 4 @@ -23,7 +24,8 @@ func _ready(): new_player.emit(self) func _physics_process(delta: float): - handle_input() + if self.state != State.HURT and self.state != State.DEAD: + handle_input() handle_movement(delta) handle_state() handle_animation() @@ -105,9 +107,33 @@ func handle_animation(): graphic.play("apex") State.FALL: graphic.play("fall") + State.HURT: + graphic.play("hurt") + State.DYING: + graphic.play("dead") + State.DEAD: + pass + func _on_graphic_animation_finished() -> void: - # switch state from apex to fall match state: - State.APEX: + State.APEX: # switch state from apex to fall state = State.FALL + State.HURT: # switch state from hurt to idle + state = State.IDLE + State.DYING: + print("firing dead signal") + state = State.DEAD + player_dead.emit(self) + State.DEAD: + pass + +func damage_player(damage: int): + if self.state != State.DYING and self.state != State.DEAD: + self.health -= damage + if self.health <= 0: + print("DEAD") + self.state = State.DYING + else: + print("player hurt") + self.state = State.HURT diff --git a/scripts/resources/character_stats.gd b/scripts/resources/character_stats.gd new file mode 100644 index 0000000..ef89702 --- /dev/null +++ b/scripts/resources/character_stats.gd @@ -0,0 +1,8 @@ +class_name CharacterStats extends Resource + +@export var health:int = 100; +@export var max_health:int = 120; +@export var starting_health:int = 100; + +@export var melee_damage:int = 10; +@export var range_damage:int = 5; diff --git a/scripts/resources/character_stats.gd.uid b/scripts/resources/character_stats.gd.uid new file mode 100644 index 0000000..0ebee1d --- /dev/null +++ b/scripts/resources/character_stats.gd.uid @@ -0,0 +1 @@ +uid://v5se2t1jjaat diff --git a/scripts/resources/player_stats.tres b/scripts/resources/player_stats.tres new file mode 100644 index 0000000..a54b57f --- /dev/null +++ b/scripts/resources/player_stats.tres @@ -0,0 +1,10 @@ +[gd_resource type="Resource" script_class="CharacterStats" format=3 uid="uid://ffycoj1dt84h"] + +[ext_resource type="Script" uid="uid://v5se2t1jjaat" path="res://scripts/resources/character_stats.gd" id="1_r32g3"] + +[resource] +script = ExtResource("1_r32g3") +health = 30 +max_health = 50 +starting_health = 30 +metadata/_custom_type_script = "uid://v5se2t1jjaat" diff --git a/scripts/resources/slime_stats.tres b/scripts/resources/slime_stats.tres new file mode 100644 index 0000000..c6ae7d8 --- /dev/null +++ b/scripts/resources/slime_stats.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="CharacterStats" format=3 uid="uid://cxkrcxxmgtyyr"] + +[ext_resource type="Script" uid="uid://v5se2t1jjaat" path="res://scripts/resources/character_stats.gd" id="1_l0etv"] + +[resource] +script = ExtResource("1_l0etv") +health = 10 +max_health = 15 +starting_health = 10 +range_damage = 0 +metadata/_custom_type_script = "uid://v5se2t1jjaat" diff --git a/scripts/scene_manager.gd b/scripts/scene_manager.gd index 47d070b..e3d2f0f 100644 --- a/scripts/scene_manager.gd +++ b/scripts/scene_manager.gd @@ -9,6 +9,8 @@ func _ready() -> void: print("scene manager is ready") GameController.destroy.connect(destroy) GameController.level_change_signal.connect(change_scene) + GameController.damage_player_signal.connect(damage_player) + # player.player_dead.connect(GameController._on_player_dead) build_level() func _process(delta: float) -> void: @@ -20,6 +22,9 @@ func build_level() -> void: update_enemies() if player: GameController.player = player + if not player.player_dead.is_connected(GameController._on_player_dead): + print("hooking up player dead signal") + player.player_dead.connect(GameController._on_player_dead) func update_enemies(): for enemy in enemies.get_children(): @@ -52,3 +57,9 @@ func update_crates() -> void: func destroy(body): if body is BrownBox: body.queue_free() + +func damage_player(damage: int): + player.damage_player(damage) + +#func player_dead_animation_finished(): + #change_scene()