Advertisement
Scroll to top
Read Time: 15 min

() translation by (you can also view the original English article)

Dalam permainan yang terbuat dari ruang-ruang terhubung seperti The Legend of Zelda, atau yang lebih baru The Binding of Isaac, atau jenis Roguelike atau bahkan Metroidvania-like, pintu memainkan bagian penting dalam navigasi dan kemajuan pemain.

Pintu memungkinkan pemain untuk bepergian dari satu ruangan ke ruangan lain atau dari satu tingkat ke tingkat selanjutnya, dan ini membuat pintu memiliki peran yang penting dalam navigasi dan koneksi dari kamar yang berbeda, dari kamar satu ke yang lain, dan dalam mendefinisikan peta sebagai dunia terbuka atau sebagai lantai dungeon. Mereka juga dapat bertindak sebagai penghalang sementara bahwa pemain perlu membuka kunci melalui mekanik tertentu (seperti mendapatkan kunci, atau mengaktifkan sakelar).

Dalam tutorial ini, saya akan mendemonstrasikan beberapa mekanika kunci, dan mengusulkan cara untuk menerapkannya dalam permainan Anda. Ini sama sekali tidak dimaksudkan sebagai satu-satunya cara atau implementasi terbaik; mereka adalah contoh praktis.

Demo interaktif dalam tutorial ini dibuat dengan alat pembuat game HTML5 Construct 2 dan harus kompatibel dengan versi gratisnya. (File CAPX tersedia pada sumber unduhan.) Namun, tutorial ini akan membantu Anda mempelajari cara menerapkan logika pintu dan kunci dalam mesin apa pun yang Anda suka. Setelah Anda mendapatkan ide di balik logika tersebut, semuanya tergantung pada pengetahuan Anda sendiri tentang alat / bahasa pengkodean Anda dan cara Anda ingin menyesuaikannya dengan permainan yang sedang Anda buat.

Mari kita menyelaminya!

Mekanika Dasar

Pintu pada dasarnya adalah sebuah blok pemandangan yang tidak dapat dilewati, mencegah karakter pemain untuk melewatinya sampai tidak terkunci. Pintu dapat memiliki status yang berbeda: terkunci atau tidak terkunci, tertutup atau terbuka.

Harus ada representasi yang jelas dari yang terakhir; pemain harus dapat mengatakan bahwa pintu sebenarnya adalah pintu dan apakah itu dalam keadaan terkunci atau tidak terkunci.

Dalam demo berikut ini, pintunya disajikan melalui dua grafik:


Ini adalah pintu yang tertutup.

Ini adalah pintu yang terbuka.

Saya juga menggunakan warna yang berbeda untuk merepresentasikan bahan yang berbeda yang mungkin dibuat oleh pintu-tapi jujur ​​saja, aspek grafisnya terserah Anda, permainan Anda, dan seluruh komponennya. Bagian yang paling penting adalah bahwa pintu harus secara jelas dapat diidentifikasi sebagai pintu, dan itu harus jelas apakah itu akan menghalangi perkembangan pemain atau membuka dan membimbing ke sisa tingkat berikutnya atau dunia.

Ketika ditutup atau dikunci, pintu harus berupa blok solid yang diam. Ketika dibuka, keadaan padat harus dinonaktifkan, yang memungkinkan karakter untuk melewatinya. Pastikan bahwa apa pun mesin tabrakan Anda, ia memungkinkan Anda untuk mengubah keadaan ini dengan mudah. Pastikan bahwa apa pun mesin tabrakan Anda, ia memungkinkan Anda untuk mengubah keadaan ini dengan mudah.

Dari perspektif pemrograman, objek pintu harus berisi atau ditautkan ke variabel Boolean is_locked. Anda dapat menentukan sprite apa yang akan ditampilkan dan apakah blok harus solid atau tidak, tergantung pada nilai variabel ini.

Untuk membuka kunci pintu, karakter harus berisi sebuah variabel Boolean has_key ketika pemain telah mengambil kunci: true jika mereka memilikinya, dan false jika mereka tidak memilikinya.

