Selama beberapa minggu sekarang saya telah bekerja secara tetap pada projek yang saya rasa mungkin menarik untuk dibincangkan, penciptaan enjin permainan video saya dalam JavaScript dan HTML5 berdasarkan kanvas.
Anda mungkin tertanya-tanya mengapa anda memilih HTML5 dan JavaScript untuk mencipta permainan video? Jawapannya kurang menarik daripada soalan, ia adalah persaingan projek yang diperlukan untuk sekolah saya (Zone01 Normandie) dan fakta bahawa bahasa mempunyai segala yang diperlukan untuk melaksanakan projek ini yang menyebabkan saya memilih teknologi ini
Tetapi sebenarnya ini bukanlah bahasa yang akan saya pilih sebagai pangkalan dan saya pasti akan memulakan pengembaraan lain jenis ini dengan bahasa yang berbeza selepas pemuktamadan yang ini.Seni bina
Ke kelas ini saya akan menambah kelas CollideBox yang akan membolehkan saya menguruskan kotak perlanggaran semua objek.
Kelas Permainan mempunyai kaedah GameLoop yang akan dilaksanakan pada setiap bingkai(imej) permainan, kaedah Cabutan yang akan dipanggil semasa setiap gelung permainan.
Bagi kelas GameObject, ia mempunyai kaedah Step, dan kaedah Draw.
Yang pertama melaksanakan setiap pusingan gelung permainan dan yang kedua setiap kali kaedah Cabutan kelas GameLoop dipanggil.
Untuk memaparkan sprite saya memilih untuk menggunakan API canva yang terbina dalam HTML5 (terbina dalam bermakna ia disertakan secara lalai)
Ia akan membolehkan saya memaparkan semua sprite dan memotong semula imej untuk mencipta animasi yang akan sangat berguna kepada saya!
Dan banyak lagi perkara menarik yang saya akan biarkan anda lihat di bawah:
Kelas GameObject
class GameObject{ constructor(game) { // Initialize the GameObject this.x = 0 this.y = 0 this.sprite_img = {file: undefined, col: 1, row: 1, fw: 1, fh: 1, step: 0, anim_speed: 0, scale: 1} this.loaded = false this.game = game this.kill = false this.collision = new CollideBox() game.gObjects.push(this) }; setSprite(img_path, row=1, col=1, speed=12, scale=1) { var img = new Image(); img.onload = () => { console.log("image loaded") this.sprite_img = {file: img, col: col, row: row, fw: img.width / col, fh: img.height / row, step: 0, anim_speed: speed, scale: scale} this.onSpriteLoaded() }; img.src = img_path } onSpriteLoaded() {} draw(context, frame) { // Draw function of game object if (this.sprite_img.file != undefined) { let column = this.sprite_img.step % this.sprite_img.col; let row = Math.floor(this.sprite_img.step / this.sprite_img.col); // context.clearRect(this.x, this.y, this.sprite_img.fw, this.sprite_img.fh); context.drawImage( this.sprite_img.file, this.sprite_img.fw * column, this.sprite_img.fh * row, this.sprite_img.fw, this.sprite_img.fh, this.x, this.y, this.sprite_img.fw * this.sprite_img.scale, this.sprite_img.fh * this.sprite_img.scale ); if (frame % Math.floor(60 / this.sprite_img.anim_speed) === 0) { // Mise à jour de step seulement à 12 fps if (this.sprite_img.step < this.sprite_img.row * this.sprite_img.col - 1) { this.sprite_img.step += 1; } else { this.sprite_img.step = 0; } } } } distance_to(pos) { return Math.sqrt((pos.x - this.x) ** 2 + (pos.y - this.y) ** 2) } collide_with(box) { if (box instanceof GameObject) { box = box.collision } return ( this.collision.x < box.x + box.w && this.collision.x + this.collision.w > box.x && this.collision.y < box.y + box.h && this.collision.y + this.collision.h > box.y ) } onStep() {}; }
Kelas Permainan
class Game { constructor(width = 1400, height = 700) { this.gObjects = []; this.toLoad = []; this.timers = []; this.layers = []; this.canvas = document.getElementsByTagName("canvas")[0] this.canvas.width = width this.canvas.height = height this.context = this.canvas.getContext("2d") this.context.globalCompositeOperation = 'source-over'; this.inputs = {}; this.mouse = {x: 0, y: 0} document.addEventListener('keydown', (e) => { this.inputs[e.key] = true; }, false); document.addEventListener('keyup', (e) => { this.inputs[e.key] = false; }, false); document.addEventListener('mousemove', (e) => { this.mouse.x = e.x; this.mouse.y = e.y; }) document.addEventListener('mouseevent', (e) => { switch (e.button) { } }) } draw(frame) { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); console.log( this.canvas.width, this.canvas.heigh) for(let i = 0; i < this.gObjects.length; i ++) { this.gObjects[i].draw(this.context, frame) } } gLoop() { let fps = Math.floor(1000 / 60) console.log(fps) let clock = 0 setInterval(() => { clock += 1 for(let i = 0; i < this.gObjects.length; i ++) { if (this.gObjects[i] != undefined) { if (this.gObjects[i].kill) { this.gObjects.splice(i, 1); continue; } this.gObjects[i].onStep(); } } this.draw(Math.floor(clock)) // context.l(); // console.log(clock) if (fps <= clock) { clock = 0 } }, fps) } keyboard_check(key) { return this.inputs[key] == true } }
"Sempurna!" boleh awak beritahu saya?
Itu terlalu mudah.
Saya bayangkan anda masih ingat bahawa pilihan teknologi yang dibuat dibuat untuk memenuhi keperluan sekolah Zone01 saya…
Sememangnya bahasa yang dipilih adalah baik tetapi saya tidak mengetahui arahan yang akan menyebabkan projek ini menjadi sangat serius…
Kami dilarang menggunakan pustaka Canva!
Apa yang seterusnya?
Devlog ini telah tamat dan anda akan mempunyai cerita yang lain tidak lama lagi, jangan risau.
Untuk devlog seterusnya saya pasti akan mencuba format baharu.
DevLogs 1.1: Enjin sudah siap, bagaimana ia berfungsi?
Memutuskan format untuk memohon devlog ini mengambil banyak masa, dan saya akui saya melengahkan sedikit atau malah menolak sepenuhnya tarikh akhir untuk menulis yang ini.
Dengan sabar mengambil alasan keragu-raguan saya untuk tidak mengerjakan subjek ini, saya kini mendapati diri saya dua bulan selepas tarikh keluaran yang dirancang menulis di kawasan rehat stesen bas Rouen manakala kereta api saya yang dibatalkan memaksa saya menunggu satu jam tambahan.
したがって、アーキテクチャの詳細はすべて無視しましょう。このアーキテクチャは、私の開発ブログの最初の部分から (キャンバスの使用を避けることによる調整を除けば) ほとんど変更されていません。
そこで、実行されたプロジェクト、チームとしての取り組み方、遭遇した問題についてお話します。
これをこのプロジェクトへのフィードバックとして捉えてください。この記事からいくつかの教訓を引き出して、あなたのプロジェクトに役立てていただければ幸いです。
このプロジェクトは、JavaScript でスーパー マリオ ブラザーズを再作成し、少なくともコードに関してはゼロから始めることでした。
仕様はシンプルで、マリオ ゲームにいくつかのレベルがあり、新しいレベルを簡単に作成できる方法が必要でした。
また、オプションを調整するためにスコアボードとメニューを作成する必要がありました。
このプロジェクトの難しさは次のとおりです:
すべての要素がプレーヤーの位置を基準にしてバックグラウンドでスクロールする必要があるため、スクロールします。
また、画面に表示されない要素を最適化すると、パフォーマンスを損なうことなくゲームの実行に必要なリソースを削減できます。
これらの問題を解決した後、このゲームを私の itch.io ページに公開し、実際にテストしてみることもできます。
この開発ブログはこれで終了します。これで、他のプロジェクトや他のテーマについて書くことができるようになります。
私が話していることに少しでも興味がある場合は、github で私のさまざまなプロジェクト (この開発ブログ内のプロジェクトを含む) をご覧ください。
今日も素敵な一日をお過ごしください!
Atas ialah kandungan terperinci Devlog - Saya sedang mencipta enjin permainan!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!