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 adalah sesuai dengan 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.
Fis donc de tous les détails de l'architecture, celle ci n'ayant que peu changer (hormis l'adaptation en évitant l'utilisation des canvas) depuis la première partie de mon devlog.
Nous allons donc parler du projet réalisé, de la manière dont nous avons travaillé en équipe et des problèmes que nous avons rencontré.
Voyez cela comme un retour d'expérience sur ce projet, et j'espère que vous parviendrai à tirer de cette rédaction quelques enseignements qui vous aiderons sur un de vos projet.
Le projet était de recréer un Super Mario Bros en JavaScript et en partant de zéro, tout du moins pour ce qui est du code.
Le cahier des charges était simple, nous devions avoir un jeu mario avec plusieurs niveau, une manière d'en créer de nouveaux simplement.
Aussi nous devions créer un tableau des scores et un menu afin de régler les options.
Les difficultés de ce projet étaient :
Le défilement car il requiert que tous les éléments défile en arrière plan relativement à la position du joueur.
Et l'optimisation des éléments qui ne sont pas affiché à l'écran permet de réduire les ressources nécessaires à faire fonctionner le jeu sans perte de performance.
Après avoir résolus ces difficultés nous avons publié ce jeu sur ma page itch.io sur laquelle même vous pouvez aller le tester.
Voila comment se termine ce devlog, maintenant terminé je vais pouvoir écrire sur d'autres projets et/ou d'autres sujets.
Si tu es même un petit peu intéressé par ce que je te raconte, tu peux aller voir mes différents projets (Dont ceux de ce devlog) sur github.
Bonne fin de journée!
Atas ialah kandungan terperinci Devlog - Saya sedang mencipta enjin permainan!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!