Bagaimana untuk menulis permainan Android pertama anda di Jawa

Pengarang: John Stephens
Tarikh Penciptaan: 1 Januari 2021
Tarikh Kemas Kini: 19 Mungkin 2024
Anonim
Java Android Room Database | Insert and Query | RecyclerView Example
Video.: Java Android Room Database | Insert and Query | RecyclerView Example

Kandungan


Terdapat banyak cara untuk mencipta permainan untuk Android dan satu cara yang penting adalah melakukannya dari awal di Android Studio dengan Java. Ini memberi anda kawalan maksimum ke atas bagaimana anda mahu permainan anda kelihatan dan berkelakuan dan proses itu akan mengajar anda kemahiran yang anda boleh gunakan dalam pelbagai senario lain - sama ada anda membuat skrin percikan untuk aplikasi atau anda hanya mahu tambah beberapa animasi. Dengan itu, tutorial ini akan menunjukkan kepada anda cara membuat permainan 2D yang mudah menggunakan Android Studio dan Java. Anda boleh mencari semua kod dan sumber di Github jika anda mahu mengikutinya.

Melaraskan

Untuk mencipta permainan kami, kami perlu menangani beberapa konsep tertentu: gelung permainan, benang dan kanvas. Untuk bermula, mulakan Android Studio. Sekiranya anda tidak memasangnya, lihat pengenalan penuh kami kepada Android Studio, yang berlaku sepanjang proses pemasangan. Sekarang mulakan projek baru dan pastikan anda memilih templat 'Tindakan Kosong'. Ini adalah permainan, jadi sudah tentu anda tidak memerlukan unsur seperti butang FAB yang merumitkan perkara.


Perkara pertama yang anda mahu lakukan ialah menukar AppCompatActivity kepada Aktiviti. Ini bermakna kita tidak akan menggunakan ciri bar tindakan.

Begitu juga, kami juga ingin membuat skrin penuh permainan kami. Tambahkan kod berikut untuk onCreate () sebelum panggilan ke setContentView ():

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

Ambil perhatian bahawa jika anda menulis beberapa kod dan ia digariskan dengan warna merah, itu mungkin bermakna anda perlu mengimport kelas. Dengan kata lain, anda perlu memberitahu Android Studio bahawa anda ingin menggunakan kenyataan tertentu dan menjadikannya tersedia. Jika anda hanya mengklik mana-mana sahaja pada perkataan yang digariskan dan kemudian tekan Alt + Enter, maka itu akan dilakukan untuk anda secara automatik!


Membuat pandangan permainan anda

Anda boleh digunakan untuk aplikasi yang menggunakan skrip XML untuk menentukan susun atur pandangan seperti butang, imej dan label. Inilah barisannya setContentView sedang buat kita.

Tetapi sekali lagi, ini adalah permainan yang bermakna ia tidak perlu mempunyai tetingkap pelayar atau menatal pandangan pendaur. Daripada itu, kami mahu menunjukkan kanvas sebaliknya. Dalam Android Studio, kanvas hanya sama seperti dalam seni: ia adalah medium yang boleh kita gunakan.

Jadi ubah baris itu untuk membaca seperti:

setContentView (GameView baru (ini))

Anda akan mendapati bahawa ini sekali lagi menggariskan merah. Tetapi sekarang jika anda menekan Alt + Enter, anda tidak mempunyai pilihan untuk mengimport kelas. Sebaliknya, anda mempunyai pilihan untuk buat kelas. Dalam erti kata lain, kita akan membuat kelas kita sendiri yang akan menentukan apa yang akan pergi ke kanvas. Inilah yang akan membolehkan kita melukis ke skrin, bukannya hanya memaparkan pandangan yang sudah siap.

Jadi klik kanan pada nama pakej di hierarki anda di sebelah kiri dan pilih Kelas baru>. Anda kini akan dibentangkan dengan tetingkap untuk membuat kelas anda dan anda akan memanggilnya GameView. Di bawah SuperClass, tulis: android.view.SurfaceView yang bermaksud bahawa kelas akan mewarisi kaedah - keupayaannya - dari SurfaceView.

Dalam kotak Antara Muka, anda akan menulis android.view.SurfaceHolder.Callback. Seperti mana-mana kelas, kita perlu membuat pembina kami. Gunakan kod ini:

