Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Tile-Based Games
Gamedevelopment

Permainan Unity 2D 'Sokoban' berasaskan Tile

by
Difficulty:BeginnerLength:LongLanguages:

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

Final product image
What You'll Be Creating

Dalam tutorial ini, kita akan meneroka pendekatan untuk membuat permainan sokoban atau crate-pusher menggunakan logik berasaskan jubin dan array dua dimensi untuk memegang data peringkat. Kami menggunakan Perpaduan untuk pembangunan dengan C sebagai bahasa skrip. Sila muat turun fail sumber yang disediakan dengan tutorial ini untuk diikuti.

1. Permainan Sokoban

Mungkin ada antara kita yang mungkin tidak memainkan variasi permainan Sokoban. Versi asal mungkin lebih tua daripada anda. Sila lihat halaman wiki untuk beberapa butiran. Pada dasarnya, kita mempunyai unsur watak atau pengguna yang dikendalikan yang harus menolak peti atau unsur-unsur serupa ke jubin destinasinya.

Tahapnya terdiri daripada kotak segi empat tepat atau segi empat tepat di mana jubin boleh menjadi satu yang tidak dapat dilalui atau satu walkable. Kita boleh berjalan di atas jubin yang boleh dilalui dan menolak peti ke atas mereka. Jubin walkable khas akan ditandakan sebagai jubin destinasi, di mana peti harus akhirnya berehat untuk menyelesaikan tahap. Watak ini biasanya dikawal menggunakan papan kekunci. Apabila semua peti telah mencapai jubin destinasi, tahap itu selesai.

Perkembangan berasaskan ubin pada dasarnya bermaksud permainan kami terdiri daripada sebilangan jubin yang tersebar dengan cara yang telah ditetapkan. Satu elemen data tahap akan mewakili bagaimana jubin perlu disebarkan untuk mencipta tahap kami. Dalam kes kami, kami akan menggunakan grid berasaskan ubin persegi. Anda boleh membaca lebih lanjut mengenai permainan berasaskan-ubin di sini di Envato Tuts +.

2. Menyediakan Projek Perpaduan

Mari lihat bagaimana kami telah menganjurkan projek Perpaduan kami untuk tutorial ini.

The Art

Untuk projek tutorial ini, kami tidak menggunakan sebarang aset seni luaran, tetapi akan menggunakan primitip sprit yang dibuat dengan versi Unity terbaru 2017.1. Imej di bawah menunjukkan bagaimana kita boleh membuat sprite berbentuk berbeza dalam Perpaduan.

How to create sprites within United 20171

Kami akan menggunakan sprit Square untuk mewakili jubin tunggal dalam grid tahap sokoban kami. Kami akan menggunakan sprite Triangle untuk mewakili watak kami, dan kami akan menggunakan sprite Circle untuk mewakili peti, atau dalam kes ini bola. Jubin tanah biasa putih, sedangkan jubin destinasi mempunyai warna yang berbeza untuk menonjol.

Data Tahap

Kami akan mewakili data tahap kami dalam bentuk array dua dimensi yang memberikan korelasi yang sempurna antara elemen logik dan visual. Kami menggunakan fail teks mudah untuk menyimpan data tahap, yang menjadikan kami lebih mudah untuk mengedit tahap di luar Perpaduan atau menukar tahap hanya dengan mengubah fail dimuatkan. Folder Sumber mempunyai fail teks tahap, yang mempunyai tahap lalai kita.

Tahap mempunyai tujuh lajur dan lima baris. Nilai 1 bermakna kita mempunyai jubin tanah pada kedudukan itu. Nilai -1 bermakna bahawa ia adalah jubin yang tidak boleh dilalui, sedangkan nilai 0 bermakna ia adalah jubin destinasi. Nilai 2 mewakili wira kami, dan 3 mewakili bola ditarik. Hanya dengan melihat data tahap, kita boleh memvisualisasikan apa tahap kita akan kelihatan.

3. Membuat Tahap Permainan Sokoban

Untuk menjaga perkara mudah, dan kerana itu bukan logik yang sangat rumit, kita hanya mempunyai satu fail skrip Sokoban.cs untuk projek itu, dan ia dilampirkan pada kamera tempat kejadian. Sila simpannya dalam editor anda semasa anda mengikuti tutorial lain.

Data Tahap Khas

