7 days of WordPress themes, graphics & videos - for free!* Unlimited asset downloads! Start 7-Day Free Trial
Advertisement
  1. Game Development
  2. Programming

Membuat Shooter Vektor Neon di XNA: The Warping Grid 

Read Time: 14 mins
This post is part of a series called Cross-Platform Vector Shooter: XNA.
Make a Neon Vector Shooter in XNA: Particle Effects

Indonesian (Bahasa Indonesia) translation by Shylchemist (you can also view the original English article)

Dalam seri tutorial ini, saya akan menunjukkan cara membuat penembak tongkat neon neon, seperti Geometri Wars, di XNA.Tujuan dari tutorial ini bukan untuk meninggalkan Anda dengan replika Perang Geometri yang sama persis, melainkan untuk membahas elemen-elemen penting yang memungkinkan Anda membuat varian berkualitas tinggi sendiri. 


Overview

Dalam seri sejauh ini kami menciptakan gameplay, mekar, dan efek partikel. Pada bagian akhir ini, kita akan membuat grid latar belakang yang dinamis dan melengkung.

Salah satu efek paling keren dalam Geometri War adalah grid latar belakang warping. Kami akan memeriksa cara membuat efek serupa dalam Shape Blaster. Grid akan menampilkan peluru, lubang hitam, dan pemain yang sedang beristirahat. Tidak sulit paksa dan terlihat mengagumkan.

Kami akan membuat grid menggunakan simulasi pegas. Di setiap persimpangan dari grid, kami akan menempatkan beban kecil dan memasang pegas di setiap sisi. Mata air ini hanya akan menarik dan tidak pernah mendorong, seperti karet gelang. Untuk menjaga grid tetap pada posisinya, massa di perbatasan grid akan berlabuh di tempatnya. Di bawah ini adalah diagram tata letak.

Grid Layout

Kami akan membuat kelas yang disebut Grid untuk membuat efek ini. Namun, sebelum kita mengerjakan jaringan itu sendiri, kita perlu membuat dua kelas pembantu: Spring dan PointMass .

Kelas PointMass 

Kelas PointMass mewakili massa yang akan kita pasang mata air. Mata air tidak pernah terhubung langsung ke mata air lainnya. Sebaliknya, mereka menerapkan kekuatan kepada massa yang mereka hubungkan, yang pada gilirannya dapat meregangkan mata air lainnya.

Ada beberapa poin menarik tentang kelas ini. Pertama, perhatikan bahwa itu menyimpan kebalikan dari massa, 1 / mass. Ini sering merupakan ide yang bagus dalam simulasi-simulasi fisika karena persamaan fisika cenderung menggunakan inversi massa lebih sering, dan karena itu memberi kita cara mudah untuk merepresentasikan benda-benda tak terhingga berat yang tak bergerak dengan mengatur massa inverse ke nol.

Kelas juga berisi damping variabel. Ini digunakan kira-kira sebagai gesekan atau hambatan udara. Secara bertahap memperlambat massa. Ini membantu membuat grid akhirnya berhenti dan juga meningkatkan stabilitas simulasi pegas.

Metode Update() melakukan pekerjaan menggerakkan titik massa setiap frame. Ini dimulai dengan melakukan symplectic Euler integration, yang berarti kita menambahkan percepatan ke kecepatan dan kemudian menambahkan kecepatan yang diperbarui ke posisi. Ini berbeda dari integrasi Euler standar di mana kami akan memperbarui kecepatan setelah memperbarui posisi.

Tip: Euler symplectic lebih baik untuk simulasi musim semi karena menghemat energi. Jika Anda menggunakan integrasi Euler secara teratur dan membuat pegas tanpa peredam, mereka akan cenderung meregangkan lebih jauh dan lebih lanjut setiap pantulan saat mereka mendapatkan energi, akhirnya melanggar simulasi Anda.

Setelah memperbarui kecepatan dan posisi, kami memeriksa apakah kecepatannya sangat kecil, dan jika demikian kami mengaturnya menjadi nol. Ini bisa menjadi penting untuk kinerja karena sifat denormalized floating-point numbers.

(Ketika angka floating-point menjadi sangat kecil, mereka menggunakan representasi khusus yang disebut nomor denormal. Ini memiliki keuntungan memungkinkan float untuk mewakili angka yang lebih kecil, tetapi itu datang dengan harga. Kebanyakan chipset tidak dapat menggunakan operasi aritmatika standar mereka pada angka denormalized dan sebaliknya harus mengemulasikannya menggunakan serangkaian langkah. Ini bisa puluhan hingga ratusan kali lebih lambat daripada melakukan operasi pada angka floating-point yang dinormalisasi. Karena kita melipatgandakan kecepatan kita dengan faktor redaman kita setiap frame, akhirnya akan menjadi sangat kecil.Kami sebenarnya tidak peduli tentang kecepatan kecil seperti itu, jadi kami cukup mengaturnya ke nol.) 

