前回の記事では、独自の戦車を描画し、その動きを制御できるようにしました。前回の記事に引き続き、戦車戦闘ゲームを実装してみましょう。
1. JS ファイルを分離する
OO のアイデアを使用して、戦車をカプセル化し、戦車の絵画もカプセル化しました。次に、これら 2 つのオブジェクトを外部の js ファイルに抽出します。ファイルの内容は次のとおりです。 :
//定义一个Hero类(后面还要改进) //x表示坦克的横坐标 //y表示纵坐标 //direct表示方向 function Hero(x,y,direct){ this.x=x; this.y=y; this.speed=1; this.direct=direct; //上移 this.moveUp=function(){ this.y-=this.speed; this.direct=0; } //右移 this.moveRight=function(){ this.x+=this.speed; this.direct=1; } //下移 this.moveDown=function(){ this.y+=this.speed; this.direct=2; } //左移 this.moveLeft=function(){ this.x-=this.speed; this.direct=3; } } //绘制坦克 function drawTank(tank){ //考虑方向 switch(tank.direct){ case 0: //向上 case 2: //向下 //设置颜色 cxt.fillStyle="#BA9658"; //左边的矩形 cxt.fillRect(tank.x,tank.y,5,30); //右边的矩形 cxt.fillRect(tank.x+17,tank.y,5,30); //画中间的矩形 cxt.fillRect(tank.x+6,tank.y+5,10,20); //画出坦克的盖子 cxt.fillStyle="#FEF26E"; cxt.arc(tank.x+11,tank.y+15,5,0,Math.PI*2,true); cxt.fill(); //画出炮筒 cxt.strokeStyle="#FEF26E"; cxt.lineWidth=1.5; cxt.beginPath(); cxt.moveTo(tank.x+11,tank.y+15); if(tank.direct==0){ //只是炮筒的方向不同 cxt.lineTo(tank.x+11,tank.y); }else{ cxt.lineTo(tank.x+11,tank.y+30); } cxt.closePath(); cxt.stroke(); break; case 1: case 3: //设置颜色 cxt.fillStyle="#BA9658"; //上边的矩形 cxt.fillRect(tank.x-4,tank.y+4,30,5); //下边的矩形 cxt.fillRect(tank.x-4,tank.y+17+4,30,5); //画中间的矩形 cxt.fillRect(tank.x+5-4,tank.y+6+4,20,10); //画出坦克的盖子 cxt.fillStyle="#FEF26E"; cxt.arc(tank.x+15-4,tank.y+11+4,5,0,Math.PI*2,true); cxt.fill(); //画出炮筒 cxt.strokeStyle="#FEF26E"; cxt.lineWidth=1.5; cxt.beginPath(); cxt.moveTo(tank.x+15-4,tank.y+11+4); if(tank.direct==1){ //只是炮筒的方向不同 cxt.lineTo(tank.x+30-4,tank.y+11+4); }else{ cxt.lineTo(tank.x-4,tank.y+11+4); } cxt.closePath(); cxt.stroke(); break; } }
前の記事に小さな質問があります。思い出させてくれた Mark_Lee に感謝します。
//画出坦克的盖子 cxt.fillStyle="#FEF26E"; cxt.arc(tank.x+15-4,tank.y+11+4,5,0,360,true); cxt.fill();
ここで描かれたタンクの蓋は丸くありません。こちらを参照してください: http://www.w3school.com.cn/html5/canvas_arc.asp
それでは、HTML の内容をご覧ください。 HTML の内容は次のとおりです:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> </head> <body onkeydown="getCommand();"> <h1>html5-坦克大战</h1> <!--坦克大战的战场--> <canvas id="tankMap" width="400px" height="300px" style="background-color:black"></canvas> <!--将tankGame04.js引入--> <script type="text/javascript" src="tankGame04.js"></script> <script type="text/javascript"> //得到画布 var canvas1 = document.getElementById("tankMap"); //得到绘图上下文 var cxt = canvas1.getContext("2d"); //我的tank //规定0向上、1向右、2向下、3向左 var hero = new Hero(40,40,0); drawTank(hero); //接收用户按键的函数 function getCommand(){ var code = event.keyCode; //键盘上字幕的ASCII码 switch(code){ case 87: hero.moveUp(); break; case 68: hero.moveRight(); break; case 83: hero.moveDown(); break; case 65: hero.moveLeft(); break; } //把画布清理 cxt.clearRect(0,0,400,300); //重新绘制 drawTank(hero); } </script> </body> </html>
2. 敵の戦車を描きます
これはすでにアイデアを持っているかもしれません。敵戦車を描くときは、自分の戦車クラスを真似て新しい関数を作って書き直した方が良いのではないでしょうか?この方法に反対する友人もいて、「これらはすべて戦車なので、戦車インスタンスを直接作成すれば済むのではないか」と言いました。 1人目の友人と2人目の友人のメソッドはオブジェクト指向のようでそうではありません。このようなゲームを作る場合、オブジェクト指向の考え方を使わないと実装できますが、非常に難しくなります。複雑。
このように考えてみましょう。私たちの戦車と敵の戦車には違いがあり、たとえば、発射する弾丸や色が異なります。しかし、この 2 つは共通点があります (どちらも戦車です)。この部分を抽象化する必要がありますか?はい、最初に Tank クラスを抽象化し、次にこの Tank クラスをそれぞれ継承します。冗談ですか? これは Java 言語ではなく、JavaScript スクリプト言語です。継承はどこから来たのでしょうか?そうですね、JavaScript ではオブジェクトの偽装を使用できます。オブジェクトの偽装は、JavaScript と ECMAScript が継承を実装するためのメソッドです。オブジェクトの偽装を学習して継承を実装する前に、まずキーワード this
function classA(color){ this.color = color; this.show = function(){alert(this.color);} } /* Note: 1> this 代表的是classA函数所构建的对象,而非函数classA对象本身这样说主要是为了避免(function is object)的影响; 2> 在构建classA对象时,是通过this来初始化的属性和方法的,如果用classB的this去冒充classA的this,那么就实现了简单的继承了 */
さて、今私たちは独自のタンクを使用し、敵の戦車は戦車のふりをします(笑)。
//定义一个Tank类(基类) function Tank(x,y,direct,color){ this.x=x; this.y=y; this.speed=1; this.direct=direct; this.color=color; //上移 this.moveUp=function(){ this.y-=this.speed; this.direct=0; } //右移 this.moveRight=function(){ this.x+=this.speed; this.direct=1; } //下移 this.moveDown=function(){ this.y+=this.speed; this.direct=2; } //左移 this.moveLeft=function(){ this.x-=this.speed; this.direct=3; } } //定义一个Hero类 function Hero(x,y,direct,color){ //下面两句话的作用是通过对象冒充达到继承的效果 this.tank=Tank; this.tank(x,y,direct,color); } //定义一个EnemyTank类 function EnemyTank(x,y,direct,color){ this.tank=Tank; this.tank(x,y,direct,color); }
このように、自分の戦車と敵の戦車を定義しましたが、戦車を描画するためにdrawTank(タンク)を変更する必要がありますか? Tank が描画されているので、それを変更する必要はありません (笑)、これはオブジェクト指向のポリモーフィズムです。
今すぐ戦車オブジェクトを作成しましょう!
//我的tank //规定0向上、1向右、2向下、3向左 var hero=new Hero(40,40,0,heroColor); //敌人的tank var enemyTanks=new Array(); for(var i=0;i<3;i++){ var enemyTank = new EnemyTank((i+1)*50,0,2,enemyColor); enemyTanks[i]=enemyTank; }
完全なコードは次のとおりです:
tankGame05.js
//为了编程方便,我们定义两个颜色数组 var heroColor=new Array("#BA9658","#FEF26E"); var enemyColor=new Array("#00A2B5","#00FEFE"); //定义一个Tank类(基类) function Tank(x,y,direct,color){ this.x=x; this.y=y; this.speed=1; this.direct=direct; this.color=color; //上移 this.moveUp=function(){ this.y-=this.speed; this.direct=0; } //右移 this.moveRight=function(){ this.x+=this.speed; this.direct=1; } //下移 this.moveDown=function(){ this.y+=this.speed; this.direct=2; } //左移 this.moveLeft=function(){ this.x-=this.speed; this.direct=3; } } //定义一个Hero类 function Hero(x,y,direct,color){ //下面两句话的作用是通过对象冒充达到继承的效果 this.tank=Tank; this.tank(x,y,direct,color); } //定义一个EnemyTank类 function EnemyTank(x,y,direct,color){ this.tank=Tank; this.tank(x,y,direct,color); } //绘制坦克 function drawTank(tank){ //考虑方向 switch(tank.direct){ case 0: //向上 case 2: //向下 //设置颜色 cxt.fillStyle=tank.color[0]; //左边的矩形 cxt.fillRect(tank.x,tank.y,5,30); //右边的矩形 cxt.fillRect(tank.x+17,tank.y,5,30); //画中间的矩形 cxt.fillRect(tank.x+6,tank.y+5,10,20); //画出坦克的盖子 cxt.fillStyle=tank.color[1]; cxt.arc(tank.x+11,tank.y+15,5,0,Math*PI*2,true); cxt.fill(); //画出炮筒 cxt.strokeStyle=tank.color[1]; cxt.lineWidth=1.5; cxt.beginPath(); cxt.moveTo(tank.x+11,tank.y+15); if(tank.direct==0){ //只是炮筒的方向不同 cxt.lineTo(tank.x+11,tank.y); }else{ cxt.lineTo(tank.x+11,tank.y+30); } cxt.closePath(); cxt.stroke(); break; case 1: case 3: //设置颜色 cxt.fillStyle="#BA9658"; //上边的矩形 cxt.fillRect(tank.x-4,tank.y+4,30,5); //下边的矩形 cxt.fillRect(tank.x-4,tank.y+17+4,30,5); //画中间的矩形 cxt.fillRect(tank.x+5-4,tank.y+6+4,20,10); //画出坦克的盖子 cxt.fillStyle="#FEF26E"; cxt.arc(tank.x+15-4,tank.y+11+4,5,0,Math*PI*2,true); cxt.fill(); //画出炮筒 cxt.strokeStyle="#FEF26E"; cxt.lineWidth=1.5; cxt.beginPath(); cxt.moveTo(tank.x+15-4,tank.y+11+4); if(tank.direct==1){ //只是炮筒的方向不同 cxt.lineTo(tank.x+30-4,tank.y+11+4); }else{ cxt.lineTo(tank.x-4,tank.y+11+4); } cxt.closePath(); cxt.stroke(); break; } }
Tank Battle.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> </head> <body onkeydown="getCommand();"> <h1>html5-坦克大战</h1> <!--坦克大战的战场--> <canvas id="tankMap" width="400px" height="300px" style="background-color:black"></canvas> <!--将tankGame04.js引入--> <script type="text/javascript" src="tankGame05.js"></script> <script type="text/javascript"> //得到画布 var canvas1=document.getElementById("tankMap"); //得到绘图上下文 var cxt=canvas1.getContext("2d"); //我的tank //规定0向上、1向右、2向下、3向左 var hero=new Hero(40,40,0,heroColor); //敌人的tank var enemyTanks=new Array(); for(var i=0;i<3;i++){ var enemyTank = new EnemyTank((i+1)*50,0,2,enemyColor); enemyTanks[i]=enemyTank; } //定时刷新我们的作战区(定时重绘) //自己的坦克,敌人坦克,子弹,炸弹,障碍物 function flashTankMap(){ //把画布清理 cxt.clearRect(0,0,400,300); //我的坦克 drawTank(hero); //敌人的坦克 for(var i=0;i<3;i++){ drawTank(enemyTanks[i]); } } flashTankMap(); //接收用户按键的函数 function getCommand(){ var code = event.keyCode; //键盘上字幕的ASCII码 switch(code){ case 87: hero.moveUp(); break; case 68: hero.moveRight(); break; case 83: hero.moveDown(); break; case 65: hero.moveLeft(); break; } flashTankMap(); } </script> </body> </html>
操作の効果:
これで私たちの戦車と敵の戦車ができました。戦いなさい、起きてください、次の記事では戦車に弾を発射させます。
上記は、Xiaoqiang の HTML5 モバイル開発ロード (8) - 戦車戦ゲーム 2 の内容です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) にご注意ください。