Im vorherigen Artikel haben wir Ihnen gezeigt, wie Sie ein Push-Box-Spiel mit JS und H5 schreiben. In diesem Artikel erfahren Sie hauptsächlich, wie Sie ein klassisches Spiel schreiben: Flappy Bird, einfache Version mit js und H5
Haftungsausschluss: Ich bin neu bei JS und H5. Wenn es bessere Verbesserungen gibt, geben Sie mir bitte Ihre Vorschläge~
1. Bei der Gestaltung des Spiels (einschließlich Vögel, Säulen usw.) müssen wir einer klaren Logik folgen : Der Vogel führt den vertikalen geraden Aufwärtswurf und die freie Fallbewegung aus, die Säule wird kontinuierlich erzeugt und bewegt sich nach links, wodurch der Vogel und die Säule isoliert werden, jeder von ihnen ist für sich)
2. Zeichnen Sie a Vogel, der nicht mit den Flügeln schlagen kann
3. Lassen Sie den Vogel fliegen (freier Fall, klicken Sie mit der Maus, um ihn vertikal zu werfen)
Logikteil (die Säule bewegt sich nach links, der Vogel trifft die Säule und das Spiel endet usw.)
5. Punkteberechnung (Punktzahl erhöht sich um 1 für jede Säule, die passiert wird)
6. Hintergrund hinzufügen (Bilder, Musik, Soundeffekte usw.) .)
Zuerst müssen wir 4 Klassen erstellen: game.html (zum Ausführen des Spiels), game.js (zum Schreiben der Logik). part), paint.js (wird zum Zeichnen von Objekten verwendet), pojo.js (wird zum Erstellen und Kapseln von Objekten verwendet)
game.html-Klasse:
In HTML5 geschrieben, müssen Sie hinzufügen, und ich bin es gewohnt, den Rand auf 0 zu setzen:
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8" /> <title>flappy bird</title> <style> /*设置边距为0*/ body{ margin:0px; overflow:hidden; } /*加背景*/ #can1{ background-image: url(背景.jpg); background-size:100%100%; } </style> <script type="text/javascript" src="pojo.js"></script> <script type="text/javascript" src="game.js"></script> <script type="text/javascript" src="paint.js"></script> <!--调用run()--> <script> window.onload = function (){ run(); }; </script> </head> <body> <!--画布标签,设置长宽像素--> <canvas id="can1" width="1536" height="733"></canvas> <!--加入背景音乐--> <audio src="bgm.mp3" autoplay loop></audio> <!--加入点击鼠标触发的音效--> <audio id="audio1" autoplay></audio> </body> </html>
Tatsächlich läuft( )-Methode wird in der HTML-Datei aufgerufen und das Tag
geschrieben Klasse: Wird zum Speichern von Klassen verwendet: Vogelsäulen. Hier führen wir eine einfache Version durch, bei der der Vogel durch eine Kreisnäherung ersetzt wird, sodass die nachfolgende Kollisionserkennung einfacher zu schreiben ist. Dabei wird der ermittelte Wert direkt geschrieben und der Variablenwert nicht zugewiesen.
Das Schreibformat ist wie folgt:
//鸟类(圆代替) function Bird(color){ //鸟的颜色 this.color = color; //鸟巩膜的颜色 this.eyeColor = 'white'; //鸟巩膜的半径 this.eyeRadius = 10; //鸟瞳孔的颜色 this.eyeInsideColor = 'black'; //鸟瞳孔的半径 this.eyeInsideRadius = '2.5'; //鸟初始位置 this.left = 100; this.top = 300; //鸟身体半径 this.size = 25; //鸟的速度 this.v = 0; //向下为+ 向上为- //分数计算 this.score = 0; //是否存活 this.isLive = true; }
Hinweis: Wir müssen alle Eigenschaften des Vogels berücksichtigen und zusammenfassen im Spiel. Verwenden Sie
in js und dann müssen wir die Säulenklasse schreiben:
//柱子类 //上面下面各一个,在一个竖直线上; //上下柱子的间隔固定; //左右两列柱子间隔固定; //柱子的粗细固定; //柱子相对鸟的速度 function Pillar(position, length){ //柱子颜色 this.color = 'lime'; //柱子向左移动速度 this.v = 8; //柱子宽度 this.width = 80; //柱子位置,是每个柱子左上角的位置 this.position = position; //柱子长度 this.length = length; //柱子是否存在,意思一会解释 this.isLive = true; //鸟是否通过当前柱子 this.isPass = false; }
Als nächstes müssen wir schreiben paint.js-Klasse, es ist auch eine ziemlich problematische Klasse. Zum Zeichnen müssen Sie
Dann zeichnen wir den Vogel, Vorher Beim Zeichnen des Vogels empfehle ich die Verwendung eines Zeichenwerkzeugs, um die allgemeine Form des Vogels zu zeichnen, damit Sie ihn später mit Code zeichnen können. Dies ist das Muster des Vogels, den ich entworfen habe (die Flügel sind etwas kompliziert und ich weiß es nicht). Wie man sie zeichnet, habe ich noch nicht im Programm gezeichnet, sorry)
//清屏 function clearScreen(ctx){ ctx.clearRect(0, 0, 1536, 750); }
Nachdem der Entwurf fertig ist, haben wir kann mit dem Malen in paint.js beginnen (ich habe den Erwerb der Leinwand und die Erstellung des Pinsels in In game.js statt in paint.js geschrieben):
Das ist wie es aussieht, wenn es gezeichnet wird (ich möchte lachen, wenn ich es nur anschaue:) )
//画鸟,同样,所有的变量属性都要考虑到,并且在画巩膜,瞳孔,嘴唇时候都要以变量作为基准!里面的参数需要耐下心来调整。 function paintBird(ctx, left, top, size, color){ ctx.beginPath(); ctx.fillStyle = color; ctx.arc(left, top, size, 0, 2*Math.PI);//left:100 top:300 size:25 ctx.fill(); //画巩膜 ctx.beginPath(); ctx.fillStyle = bird.eyeColor; ctx.arc(left+13,top-8,bird.eyeRadius,0,2*Math.PI); ctx.fill(); //画瞳孔 ctx.beginPath(); ctx.fillStyle = bird.eyeInsideColor; ctx.arc(left+18,top-8,bird.eyeInsideRadius,0,2*Math.PI); ctx.fill(); //画嘴唇 ctx.beginPath(); ctx.strokeStyle = 'black'; ctx.fillStyle = '#FC6747'; ctx.moveTo(left+4, top+3); ctx.lineTo(left+29, top+3); ctx.lineTo(left+33, top+6); ctx.lineTo(left+29, top+9); ctx.lineTo(left+32, top+12); ctx.lineTo(left+29, top+15); ctx.lineTo(left+4, top+15); ctx.lineTo(left+1, top+9); ctx.closePath(); ctx.stroke(); ctx.fill(); ctx.beginPath(); ctx.strokeStyle = 'black'; ctx.moveTo(left+1,top+9); ctx.lineTo(left+29,top+9); ctx.stroke(); //画翅膀,简易版先不画 }
Dann zeichne die Säulen:
Dann müssen wir auch den Punktestand anzeigen:
//画柱子,我用了渐变色,虽然调整的并不是很好,但是还能看 function paintPillar(ctx, left, top, width, height){ ctx.beginPath(); var grd=ctx.createLinearGradient(left,top,left+height,top); grd.addColorStop(0,"green"); grd.addColorStop(0.45,"white"); grd.addColorStop(1,"green"); ctx.fillStyle = grd; ctx.fillRect(left, top, width, height); }
Zu diesem Zeitpunkt haben wir die Hälfte der Arbeit erledigt das schwierigste game.js, das Logik, Kollision, Bewegung, Punktestand und viele andere Aspekte berücksichtigen muss.
//计分 function paintScore(ctx, score){ ctx.fillStyle = 'red'; ctx.font = '40px 黑体'; ctx.fillText('分数:'+score, 1320, 40); }
Stellen Sie zunächst vor, wie Sie den freien Fall eines Vogels gestalten:
Folgen Sie den Anweisungen Mit der obigen Methode schreiben Sie das Programm wie folgt:
Als nächstes folgt game.js. Der einfachen Erklärung halber erkläre ich es beim Schreiben direkt im Code:
//点击鼠标事件 document.onmousedown = function (ev){ //每点击一下出来音效 var oAudio = document.getElementById('audio1'); oAudio.src = '扇翅膀emm.wav'; //每点击一下做一次竖直上抛 jump(bird); } //鸟自由落体 function drop(bird){ bird.top = bird.top+bird.v; bird.v++; } //设置竖直上抛,直接将速度修改为负数即可 function jump(bird){ bird.v = -13; }
4. Zusammenfassung:
//游戏逻辑中枢 //创建鸟的对象 var bird = new Bird('#FBEE30'); //创建柱子对象,把20个柱子放到数组中 var pillar = new Array(20); var count = 0; function run(){ //获取画布 var oCan = document.getElementById('can1'); //创建画笔,2d var ctx = oCan.getContext('2d'); //这timer1是游戏页面显示的东西的线程,每25毫秒刷新一次 var timer1 = setInterval(function (){ //每次画之前先清屏 clearScreen(ctx); //判断鸟是否碰上柱子(是否死亡),死亡则弹框,结束线程 if(!bird.isLive){ alert('游戏结束!你的分数是'+bird.score+'!你好菜啊!') clearInterval(timer1); clearInterval(timer2); } //降落一下 drop(bird); //判断鸟是否通过柱子 for(var i = 0; i < pillar.length; i++){ if(pillar[i] != null && pillar[i].isLive){ //移动柱子 movePillar(pillar[i]); //画柱子 paintPillar(ctx, pillar[i].position.x, pillar[i].position.y, pillar[i].width, pillar[i].length); //计分,如果每个鸟的身体(圆)的左边通过一个柱子的最右边时,加一分 if(pillar[i].position.x+pillar[i].width <= bird.left-bird.size && !pillar[i].isPass){ //这里是因为每次通过上下两个柱子,如果是++的话就会每次加2,所以用+=0.5 bird.score += 0.5; //通过的柱子将isPass设置为true,否则程序将默认鸟通过了所有柱子,就会加每次21 pillar[i].isPass = true; } } } //检验鸟碰到柱子 for(var i = 0; i < pillar.length; i++){ if(pillar[i] != null && pillar[i].isLive){ judgeImpact(bird, pillar[i]); } } //死亡后执行 //画鸟 paintBird(ctx, bird.left, bird.top, bird.size, bird.color); paintScore(ctx, bird.score); }, 25); //这个timer2是创建柱子的线程 var timer2 = setInterval(function (){ //上面的柱子的长度 var l = Math.random()*330+100; //上面柱子,用json传变量 pillar[count++] = new Pillar({x:1536, y:0}, l); //下面柱子 pillar[count++] = new Pillar({x:1536, y:l+200}, 733-l-200); //如果柱子达到20个,自动将第20个设置为第0个,节省了内存,属于算法优化 if(count == 20){ count = 0; } }, 1100); } //点击鼠标事件 document.onmousedown = function (ev){ //每点击一下出来音效 var oAudio = document.getElementById('audio1'); oAudio.src = '扇翅膀emm.wav'; //每点击一下做一次竖直上抛 jump(bird); } //鸟自由落体 function drop(bird){ bird.top = bird.top+bird.v; bird.v++; } //设置竖直上抛,直接将速度修改为负数即可 function jump(bird){ bird.v = -13; } //移动柱子 function movePillar(pillar){ pillar.position.x -= pillar.v; //如果柱子移动出画布,将isLive设置为false if(pillar.position.x < -80){ pillar.isLive = false; } } //检测鸟和柱子碰撞 function judgeImpact(bird, pillar){ //碰到上边框,死亡 if(bird.top < bird.size){ bird.isLive = false; bird.top = bird.size; } //碰到下边框,死亡 else if(bird.top > 733-bird.size){ bird.isLive = false; bird.top = 733-bird.size; } //当小鸟嵌入上下柱子的左边时(检验鸟是否碰到柱子的左边) if(Math.abs(bird.left-pillar.position.x) <= bird.size){ //碰到上面柱子的左边 if(pillar.position.y == 0){ if(bird.top < pillar.length){ bird.isLive = false; bird.left = pillar.position.x-bird.size; } } //碰到下面柱子的左边 else{ if(bird.top > pillar.position.y){ bird.isLive = false; bird.left = pillar.position.x-bird.size; } } } //如果是上面柱子 if(pillar.position.y == 0){ //如果小鸟高度小于上面柱子 if(Math.abs(bird.top-pillar.length) <= bird.size){ //并且小鸟在两个柱子之间,死亡 if(bird.left+bird.size > pillar.position.x && bird.left+bird.size < pillar.position.x+pillar.width+30){ bird.isLive = false; bird.top = pillar.length+bird.size; } } } //如果是下面柱子 else{ //如果小鸟高度大于 下面柱子上方距离顶部的高度 if(Math.abs(bird.top-pillar.position.y) <= bird.size){ //并且小鸟在两个柱子之间,死亡 if(bird.left+bird.size > pillar.position.x && bird.left+bird.size < pillar.position.x+pillar.width+30){ bird.isLive = false; bird.top = pillar.position.y-bird.size; } } } }
paintPillar(ctx, pillar[i].position.x, pillar[i].position.y, pillar[i].width, pillar[i].length);
2.关于柱子,我们必须符合这一条逻辑:先创建柱子数组(array),然后创建每个柱子,再画柱子,再移动,四个步骤缺一不可。
3.其中有对于算法的优化:在创建柱子的数组中,我们没有设置很多个柱子(比如说10000,虽然也不可能达到那么高的分),因为这样每25毫秒就要创建那么多柱子,再画和移动,内存占用很高,我们只用建立一个能存放20个柱子的数组,出屏幕的清掉,位置由新的代替,这样就极大程度减少了对内存的需要。
4.关于调试参数(比如说画鸟),要耐心调整,直到满意为止。
5.在检测鸟和柱子的碰幢时候,需要在逻辑上下功夫,建议先在稿纸上画出碰撞条件,再编写程序。
Das obige ist der detaillierte Inhalt vonJavaScript und HTML5 zum Schreiben einer einfachen Version des Spiels Flappy Bird. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!