Dalam mekanika dasar ini, kunci bertindak sebagai bagian dari inventarisasi karakter, dan satu kunci membuka semua pintu. Menggunakan kunci di pintu tidak akan memakannya; kunci akan tetap dalam inventaris karakter.

Untuk memvisualisasikannya, kita hanya dapat menampilkan gambar kunci di HUD untuk membiarkan pemain tahu bahwa dia "memiliki" kunci yang dapat membuka pintu setelah karakter mengambilnya (dengan memindahkan karakter di atas kunci di ruangan).

Pertimbangkan contoh dasar berikut:

Klik demo untuk memberi fokus, lalu kontrol karakter menggunakan tombol panah keyboard Anda dan lakukan tindakan dengan tombol spasi. (Dalam contoh ini, tindakannya adalah "buka pintu".)

Dinding adalah blok padat yang tidak memungkinkan karakter untuk masuk ketika bertabrakan dengan mereka. Pintu tertutup juga merupakan bahan padat.

Untuk membuka pintu, karakter harus berada dalam keadaan 64 piksel dari pintu dan memiliki kunci (yaitu, variabel Boolean has_key yang menentukan apakah karakter memiliki kunci dalam inventarisnya harus true).

Dalam kondisi tersebut, ketika pemain menekan tombol spasi, keadaan pintu yang sesuai diubah. Variabel Boolean locked disetel menjadi false, dan status "padat" dinonaktifkan.

Dalam pseudocode, akan terlihat seperti ini:

1
Door.Locked = True
2
    Door.AnimationFrame = 0 
3
//The animation frame that displays the door as locked

4
    Door.Solid = Enabled 
5
//The solid state of the door is enabled

6
7
Door.Locked = False
8
    Door.AnimationFrame = 1 
9
//The animation frame that displays the door as opened

10
    Door.Solid = Disabled 
11
//The solid state of the door is disabled

12
13
Keyboard Key "Space" is pressed
14
and Distance(Character,Door) <= 64px
15
and Door.Locked = True
16
and Character.Has_Key = True 
17
//The player has a key

18
    Door.Locked = False
19
    
20
Keyboard Key "Space" is pressed
21
and Distance(Character,Door) <= 64px
22
and Door.Locked = True
23
and Character.Has_Key = False 
24
//The player does not have a key

25
    Text.text = "You don't have a key for that door"

Pengingat: Kode ini tidak mewakili bahasa tertentu; Anda harus dapat menerapkannya dalam bahasa apa pun yang Anda inginkan.

Anda juga dapat mencatat bahwa kami melakukan pemeriksaan ketika pemain tidak memiliki kunci yang diharapkan, dan menampilkan pesan umpan balik yang menjelaskan mengapa pintu tidak terkunci. Anda dapat menangani pengecekan ini agar sesuai dengan permainan Anda — ketahuilah bahwa memberikan umpan balik kepada pemain Anda bahwa aksinya terdaftar merupakan ide bagus, dan jelaskan alasan mengapa itu tidak komplit.

Ini adalah sebuah logika pintu dan kunci yang sangat dasar serta bagaimana menerapkannya. Di sisa- sisa tutorial ini, kita akan melihat sistem kunci lain yang merupakan varian dari sistem dasar ini.

Sistem Kunci yang Berbeda

Kita telah melihat sistem dasar di mana kuncinya adalah seluruh bagian inventaris karakter dan satu kunci membuka semua pintu dan dapat digunakan kembali untuk membuka beberapa pintu. Mari kita membangun ini.

Contoh KeyStack

Pada contoh berikut, karakter akan memiliki stack (setumpuk) kunci dalam inventarisnya. Meskipun ada beberapa warna pintu yang berbeda, perbedaannya merupakan perbedaan grafis — objek pintu secara logis sama dengan contoh dasar, dan satu jenis kunci dapat membuka salah satunya. Namun, kali ini, setiap kali Anda menggunakan kunci untuk membuka pintu, kunci itu dihilangkan dari tumpukan.

