Compare commits

..
4 Commits
Author SHA1 Message Date
OddlyTimbot 6355c31a7c player hurt working with signals 2024-10-07 14:24:38 -04:00
OddlyTimbot a6fc6acc12 scene manager update 2024-10-07 13:52:03 -04:00
OddlyTimbot 7f4bc01dbe instructions for player death 2024-10-01 20:16:45 -04:00
OddlyTimbot 723d677a81 working player death animation 2024-10-01 19:56:32 -04:00
7 changed files with 185 additions and 17 deletions

No files matched your search

+77 -1
View File
@@ -1 +1,77 @@
Please update with readme
Week 5 Challenge - Player Death Animation
First, we need to make a slight update to the logic in the game controller.
## Game Controller
This change ensures that our signal to kill the player can ONLY happen once, by checking that the health is above zero before issuing the signal.
```
func playerDamage():
#one can not kill what is dead....
if player.health >0:
player.health -= 20
#is the player dead?
if player.health <= 0:
#kill him
playerDeath.emit()
```
## Scene Manager
In the scene_manager, we have created a connection that listens for the game controller issuing the player death command:
`GameController.playerDeath.connect(killPlayer)`
We must change the `killPlayer` function. It will tell the player to die, but will then start a timer rather than immediatly reloading the scene.
```
func killPlayer():
# tell player to die - starts death animation
player.killPlayer()
if timer.is_stopped():
timer.start(4)
```
Notice that we only start the timer *if it is not already running*. Otherwise if the scene_manager happens to hear more `playerDeath` signals from the GameController, it will keep restarting the timer.
The `resetWorld` function is connected to the `timeout` event of the timer. It looks like this:
```
func resetWorld():
print("screne manager resetting world")
GameController.resetPlayer()
get_tree().reload_current_scene()
```
## Player
Lastly, the player code needs to ensure that the user can not do anything when their death animation is playing.
A simple way to do this is to create a boolean that simply keeps track of whether they are alive or not.
`var living = true`
We can then update the `killPlayer` function to check if the player is currently living and update the variable before calling the death animation.
```
func killPlayer():
print("kill the player")
if living:
living = false
#play death animation
playerSprite.play("death")
```
With the `living` variable set to false, we simply check the variable before doing *anything* in the `_physics_process` function.
```
func _physics_process(delta: float) -> void:
if living:
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
.......and so forth....
```
When the timer ends and the scene reloads, all of these variables will be reset and the loop begins again.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b2brlauvni08o"
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/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
+38 -2
View File
@@ -1,9 +1,10 @@
[gd_scene load_steps=39 format=3 uid="uid://dbgc24hrbtvxm"]
[gd_scene load_steps=44 format=3 uid="uid://dbgc24hrbtvxm"]
[ext_resource type="Script" path="res://scripts/player.gd" id="1_5qpif"]
[ext_resource type="Texture2D" uid="uid://d6d3re6epsh4" path="res://assets/graphics/player/death/Player Death 64x64.png" id="2_t1yra"]
[ext_resource type="Texture2D" uid="uid://pdvgf3y1lquv" path="res://assets/graphics/player/idle/Player Idle 48x48.png" id="2_vcmr0"]
[ext_resource type="Texture2D" uid="uid://cvh48exhs1ir1" path="res://assets/graphics/player/run/player run 48x48.png" id="3_a03rx"]
[ext_resource type="Texture2D" uid="uid://b2brlauvni08o" path="res://assets/graphics/player/hurt/Player Hurt 48x48.png" id="3_a70o5"]
[ext_resource type="Texture2D" uid="uid://d0kfe5ms2vjbr" path="res://assets/graphics/player/jump/player jump 48x48.png" id="3_mvdmt"]
[sub_resource type="AtlasTexture" id="AtlasTexture_uru55"]
@@ -46,6 +47,22 @@ region = Rect2(384, 0, 48, 48)
atlas = ExtResource("2_t1yra")
region = Rect2(432, 0, 48, 48)
[sub_resource type="AtlasTexture" id="AtlasTexture_me361"]
atlas = ExtResource("3_a70o5")
region = Rect2(0, 0, 48, 48)
[sub_resource type="AtlasTexture" id="AtlasTexture_5yslj"]
atlas = ExtResource("3_a70o5")
region = Rect2(48, 0, 48, 48)
[sub_resource type="AtlasTexture" id="AtlasTexture_l8y4s"]
atlas = ExtResource("3_a70o5")
region = Rect2(96, 0, 48, 48)
[sub_resource type="AtlasTexture" id="AtlasTexture_vc70i"]
atlas = ExtResource("3_a70o5")
region = Rect2(144, 0, 48, 48)
[sub_resource type="AtlasTexture" id="AtlasTexture_etdvv"]
atlas = ExtResource("2_vcmr0")
region = Rect2(0, 0, 48, 48)
@@ -169,6 +186,23 @@ animations = [{
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_me361")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_5yslj")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_l8y4s")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_vc70i")
}],
"loop": false,
"name": &"hurt",
"speed": 12.0
}, {
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_etdvv")
}, {
"duration": 1.0,
@@ -256,7 +290,7 @@ metadata/_edit_group_ = true
texture_filter = 1
position = Vector2(0, -7)
sprite_frames = SubResource("SpriteFrames_wlxdo")
animation = &"death"
animation = &"hurt"
autoplay = "idle"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
@@ -274,3 +308,5 @@ position = Vector2(12, -5)
[node name="MarkerLeft" type="Node2D" parent="."]
position = Vector2(-15, -5)
[connection signal="animation_finished" from="AnimatedSprite2D" to="." method="_on_animation_finished"]
+5 -1
View File
@@ -4,6 +4,7 @@ var coinsCollected:int = 0
var player:Resource
signal playerDeath
signal playerHurt
func _ready() -> void:
print("Game controller is ready")
@@ -18,10 +19,13 @@ func resetPlayer():
player.health = player.max_health
func playerDamage():
#one can not kill what is dead....
if player.health >0:
player.health -= 20
print("Player health is : "+str(player.health) )
#is the player dead?
if player.health <= 0:
#kill him
playerDeath.emit()
else:
playerHurt.emit()
+23 -10
View File
@@ -6,6 +6,10 @@ const JUMP_VELOCITY = -400.0
const PUSH_FORCE = 700
var faceLeft = false
var living = true
signal playerDead
# can i push right or left
var pushLeftEnabled = false
var pushRightEnabled = false
@@ -16,15 +20,24 @@ var pushRightEnabled = false
@onready var playerSprite: AnimatedSprite2D = $AnimatedSprite2D
var pushTarget
var animPlaying = "idle"
var bullet = preload("res://scenes/bullet.tscn")
func killPlayer():
print("kill the player")
if living:
living = false
animPlaying = "death"
#play death animation
playerSprite.play("death")
func hurtPlayer():
animPlaying="hurt"
print("player should get hurt")
playerSprite.play("hurt")
func _physics_process(delta: float) -> void:
if living and not animPlaying=="hurt":
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
@@ -34,26 +47,19 @@ func _physics_process(delta: float) -> void:
velocity.y = JUMP_VELOCITY
if Input.is_action_just_pressed("Shove") && pushLeftEnabled && faceLeft:
print("shove a box on the left")
pushTarget.apply_central_impulse(Vector2(-1,0) * PUSH_FORCE * 1.5)
pushLeftEnabled = false
if Input.is_action_just_pressed("Shove") && pushRightEnabled && not faceLeft:
print("shove a box on the right")
pushTarget.apply_central_impulse(Vector2(1,0) * PUSH_FORCE * 1.5)
pushRightEnabled=false
if Input.is_action_just_pressed("shoot"):
if faceLeft:
print("shoot left")
# mybullet.setSpeed(-700)
#mybullet.transform = marker_left.global_transform
%SceneManager.placeBullet(-700, marker_left.global_transform)
else:
print("shoot right")
#mybullet.transform = marker_right.global_transform
%SceneManager.placeBullet(700, marker_right.global_transform)
@@ -71,6 +77,7 @@ func _physics_process(delta: float) -> void:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
if is_on_floor():
if direction == 0:
playerSprite.play("idle")
@@ -86,7 +93,6 @@ func _physics_process(delta: float) -> void:
c.get_collider().apply_central_impulse(-c.get_normal()* 100)
if left_ray.is_colliding():
print("left ray collision")
var collider = left_ray.get_collider()
if collider is Node:
if collider.is_in_group("pushables"):
@@ -97,7 +103,6 @@ func _physics_process(delta: float) -> void:
pushLeftEnabled = false
if right_ray.is_colliding():
print("right ray collision")
var collider = right_ray.get_collider()
if collider is Node:
if collider.is_in_group("pushables"):
@@ -105,3 +110,11 @@ func _physics_process(delta: float) -> void:
pushTarget = collider
else:
pushRightEnabled = false
func _on_animation_finished() -> void:
print(animPlaying + " finished playing.")
if animPlaying == "hurt":
animPlaying="idle"
if animPlaying=="death":
playerDead.emit()
+8 -3
View File
@@ -28,6 +28,8 @@ func _ready() -> void:
n.playerDamage.connect(GameController.playerDamage)
#GameController signals
GameController.playerDeath.connect(killPlayer)
GameController.playerHurt.connect(hurtPlayer)
player.playerDead.connect(deadPlayer)
func boxTrap():
print("Trigger a box trap!")
@@ -64,12 +66,15 @@ func crateFactory():
return myCrate
func killPlayer():
print("kill the player now")
# tell player to die - starts death animation
player.killPlayer()
timer.start(3)
func hurtPlayer():
player.hurtPlayer()
func deadPlayer():
if timer.is_stopped():
timer.start(1)
func resetWorld():
print("screne manager resetting world")
GameController.resetPlayer()
get_tree().reload_current_scene()