Game Boy di C #

Ketika saya baru mulai pemrograman, saya pikir, seperti banyak orang, saya ingin membuat game. Tetapi sebelum saya ada banyak masalah arsitektur yang saya tidak tahu bagaimana menyelesaikannya, saya bahkan tidak mendengar tentang buffering ganda, dan saya ingin mendapatkan hasilnya sesegera mungkin. Oleh karena itu, saya baru-baru ini memutuskan untuk menulis sebuah proyek yang memungkinkan untuk membuat game sederhana tanpa masalah. Game dalam proyek ini dapat dibuat seperti GameBoy, yaitu: tetris, ular, dll. Tapi Anda juga bisa mengkliknya dengan mouse.

Tautan ke proyek di GitHub .

Pada artikel ini saya ingin melihat pembuatan ular.

Hal pertama yang perlu Anda mulai adalah membuat kelas game Anda sendiri dan mewarisi dari kelas dasar Game.

class Snake : Game 

itu sudah mengimplementasikan bidang bermain dan peristiwa yang terjadi ketika game bertransisi dari satu negara ke negara lain. Intinya, yang perlu kita lakukan hanyalah mendeklarasikan penanganan acara.

 public Snake() : base() { OnPreview += BasePreview; OnNewGame += Snake_OnNewGame; OnUpdateGame += Snake_OnUpdateGame; OnGameOver += DrawScore; } 

Untuk acara OnPreview dan OnGameOver, sudah ada stubs yang sudah jadi di kelas Game, Anda tidak bisa mengimplementasikannya. Tetap hanya untuk menginisialisasi game baru dan memproses acara pembaruan.

 private GameBlock head; private List<GameBlock> body; private GameBlock eat; private void Snake_OnNewGame() { head = new GameBlock() { X = 10, Y = 10, Vector = Vector.Up, Color = GameColor.Green }; body = new List<GameBlock>(); body.Add( head ); body.Add( new GameBlock() { X = 10, Y = 11, Vector = Vector.Up, Color = GameColor.Black } ); body.Add( new GameBlock() { X = 10, Y = 12, Vector = Vector.Up, Color = GameColor.Black } ); CreateEat(); DrawField(); } 

Anda dapat bekerja dengannya secara langsung untuk menggambar bidang, atau Anda dapat menggunakan kelas GameBlock yang sudah jadi, itu mengimplementasikan hal-hal seperti posisi, arah gerakan dan warna.

Dalam fungsi ini, kami mendeklarasikan tubuh ular, membuat potongan makanan pertama dan menampilkan apa yang terjadi di lapangan.

 private void CreateEat() { var emptyBlocks = new List<GameBlock>(); for( int i = 0; i < MainForm.FIELD_SIZE; i++ ) for( int j = 0; j < MainForm.FIELD_SIZE; j++ ) if( CheckEmptyBlock( i, j ) ) emptyBlocks.Add(new GameBlock() { X = i, Y = j, Color = GameColor.Red } ); if (emptyBlocks.Count > 0) eat = emptyBlocks[random.Next( emptyBlocks.Count )]; } 

Untuk membuat makanan, kami mendapatkan daftar blok kosong dan dengan bantuan pengacak (yang sudah dinyatakan dalam Game) pilih acak. Jika ular telah menempati seluruh bidang, ada tanda centang pada ukuran daftar.

Sebenarnya, fungsi memeriksa sel kosong:

 private bool CheckEmptyBlock(int x, int y) => !( x < 0 || y < 0 || x == MainForm.FIELD_SIZE || y == MainForm.FIELD_SIZE ) && !body.Exists( a => a.Equals( new GameBlock() { X = x, Y = y } ) ); 

Render bidang adalah sebagai berikut:

 private void DrawField() { Field.Clear( GameColor.White ); Field.DrawGameBlock( eat ); Field.DrawGameBlocks( body ); WriteScore(); } 

Karena tidak sulit ditebak, bidang dibersihkan dalam warna putih dan makanan dengan ular ditampilkan. WriteScore adalah fitur standar lain untuk menampilkan skor di bilah status khusus.

Jadi, kita beralih ke acara pembaruan game, yang terjadi dengan frekuensi 300 ms.

 private void Snake_OnUpdateGame( Controller controller ) { ControlMove( controller.GameKey ); if( CheckGameOver() ) GameOver(); else SnakeMove(); } 

Empat hal terjadi di dalamnya: mengubah arah gerakan, memeriksa akhir permainan, memanggil acara akhir pertandingan dan memindahkan ular jika semuanya beres.

 private void ControlMove( GameKey key ) { switch( key ) { case GameKey.Left: head.Vector = head.Vector == Vector.Right ? Vector.Right : Vector.Left; break; case GameKey.Right: head.Vector = head.Vector == Vector.Left ? Vector.Left : Vector.Right; break; case GameKey.Up: head.Vector = head.Vector == Vector.Down ? Vector.Down : Vector.Up; break; case GameKey.Down: head.Vector = head.Vector == Vector.Up ? Vector.Up : Vector.Down; break; default: break; } } 

Untuk mengubah arah pergerakan ular, kita perlu mengubah vektor di kepalanya. Oleh karena itu, dalam kontrol gerakan ada pemeriksaan untuk kasus inversi vektor, sehingga ular tidak mulai memanjat pada dirinya sendiri.

 private bool CheckGameOver() { switch( head.Vector ) { case Vector.Up: return !CheckEmptyBlock( head.X, head.Y - 1 ); case Vector.Down: return !CheckEmptyBlock( head.X, head.Y + 1 ); case Vector.Left: return !CheckEmptyBlock( head.X - 1, head.Y ); case Vector.Right: return !CheckEmptyBlock( head.X + 1, head.Y ); default: throw new NotImplementedException(); } } 

Untuk mengecek akhir gim, cukup mengecek apakah blok di arahnya bebas atau tidak. Seperti yang Anda duga, makanan dalam cek diabaikan.

Tetap mengurai fungsi pergerakan ular:

 private void SnakeMove() { var temp = body.Last().Copy(); foreach( var block in body ) block.Move(); for( int i = body.Count - 1; i > 0; i-- ) body[i].Vector = body[i - 1].Vector; if( head.Equals( eat ) ) { score++; body.Add( temp ); CreateEat(); } DrawField(); } 

Ujung ekor disalin sehingga jika makanan telah tercapai, tambahkan sebagai perpanjangan ular. Memindahkan blok tidak sulit, karena fungsi ini sudah diterapkan di kelas blok. Kemudian vektor-vektor didistribusikan pada pergerakan ular dan diperiksa untuk persimpangan dengan makanan. Jika makanan ditemukan, tagihan bertambah, ular tumbuh dan makanan baru tercipta. Agar permainan kami muncul di daftar permainan, Anda perlu menambahkannya ke inisialisasi formulir:

 List<Game> games = new List<Game>(); games.Add( new Snake() ); games.Add( new Tetris() ); games.Add( new Life() ); Application.Run( new MainForm( games ) ); 

Itu saja. Seluruh kode permainan hanya membutuhkan 102 baris. Seperti yang dapat Anda lihat dari contoh, tetris dan kehidupan game telah ditambahkan ke proyek. Di bawah ini Anda dapat menemukan hasilnya.

gambar
Menu pemilihan game

gambar
Proses permainan

gambar
Akhir dari game

Source: https://habr.com/ru/post/id448604/


All Articles