benang MainThread swasta; permainan awam awam (konteks konteks) {super (konteks); getHolder (). addCallback (ini); }

Setiap kali kelas kita dipanggil untuk membuat objek baru (dalam kes ini permukaan kita), ia akan menjalankan pembina dan ia akan mewujudkan permukaan baru. Talian 'super' memanggil superclass dan dalam kes kita, itu SurfaceView.

Dengan menambah Panggil balik, kami dapat memintas acara.

Sekarang mengatasi beberapa kaedah:

@Override public void surfaceChanged (SurfaceHolder holder, int int, width int, height int) {} @Override public void surfaceCreated (SurfaceHolder holder) {} @Override public void surfaceDestroyed (SurfaceHolder holder) {}

Ini pada dasarnya membolehkan kita untuk menimpa (dengan itu nama) kaedah dalam superclass (SurfaceView). Anda seharusnya tidak mempunyai garis bawah merah dalam kod anda. Nice.

Anda hanya mencipta kelas baru dan setiap kali kita merujuknya, ia akan membina kanvas untuk permainan anda untuk dicat ke atas. Kelas buat objek dan kita memerlukan satu lagi.

Membuat benang

Kelas baru kami akan dipanggil MainThread. Dan tugasnya adalah untuk membuat thread. Satu thread pada asasnya seperti garpu kod selari yang boleh berjalan secara bersamaan di samping utama sebahagian daripada kod anda. Anda boleh mempunyai banyak benang yang mengendalikan semua sekaligus, dengan itu membolehkan sesuatu terjadi pada masa yang sama dan bukan mengikuti urutan yang ketat. Ini penting untuk permainan, kerana kita perlu memastikan bahawa ia terus berjalan lancar, walaupun banyak berlaku.

Buat kelas baru anda seperti yang anda lakukan sebelum ini dan kali ini ia akan diperluaskan Thread. Dalam pembina kita hanya akan memanggil super (). Ingat, itu kelas super, iaitu Thread, dan yang boleh melakukan semua pengangkat berat untuk kami. Ini seperti mencipta program untuk mencuci pinggan yang hanya memanggil mesin basuh().

Apabila kelas ini dipanggil, ia akan membuat benang berasingan yang berfungsi sebagai cabang utama. Dan ia dari di sini bahawa kami ingin mencipta GameView kami. Ini bermakna kita juga perlu merujuk kepada kelas GameView dan kami juga menggunakan SurfaceHolder yang mengandungi kanvas. Jadi jika kanvas adalah permukaan, SurfaceHolder adalah kuda. Dan GameView adalah apa yang meletakkan semuanya bersama-sama.

Perkara penuh sepatutnya seperti:

MainThread kelas awam memanjangkan Thread {permukaan Permukaan SurfaceHolder swasta; permainan GameView peribadi; MainThread awam (SurfaceHolder surfaceHolder, GameView gameView) {super (); this.surfaceHolder = surfaceHolder; this.gameView = gameView; }}

Schweet. Kami kini mempunyai GameView dan benang!

Mewujudkan gelung permainan

Kami kini mempunyai bahan mentah yang kami perlukan untuk membuat permainan kami, tetapi tidak ada yang berlaku. Ini adalah di mana gelung permainan masuk. Pada asasnya, ini adalah satu lingkaran kod yang berjalan bulat dan bulat dan memeriksa input dan pembolehubah sebelum melukis skrin. Matlamat kami adalah untuk menjadikan ini sebagai konsisten yang mungkin, supaya tidak ada gagak atau cegukan dalam framerate, yang akan saya pelajari sedikit kemudian.

Buat masa sekarang, kami masih berada di dalam MainThread kelas dan kita akan mengatasi kaedah dari superclass. Yang satu ini berlari.

Dan sedikit perkara seperti ini:

@Override public void run () {while (running) {canvas = null; cuba {kanvas = this.surfaceHolder.lockCanvas (); disegerakkan (permukaanHolder) {this.gameView.update (); this.gameView.draw (kanvas); }} catch (Exception e) {} finally {if (canvas! = null) {try {surfaceHolder.unlockCanvasAndPost (canvas); } tangkapan (Pengecualian e) {e.printStackTrace (); }}}}}