Sejauh pengkodean yang diperhatikan, modifikasi ini sebagian besar terjadi pada tingkat karakter. Alih-alih memiliki variabel Boolean has_key, Anda akan ingin memiliki variabel numerik yang akan menahan jumlah kunci yang dimiliki karakter "dalam stok".

Setiap kali karakter mengambil kunci, tambahkan 1 ke variabel ini untuk merepresentasikan tumpukan yang naik. Setiap kali karakter membuka pintu, kurangi 1 dari variabel ini untuk mewakili penggunaan kunci. (Di dunia game video, kunci dihancurkan segera setelah digunakan sekali.)

Modifikasi lain adalah ketika pemain menekan tombol spasi: alih-alih memeriksa bahwa variabel Boolean has_key adalah true, kami sebenarnya ingin memeriksa bahwa nilai KeyStack lebih dari nol, sehingga kita dapat mengkonsumsi kunci setelah membuka pintu.

Dalam pseudocode akan terlihat seperti ini:

1
Doors mechanics =  same as in the basic example above.
2
3
Keyboard Key "Space" is pressed
4
and Character.KeyStack > 0
5
and Distance(Character, Door) <= 64
6
and Door.Locked = True
7
    Character.KeyStack = Character.KeyStack - 1
8
    Door.Locked = False

Contoh WhichKey

Dalam contoh baru ini, kami akan mempertimbangkan skenario di mana jenis-jenis pintu yang berbeda memerlukan jenis kunci yang berbeda untuk dibuka kuncinya.

Di sini, seperti pada contoh dasar pertama, kunci akan menjadi bagian dari inventaris karakter. Kami akan kembali menggunakan variabel Boolean untuk menentukan apakah karakter telah mengambil kunci yang diperlukan. Dan karena kita akan memiliki kunci yang berbeda, kita juga akan memiliki berbagai jenis pintu (pintu hitam, pintu merah, pintu emas) yang juga akan membutuhkan kunci yang sesuai untuk memungkinkan mereka dibuka (kunci hitam, kunci merah, kunci emas, masing-masing).

Objek pintu akan menggunakan sprite yang berbeda untuk menunjukkan materi mereka, dan akan berisi variabel numerik bernama WhichKey yang akan menunjukkan jenis kunci yang diharapkan serta jenis grafik yang seharusnya ditampilkan. Nilai-nilai kunci yang berbeda terkandung sebagai variabel konstan, untuk keterbacaan yang lebih baik.

Dalam pseudocode:

1
CONSTANT BLACK_KEY = 0
2
CONSTANT RED_KEY = 1
3
CONSTANT GOLD_KEY = 2
4
5
Door mechanics are the same as in the basic example.
6
7
Keyboard Key "Space" is pressed
8
    //The door requires a black key but the character doesn't have one

9
    If Door.Locked = True
10
    and Door.WhichKey = BLACK_KEY
11
    and Character.Has_Black_Key = False
12
    and Distance(Door,Character) <= 64
13
        Text.text="You need a black key for this door"
14
    
15
    //The door requires a red key but the character doesn't have one

16
    Else If Door.Locked = True
17
    and Door.WhichKey = RED_KEY
18
    and Character.Has_Red_Key = False
19
    and Distance(Door,Character) <= 64
20
        Text.text="You need a red key for this door"
21
    
22
    //The door requires a gold key but the character doesn't have one

23
    Else If Door.Locked = True
24
    and Door.WhichKey = GOLD_KEY
25
    and Character.Has_Gold_Key = False
26
    and Distance(Door,Character) <= 64
27
        Text.text="You need a red key for this door"
28
    
29
    //The door requires a black key and the character has one

30
    Else If Door.Locked = True
31
    and Door.WhichKey = BLACK_KEY
32
    and Character.Has_Black_Key = True
33
    and Distance(Door,Character) <= 64
34
        Door.Locked = False
35
    
36
    //The door requires a red key and the character has one

