Jadi apa yang dilakukan oleh geek diri ketika berhadapan dengan soalan sedemikian? Mereka menulis permainan platform 2-D, sampingan, tentu saja!
Dalam siri dua bahagian ini, anda akan belajar cukup HTML, CSS, dan JavaScript untuk membolehkan anda membina permainan platform JavaScript anda sendiri. Saya telah menggunakan prototaip perpustakaan JavaScript dalam contoh -contoh, semata -mata kerana ia adalah apa yang saya tahu - banyak perpustakaan JavaScript lain yang ada mungkin mempunyai keupayaan yang setara.
Sebelum kita sampai ke perkara yang menyeronokkan, kita perlu menjalankan beberapa teknik JavaScript yang canggih yang akan membolehkan kita menipu pelayar anda untuk memikirkan ia adalah konsol permainan 8-bit.
Takeaways Key
Mari lihat beberapa kod JS yang membina kelas baru, dan kemudian mencipta objek baru:
// Declare the class <br> function WalkingSprite(element, x, y) { <br> this.x = x; <br> this.y = y; <br> this.element = element; <br> } <br> <br> WalkingSprite.prototype = { <br> x: 0, <br> y: 0, <br> element: null, <br> <br> walk: function(direction) { <br> this.x += direction; <br> } <br> } <br> <br> koopa = new WalkingSprite(null, 10, 10); <br> koopa.walk(20); <br> alert(koopa.x + "," + koopa.y);
pandangan sepintas lalu mengenai kod ini menunjukkan bahawa kami telah membina kelas baru yang dipanggil Walkingsprite yang mempunyai tiga sifat (elemen, x dan y) dan satu fungsi, yang dipanggil Walk. Jika kita instantiate versi baru objek dan memanggilnya fungsi berjalan, objek Koopa kita kini akan berada di titik koordinat (20, 30). Mengisytiharkan kelas dengan cara ini adalah sedikit rumit - kita perlu membuat kelas, dan kemudian mengemas kini prototaip. Syukurlah, prototaip (perpustakaan) telah merangkumi ia menjadi fungsi berguna yang dipanggil class.create. Kod di atas menjadi ini:
var WalkingSprite = Class.create({ <br> x: 0, <br> y: 0, <br> element: null, <br> <br> initialize: function(element, x, y) { <br> this.element = element; <br> this.x = x; <br> this.y = y; <br> }, <br> <br> walk: function(steps) { <br> this.x += steps; <br> } <br> }); <br> <br> koopa = new WalkingSprite(null, 10, 10); <br> koopa.walk(20); <br> alert(koopa.x + "," + koopa.y);
Satu lagi komponen asas OOP adalah konsep warisan. Pada asasnya, jika anda mempunyai kelas asas yang mempunyai pembolehubah dan fungsi tertentu, semua kelas yang extend kelas mewarisi pembolehubah dan fungsi tersebut. Anda kemudian boleh menambah fungsi tambahan dan bahkan mengatasi fungsi tersebut untuk melakukan sesuatu yang lain. Ini boleh menjadi sangat berguna dalam permainan kami, kerana semua watak kami mungkin akan mempamerkan beberapa sifat biasa - mereka semua boleh berjalan di sekitar skrin - tetapi mungkin hanya satu jenis watak yang boleh melompat. Bunyi seperti calon yang sempurna untuk warisan.
Malangnya, JavaScript tidak menyokong warisan secara asli. Jadi, mengapa saya membazirkan perenggan terakhir yang memberitahu anda mengenainya? Nah, dengan sedikit penipuan, kita boleh mencontohi warisan kelas di JavaScript.
Kerana segala -galanya dalam JavaScript (termasuk fungsi dalam kelas kita) adalah pembolehubah, kita boleh memberikan nilai mereka kepada pembolehubah lain. Jadi, jika kita berfikir tentang warisan apa yang kedua, semua yang perlu kita lakukan untuk mencontohi, adalah untuk menyalin sifat dan fungsi dari kelas induk ke kelas kanak -kanak. Jika kita mahu mewarisi dari kelas yang kita buat di atas, kita boleh melakukan ini:
// Declare the class <br> function WalkingSprite(element, x, y) { <br> this.x = x; <br> this.y = y; <br> this.element = element; <br> } <br> <br> WalkingSprite.prototype = { <br> x: 0, <br> y: 0, <br> element: null, <br> <br> walk: function(direction) { <br> this.x += direction; <br> } <br> } <br> <br> // Create the child class <br> JumpingAndWalkingSprite = WalkingSprite; <br> JumpingAndWalkingSprite.prototype = { <br> x: 0, <br> y: 0, <br> walk: WalkingSprite.prototype.walk <br> jump: function() { <br> y += 20; <br> } <br> }
Jalankan kod, dan anda akan mempunyai kelas baru yang mempunyai dua sifat dan satu fungsi dari ibu bapanya, ditambah satu fungsi baru: lompat. Satu -satunya perkara, pengekodan seperti ini tidak benar -benar berskala; Bagaimana jika anda menambah fungsi itik ke kelas induk? Anda perlu melalui setiap kelas kanak -kanak dan menambah tandatangan fungsi. Sekali lagi, prototaip untuk menyelamatkan! Fungsi kelas.Buat yang kita pelajari sebelum ini boleh mengambil kelas lain sebagai hujah pertama. Kelas yang dibekalkan ini akan menjadi ibu bapa, dan ia secara dinamik akan mencari semua sifat dan fungsi untuk kami, secara automatik menyuntik mereka ke dalam kelas kanak -kanak. Jadi perkara di atas akan menjadi:
var JumpingAndWalkingSprite = Class.create(WalkingSprite); <br> <br> mario = new JumpingAndWalkingSprite(null, 10, 10); <br> mario.walk(10): <br> alert(mario.x + "," + mario.y); <br> mario.jump(); <br> alert(mario.x + "," + mario.y); <br>
Seperti yang dijangkakan, kelas baru mempunyai semua sifat yang sama dari kelas induk! Jadi bagaimana dengan menambah dan mengatasi sifat dan fungsi? Kami menunjukkan di atas bagaimana untuk melakukan ini secara manual, tetapi prototaip membolehkan kita menentukan fungsi baru menggunakan class.create:
// Declare the class <br> function WalkingSprite(element, x, y) { <br> this.x = x; <br> this.y = y; <br> this.element = element; <br> } <br> <br> WalkingSprite.prototype = { <br> x: 0, <br> y: 0, <br> element: null, <br> <br> walk: function(direction) { <br> this.x += direction; <br> } <br> } <br> <br> koopa = new WalkingSprite(null, 10, 10); <br> koopa.walk(20); <br> alert(koopa.x + "," + koopa.y);
di sini, kami telah mengatasi fungsi berjalan kaki dan menambah fungsi lompat. Hang On - Kembali trak - Di manakah $ super variable muncul dari? Soalan yang baik! Apabila menggunakan warisan, kadang -kadang boleh berguna untuk menjalankan versi kelas induk fungsi. Dalam kes ini, kami membuat watak berjalan dua kali sejauh yang asalnya diminta dengan menggandakan pemboleh ubah input, dan lulus nilai baru ini kepada kelas induk. Prototaip akan membekalkan versi kelas induk 'fungsi dalam pembolehubah super $, jika anda mengisytiharkan $ super sebagai argumen pertama tandatangan fungsi. Ini membolehkan anda dengan mudah memanggil versi induk fungsi dari dalam versi yang ditindas. Anda akan melihat bahawa fungsi lompat baru tidak mempunyai pembolehubah super $; Kami tidak menggunakannya, jadi kami tidak perlu membekalkannya. Jika kita memerlukannya, kita hanya boleh menambahnya sebagai hujah pertama tandatangan fungsi.
Sekarang kita mempunyai kelas JavaScript yang ditulis, tidakkah ia menjadi sejuk jika kita dapat memberitahu elemen HTML untuk menjadi objek walkingsprite hanya dengan memberikan nama kelas tertentu? Dalam JavaScript 1.6, anda boleh mencari semua elemen DOM dengan nama kelas tertentu menggunakan fungsi Document.GetElementByClassName. Walau bagaimanapun, kebanyakan pelayar tidak menyokong versi 1.6 lagi. Nasib baik, Prototaip memberikan kami fungsi $$ - lulus pemilih CSS dan ia akan mengembalikan pelbagai elemen yang sepadan.
Lihat kod berikut:
var WalkingSprite = Class.create({ <br> x: 0, <br> y: 0, <br> element: null, <br> <br> initialize: function(element, x, y) { <br> this.element = element; <br> this.x = x; <br> this.y = y; <br> }, <br> <br> walk: function(steps) { <br> this.x += steps; <br> } <br> }); <br> <br> koopa = new WalkingSprite(null, 10, 10); <br> koopa.walk(20); <br> alert(koopa.x + "," + koopa.y);
Pertama kita membuat kelas WalkingSprite, dan kemudian kelas Koopasprite yang menggunakan kelas WalkingSprite sebagai ibu bapanya. Seterusnya, kami membuat pelbagai objek Koopasprite dengan memilih semua elemen dalam dokumen yang mempunyai nama kelas "Koopa".
Sekarang, kita mempunyai pelbagai objek Koopasprite, dengan rujukan kepada unsur -unsur DOM yang sepadan (ini menjadi penting kemudian). Apa yang telah kita lakukan di sini adalah asas JavaScript yang tidak mengganggu . Sekarang kita telah menemui unsur -unsur HTML yang kita berminat, kita boleh mengikat peristiwa (seperti Onclick dan Onfocus), menghidupkan mereka, atau membuatnya hilang!
Oleh kerana kita tidak menulis permainan pengembaraan yang didorong teks, kita memerlukan cara menghidupkan watak kita. Ini melampaui menggerakkan mereka di sekitar skrin, yang akan ditutup kemudian. Ia juga akan menjadi baik jika kita dapat membuat watak -watak kelihatan seperti mereka berjalan, melompat, atau menghisap. Untuk melakukan ini, kami akan memanggil Trik CSS lama: Hack Kedudukan Latar Belakang.
Idea ini mudah: Kami membina reben imej yang membentuk bingkai animasi kami, dan kemudian kitaran melalui mereka dengan mengalihkannya ke kiri dan kanan x bilangan piksel. Berikut adalah contoh imej latar belakang:
Seperti yang anda lihat, kami mempunyai 12 bingkai dalam satu imej, setiap 48 piksel selain. Jika kita mempunyai div kelas Mario, CSS untuk beberapa bingkai yang berbeza mungkin kelihatan seperti ini:
// Declare the class <br> function WalkingSprite(element, x, y) { <br> this.x = x; <br> this.y = y; <br> this.element = element; <br> } <br> <br> WalkingSprite.prototype = { <br> x: 0, <br> y: 0, <br> element: null, <br> <br> walk: function(direction) { <br> this.x += direction; <br> } <br> } <br> <br> koopa = new WalkingSprite(null, 10, 10); <br> koopa.walk(20); <br> alert(koopa.x + "," + koopa.y);
Dalam enjin permainan kami, kami akan mengubah kedudukan imej latar belakang menggunakan JavaScript. Untuk menetapkan kedudukan latar belakang di JS, anda memanipulasi gaya elemen.BackgroundPosition atribut. Kod berikut mencipta kelas baru yang dipanggil Mariosprite yang menambah fungsi memberikan kepada kelas Walkingsprite induk. Fungsi baru ini dipanggil berulang kali dengan kelewatan masa, dan akan menghidupkan Mario berjalan menggunakan dua bingkai:
var WalkingSprite = Class.create({ <br> x: 0, <br> y: 0, <br> element: null, <br> <br> initialize: function(element, x, y) { <br> this.element = element; <br> this.x = x; <br> this.y = y; <br> }, <br> <br> walk: function(steps) { <br> this.x += steps; <br> } <br> }); <br> <br> koopa = new WalkingSprite(null, 10, 10); <br> koopa.walk(20); <br> alert(koopa.x + "," + koopa.y);
menggunakan pemasa
t sehingga kita memberitahu ia untuk berhenti. Kami akan melaksanakan yang terakhir, menggunakan fungsi setInterval:
// Declare the class <br> function WalkingSprite(element, x, y) { <br> this.x = x; <br> this.y = y; <br> this.element = element; <br> } <br> <br> WalkingSprite.prototype = { <br> x: 0, <br> y: 0, <br> element: null, <br> <br> walk: function(direction) { <br> this.x += direction; <br> } <br> } <br> <br> // Create the child class <br> JumpingAndWalkingSprite = WalkingSprite; <br> JumpingAndWalkingSprite.prototype = { <br> x: 0, <br> y: 0, <br> walk: WalkingSprite.prototype.walk <br> jump: function() { <br> y += 20; <br> } <br> }
Ia mungkin berbaloi menerangkan batasan JS yang akan kembali menggigit kami kemudian: JavaScript tidak berbilang threaded. Ini bermakna tidak ada cara untuk mendapatkan dua blok kod yang berjalan pada masa yang sama. Anda boleh
mengganggu satu lagi kod dengan menubuhkan pemasa satu tembakan dengan selang satu milisaat, yang akan memaksa pelayar anda untuk menjalankan fungsi panggil balik pada peluang seterusnya, tetapi sekeping kod yang terganggu akan dihentikan, dan tidak akan terus melaksanakan sehingga fungsi mengganggu telah selesai. Jadi menetapkan pemasa untuk membakar setiap satu milisaat tidak menjamin fungsi anda akan dipanggil dengan cepat. Kami akan melihat akibat ini apabila saya bercakap mengenai gelung itu.
Jelas sekali, permainan memerlukan beberapa jenis input manusia, sama ada melalui papan kekunci, tetikus, atau kayu bedik. Oleh itu, untuk permainan kami menjadi lebih daripada sprite pegun yang berjalan di tempat, kami perlu memberi respons kepada input dari pengguna; Dalam JavaScript, ini dipanggil event Mendengarkan .
Terdapat dua model acara yang berbeza bergantung kepada rasa pelayar yang anda miliki (kejutan, kejutan), dan walaupun prototaip melakukan pekerjaan yang hebat dalam merangkumi nuansa kedua -duanya, ia patut mengetahui apa yang berlaku di bawah tudung.
Anda boleh memilih sama ada peristiwa bergerak melalui DOM ke elemen yang melepaskannya (penangkapan acara), dari elemen (peristiwa menggelegak), atau gabungan kedua -duanya (model W3C rasmi). Berikut adalah perwakilan grafik apa yang berlaku. Mereka yang berada di Internet Explorer Land terjebak dengan acara menggelegak, sementara pelayar lain menyokong kedua -duanya.
Jika anda telah bermain dengan web untuk seketika, anda mungkin biasa dengan pengendalian acara sebaris menggunakan atribut seperti Onmouseover atau OnClick. Teknik ini bersamaan dengan menggunakan atribut gaya dalam CSS - ia jahat, jangan lakukannya. Syukurlah, terdapat beberapa cara untuk mengikat peristiwa secara dinamik ke unsur -unsur dalam JavaScript. Pertimbangkan kod berikut:
// Declare the class <br> function WalkingSprite(element, x, y) { <br> this.x = x; <br> this.y = y; <br> this.element = element; <br> } <br> <br> WalkingSprite.prototype = { <br> x: 0, <br> y: 0, <br> element: null, <br> <br> walk: function(direction) { <br> this.x += direction; <br> } <br> } <br> <br> koopa = new WalkingSprite(null, 10, 10); <br> koopa.walk(20); <br> alert(koopa.x + "," + koopa.y);
di sini kita mempunyai tiga kaedah yang berbeza untuk melampirkan peristiwa ke unsur -unsur di DOM. Yang pertama - menggunakan AddEventListener - adalah cara standard W3C untuk melakukan sesuatu; Parameter pertama adalah nama acara, yang kedua adalah nama fungsi panggil balik, dan yang ketiga adalah boolean yang menunjukkan sama ada kita menangkap (palsu) atau menggelegak (benar). Yang kedua - menggunakan lampiran - adalah cara Explorer Internet; Ia pada dasarnya adalah tandatangan yang sama dengan versi W3C, tanpa parameter ketiga kerana IE hanya menyokong peristiwa menggelegak. Yang terakhir - menggunakan harta OnClick Element - adalah kaedah yang berfungsi dalam semua pelayar.
peristiwa seperti Mouseover dan Mouseout cukup mudah, tetapi peristiwa papan kekunci sedikit lebih kompleks kerana kita perlu tahu apa kunci ditekan. Dalam kes ini, kita perlu mendapatkan maklumat dari objek acara JavaScript; Sama ada objek acara disalurkan ke dalam fungsi panggil balik, atau jika anda berada di tanah IE, objek acara global dibuat dalam objek tetingkap: window.event, yang mempunyai maklumat yang kami perlukan.
Berikut adalah contoh:
var WalkingSprite = Class.create({ <br> x: 0, <br> y: 0, <br> element: null, <br> <br> initialize: function(element, x, y) { <br> this.element = element; <br> this.x = x; <br> this.y = y; <br> }, <br> <br> walk: function(steps) { <br> this.x += steps; <br> } <br> }); <br> <br> koopa = new WalkingSprite(null, 10, 10); <br> koopa.walk(20); <br> alert(koopa.x + "," + koopa.y);
// Declare the class <br> function WalkingSprite(element, x, y) { <br> this.x = x; <br> this.y = y; <br> this.element = element; <br> } <br> <br> WalkingSprite.prototype = { <br> x: 0, <br> y: 0, <br> element: null, <br> <br> walk: function(direction) { <br> this.x += direction; <br> } <br> } <br> <br> // Create the child class <br> JumpingAndWalkingSprite = WalkingSprite; <br> JumpingAndWalkingSprite.prototype = { <br> x: 0, <br> y: 0, <br> walk: WalkingSprite.prototype.walk <br> jump: function() { <br> y += 20; <br> } <br> }
var JumpingAndWalkingSprite = Class.create(WalkingSprite); <br> <br> mario = new JumpingAndWalkingSprite(null, 10, 10); <br> mario.walk(10): <br> alert(mario.x + "," + mario.y); <br> mario.jump(); <br> alert(mario.x + "," + mario.y); <br>
Menyediakan pengendali acara kami menggunakan Event.Observe membolehkan kami menjatuhkan ujian bersyarat yang memeriksa sama ada kami mempunyai objek acara melalui parameter fungsi, atau dari acara tetingkap. Ini semua ditangani dengan lancar untuk kami dengan prototaip.
Pada ketika ini, kami telah meneroka objek dan kelas JavaScript (termasuk konsep OOP seperti warisan), cara menggunakan kelas JavaScript dan CSS untuk memberikan tingkah laku elemen, bagaimana menggunakan pemasa untuk membolehkan kita berulang kali melaksanakan tugas (seperti animasi), dan asas -asas mendengar peristiwa. Ini memberi kami JavaScript yang cukup dalam kotak alat kami untuk membolehkan kami mendapatkan teras membina permainan platform. Dalam artikel seterusnya, saya akan meliputi mencipta enjin perlanggaran asas-gelung animasi-dan menunjukkan kepada anda beberapa helah untuk menatal tetingkap penyemak imbas untuk mendapatkan kesan sampingan yang sah 80-an.
Sementara itu, lihat demo yang meletakkan teori di atas ke dalam amalan (petunjuk: tekan kekunci anak panah dan lihat apa yang berlaku). Anda boleh memuat turun Arkib Kod untuk artikel ini - lihat jika anda boleh memperluaskannya sendiri, kerana anda perlu memahami apa yang sedang berlaku untuk artikel kedua dalam siri ini. Sehingga masa depan ...
Bolehkah JavaScript digunakan untuk membuat bot? Bagaimana?
Atas ialah kandungan terperinci Menggodam javascript untuk keseronokan dan keuntungan: Bahagian I. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!