Data tahap yang diwakili oleh pelbagai 2D tidak hanya digunakan untuk membuat grid awal tetapi juga digunakan sepanjang permainan untuk mengesan perubahan tahap dan kemajuan permainan. Ini bermakna nilai semasa tidak mencukupi untuk mewakili beberapa negeri peringkat semasa permainan.

Setiap nilai mewakili keadaan jubin yang sepadan di peringkat. Kami memerlukan nilai tambahan untuk mewakili bola di jubin destinasi dan wira di jubin destinasi, masing-masing adalah -3 dan -2. Nilai-nilai ini boleh menjadi nilai yang anda berikan dalam skrip permainan, tidak semestinya nilai yang sama yang kami gunakan di sini.

Parsing File Text Level

Langkah pertama adalah untuk memuatkan data tahap kami ke dalam array 2D dari fail teks luar. Kami menggunakan kaedah ParseLevel untuk memuat nilai rentetan dan memecahnya untuk mengisi paras levelData 2D kami.

Semasa menghuraikan, kami menentukan bilangan baris dan lajur yang ada pada tahap kami semasa kami mengisi levelData kami.

Tahap Lukisan

Sebaik sahaja kami mempunyai data tahap kami, kami dapat menarik tahap kami pada skrin. Kami menggunakan kaedah CreateLevel untuk berbuat demikian.

Untuk tahap kami, kami telah menetapkan nilai jubin sebanyak 50, yang merupakan panjang sisi satu jubin persegi di grid tahap kami. Kami gelung melalui array 2D kami dan menentukan nilai yang disimpan pada setiap indeks i dan j array. Jika nilai ini bukan Tile (-1) yang tidak sah maka kami membuat jubin bernama GameObject baru. Kami melampirkan komponen SpriteRenderer ke jubin dan menetapkan Sprite atau Warna yang sepadan bergantung pada nilai pada indeks tatasusunan.

Semasa meletakkan wira atau bola, kita perlu terlebih dahulu membuat jubin tanah dan kemudian buat jubin ini. Oleh kerana wira dan bola perlu mengawal jubin tanah, kami memberikan SpriteRenderer mereka sebagai penyortir yang lebih tinggi. Semua jubin ditugaskan tempatanScale of tileSize jadi mereka 50x50 di tempat kejadian kami.

Kami menjejaki bilangan bola di tempat kejadian kami menggunakan pembolehubah ballCount, dan harus ada bilangan jubin destinasi yang sama atau lebih tinggi di peringkat kami untuk membuat penyelesaian tahap mungkin. Keajaiban berlaku dalam satu baris kod di mana kita menentukan kedudukan setiap jubin menggunakan kaedah GetScreenPointFromLevelIndices (int row, int col).

Kedudukan dunia jubin ditentukan dengan mendarabkan indeks tahap dengan nilai jubin. Pembolehubah middleOffset digunakan untuk menyelaraskan tahap di tengah-tengah skrin. Perhatikan bahawa nilai baris didarabkan dengan nilai negatif untuk menyokong paksi y terbalik dalam Perpaduan.

4. Sokoban Logic

Sekarang bahawa kami telah memaparkan tahap kami, mari meneruskan ke logik permainan. Kita perlu mendengar input tekan utama pengguna dan memindahkan pahlawan berdasarkan input. Akhbar utama menentukan gerakan gerakan yang diperlukan, dan wira itu perlu dipindahkan ke arah itu. Terdapat pelbagai senario untuk dipertimbangkan sebaik sahaja kita menentukan arah pergerakan yang diperlukan. Katakan jubin di sebelah wira ke arah ini adalah jubinK.

  • Adakah terdapat jubin di tempat kejadian pada kedudukan itu, atau di luar grid kami?
  • Adakah tileK jubin yang boleh dilalui?
  • Adakah tileK diduduki oleh bola?

Sekiranya kedudukan tileK berada di luar grid, kita tidak perlu melakukan apa-apa. Jika tileK sah dan boleh dilayari, maka kita perlu memindahkan wira ke kedudukan itu dan mengemas kini array levelData kami. Jika tileK mempunyai bola, maka kita perlu mempertimbangkan tetangga seterusnya dalam arah yang sama, katakan tileL.

  • Adakah jubin di luar grid?
  • Adakah tileL jubin yang boleh dilalui?
  • Adakah jubin diduduki oleh bola?

