บทเรียนการสร้างเกม 2D ด้วย Godot Engine สำหรับการสร้าง Simple AI ผ่านการ Re-Spawn พร้อมตรวจสอบการชนกันของ Node2D ด้วย CollisionShape2D
กรุณาศึกษาบทเรียนก่อนหน้า:
- เขียนเกม 2D ด้วย Godot Engine
- เขียนเกม 2D ด้วย Godot Engine การใช้ Animated Sprite Node
- เขียนเกม 2D ด้วย Godot Engine การควบคุมคัวละคร Full Movement
- เขียนเกม 2D ด้วย Godot Engine จัดการ Camera2D และยิง Bullet
บทเรียนนี้จะเป็นการต่อยอดจากบทเรียนก่อนหน้า คือมีการ Control ตัวละคร และยิงกระสุนเป็นที่เรียบร้อยแล้ว ดูได้จาก Video Tutorial บน Youtube ได้
ประกอบกับบทความ
ที่มี Scene ชื่อ global พร้อม GDscript ชื่อ global.gd ให้เราเปิดแก้ไข Script ตัว global.gd เป็นดังนี้:
extends Node2D var global_direction = 0 var random_spawn = 0 func _ready(): set_process(true) pass func _process(delta): random_spawn = randi() % 300 pass
กำหนดตัวแปรมาทำการ random ตัว Spawn เก็บลง random_spawn ผ่านคำสั่ง randi() % 300 คือการ Random ที่ 0 ไปถึง 300
ตัวแปรทั้งหมดใน global.gd จะเป็น Global Var สามารถดึงไปใช้ได้หมดทุกๆ scene ดังนั้น เราจะใช้ ตัวแปรทั้ง 2 นี้มาใช้กับโปรแกรมเกมของเรา
หลังจากนั้น ให้เราสร้าง Scene ใหม่ขึ้นมา เพิ่ม KinematicBody2D เข้าไป แล้ว Save เป็น Enemy.xml เพื่อสร้างศัตรูเพิ่ม
หลังจากนั้นก็ไปสร้างชุด AnimatedSprite และ กำหนด CollisionShape2D ให้กับ Enemy ของเรา
ที่ตัว AnimatedSprite ให้ตั้งค่า Playing เป็น On จะทำให้ AnimatedSprite เล่นเองอัตโนมัติตาม Frame ของมัน
สร้าง npc.gd ขึ้นมาที่ KinematicBody2D ของศัตรู Enemy ของเรา
extends KinematicBody2D #AI Enemy var wait_time = 0.0 var end_time = 0.1 var destroy_time = 0.17 func _ready(): set_process(true) pass func _process(delta): #Gravity move(Vector2(0,15)) #SimpleMovement translate(Vector2(-1,0)) if self.is_colliding(): if self.get_collider().get_name() == "bullet(Clone)": #print (self.get_collider().get_name()) wait_time += delta print ("Hit") if wait_time > end_time: get_node("CollisionShape2D").set_trigger(true) if wait_time >= destroy_time: destroy() func destroy(): queue_free()
ไม่ต้องคิดไรมากให้มันเดินไปทางซ้ายอย่างเดียวแบบ AI โง่ๆ ใน Contra
translate(Vector2(-1,0))
เช็คการชนกันของวัตถุ ว่าถ้าชนกับ Bullet ที่เรา Clone ขึ้นมาผ่านชื่อ “bullet(Clone)” ให้ Print ค่าว่า “Hit” แล้วหน่วงเวลาตายให้เปิด set_trigger(true) ตัวละครก็จะหล่นจากฉากไป พร้อมกับ destroy() ไปเรียก queue_free() เพื่อทำลาย Node
กลับมาที่ Scene หลักของเรา ให้เราเพิ่ม child node เข้าไปที่ World ตั้งชื่อว่า Node2D-Spawn
หลังจากนั้นเพิ่ม Script ใหม่เข้าไปที่ World ว่า: stage1.gd
extends Node2D var enemy = preload("res://Enemy.xml") var sp_random func _ready(): set_process(true) pass func _process(delta): sp_random = global.random_spawn if sp_random == 199: var enemy_instance = enemy.instance() enemy_instance.set_name("enemy(Clone)") get_node("Node2D-Spawn").add_child(enemy_instance) pass
ถ้ามีการ Random ผ่านเรียกตัวแปร global.random_spawn เป็น 199 ให้ instant Enemy ที่เราไปดึง Enemy.xml ชื่อว่า enemy(Clone) โดยให้ Spawn ออกมาจาก
get_node("Node2D-Spawn").add_child(enemy_instance)
ส่วนตัว Player เพิ่ม code เล็กน้อยใน func _process(delta) ว่า:
if self.is_colliding(): anim.play("death") print("Enemy") move(Vector2(10 * -global.global_direction, 0))
ทดสอบให้รันเกม รอศัตรูปรากฏแล้วเดินเข้าไปชน
ส่วน Enemy ให้เราลอง ยิงกระสุนไปใส่มันดู จะเห็นว่า Enemy นั้นร่วงตกลงไปจากฉาก แก้ไข bullet.xml ตรง CollisionShape2D เอา trigger ออก
จะเห็นว่าตัวอย่างนี้ไม่ยากเลยหากจะประยุกต์ทำ CollisionShape2D
ดาวน์โหลด Source Code: https://github.com/banyapondpu/godot_tutorial_ellende