Cara menulis game Android pertama Anda di Jawa

Pengarang: John Stephens
Tanggal Pembuatan: 1 Januari 2021
Tanggal Pembaruan: 19 Boleh 2024
Anonim
cara memainkan minecraft Java di android || pojav launcher tutorial
Video: cara memainkan minecraft Java di android || pojav launcher tutorial

Isi


Ada banyak cara untuk membuat game untuk Android dan satu cara penting adalah melakukannya dari awal di Android Studio dengan Java. Ini memberi Anda kontrol maksimum atas bagaimana Anda ingin permainan Anda terlihat dan berperilaku dan prosesnya akan mengajarkan Anda keterampilan yang dapat Anda gunakan dalam berbagai skenario lain juga - apakah Anda membuat splash screen untuk suatu aplikasi atau Anda hanya ingin tambahkan beberapa animasi. Dengan mengingat hal itu, tutorial ini akan menunjukkan kepada Anda cara membuat game 2D sederhana menggunakan Android Studio dan Java. Anda dapat menemukan semua kode dan sumber daya di Github jika Anda ingin mengikuti.

Pengaturan

Untuk membuat game kami, kami perlu berurusan dengan beberapa konsep spesifik: loop game, utas dan kanvas. Untuk memulainya, mulai Android Studio. Jika Anda belum menginstalnya, lihat pengantar lengkap kami untuk Android Studio, yang membahas proses pemasangan. Sekarang mulailah proyek baru dan pastikan Anda memilih templat ‘Empty Activity’. Ini adalah permainan, jadi tentu saja Anda tidak memerlukan elemen seperti tombol FAB yang memperumit masalah.


Hal pertama yang ingin Anda lakukan adalah berubah AppCompatActivity untuk Aktivitas. Ini berarti kami tidak akan menggunakan fitur bilah tindakan.

Demikian pula, kami juga ingin menjadikan layar permainan kami penuh. Tambahkan kode berikut ke onCreate () sebelum panggilan ke setContentView ():

getWindow (). setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); this.requestWindowFeature (Window.FEATURE_NO_TITLE);

Perhatikan bahwa jika Anda menulis beberapa kode dan itu digarisbawahi dalam warna merah, itu mungkin berarti Anda perlu mengimpor kelas. Dengan kata lain, Anda perlu memberi tahu Android Studio bahwa Anda ingin menggunakan pernyataan tertentu dan membuatnya tersedia. Jika Anda hanya mengklik di mana saja pada kata yang digarisbawahi dan kemudian tekan Alt + Enter, maka itu akan dilakukan untuk Anda secara otomatis!


Membuat tampilan game Anda

Anda dapat digunakan untuk aplikasi yang menggunakan skrip XML untuk menentukan tata letak tampilan seperti tombol, gambar, dan label. Inilah garisnya setContentView lakukan untuk kita.

Tapi sekali lagi, ini adalah permainan yang berarti tidak perlu memiliki jendela browser atau menggulir tampilan pendaur ulang. Alih-alih itu, kami ingin menunjukkan kanvas sebagai gantinya. Di Android Studio, kanvas sama dengan kanvas dalam seni: kanvas yang dapat kita gunakan untuk menggambar.

Jadi ubah baris itu menjadi seperti:

setContentView (GameView baru (ini))

Anda akan menemukan bahwa ini sekali lagi digarisbawahi merah. Tapi sekarang jika Anda menekan Alt + Enter, Anda tidak memiliki opsi untuk mengimpor kelas. Sebagai gantinya, Anda memiliki opsi untuk membuat kelas. Dengan kata lain, kami akan membuat kelas kami sendiri yang akan menentukan apa yang akan terjadi di kanvas. Inilah yang akan memungkinkan kita untuk menggambar ke layar, bukan hanya menampilkan tampilan yang sudah jadi.

Jadi klik kanan pada nama paket dalam hierarki Anda di sebelah kiri dan pilih Baru> Kelas. Anda sekarang akan diberikan jendela untuk membuat kelas Anda dan Anda akan menyebutnya GameView. Di bawah SuperClass, tulis: android.view.SurfaceView yang berarti bahwa kelas akan mewarisi metode - kemampuannya - dari SurfaceView.

