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.