Metode IncreaseDamping() digunakan untuk sementara meningkatkan jumlah redaman. Kami akan menggunakan ini nanti untuk efek tertentu.

Kelas Musim Semi 

Pegas menghubungkan dua titik massa, dan, jika membentang melewati panjang alami, berlaku kekuatan yang menarik massa bersama. Mata air mengikuti versi modifikasi Hooke's Law dengan redaman:

\ [f = -kx - bv \] 

  • \(f\) adalah gaya yang dihasilkan oleh pegas. 
  • \(k\) adalah konstanta pegas, atau kekakuan pegas. 
  • \(x\) adalah jarak pegas merentang di luar panjang alami. 
  • \(b\) adalah faktor redaman. 
  • \(v\) adalah kecepatannya. 

Kode untuk kelas Spring adalah sebagai berikut. 

Ketika kita membuat pegas, kita mengatur panjang alami pegas menjadi sedikit lebih rendah dari jarak antara dua titik akhir. Ini menjaga kisi-kisi tetap kencang meskipun saat istirahat dan memperbaiki penampilan. 

Metode Update() pertama kali memeriksa apakah pegas merentang melampaui panjang alami. Jika tidak diregangkan, tidak ada yang terjadi. Jika ya, kami menggunakan Hukum Hooke yang dimodifikasi untuk menemukan gaya dari pegas dan menerapkannya pada dua massa yang terhubung.

Membuat Grid 

Sekarang kita memiliki kelas bertingkat yang diperlukan, kita siap untuk membuat grid. Kami mulai dengan membuat objek PointMass di setiap persimpangan di grid. Kami juga membuat beberapa objek PointMass anchor yang tidak dapat dipindahkan untuk menahan grid di tempatnya.Kami kemudian menghubungkan massa dengan mata air.

Yang pertama for loop menciptakan baik massa biasa dan massa tak bergerak di setiap persimpangan grid. Kami tidak akan benar-benar menggunakan semua massa yang tak bergerak, dan massa yang tidak terpakai hanya akan menjadi sampah yang dikumpulkan beberapa saat setelah konstruktor berakhir. Kita bisa mengoptimalkan dengan menghindari membuat objek yang tidak perlu, tetapi karena grid biasanya hanya dibuat sekali, itu tidak akan membuat banyak perbedaan. 

Selain menggunakan titik jangkar massa di sekitar perbatasan grid, kami juga akan menggunakan beberapa jangkar massa di dalam grid. Ini akan digunakan untuk dengan sangat lembut membantu menarik grid kembali ke posisi semula setelah mengalami deformasi.

Karena titik jangkar tidak pernah bergerak, mereka tidak perlu memperbarui setiap bingkai. Kami hanya dapat menghubungkan mereka ke mata air dan melupakannya. Oleh karena itu, kami tidak memiliki variabel anggota dalam kelas Grid untuk massa ini. 

Ada sejumlah nilai yang dapat Anda atur dalam kreasi kisi. Yang paling penting adalah kekakuan dan redaman mata air. Kekakuan dan redaman jangkar perbatasan dan jangkar interior diatur secara independen dari mata air utama. Nilai kekakuan yang lebih tinggi akan membuat pegas berosilasi lebih cepat, dan nilai peredaman yang lebih tinggi akan menyebabkan pegas melambat lebih cepat. 

Memanipulasi Grid 

Agar grid bisa bergerak, kita harus memperbaruinya setiap frame. Ini sangat sederhana karena kami sudah melakukan semua kerja keras di kelas PointMass dan Spring

Sekarang kita akan menambahkan beberapa metode yang memanipulasi grid. Anda dapat menambahkan metode untuk segala jenis manipulasi yang dapat Anda pikirkan. Kami akan mengimplementasikan tiga jenis manipulasi di sini: mendorong bagian grid dalam arah tertentu, mendorong grid keluar dari beberapa titik, dan menarik grid ke arah beberapa titik. Ketiganya akan mempengaruhi grid dalam radius tertentu dari beberapa titik target. Di bawah ini adalah beberapa gambar manipulasi ini dalam aksi.