Di kotak Antarmuka, Anda akan menulis android.view.SurfaceHolder.Callback. Seperti halnya kelas apa pun, kita sekarang perlu membuat konstruktor kita. Gunakan kode ini:

utas MainThread pribadi; GameView publik (Konteks konteks) {super (konteks); getHolder (). addCallback (ini); }

Setiap kali kelas kita dipanggil untuk membuat objek baru (dalam hal ini permukaan kita), itu akan menjalankan konstruktor dan itu akan membuat permukaan baru. Garis "super" memanggil superclass dan dalam kasus kami, itu adalah SurfaceView.

Dengan menambahkan Callback, kami dapat mencegat acara.

Sekarang timpa beberapa metode:

@Override public void surfaceChanged (SurfaceHolder holder, format int, int int, int int) {} @Override public void surfaceCreated (SurfaceHolder holder) {} @Override public void surfaceDestroyed (pemegang SurfaceHolder) {}

Ini pada dasarnya memungkinkan kita untuk menimpa (karena itu namanya) metode dalam superclass (SurfaceView). Anda seharusnya tidak lagi memiliki garis bawah merah dalam kode Anda. Bagus.

Anda baru saja membuat kelas baru dan setiap kali kita merujuknya, itu akan membangun kanvas untuk permainan Anda. Kelas membuat benda dan kita perlu satu lagi.

Membuat utas

Kelas baru kita akan dipanggil MainThread. Dan tugasnya adalah membuat utas. Utas pada dasarnya seperti garpu paralel kode yang dapat berjalan secara bersamaan di samping utama bagian dari kode Anda. Anda dapat memiliki banyak utas yang berjalan sekaligus, sehingga memungkinkan hal-hal terjadi secara bersamaan daripada mengikuti urutan yang ketat. Ini penting untuk sebuah gim, karena kita perlu memastikan gim ini terus berjalan dengan lancar, bahkan ketika banyak yang terjadi.

Buat kelas baru Anda seperti yang Anda lakukan sebelumnya dan kali ini akan diperluas Benang. Di konstruktor, kami hanya akan menelepon super(). Ingat, itu adalah kelas super, yaitu Thread, dan yang dapat melakukan semua pekerjaan berat untuk kita. Ini seperti membuat program untuk mencuci piring yang baru saja menelepon mesin cuci().

Ketika kelas ini dipanggil, itu akan membuat utas terpisah yang berjalan sebagai cabang dari hal utama. Dan itu dari sini bahwa kami ingin membuat GameView kami. Itu artinya kita juga perlu mereferensikan kelas GameView dan kita juga menggunakan SurfaceHolder yang berisi kanvas. Jadi jika kanvas adalah permukaan, SurfaceHolder adalah kuda-kuda. Dan GameView adalah yang menyatukan semuanya.

Seharusnya terlihat seperti ini:

kelas publik MainThread memperluas Thread {private SurfaceHolder surfaceHolder; GameView gameView pribadi; publik MainThread (SurfaceHolder surfaceHolder, GameView gameView) {super (); this.surfaceHolder = surfaceHolder; this.gameView = gameView; }}

Schweet. Kami sekarang memiliki GameView dan utas!

Membuat loop game

Kami sekarang memiliki bahan baku yang kami butuhkan untuk membuat game kami, tetapi tidak ada yang terjadi. Di sinilah loop game masuk. Pada dasarnya, ini adalah loop kode yang berputar-putar dan memeriksa input dan variabel sebelum menggambar layar. Tujuan kami adalah untuk membuat ini se konsisten mungkin, sehingga tidak ada gagap atau cegukan di framerate, yang akan saya bahas nanti.

Untuk saat ini, kami masih di MainThread kelas dan kami akan mengganti metode dari superclass. Yang ini menjalankan.

Dan sedikit seperti ini:

@Override public void run () {while (running) {canvas = null; coba {canvas = this.surfaceHolder.lockCanvas (); disinkronkan (surfaceHolder) {this.gameView.update (); this.gameView.draw (kanvas); }} catch (Exception e) {} akhirnya {if (canvas! = null) {coba {surfaceHolder.unlockCanvasAndPost (canvas); } catch (Exception e) {e.printStackTrace (); }}}}}