Anda akan melihat banyak yang menggariskan, jadi kita perlu menambah beberapa lagi pemboleh ubah dan rujukan. Kepala kembali ke atas dan tambahkan:

Permukaan SurfaceHolder swasta; permainan GameView peribadi; menjalankan boolean swasta; Kanvas Kanvas statik awam;

Ingat untuk mengimport kanvas. Kanvas adalah perkara yang sebenarnya akan dilukiskan. Bagi 'lockCanvas', ini penting kerana ia pada dasarnya membekukan kanvas untuk membolehkan kami menggunakannya. Itu penting kerana jika tidak, anda boleh mempunyai beberapa benang yang cuba menggambarnya sekaligus. Hanya tahu bahawa untuk mengedit kanvas, anda mesti terlebih dahulu kunci kanvas.

Kemaskini adalah kaedah yang akan kami buat dan ini adalah di mana keseronokan akan berlaku kemudian.

The cuba dan tangkapan Sementara itu hanya keperluan Java yang menunjukkan kita bersedia untuk mencoba dan mengendalikan pengecualian (kesalahan) yang mungkin terjadi jika kanvas tidak siap dll.

Akhirnya, kami mahu dapat memulakan thread kami apabila kami memerlukannya. Untuk melakukan ini, kita memerlukan kaedah lain di sini yang membolehkan kita menetapkan perkara dalam gerakan. Itulah yang berjalan pemboleh ubah adalah untuk (perhatikan bahawa Boolean adalah sejenis pembolehubah yang hanya pernah benar atau palsu). Tambah kaedah ini kepada MainThread kelas:

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

Tetapi pada ketika ini, satu perkara masih harus ditonjolkan dan itu kemas kini. Ini kerana kami belum mencipta kaedah kemas kini. Jadi pop balik ke dalam GameView dan kini menambah kaedah.

kemas kini awam tidak sah () {}

Kita juga perlu mulakan benang itu! Kita akan buat ini dalam diri kita permukaanCreated kaedah:

@Override permukaan kekosongan awamCreated (pemegang SurfaceHolder) {thread.setRunning (true); thread.start (); }

Kita juga perlu menghentikan thread apabila permukaannya musnah. Seperti yang mungkin anda fikirkan, kami mengendalikan perkara ini di permukaan yang dihancurkan kaedah. Tetapi melihat kerana ia sebenarnya boleh mengambil beberapa percubaan untuk menghentikan thread, kita akan meletakkan ini dalam gelung dan digunakan cuba dan tangkapan sekali lagi. Seperti demikian:

@Override permukaan kekosongan awamDisistem (pemegang SurfaceHolder) {boolean retry = true; sementara (cuba semula) {cuba {thread.setRunning (false); thread.join (); } menangkap (InterruptedException e) {e.printStackTrace (); } retry = false; }}

Dan akhirnya, tuju kepada pembina dan pastikan untuk membuat contoh baru thread anda, jika tidak, anda akan mendapat pengecualian penunjuk null yang ditakuti! Dan kemudian kami akan membuat GameView fokus, bermakna ia boleh mengendalikan peristiwa.

thread = new MainThread (getHolder (), this); setFocusable (benar);

Sekarang kamu boleh akhirnya sebenarnya menguji perkara ini! Itu betul, klik jalankan dan itu sepatutnya sebenarnya berjalan tanpa sebarang kesilapan. Bersiaplah untuk ditiup!

Itu ... itu ... skrin kosong! Semua kod itu. Untuk skrin kosong. Tetapi, ini adalah skrin kosong peluang. Anda mempunyai permukaan anda dan berjalan dengan gelung permainan untuk mengendalikan acara. Sekarang semua yang tersisa adalah membuat perkara berlaku. Ia tidak kira jika anda tidak mengikuti segala sesuatu dalam tutorial sehingga ke tahap ini. Titiknya, anda hanya boleh mengitar semula kod ini untuk mula membuat permainan yang mulia!

Melakukan grafik

Betul, sekarang kita mempunyai skrin kosong untuk dimuatkan, semua yang perlu kita lakukan ialah menariknya. Nasib baik, itulah bahagian yang mudah. Apa yang perlu anda lakukan adalah untuk mengatasi kaedah cabutan dalam kami GameView kelas dan kemudian tambahkan beberapa gambar cantik:

@Override draw void awam (Kanvas kanvas) {super.draw (kanvas); jika (kanvas! = null) {kanvas.drawColor (Color.WHITE); Cat cat = Cat baru (); paint.setColor (Color.rgb (250, 0, 0)); kanvas.drawRect (100, 100, 200, 200, cat); }}

Jalankan ini dan anda kini perlu mempunyai persegi merah yang cantik di bahagian atas sebelah kiri skrin yang tidak berwarna putih. Ini sememangnya penambahbaikan.

Anda secara teorinya boleh mencipta keseluruhan permainan anda dengan melekatinya di dalam kaedah ini (dan mengesahkan onTouchEvent untuk mengendalikan input) tetapi itu tidak akan menjadi cara yang sangat baik untuk melakukan sesuatu. Meletakkan Cat baru di dalam gelung kami akan memperlahankan hal-hal yang lebih rendah dan bahkan jika kami meletakkan ini di tempat lain, menambah terlalu banyak kod kepada yang lukis kaedah akan menjadi hodoh dan sukar untuk diikuti.

Sebaliknya, ia lebih masuk akal untuk mengendalikan objek permainan dengan kelas mereka sendiri. Kami akan memulakan dengan satu yang menunjukkan watak dan kelas ini akan dipanggil CharacterSprite. Teruskan dan buatlah itu.

Kelas ini akan menarik satu sprite ke kanvas dan akan kelihatan seperti itu

kelas awam CharacterSprite {imej Bitmap peribadi; public CharacterSprite (Bitmap bmp) {image = bmp; } lukisan undian awam (kanvas kanvas) {kanvas.drawBitmap (imej, 100, 100, null); }}

Sekarang untuk menggunakan ini, anda perlu memuat bitmap terlebih dahulu dan kemudian memanggil kelas dari GameView. Tambah rujukan kepada Watak peribadiSprite characterSprite dan kemudian di permukaanCreated kaedah, tambah garisan:

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

Seperti yang anda dapat lihat, bitmap yang kami muatkan disimpan dalam sumber dan dipanggil avdgreen (ia dari permainan terdahulu). Sekarang semua yang perlu anda lakukan adalah lulus bitmap ke kelas baru di dalam lukis kaedah dengan:

characterSprite.draw (kanvas);

Sekarang klik jalankan dan anda akan nampak grafik anda muncul di skrin anda! Ini adalah BeeBoo. Saya sering melukisnya di buku teks sekolah saya.

Bagaimana jika kita mahu membuat lelaki kecil ini bergerak? Mudah: kami hanya membuat pembolehubah x dan y untuk jawatannya dan kemudian mengubah nilai-nilai ini dalam satu kemas kini kaedah.

Jadi tambahkan rujukan kepada anda CharacterSprite dan kemudian gambarkan bitmap anda x, y. Buat kaedah pengemaskinian di sini dan buat masa sekarang kita akan cuba:

y ++;

Setiap kali gelung permainan berjalan, kami akan memindahkan watak ke skrin. Ingat, y koordinat diukur dari bahagian atas jadi 0 adalah bahagian atas skrin. Sudah tentu kita perlu memanggil kemas kini kaedah dalam CharacterSprite daripada kemas kini kaedah dalam GameView.

Tekan main lagi dan sekarang anda akan melihat bahawa imej anda perlahan-lahan mengesan skrin. Kami tidak memenangi mana-mana anugerah permainan sahaja tetapi ia adalah permulaan!

Baiklah, buat sesuatu sedikit lebih menarik, saya hanya akan menggugurkan kod bola 'bouncy ball' di sini. Ini akan membuat kita melantun grafik sekitar skrin di luar tepi, seperti screensaver Windows lama. Awak tahu, orang yang aneh yang hipnosis.

kemas kini pembohongan awam () {x + = xVelocity; y + = yVelocity; jika ((x & gt; screenWidth - image.getWidth ()) || (x & lt; 0)) {xVelocity = xVelocity * -1; } jika {(y & gt; screenHeight - image.getHeight ()) || (y & lt; 0)) {yVelocity = yVelocity * -1; }}

Anda juga perlu menentukan pembolehubah ini:

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

Pengoptimuman

