[Tạo 2D Platformer Game với Godot] Phần 12: Tiêu diệt kẻ thù

Trong phần này, mình sẽ hướng dẫn bạn cách để có thể tiêu diệt kẻ thù khi player tấn công nhé. Và trong phần sau thì mình sẽ hướng dẫn bạn cách để kẻ thù có thể tiêu diệt Player.

Tiêu diệt kẻ thù

Về đầu tiên, mình sẽ phải tạo 1 cái Area2D ở Scene Player và cái Area2D này sẽ luôn luôn tắt và chỉ được bật khi tấn công. Mình tạo thêm 1 cái gọi là hurtbox ở Scene kẻ thù và nếu như hitbox của Player được bật và va chạm với hurtbox của kẻ thù thì tức là Player đã đánh trúng kẻ thù và sau đó máu của kẻ thù sẽ bị trừ và < 0 thì sẽ biến mất.

Hitbox

Add

Mình sẽ tạo thêm 1 cái Area2D ở Scene player và rename nó là Hitbox và add thêm CollisionShape2D

Sau đó chỉnh Shape cho bằng với chỗ tấn công ở animation tấn công.

Sau đó mình sẽ kết nối tín hiệu frame change vào script. Ở đây, mình kết nối cái này là do mình muốn biết nếu như đang ở trong animation tấn công mà nó đã tới frame cần bật hitbox thì mình sẽ bật nó.

Frame 3 là frame mà mình muốn bật hitbox.

Script

 

extends KinematicBody2D

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

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)


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 
        

Ở bên trên là full code.

Mình khai báo 1 biến mới là : var satthuong = 10 tác dụng của nó thì xem tên nha.

Ở hàm frame change đoạn if animation.animation == "tancong": là mình kiểm tra nếu như đang là animation tấn công và if animation.frame == 3:là nếu như frame bằng 3 mình sẽ bật hitbox  và ngược lại.

Hurtbox

 Add

Bạn add cái Area2D và rename là Hurtbox + them CollisionShape2D

Về CollisionShape2D thì nó bằng với ColllisionShape2D của KinematicBody.

Sau đó thì kết nối cái tín hiệu cho nó, ở đây mình kết nối tín hiệu area_entered chứ không phải body entered là vì Hitbox nó là area2d chứ không phải là body.

Và kết nối để kiểm tra nếu như hitbox đi vào thì sẽ làm gì đó….

Script

extends KinematicBody2D


var tocdo = 80
var trongluc = 10
var chuyendong = Vector2()
var huong_dichuyen = 1
onready var animation = $AnimatedSprite
var dangtancong = false
var mau = 20
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":
		mau -= area.get_parent().satthuong

Trên đây sẽ là full đoạn code của phần này.

Mình tạo 1 biến mới tên mau và đây là biến máu của kẻ thù.

Dòng  if area.get_parent().name == "Player": của area_entered là mình sẽ kiểm tra tên bố mẹ của area2D là Player thì mau sẽ -= satthuong của Player.

Và ở hàm Physics mình sẽ check nếu máu <= 0 thì chạy animation chết, và ở hàm animation finshed mình sẽ check nếu animation kết thúc là chết -> queue_free() ( đây là hàm giúp bạn xoá node khỏi tree ).

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

 

 

 

Đánh giá post
Exit mobile version