[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player

Trong phần này mình sẽ hướng dẫn bạn tiêu diệt Player khi kẻ thù tấn công và Player sẽ hết máu.

Tiêu diệt player

Phần này cũng tương tự như phần trước nhưng mà phần này là mình sẽ add hitbox ở kẻ thù và hurtbox ở Player.

Hitbox

Add

[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 16

Bạn add area2D vào Scene kẻ thù cho mình và rename là Hitbox.[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 17

[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 18

Và set CollisionShape2D rồi đặt nó ở chỗ frame tấn công ở animation tấn công và nhớ tắt nó đi.

[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 19 [Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 20 [Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 21

[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 22

Sau đó cũng kết nối tìn hiệu như ở phần trước.

Script

 

extends KinematicBody2D

# Di chuyn
var tocdo = 80
var trongluc = 10
var chuyendong = Vector2()
var huong_dichuyen = 1
# Animation
onready var animation = $AnimatedSprite
var dangtancong = false
# Chi so
var mau = 20
var satthuong = 5

func _physics_process(delta):
    if dangtancong == false:
        chuyendong.x = tocdo * huong_dichuyen
        chuyendong.y += trongluc
        chuyendong = move_and_slide(chuyendong,Vector2.UP)
        animation.play("dichuyen")
        
        if $RayCast2D.is_colliding() == false:
            huong_dichuyen = huong_dichuyen * -1
            scale.x = scale.y * huong_dichuyen
        
        if is_on_wall() and $XacDinhPlayer.is_colliding() == false:
            huong_dichuyen = huong_dichuyen * -1
            scale.x = scale.y * huong_dichuyen
    
    var coll = $XacDinhPlayer.get_collider()
    if coll != null and coll.name == "Player" and dangtancong == false:
        dangtancong = true
        animation.play("tancong")
    if mau <= 0:
        animation.play("chet")


func _on_AnimatedSprite_animation_finished():
    if animation.animation == "tancong":
        dangtancong = false
    if animation.animation == "chet":
        queue_free()


func _on_Hurtbox_area_entered(area):
    if area.get_parent().name == "Player" and area.get_parent().dangtancong == true:
        mau -= area.get_parent().satthuong



func _on_AnimatedSprite_frame_changed():
    if animation.animation == "tancong":
        if animation.frame == 3:
            $Hitbox/CollisionShape2D.disabled = false
        else:
            $Hitbox/CollisionShape2D.disabled = true

Phần code thì nó cũng thêm tương tự như ở phần trước thôi.

Mình thêm biến satthuong, rồi kiẻm tra nếu là frame tấn công thì bật hitbox và ngược lại.

Đoạn area.get_parent().dangtancong == true là mình dùng để xác định rằng cái hitbox va chạm vào hurtbox của kẻ thù không bị trùng bởi chính nó.

Hurtbox

Add

[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 23

Tạo area2D và rename là Hurtbox ở Scene Player

[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 24Set collisionshape của hurtbox sao cho giống với Collisionshape của node gốc.

[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 25 [Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 26 [Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 27 [Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 28

Xong sau đó add tín hiệu như phần trước.

Script

 

extends KinematicBody2D

var tocdo = 200
var trongluc = 10
var chuyendong = Vector2()
var huong_dichuyen = 1
onready var animation = $AnimatedSprite
var dangtancong = false

var mau = 20
var satthuong = 10

func _physics_process(delta):
    
    if !dangtancong:
        huong_dichuyen = Input.get_axis("ui_left","ui_right")
        if huong_dichuyen != 0:
            chuyendong.x = lerp(chuyendong.x,huong_dichuyen * tocdo,0.5)
            animation.play("chay")
            scale.x = scale.y * huong_dichuyen
        else:
            chuyendong.x = lerp(chuyendong.x,0,0.5)
            animation.play("dungyen")

        if is_on_floor():
            if Input.is_action_just_pressed("ui_accept") :
                chuyendong.y = -250
        else:
            animation.play("nhay")
    if Input.is_key_pressed(KEY_J) and is_on_floor():
        dangtancong = true
        chuyendong.x = 0
        animation.play("tancong")
    
    chuyendong.y += trongluc 
    chuyendong.normalized()
    chuyendong = move_and_slide(chuyendong,Vector2.UP)
    
    if mau <= 0:
        set_physics_process(false)
        animation.play("chet")
        $CollisionShape2D.disabled = true
func _on_AnimatedSprite_animation_finished():
    if animation.animation == "tancong":
        dangtancong = false
func _on_AnimatedSprite_frame_changed():
    if animation.animation == "tancong":
        if animation.frame == 3:
            $Hitbox/CollisionShape2D.disabled = false
        else:
            $Hitbox/CollisionShape2D.disabled = true 
        



func _on_Hurtbox_area_entered(area):
    if area.name == "Hitbox" and area.get_parent().dangtancong == true:
        mau -= area.get_parent().satthuong
    pass # Replace with function body.

Phần code thì mình nghĩ qua phần trước và 1 ít ở bên trên là bạn đã có thể hiểu được các đoạn code này.

Ở đây, hầu hết đều giống nhau nhưng chỉ có 1 chỗ là bạn nên lưu ý.

Chú ý dòng if mau <= 0: đây sẽ là dòng quan trọng ở Phần này và ở Player. Bên dưới đó mình sẽ không chạy hàm queue_free() bởi vì hầu hết các game Platformer khi Player chết thì sẽ trở về 1 điểm đã lưu hoặc là về lại menu chứ không có xoá đi làm gì.

Dòng set_physics_process(false) là mình vô hiệu hoá hàm physics_process.

$CollisionShape2D.disabled = true là mình tắt cái CollisionShape2D của Player vì khi Player chết mà không tắt nó vẫn sẽ xác định là player còn sống và tiếp tục tấn công.

[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 29

Sau đó, bạn vô AnimatedSprite -> animation chết và tắt Loop đi nếu không thì khi chạy animation chết nó  sẽ bị lặp lại.[Tạo 2D Platformer Game với Godot] Phần 13: Tiêu diệt Player 30

Đây là kết quả cuối cùng.

Tổng kết

Vậy là đã xong phần tiêu diệt kẻ thù và nhân vật ! Hẹn gặp bạn ở phần tiếp theo.

 

Previous Post Next Post