Terdapat banyak lebih banyak untuk menyelidiki di sini, daripada mengendalikan input pemain, untuk mengukur imej, untuk menguruskan mempunyai banyak aksara yang bergerak di sekeliling skrin sekali gus. Sekarang, watak melantun tetapi jika anda melihat dengan teliti terdapat sedikit gagap. Ia tidak mengerikan tetapi fakta bahawa anda boleh melihatnya dengan mata kasar adalah sesuatu tanda amaran. Kelajuan juga banyak berubah pada emulator berbanding dengan peranti fizikal. Sekarang bayangkan apa yang berlaku apabila anda ada tan meneruskan skrin sekali gus!

Terdapat beberapa penyelesaian untuk masalah ini. Apa yang saya mahu lakukan untuk bermula dengan, adalah untuk membuat integer peribadi dalam MainThread dan panggil itu targetFPS. Ini akan mempunyai nilai 60.Saya akan cuba dan mendapatkan permainan saya untuk berjalan pada kelajuan ini dan sementara itu, saya akan menyemak untuk memastikan ia. Untuk itu, saya juga mahu dipanggil double peribadi purata FPS.

Saya juga akan mengemas kini berlari kaedah untuk mengukur berapa lama setiap gelung permainan diambil dan kemudian ke jeda gelang permainan itu buat sementara waktu jika di hadapan targetFPS. Kami kemudian akan mengira berapa lama ia sekarang ambil dan cetak supaya kita dapat melihatnya dalam log.

@Override public void run () {startTime lama; masa yang panjangMillis; tunggu lama; totalTime = 0 panjang; int frameCount = 0; targetTime = 1000 / targetFPS yang panjang; semasa (berjalan) {startTime = System.nanoTime (); kanvas = null; cuba {kanvas = this.surfaceHolder.lockCanvas (); disegerakkan (permukaanHolder) {this.gameView.update (); this.gameView.draw (kanvas); }} catch (Exception e) {} finally {if (canvas! = null) {try {surfaceHolder.unlockCanvasAndPost (canvas); } tangkapan (Pengecualian e) {e.printStackTrace (); }}} timeMillis = (System.nanoTime () - startTime) / 1000000; waitTime = targetTime - timeMillis; cuba {this.sleep (waitTime); } tangkapan (Pengecualian e) {} totalTime + = System.nanoTime () - startTime; frameCount ++; jika (frameCount == targetFPS) {averageFPS = 1000 / ((totalTime / frameCount) / 1000000); frameCount = 0; totalTime = 0; System.out.println (averageFPS); }}}

Sekarang permainan kami sedang cuba mengunci FPS ke 60 dan anda harus mendapati bahawa ia umumnya mengukur FPS 58-62 yang agak mantap pada peranti moden. Pada emulator walaupun anda mungkin mendapat hasil yang berbeza.

Cuba ubah 60 hingga 30 dan lihat apa yang berlaku. Permainan ini melambatkan dan ia sepatutnya kini baca 30 di logcat anda.

Menutup Pikiran

Terdapat beberapa perkara lain yang boleh kita lakukan untuk mengoptimumkan prestasi. Terdapat catatan blog hebat mengenai subjek di sini. Cobalah untuk tidak mencipta contoh-contoh baru Cat atau bitmaps di dalam gelung dan lakukan semua permulaan di luar sebelum permainan bermula.

Jika anda merancang untuk mencipta permainan Android hit seterusnya maka ada pasti cara-cara yang lebih mudah dan lebih berkesan untuk meneruskannya pada hari-hari ini. Tetapi masih ada senario kes penggunaan untuk dapat melukis kanvas dan kemahiran yang sangat berguna untuk ditambah ke repertoir anda. Saya harap panduan ini telah membantu sedikit dan ingin anda nasib yang terbaik dalam usaha pengekodan anda yang akan datang!

SeterusnyaPanduan pemula ke Jawa

etiap ekarang dan kemudian, kita mencari cabaran. euatu yang menguji otak dan reflek kita. Cabaran boleh datang dari mana aja dan terdapat beberapa permainan yang angat ukar di Android. Dalam eetenga...

Google Play telah berada di ekelilingnya elagi mempunyai Android endiri. Malah, udah lebih 10 tahun ekarang. Oleh itu, ebenarnya ada beberapa aplikai yang telah mencapai popular yang benar elama bert...

Menarik