Hanya dalam kes di mana jubin adalah jubin yang boleh dilalui, tidak diduduki sekiranya kita memindahkan pahlawan dan bola di jubinK ke jubin dan jubin masing-masing. Selepas pergerakan yang berjaya, kita perlu mengemas kini array levelData.

Fungsi Menyokong

Logik di atas bermaksud bahawa kita perlu tahu jubin mana yang kita wira saat ini. Kita juga perlu menentukan sama ada jubin tertentu mempunyai bola dan harus mempunyai akses ke bola itu.

Untuk memudahkan ini, kami menggunakan Dictionary called occupants yang menyimpan GameObject sebagai kunci dan indeks arraynya disimpan sebagai Vector2 sebagai nilai. Dalam kaedah CreateLevel, kita mengisi penghuni apabila kita membuat wira atau bola. Sebaik sahaja kita mempunyai kamus yang dihuni, kita boleh menggunakan GetOccupantAtPosition untuk mendapatkan kembali GameObject pada indeks array tertentu.

Kaedah IsOccupied menentukan sama ada nilai levelData pada indeks yang disediakan mewakili bola.

Kami juga memerlukan satu cara untuk memeriksa sama ada kedudukan yang diberikan di dalam grid kami dan jika jubin itu boleh dilalui. Kaedah IsValidPosition menyemak indeks tahap yang diluluskan sebagai parameter untuk menentukan sama ada ia berada di dalam dimensi tahap kami. Ia juga menyemak sama ada kita mempunyai Tahap yang tidak sah sebagai indeks itu di levelData.

Menjawab Input Pengguna

Dalam kaedah Update skrip permainan kami, kami menyemak peristiwa pengguna KeyUp dan bandingkan dengan kekunci input kami yang disimpan dalam array userInputKeys. Sebaik sahaja arah pergerakan yang diperlukan ditentukan, kami memanggil kaedah TryMoveHero dengan arah sebagai parameter.

Kaedah TryMoveHero adalah di mana logik permainan inti kami dijelaskan pada permulaan bahagian ini dilaksanakan. Sila pergi melalui kaedah berikut dengan teliti untuk melihat bagaimana logik dilaksanakan seperti yang dijelaskan di atas.

Untuk mendapatkan kedudukan seterusnya dalam arah tertentu berdasarkan kedudukan yang disediakan, kami menggunakan kaedah GetNextPositionAlong. Ia hanya masalah kenaikan atau penurunan salah satu indeks mengikut arah.

Sebelum menggerakkan wira atau bola, kita perlu membersihkan posisi mereka yang kini diduduki dalam array levelData. Ini dilakukan menggunakan kaedah RemoveOccupant.

Sekiranya kita mendapati heroTile atau ballTile di indeks yang diberikan, kita perlu menetapkannya ke GroundTile. Sekiranya kita menemui seorang heroOnDestinationTile atau ballOnDestinationTile maka kita perlu menetapkannya ke destinasiTile.

Penyelesaian Aras

Tahap lengkap apabila semua bola berada di destinasi mereka.

A Completed Level

Selepas setiap pergerakan yang berjaya, kami memanggil kaedah CheckCompletion untuk melihat apakah tahap selesai. Kami gelung melalui array levelData kami dan mengira bilangan bolaOnDestinationTile kejadian. Jika nombor ini sama dengan jumlah bola kami yang ditentukan oleh ballCount, tahap itu selesai.

Kesimpulan

Ini adalah pelaksanaan logik sokoban yang mudah dan cekap. Anda boleh membuat tahap anda sendiri dengan mengubah fail teks atau membuat yang baru dan mengubah pembolehubah levelName untuk menunjuk ke fail teks baru anda.

Pelaksanaan semasa menggunakan papan kekunci untuk mengawal wira. Saya akan menjemput anda untuk mencuba dan menukar kawalan untuk berasaskan ketuk supaya kami dapat menyokong peranti berasaskan sentuh. Ini akan melibatkan penambahan penemuan laluan 2D juga jika anda suka mengetuk mana-mana jubin untuk memimpin wira di sana.

Terdapat tutorial tindak lanjut di mana kami akan meneroka bagaimana projek semasa boleh digunakan untuk membuat versi sokoban isometrik dan hexagonal dengan perubahan minimum.

Advertisement
Advertisement
Advertisement
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.