37
    Else If Door.Locked = True
38
    and Door.WhichKey = RED_KEY
39
    and Character.Has_Red_Key = True
40
    and Distance(Door,Character) <= 64
41
        Door.Locked = False
42
    
43
    //The door requires a gold key and the character has one

44
    Else If Door.Locked = True
45
    and Door.WhichKey = GOLD_KEY
46
    and Character.Has_Gold_Key = True
47
    and Distance(Door,Character) <= 64
48
        Door.Locked = False

Ini adalah sebuah variasi pada contoh dasar yang memungkinkan beberapa jenis kunci dan pintu dan yang tidak mengkonsumsi kunci untuk membuka pintu. Setelah Anda memiliki kunci, itu adalah bagian dari inventaris Anda — bagian dari "statistik" karakter.

Contoh Switch

Kali ini, alih-alih melakukan aksi langsung pada pintu, pemain harus mengaktifkan tombol khusus untuk membuka atau menutup pintu tertentu.

Pintu-pintu di sini pada dasarnya adalah objek yang sama seperti pada contoh dasar. Mereka bisa menampilkan grafik yang berbeda, tetapi logika objeknya masih sama. Ada tambahan meskipun: kita menambahkan dua variabel numerik DoorID dan SwitchID, yang kita gunakan untuk mengetahui tombol switch mana yang diikat ke pintu mana.

Switches adalah jenis objek baru yang saya pilih untuk membuat solid (tetapi Anda tidak perlu melakukannya). Mereka berisi variabel Boolean, Activated, dan variabel numerik DoorID dan SwitchID yang, seperti yang bisa Anda tebak, kami gunakan untuk menentukan tombol mana yang diikat ke pintu mana.

Jadi ketika sebuah tombol telah Activated: True, pintu "tertaut" diatur agar menjadi Locked: False. Tindakan kita dengan tombol spasi kemudian akan terjadi ketika ada tombol di samping pintu. Perhatikan tidak adanya kunci dalam contoh ini dikarenakan switch yang bertindak sebagai kunci:

Kita hanya bisa menggunakan kode sederhana yang memeriksa tautan-saklar pintu di ruang yang sama (karena contoh ini menampilkan tiga pintu dan switch di ruangan yang sama), tetapi kemudian, kita akan melihat bahwa kita mungkin memiliki switch yang bekerja di pintu yang ada di dalam ruangan lain, dan tindakan mereka tidak akan terjadi pada saat yang tepat ketika pemain mengaktifkan switch; itu akan terjadi nanti, ketika ruang baru dimuat.

Untuk alasan ini, kita perlu ketekunan. Salah satu pilihan untuk ini adalah menggunakan array untuk melacak data seperti keadaan switch (yaitu, apakah setiap switch diaktifkan atau tidak).

Didalam pseudocode:

1
CONSTANT SWITCH_DOORID = 0
2
CONSTANT SWITCH_ACTIVATION = 1
3
//Those constants will allow us to keep a readable reminder of the array coordinates

4
<br>//Define some array

5
//The X coordinate of the array will correspond to the SwitchID value

6
//The Y-0 coordinate will be the DoorID

7
//The Y-1 coordinate will be the activation state

8
aSwitch(number of switches,2)
9
//2 is the height (Y) number, often 0-based.

10
<br>Run some association of the SwitchIDs with DoorIDs
11
12
Door mechanic is still the same as in the basic example.
13
14
//Displaying the correct switch graphic according to their activation state

15
Switch.Activated = True
16
    Display the animation frame Switch_ON
17
Switch.Activated = False
18
    Display the animation frame Switch_OFF
19
20
Keyboard Key "Space" is pressed
21
and Distance(Character, Switch) <= 64
22
    Switch.Toggle(Activated) 
23
    //A function that will set the value to either True or False)

24
    aSwitch(Switch.SwitchID,SWITCH_ACTIVATION) = Switch.Activated