Anda akan melihat banyak garis bawah, jadi kami perlu menambahkan beberapa variabel dan referensi. Kembali ke atas dan tambahkan:

SurfaceHolder pribadi SurfaceHolder pribadi; GameView gameView pribadi; berjalan boolean pribadi; kanvas kanvas publik statis;

Ingatlah untuk mengimpor Kanvas. Kanvas adalah hal yang akan kita gambar. Mengenai ‘lockCanvas’, ini penting karena inilah yang pada dasarnya membekukan kanvas untuk memungkinkan kita menggambar di atasnya. Itu penting karena jika tidak, Anda dapat memiliki beberapa utas yang mencoba untuk menggunakannya sekaligus. Hanya tahu bahwa untuk mengedit kanvas, Anda harus terlebih dahulu mengunci kanvas.

Pembaruan adalah metode yang akan kita buat dan di sinilah hal-hal menyenangkan akan terjadi nanti.

Itu mencoba dan menangkap sementara itu hanyalah persyaratan Java yang menunjukkan bahwa kami bersedia mencoba dan menangani pengecualian (kesalahan) yang mungkin terjadi jika kanvas tidak siap dll.

Akhirnya, kami ingin dapat memulai utas kami saat kami membutuhkannya. Untuk melakukan ini, kita perlu metode lain di sini yang memungkinkan kita untuk mengatur segala sesuatunya. Itu apa adanya berlari variabel adalah untuk (perhatikan bahwa Boolean adalah jenis variabel yang hanya benar atau salah). Tambahkan metode ini ke MainThread kelas:

public void setRunning (boolean isRunning) {running = isRunning; }

Tetapi pada titik ini, satu hal masih harus disorot dan itu memperbarui. Ini karena kami belum membuat metode pembaruan. Jadi muncul kembali GameView dan sekarang tambahkan metode.

pembaruan publik yang kosong () {}

Kita juga perlu mulai utas! Kami akan melakukan ini di kami surfaceCreated metode:

@Override public void surfaceCreated (pemegang SurfaceHolder) {thread.setRunning (true); thread.start (); }

Kita juga harus menghentikan utas saat permukaan dihancurkan. Seperti yang mungkin sudah Anda duga, kami menangani ini di surfaceDestroyed metode. Tetapi melihat ini benar-benar dapat mengambil beberapa upaya untuk menghentikan utas, kami akan menempatkan ini dalam satu lingkaran dan digunakan mencoba dan menangkap lagi. Seperti itu:

@Override public void surfaceDestroyed (pemegang SurfaceHolder) {boolean retry = true; while (coba lagi) {coba {thread.setRunning (false); thread.join (); } catch (InterruptedException e) {e.printStackTrace (); } coba lagi = false; }}

Dan akhirnya, buka konstruktor dan pastikan untuk membuat instance baru dari utas Anda, jika tidak, Anda akan mendapatkan pengecualian penunjuk nol yang ditakuti! Dan kemudian kita akan membuat GameView menjadi fokus, artinya GameView dapat menangani acara.

utas = MainThread baru (getHolder (), ini); setFocusable (true);

Sekarang kamu bisa akhirnya sebenarnya menguji hal ini! Itu benar, klik jalankan dan itu harus sebenarnya berjalan tanpa kesalahan. Bersiaplah untuk terpesona!

Ini ... itu ... layar kosong! Semua kode itu. Untuk layar kosong. Tapi, ini adalah layar kosong kesempatan. Anda memiliki permukaan dan berjalan dengan lingkaran permainan untuk menangani acara. Sekarang yang tersisa adalah mewujudkannya. Bahkan tidak masalah jika Anda tidak mengikuti semua yang ada di tutorial hingga saat ini. Intinya adalah, Anda cukup mendaur ulang kode ini untuk mulai membuat game yang luar biasa!

Melakukan grafik

Benar, sekarang kita memiliki layar kosong untuk menggambar, yang perlu kita lakukan hanyalah menggambar di atasnya. Untungnya, itulah bagian yang sederhana. Yang perlu Anda lakukan adalah mengganti metode menggambar di GameView kelas dan kemudian tambahkan beberapa gambar cantik:

@Override public void draw (Canvas canvas) {super.draw (canvas); if (canvas! = null) {canvas.drawColor (Color.WHITE); Cat cat = Cat baru (); paint.setColor (Color.rgb (250, 0, 0)); canvas.drawRect (100, 100, 200, 200, paint); }}

Jalankan ini dan Anda sekarang harus memiliki kotak merah cantik di kiri atas layar yang berwarna putih. Ini tentu merupakan peningkatan.

Secara teoritis Anda bisa membuat hampir seluruh permainan dengan menempelnya di dalam metode ini (dan menimpanya onTouchEvent untuk menangani input) tetapi itu tidak akan menjadi cara yang sangat baik untuk melakukan sesuatu. Menempatkan Paint baru di dalam loop kita akan memperlambat banyak hal dan bahkan jika kita meletakkan ini di tempat lain, menambahkan terlalu banyak kode ke seri Metode akan menjadi jelek dan sulit untuk diikuti.

Sebaliknya, jauh lebih masuk akal untuk menangani objek game dengan kelas mereka sendiri. Kami akan mulai dengan karakter yang menunjukkan karakter dan kelas ini akan dipanggil CharacterSprite. Silakan dan buat itu.

Kelas ini akan menggambar sprite ke kanvas dan akan terlihat seperti itu

public class CharacterSprite {gambar Bitmap pribadi; CharacterSprite publik (Bitmap bmp) {image = bmp; } public void draw (Canvas canvas) {canvas.drawBitmap (image, 100, 100, null); }}

Sekarang untuk menggunakan ini, Anda harus memuat bitmap terlebih dahulu dan kemudian memanggil kelas dari GameView. Tambahkan referensi ke private CharacterSprite characterSprite dan kemudian di surfaceCreated metode, tambahkan baris:

characterSprite = CharacterSprite baru (BitmapFactory.decodeResource (getResources (), R.drawable.avdgreen));

Seperti yang Anda lihat, bitmap yang kami muat disimpan dalam sumber daya dan disebut avdgreen (berasal dari game sebelumnya). Sekarang yang perlu Anda lakukan adalah meneruskan bitmap itu ke kelas baru di seri metode dengan:

characterSprite.draw (kanvas);

Sekarang klik jalankan dan Anda akan melihat grafik Anda muncul di layar Anda! Ini adalah BeeBoo. Saya biasa menggambarnya di buku pelajaran sekolah saya.

Bagaimana jika kita ingin membuat si kecil ini bergerak? Sederhana: kami hanya membuat variabel x dan y untuk posisinya dan kemudian mengubah nilai-nilai ini dalam memperbarui metode.

Jadi tambahkan referensi ke blog Anda CharacterSprite lalu gambar bitmap Anda di x, y. Buat metode pembaruan di sini dan untuk saat ini kami hanya akan mencoba:

y ++;

Setiap kali loop game berjalan, kami akan memindahkan karakter ke layar. Ingat, y Koordinat diukur dari atas jadi 0 adalah bagian atas layar. Tentu saja kita perlu memanggil memperbarui metode dalam CharacterSprite dari memperbarui metode dalam GameView.

Tekan mainkan lagi dan sekarang Anda akan melihat bahwa gambar Anda secara perlahan menelusuri layar. Kami belum memenangkan penghargaan game apa pun tetapi ini adalah awal!

Oke, untuk membuat sesuatu sedikit lebih menarik, saya hanya akan menjatuhkan beberapa kode 'bola melenting' di sini. Ini akan membuat grafik kita terpental di sekitar layar dari tepi, seperti screensaver Windows lama itu. Anda tahu, yang anehnya hipnosis.

pembaruan public void () {x + = xVelocity; y + = yVelocity; if ((x & gt; screenWidth - image.getWidth ()) || (x & lt; 0)) {xVelocity = xVelocity * -1; } if ((y & gt; screenHeight - image.getHeight ()) || (y & lt; 0)) {yVelocity = yVelocity * -1; }}

Anda juga perlu mendefinisikan variabel-variabel ini:

private int xVelocity = 10; private int yVelocity = 5; private int screenWidth = Resources.getSystem (). getDisplayMetrics (). widthPixels; private int screenHeight = Resources.getSystem (). getDisplayMetrics (). heightPixels;

Optimasi