Bullets repelling the grid outwardsBullets repelling the grid outwardsBullets repelling the grid outwards
Peluru menangkis kisi keluar.
Sucking the grid inwardsSucking the grid inwardsSucking the grid inwards
Menghisap grid ke dalam. 
Wave created by pushing the grid along the z-axisWave created by pushing the grid along the z-axisWave created by pushing the grid along the z-axis
Gelombang dibuat dengan mendorong grid sepanjang sumbu z. 

Kami akan menggunakan ketiga metode ini dalam Shape Blaster untuk efek yang berbeda. 

Rendering Grid 

Kami akan menggambar grid dengan menggambar segmen garis antara setiap pasangan titik yang berdekatan. Pertama, kita akan membuat metode perluasan pada SpriteBatch yang memungkinkan kita untuk menggambar segmen garis dengan mengambil tekstur dari satu piksel dan merentangkannya menjadi sebuah garis.

Buka kelas Art dan deklarasikan tekstur untuk piksel. 

Anda dapat mengatur tekstur piksel dengan cara yang sama kami mengatur gambar lainnya, atau Anda dapat menambahkan dua baris berikut ke metode Art.Load().

Ini hanya menciptakan tekstur 1x1px baru dan menetapkan satu-satunya piksel menjadi putih. Sekarang tambahkan metode berikut di kelas Extensions.

Metode ini membentang, memutar, dan mewarnai tekstur piksel untuk menghasilkan garis yang kita inginkan. 

Selanjutnya, kita perlu metode untuk memproyeksikan titik grid 3D ke layar 2D kami. Biasanya ini mungkin dilakukan dengan menggunakan matriks, tetapi di sini kita akan mengubah koordinat secara manual. 

Tambahkan yang berikut ke kelas Grid.

Transformasi ini akan memberikan grid pandangan perspektif di mana titik jauh muncul lebih dekat bersama di layar. Sekarang kita dapat menggambar grid dengan mengulang melalui baris dan kolom dan menggambar garis di antara mereka. 

Dalam kode di atas, p adalah titik kita saat ini di grid, kiriadalah titik langsung ke kiri dan ke atas adalah titik tepat di atasnya. Kami menggambar setiap baris ketiga lebih tebal secara horizontal dan vertikal untuk efek visual. 

Interpolasi 

Kita dapat mengoptimalkan grid dengan meningkatkan kualitas visual untuk sejumlah mata air tertentu tanpa meningkatkan biaya kinerja secara signifikan. Kami akan melakukan dua optimasi seperti itu. 

Kami akan membuat jaringan lebih padat dengan menambahkan segmen garis di dalam sel-sel grid yang ada. Kami melakukannya dengan menggambar garis dari titik tengah satu sisi sel ke titik tengah sisi yang berlawanan. Gambar di bawah ini menunjukkan garis interpolasi baru berwarna merah. 

Interpolated LinesInterpolated LinesInterpolated Lines
Grid dengan garis interpolasi terbuka dengan warna merah

Menggambar garis interpolasi sangat mudah. Jika Anda memiliki dua poin, a dan b, titik tengahnya adalah (a + b) / 2 .Jadi, untuk menggambar garis interpolasi, kami menambahkan kode berikut di dalam for loops metode Draw() kami .

Perbaikan kedua adalah melakukan interpolasi pada segmen garis lurus kami untuk membuatnya menjadi kurva yang lebih halus. XNA menyediakan metode Vector2.CatmullRom() berguna yang melakukan Catmull-Rom interpolation.  Anda melewatkan metode empat titik berurutan pada garis lengkung, dan akan mengembalikan titik-titik sepanjang kurva halus antara titik kedua dan ketiga yang Anda berikan.

Argumen kelima untuk Vector2.CatmullRom() adalah faktor pembobotan yang menentukan titik mana pada kurva interpolasi yang dihasilkannya.  Faktor pembobot 0 atau 1 masing-masing akan mengembalikan titik kedua atau ketiga yang Anda berikan, dan faktor pembobotan 0.5 akan mengembalikan titik pada kurva interpolasi di antara dua titik.  Dengan secara berangsur-angsur menggerakkan faktor pembobotan dari nol ke satu dan menggambar garis di antara titik-titik yang dikembalikan, kita dapat menghasilkan kurva yang sangat mulus.  Namun, untuk menjaga biaya kinerja rendah, kami hanya akan mengambil satu titik interpolasi menjadi pertimbangan, pada faktor pembobotan 0.5 . Kami kemudian mengganti garis lurus asli di grid dengan dua garis yang bertemu pada titik interpolasi.

Diagram di bawah ini menunjukkan efek interpolasi ini.

Catmull-Rom Interpolation