25
    //It can depend on your coding language, but the idea is to set the value in the array where X is the SwitchID and where Y is the state of activation of the switch. The value itself is supposed to be the equivalent of the Switch.Activated boolean value.

26
27
Door.DoorID = aSwitch(Switch.SwitchID,SWITCH.DOORID)
28
//Allows us to make sure we're applying/selecting the correct door instance

29
    //Now according to the activation value, we lock or unlock the door

30
    aSwitch(Switch.SwitchID,SWITCH.ACTIVATION) = True
31
        Door.Locked = False
32
    aSwitch(Switch.SwitchID,SWITCH.ACTIVATION) = False
33
        Door.Locked = True

Untuk contoh spesifik ini, di mana switch berada di ruangan yang sama dengan pintu yang terhubung dengan mereka, menggunakan teknik array terlalu berlebihan. Jika permainan Anda diatur sedemikian rupa sehingga setiap tombol yang beraksi di pintu akan diposisikan di ruangan yang sama, maka dengan segala cara, gunakan metode yang lebih sederhana, singkirkan array, dan periksa objek yang hanya ada di layar.

Contoh Plate-Switch

Plate-switch mirip dengan switch, dalam arti bahwa mereka diaktifkan atau tidak, dan bahwa kita dapat menghubungkannya ke pintu untuk mengunci atau membuka kunci mereka. Perbedaannya terletak pada bagaimana pelat diaktifkan dengan melalui tekanan.

Dalam contoh tampilan top-down ini, pelat switch akan diaktifkan setiap kali karakter tersebut tumpang tindih. Anda dapat menekan tombol spasi untuk menjatuhkan batu pada pelat switch, membiarkannya diaktifkan bahkan ketika karakter tidak berdiri di atasnya.

Implementasi ini mirip dengan contoh sebelumnya, dengan dua modifikasi kecil:

  • Anda harus mengaktifkan pelat-switch ketika karakter atau batu ada di atasnya.
  • Anda harus membuat tombol spasi menjatuhkan batu (dari inventaris) ke pelat-switch.
1
//Most of the implementation is the same as the previous example replace the Switch object with PlateSwitch object

2
3
//Plate-Switch Mechanic

4
Character OR Rock is NOT overlapping PlateSwitch
5
    PlateSwitch.Activated = False
6
    aSwitch(PlateSwitch.SwitchID,SWITCH_ACTIVATION) = PlateSwitch.Activated
7
    
8
    Door.DoorID = aSwitch(PlateSwitch.SwitchID,SWITCH.DOORID)
9
    //Allows us to make sure we're applying/selecting the correct door instance

10
        Door.Locked = True
11
12
Character OR Rock is overlapping PlateSwitch
13
    PlateSwitch.Activated = True
14
    aSwitch(PlateSwitch.SwitchID,SWITCH_ACTIVATION) = PlateSwitch.Activated
15
16
    Door.DoorID = aSwitch(PlateSwitch.SwitchID,SWITCH.DOORID)
17
    //Allows us to make sure we're applying/selecting the correct door instance

18
        Door.Locked = False
19
        
20
Keyboard Key "Space" is pressed
21
And Character is overlapping PlateSwitch
22
    Spawn Rock at PlateSwitch.position
23

Contoh Mobs

Mekanik kunci lain yang mungkin adalah mengharuskan pemain untuk menyingkirkan semua musuh (juga dikenal sebagai mobs) di ruangan atau area untuk memicu membuka kunci pintu.

Untuk contoh ini, saya telah membuat beberapa area dalam satu kamar; masing-masing daerah memiliki pintu dan beberapa massa (meskipun musuh-musuh itu tidak bergerak dan tidak menangani kerusakan).
Setiap area memiliki warna tersendiri.

Tombol spasi akan membuat karakter memecat beberapa proyektil; tiga proyektil akan membunuh massa.