Ada banyak lebih untuk mempelajari di sini, dari menangani input pemain, untuk menskala gambar, hingga mengelola memiliki banyak karakter yang bergerak di sekitar layar sekaligus. Saat ini, karakter sedang memantul tetapi jika Anda melihat sangat dekat ada sedikit kegagapan. Ini tidak mengerikan tetapi kenyataan bahwa Anda dapat melihatnya dengan mata telanjang adalah semacam tanda peringatan. Kecepatannya juga sangat bervariasi pada emulator dibandingkan dengan perangkat fisik. Sekarang bayangkan apa yang terjadi ketika Anda memilikinya ton terjadi di layar sekaligus!

Ada beberapa solusi untuk masalah ini. Apa yang ingin saya lakukan sebagai permulaan, adalah membuat integer pribadi MainThread dan menyebutnya targetFPS. Ini akan memiliki nilai 60.Saya akan mencoba dan membuat permainan saya berjalan pada kecepatan ini dan sementara itu, saya akan memeriksa untuk memastikannya. Untuk itu, saya juga menginginkan private double bernama rata-rata FPS.

Saya juga akan memperbarui menjalankan metode untuk mengukur berapa lama setiap loop permainan mengambil dan kemudian ke jeda loop game itu sementara jika berada di depan targetFPS. Kami kemudian akan menghitung berapa lama sekarang mengambil dan kemudian mencetaknya sehingga kita bisa melihatnya di log.

@Override public void run () {long startTime; long timeMillis; waktu tunggu yang lama; long totalTime = 0; int frameCount = 0; targetTime panjang = 1000 / targetFPS; while (running) {startTime = System.nanoTime (); canvas = null; coba {canvas = this.surfaceHolder.lockCanvas (); disinkronkan (surfaceHolder) {this.gameView.update (); this.gameView.draw (kanvas); }} catch (Exception e) {} akhirnya {if (canvas! = null) {coba {surfaceHolder.unlockCanvasAndPost (canvas); } catch (Exception e) {e.printStackTrace (); }}} timeMillis = (System.nanoTime () - startTime) / 1000000; waitTime = targetTime - timeMillis; coba {this.sleep (waitTime); } catch (Exception e) {} totalTime + = System.nanoTime () - startTime; frameCount ++; if (frameCount == targetFPS) {averageFPS = 1000 / ((totalTime / frameCount) / 1000000); frameCount = 0; totalTime = 0; System.out.println (averageFPS); }}}

Sekarang game kami mencoba untuk mengunci FPS menjadi 60 dan Anda akan menemukan bahwa itu umumnya mengukur FPS 58-62 yang cukup mantap pada perangkat modern. Namun pada emulator Anda mungkin mendapatkan hasil yang berbeda.

Coba ubah 60 menjadi 30 dan lihat apa yang terjadi. Permainan melambat dan itu harus sekarang baca 30 di logcat Anda.

Pikiran Penutup

Ada beberapa hal lain yang dapat kita lakukan untuk mengoptimalkan kinerja juga. Ada posting blog yang bagus tentang masalah ini di sini. Cobalah untuk menahan diri dari tidak pernah membuat instance baru Paint atau bitmap di dalam loop dan lakukan semua inisialisasi di luar sebelum pertandingan dimulai.

Jika Anda berencana membuat gim Android hit berikutnya, maka ada pasti cara yang lebih mudah dan lebih efisien untuk melakukannya hari ini. Tapi pasti masih ada skenario penggunaan kasus untuk bisa menggambar di atas kanvas dan itu adalah keterampilan yang sangat berguna untuk ditambahkan ke daftar lagu Anda. Saya harap panduan ini telah membantu sedikit dan berharap Anda yang terbaik dalam usaha coding Anda yang akan datang!

LanjutPanduan pemula untuk Java

Pada 2016, toko buku komik digital milik Amazon, Comixology, meluncurkan layanan baru bernama Comixology Unlimited. Itu eperti Netflix untuk komik, yang memungkinkan orang membaca ribuan koleki dan at...

Hanya ada atu paket dengan dua metode pembayaran:$ 74,99 ditambah pajak yang ditagih etiap tahun$ 7,99 ditambah pajak yang ditagih etiap bulanRencana tahunan memiliki penghematan biaya 20 peren ecara ...

Menarik