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.
Tham gia kênh Telegram của AnonyViet 👉 Link 👈 |
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
Bạn add area2D vào Scene kẻ thù cho mình và rename là Hitbox.
Và set CollisionShape2D rồi đặt nó ở chỗ frame tấn công ở animation tấn công và nhớ tắt nó đi.
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 area2D và rename là Hurtbox ở Scene Player
Set collisionshape của hurtbox sao cho giống với Collisionshape của node gốc.
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.
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.
Đâ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.
Câu hỏi thường gặp
Làm thế nào để tạo Hitbox cho kẻ thù trong Godot?
Thêm một Area2D vào Scene của kẻ thù, đổi tên thành “Hitbox”, thêm một CollisionShape2D vào Area2D và đặt nó vào frame tấn công trong animation. Nhớ tắt CollisionShape2D khi không tấn công.
Làm thế nào để tạo Hurtbox cho nhân vật Player?
Thêm một Area2D vào Scene của Player, đổi tên thành “Hurtbox”, và thêm một CollisionShape2D vào Area2D. Điều chỉnh CollisionShape2D sao cho phù hợp với hình dạng của nhân vật.
Tôi có thể làm gì khi Player hết máu?
Trong script của Player, khi biến mau
<= 0, sử dụng set_physics_process(false)
để ngừng xử lý vật lý và $CollisionShape2D.disabled = true
để vô hiệu hóa va chạm. Bạn có thể thêm xử lý khác như chuyển về màn hình menu hoặc điểm kiểm tra.