Mekanika semacam ini digunakan dalam The Legend of Zelda dan The Binding of Isaac, dan berputar di sekitar fungsi memeriksa jumlah musuh yang hidup di ruangan atau daerah. Dalam contoh ini, setiap area berwarna memegang hitungan mob yang hidup, dimulai ketika ruangan dimuat, dan diikat ke pintu. Kematian setiap mob mengurangi 1 dari counter ini; setelah turun menjadi 0, status Locked pintu diubah menjadi False.

1
//On start of the game

2
For each Area
3
    For each Mob overlapping Area
4
        Area.AliveMobs = Area.AliveMobs + 1
5
<br>Door mechanic is the same as in the basic example<br>
6
Keyboard Key "Space" is pressed
7
    Spawn a Projectile from Character's position

8


9
Projectile collides with Mob

10
    Mob.HP = Mob.HP - 1

11
    Destroy Projectile

12


13
Mob.HP <=0 //Mob is dead

14
and Mob is overlapping Area

15
    Destroy Mob

16
    Area.AliveMobs = Area.AliveMobs - 1

17


18
Area.AliveMobs <= 0

19
and Door is linked to Area //By means of an ID, a pointer or whatever

20
    Door.Locked = False

Dalam contoh ini, Area adalah sprite berwarna dengan variabel numerik terkait, AliveMobs, yang menghitung jumlah massa yang tumpang tindih dengan area tersebut. Setelah semua mob di suatu area dikalahkan, pintu yang bersangkutan tidak terkunci (menggunakan mekanik yang sama seperti yang telah kita lihat sejak contoh dasar).

Contoh Navigasi

Seperti yang saya sebutkan dalam pendahuluan, pintu dapat bertindak sebagai penghalang rintangan, tetapi juga dapat digunakan untuk memungkinkan karakter pemain untuk bernavigasi dari kamar ke kamar lain.

Dalam contoh ini, pintu akan dibuka secara default karena kami lebih tertarik pada aspek navigasi.

Mekanik sangat tergantung pada permainan yang Anda buat, serta cara Anda menangani struktur data untuk lantai Anda. Saya tidak akan membahas detail bagaimana implementasi saya bekerja di sini, karena sangat spesifik untuk Membangun 2, tetapi Anda dapat menemukannya di file sumber jika Anda mau.

Kesimpulan

Sepanjang artikel ini, kita telah melihat bagaimana pintu adalah penghalang sementara yang membutuhkan kunci atau pembuka kunci mekanika seperti switch, pelat switch, atau bahkan kematian mobs. Kami juga telah melihat bagaimana mereka dapat bertindak sebagai "jembatan", memungkinkan navigasi melalui berbagai area di dunia game.

Sebagai pengingat cepat, berikut beberapa kemungkinan mekanisme kunci:

  • Satu kunci untuk semua pintu, sebagai bagian dari inventaris.
  • Kunci konsumsi: setiap kali Anda membuka pintu, satu kunci akan diambil dari tumpukan kunci Anda.
  • Pintu yang berbeda membutuhkan kunci yang berbeda.
  • Switch, atau pelat switch, di mana Anda tidak bertindak langsung di pintu untuk membuka kunci tetapi melalui perangkat yang terpisah dan tertaut.
  • Membunuh semua massa dari suatu daerah secara otomatis membuka pintu.

Jika Anda mencampurkan semua mekanik itu dalam permainan, Anda bisa berakhir dengan sesuatu seperti ini:

Di sini kita memiliki pilihan yang bagus dari berbagai mekanisme pintu dan kunci, yang mengharuskan pemain untuk melewati beberapa ruangan untuk membuka kunci berbagai pintu. Untuk tujuan pembelajaran, Anda mungkin ingin mereproduksi ini di lingkungan pemrograman Anda sendiri, menggunakan semua implementasi sebelumnya yang telah kami lalui.

Saya harap Anda menikmati artikel ini yang mungkin akan bermanfaat bagi Anda, dan saya ingin mengingatkan bahwa Anda dapat menemukan sumber dari semua demo di Github. Anda dapat membuka dan mengeditnya dalam versi gratis Construct 2 (versi r164.2 atau versi diatasnya).

Referensi

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.