Karena segmen garis dalam grid sudah kecil, menggunakan lebih dari satu titik interpolasi umumnya tidak membuat perbedaan yang nyata. 

Seringkali, garis-garis di grid kita akan sangat lurus dan tidak akan memerlukan smoothing. Kita dapat memeriksa ini dan menghindari menggambar dua garis, bukan satu. Kami memeriksa apakah jarak antara titik interpolasi dan titik tengah garis lurus lebih besar dari satu piksel. Jika ya, kita asumsikan garis melengkung dan kita menggambar dua segmen garis. Modifikasi metode Draw() kami untuk menambahkan interpolasi Catmull-Rom untuk garis horizontal ditunjukkan di bawah ini. 

Gambar di bawah ini menunjukkan efek smoothing. Titik hijau digambar pada setiap titik interpolasi untuk mengilustrasikan dengan lebih baik di mana garis-garis diperhalus. 

Smoothed Grid LinesSmoothed Grid LinesSmoothed Grid Lines

Menggunakan Grid dalam Shape Blaster 

Sekarang saatnya menggunakan grid di game kami. Kita mulai dengan mendeklarasikan variabel Grid publik statis di GameRoot dan membuat grid dalam method GameRoot.Initialize(). Kami akan membuat grid dengan kira-kira 1600 poin seperti itu.

Kemudian kita memanggil Grid.Update() dan Grid.Draw() dari metode Update() dan Draw() di GameRoot . Ini akan memungkinkan kita melihat grid ketika kita menjalankan game. Namun, kita masih perlu membuat berbagai objek game yang berinteraksi dengan grid. 

Peluru akan mengusir grid. Kami sudah membuat metode untuk melakukan ini yang disebut ApplyExplosiveForce(). Tambahkan baris berikut ke method Bullet.Update().  

Ini akan membuat peluru mengusir grid secara proporsional sesuai kecepatannya. Itu sangat mudah. 

Sekarang mari kita bekerja pada lubang hitam. Tambahkan baris ini ke BlackHole.Update()

Hal ini membuat lubang hitam menyedot grid dengan jumlah kekuatan yang bervariasi.  Saya menggunakan kembali variabel sprayAngle , yang akan menyebabkan gaya pada grid untuk berdenyut sinkron dengan sudut yang disemprotkan partikel (meskipun pada setengah frekuensi karena pembagian oleh dua). Gaya yang diteruskan akan bervariasi secara sinusoidal antara 10 dan 30. 

Akhirnya, kita akan menciptakan gelombang kejut di grid ketika kapal pemain bereaksi setelah kematian.  Kami akan melakukannya dengan menarik grid sepanjang sumbu z dan kemudian memungkinkan kekuatan untuk merambat dan memantul melalui pegas. Sekali lagi, ini hanya membutuhkan modifikasi kecil untuk PlayerShip.Update()


Apa berikutnya? 

Kami memiliki gameplay dan efek dasar yang diterapkan.Terserah Anda untuk mengubahnya menjadi permainan yang lengkap dan dipoles dengan cita rasa Anda sendiri. Coba tambahkan beberapa mekanika baru yang menarik, beberapa efek baru yang keren, atau kisah unik. Jika Anda tidak yakin harus mulai dari mana, berikut beberapa saran. 

  • Buat tipe musuh baru seperti ular atau musuh yang meledak. 
  • Buat jenis senjata baru seperti mencari rudal atau lightning gun.
  • Tambahkan layar judul dan menu utama. 
  • Tambahkan tabel skor tinggi. 
  • Tambahkan beberapa powerup seperti perisai atau bom. Untuk poin bonus, berkreasi dengan kekuatan Anda. Anda dapat membuat powerups yang memanipulasi gravitasi, mengubah waktu, atau tumbuh seperti organisme.  Anda dapat memasang bola raksasa yang berbasiskan fisika ke kapal untuk menghancurkan musuh. Bereksperimen untuk menemukan powerup yang menyenangkan dan membantu game Anda menonjol.
  • Buat beberapa level. Tingkat yang lebih keras dapat memperkenalkan musuh yang lebih keras dan senjata dan powerup yang lebih canggih. 
  • Izinkan pemain kedua untuk bergabung dengan gamepad. 
  • Biarkan arena bergulir sehingga mungkin lebih besar dari jendela permainan.
  • Tambahkan bahaya lingkungan seperti laser. 
  • Tambahkan sistem toko atau leveling dan izinkan pemain untuk mendapatkan peningkatan. 

Terima kasih sudah membaca! 

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 Game Development tutorials. Never miss out on learning about the next big thing.
Advertisement
Scroll to top
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.