Di pelajaran ini, kita bakal nambahin animasi serangan dasar ke pemain dan mendeteksi collision antara serangan pemain (basic attack) dan enemy. Proses ini melibatkan setup attack input, bikin hitboxes (di pemain) dan hurtboxes (di enemy), dan ngontrol kapan hitbox itu aktif biar enemy cuma kena damage pas frame serangan beneran aja.
Adding an Attack Animation#
Pertama, kita butuh animasi yang nunjukin karakter kita pas lagi nyerang.
Create the Animation
Bukaheavy_blade.tscn
(scene pemain), pilih AnimationPlayer, dan bikin animasi baru bernamabasic_attack
. Tambahin frames (atau keyframes) yang nampilin gerakan ayunan senjata karaktermu. Dengan begitu, kita punya rangkaian animasi khusus buat serangan, terpisah dari idle dan run.Adjust Timing and Frames
Setelah nambahin frames, atur durasinya biar gerakannya terasa responsif. Kalau kepanjangan, karaktermu bisa kerasa lamban; kalau kependekan, animasinya nyaris ga kelihatan. Silakan coba-coba speed yang berbeda sampai kelihatan pas.
Sampai tahap ini, kamu udah punya animasi yang kelihatan oke di editor, tapi belum dipicu sama input di dalam game.
Ini contoh basic attack animation punyaku (kalau mau, kamu bisa aja tiru):
Adding Attack Input#
Sekarang, kita bikin biar pas pemain mencet tombol tertentu, animasi basic_attack
langsung main.
Create a New Input Action
Masuk ke Project > Project Settings > Input Map, terus tambahin action baru namanyabasic_attack
, dan pasang di tombolZ
. Dengan gini, logika serangan terpisah dari tombol spesifik, jadi kalau mau diganti, tinggal atur di sini.Detect Input in Your Script
Diheavy_blade.gd
, tambahin atau modif_unhandled_input(event)
buat ngecek actionbasic_attack
. Kalau ditekan, langsung mainin animasibasic_attack
:func _unhandled_input(event): if event.is_action_pressed("basic_attack"): animation_player.play("basic_attack")
Avoid Overwriting the Attack Animation
Mungkin kamu udah punya kode yang ngatur frame Sprite2D pas pemain gerak, jadi pastiin ga menimpa animasibasic_attack
pas gerak. Tambahin cek sederhana di_process(delta)
atau fungsi gerakan, supaya animasi gerak ga jalan kalaubasic_attack
lagi main:... if animation_player.current_animation != "basic_attack": if velocity.x > 0: animation_player.play("move_right") elif velocity.x < 0: animation_player.play("move_left") elif velocity.y != 0: animation_player.play("move_right") else: animation_player.play("idle") ...
Sekarang, pencet Z
bakal mancing animasi serangan. Tapi sejauh ini, belum berdampak apa-apa di game.
Creating a Dummy Enemy#
Kita bikin enemy dummy buat ngetes efek serangan pemain.
New Scene for the Enemy
Bikin scene baru namanyadummy.tscn
, dan pake Sprite2D sebagai root node. Pasang tekstur apa aja sebagai placeholder enemy, atau pakai yang aku kasih:Basic Setup
Enemy ini ga bakal gerak atau nyerang balik dulu—cuma ada buat ngetes hit. Tambahin script simpel (dummy.gd
) kalo mau siapin logic HP atau lainnya. Sesuaikan scale kalau kegedean atau kekecilan.
Making a Lobby Scene#
Kita perlu satu scene yang isinya player dan dummy enemy bareng biar bisa saling interaksi.
Create
lobby.tscn
Bikinlobby.tscn
, tambahin Node2D sebagai root. Ini bakal jadi “ruangan” atau “level” tempat kamu naro objek.Instance Player and Enemy
Tarikheavy_blade.tscn
(player) dandummy.tscn
(enemy) ke dalamlobby.tscn
. Atur posisinya sesukamu.Test It Out
Coba jalaninlobby.tscn
, gerakin pemain, dan tekanZ
buat nyerang. Kamu bakal lihat animasinya, tapi enemy belum bereaksi karena kita belum setup collision atau sistem damage.
Making the Enemy Take Damage#
Kalau ngomongin serangan, umumnya ada dua sisi:
- Hitbox: Area di karakter penyerang yang menghasilkan damage.
- Hurtbox: Area di karakter yang diserang, tempat damage bisa diterima.
Adding a Hitbox#
Player Hitbox#
Add an Area2D
Diheavy_blade.tscn
, tambahin child node ke root node pemain. Kasih namaBasicAttackHitbox
dan set ke Area2D. Node ini yang bakal deteksi overlap sama enemy.Add a CollisionShape2D
Sebagai child dariBasicAttackHitbox
, tambahin CollisionShape2D. Atur ukuran dan bentuknya biar kurang lebih sesuai area serangan.Assign Collision Layers
Di InspectorBasicAttackHitbox
, set Collision Layer ke1
dan Collision Mask ke2
. Ini berarti dia ada di layer 1 dan bakal mendeteksi objek di layer 2.
Enemy Hurtbox#
Add an Area2D
Didummy.tscn
, tambahin child node namanyaHurtbox
(juga Area2D). Ini nentuin area dimana enemy bisa kena serangan.Add a CollisionShape2D
Di dalamHurtbox
, tambahin CollisionShape2D yang nutupin sprite enemy.Assign Collision Layers
Di Inspector, set Collision Layer ke2
dan Collision Mask ke1
. Artinya, hurtbox enemy ada di layer 2 dan ngecek objek di layer 1—pas buat hitbox player.
Dengan atur layer dan mask kayak gini, hitbox player cuma berinteraksi sama hurtbox enemy, ga bentrok sama layer lain.
Connecting Signals and Dealing Damage#
Hitbox dan hurtbox udah ada, sekarang kita bikin enemy bereaksi pas keduanya overlap.
Enable Monitoring
DiBasicAttackHitbox
danHurtbox
, centang Monitoring dan Monitorable biar bisa mendeteksi overlap.Connect
area_entered
on the Enemy
PilihHurtbox
didummy.tscn
, buka tab Node > Signals, sambunginarea_entered
kedummy.gd
. Fungsi bakal keliatan kayak gini:func _on_hurtbox_area_entered(area: Area2D): if area.name == "BasicAttackHitbox": queue_free()
Buat ngetes, kita langsung pake
queue_free()
biar enemy hilang. Tapi ini bakal kepicu meski hitbox aktif pas idle. Kita bakal benerin ini abis ini.Buat debugging, kamu bisa show collision di debug menu.
Activating the Hitbox Only During Attack#
Disable Hitbox by Default
Di InspectorCollisionShape2D
dalamBasicAttackHitbox
, centang Disabled. Jadi default-nya hitbox mati sampe kita aktifin.Toggle via Animation
Balik keheavy_blade.tscn
, buka AnimationPlayer. Di animasibasic_attack
, tambahin Property Track buat propertidisabled
diBasicAttackHitbox
CollisionShape2D
. Di frame dimana serangan “kena”, set kefalse
(aktif), terus di akhir ayunan, set balik ketrue
(nonaktif).
Sekarang, enemy cuma kena damage di frame serangan yang bener-bener aktif.
Adding Health Logic to the Enemy#
Kalau ga mau enemy langsung hilang sekali pukul, bisa tambahin HP:
var hp = 3
func _on_hurtbox_area_entered(area: Area2D):
if area.name == "BasicAttackHitbox":
hp -= 1
if hp <= 0:
queue_free()
Dengan begitu, enemy butuh beberapa kali pukulan sebelum kalah.
Conclusion#
Dengan langkah-langkah di atas, kamu udah:
- Bikin animasi basic attack dan mengaitkannya ke input action.
- Ngejaga biar animasi gerak ga tumpang tindih sama animasi serangan.
- Nambah Area2D buat bikin sistem hitbox/hurtbox sederhana.
- Manfaatin collision layers dan masks biar cuma serangan player yang bentrok sama hurtbox enemy.
- Aktifin hitbox cuma di frame serangan lewat timeline animasi.
- Nambahin opsi health buat enemy (atau ga sama sekali) dan lenyap kalau habis.
Dengan pondasi ini, kamu bisa ngembangin combat system lebih jauh: nambah tipe serangan lain, variasi damage, knockback buat enemy, atau AI yang lebih cerdas. Sekarang game-mu udah punya combat loop dasar—tekan Z
buat nyerang dan lihat dummy enemy bereaksi (atau mati).
Sampai ketemu di pelajaran berikutnya! 🚀