首頁  >  文章  >  web前端  >  利用HTML5 Canvas製作簡單的打手槍遊戲_html5教學技巧

利用HTML5 Canvas製作簡單的打手槍遊戲_html5教學技巧

WBOY
WBOY原創
2016-05-16 15:46:342068瀏覽

以前、Donnet の DEMO でオナニー ゲームを見て、その写真と音声を書き留めました。 。 。 。趣味で書き直しました。娯楽のためだけに。 。 。 。 。 。フレームワークは使用せず、すべての js を自分で書きます。 。 。 。 。 。これは、Canvas を初めてプレイする人にとっては役立つかもしれない簡単なチュートリアルです。ご容赦ください。

早速、デモ: 飛行機ゲームから始めましょう。元の投稿者はこれをただ楽しむために書いたもので、本格的なゲームに書き込むつもりはありませんでした。

本題に入りましょう: オナニー ゲーム ファイルには、index.html エントリ ファイル、allSprite.js スプライトのロジック処理ファイル、loading.js 読み込み処理ファイル、および data.js (一部の初期化データ) が含まれています。

まず、通常のゲームは基本的にロードが必要です。ロード ページは、スプライト シートの画像、オーディオなどを含むデータを事前にロードするために使用されます。これは小規模なゲームであるため、一部のオーディオと画像のみをロードする必要があります。内部の読み込みコードは主に次のとおりです。その他は読み込みアニメーションを作成するためのものです。興味がある場合は、デモのコンソールをご覧ください。 >

XML/HTML コード
コンテンツをクリップボードにコピー
  1. loadImg:function(datas){
  2. var _this = this;   
  3. var dataIndex = 0;   
  4. li();   
  5. function li(){
  6. if(datas[dataIndex].indexOf("mp3")>=0){
  7. var audio = document.createElement("audio");   
  8. document.body.appendChild(audio);   
  9. audio.preload = "auto";   
  10. audio.src = datas[dataIndex];   
  11. audio.oncanplaythrough = function(){
  12. this.oncanplaythrough = null;   
  13. dataIndex ;   
  14. if(dataIndex===datas.length){
  15. _this.percent = 100;   
  16. }else {
  17. _this.percent = parseInt(dataIndex/datas.length*100);   
  18. li.call(_this);   
  19. }
  20. }
  21. }其他 {  
  22.                     preLoadImg(datas[dataIndex] , function(){  
  23.                         dataIndex ;   
  24.            地
  25.                             ;   
  26.                         } 其他 {   
  27.                             (dataIndex/datas.length*100);                                   
  28.                         }   
  29.                     })                    }                }   
  30.         },   
  31.   
  32. //再貼出preLoadImg的方法   
  33. 函數 preLoadImg(src, 回調){   
  34.     var img
  35.  = new
  36.  Image();   
  37.     img.src
  38.  = src;   
  39.     if(img.complete){            callback.call(img);        }其他 {   
  40.         img.onload = 函數
  41.             callback.call(img);   
  42.         }   
  43.     }   
  44. }     


    まず、配列を使用してファイルへのリンクを data.js に保存し、次にこれらのリンクが画像であるかオーディオであるかを判断します。画像の場合は、preLoadImg を使用して画像をロードします。非常に簡単で、新しい画像を作成し、それにリンクを割り当て、ロード後にコールバックするだけです。オーディオは、HTML5 オーディオ dom オブジェクトを生成し、それにリンクを割り当てることによってロードされます。オーディオには「canplaythrough」イベントがあり、ブラウザーがバッファリングのために停止せずに指定されたオーディオ/ビデオの再生を継続できると予想される場合、canplaythrough イベントが発生します。これは、canplaythrough が呼び出された時点でオーディオがほぼロードされており、次のオーディオをロードできることを意味します。このように、すべてがロードされた後、コールバックが行われ、ゲームが開始されます。

    ゲームが始まりました。ゲームには多くのオブジェクトが必要になるため、異なるオブジェクト間の各フレームの動きをビヘイビアーを使用して個別に記述することができます。

    XML/HTML コードコンテンツをクリップボードにコピー
    1. W.Sprite = 関数(name , painter , behaviors , args){
    2. if(名前 !== 未定義) this.name = 名前;   
    3. if(ペインター !== 未定義) this.painter = ペインター;   
    4. this.top = 0;   
    5. this.left = 0;   
    6. this.width = 0;   
    7. この高さ = 0;   
    8. this.velocityX = 3;   
    9. this.velocityY = 2;   
    10. this.visible = true;   
    11. this.animating = false;   
    12. this.behaviors = 動作;   
    13. this.rotateAngle = 0;   
    14. this.blood = 50;   
    15. this.fullBlood = 50;   
    16. if(名前==="計画"){
    17. this.rotateSpeed = 0.05;   
    18. this.rotateLeft = false;   
    19. this.rotateRight = false;   
    20. this.fire = false;   
    21. this.firePerFrame = 10;   
    22. this.fireLevel = 1;   
    23. }else if(名稱==="星星"){   
    24.         this.width = 數學
    25. 數學
    26. 2;            this.speed = 
    27. 1
    28. this1this         
    29. this.lightLength
    30.  = 5;            
    31. this.cacheCanvas = 文件
    32.         this.cacheCtx = this.cachevasCtx = this.cachevas.getContext'2005);   
    33.         這個this.cacheCanvas.width = this.width 2.Lengength*;   
    34.         
    35. 這個this.cacheCanvas.height =this.width this.width this.Length*width   
    36.         this.painter.cache(this);        }else if(名稱==="badPlan"){   
    37.         this.badKind = 1;   
    38.         this.speed = 2;   
    39.         this.rotateAngle = 
    40. 數學
    41.     }else if(名稱==="missle"){            
    42. this.width = missleWidth;   
    43.     }else if(名稱==="boom"){            
    44. this.width = boomWidth = 
    45. boomWidth
    46.  = boomWidth = boomWidth = boomWidth;   
    47.     }else if(名稱==="食物"){            
    48. this.width = 40 = 40
    49. 40
    50. ;            this.speed = 3;            this.kind = 「升級」 = 「升級」 = 「升級」    }  
    51.     this.toLeft = false;   
    52.     this.toTop = false;   
    53.     this.toRight = false;   
    54.     this.toBottom = false;   
    55.   
    56.     this.outArcRadius = 數學.s
    57. *
    58. .s
    59. *
    60. .s.s
    61.   
    62.     if(args){   
    63.         for(var arg in args){   
    64.             這[arg] = args[arg];   
    65.         }   
    66.     }    }   
    67. Sprite.prototype = {   
    68.     建構子:Sprite,        paint:function(){   
    69.         if(
    70. this.name==="badPlan"){this.update();} 
    71.   
    72.         if(this.painter !== 未定義 && this.visible){   
    73.             if(this.name!=="badPlan") {   
    74.                 this.update();                }                if(this.name==="計劃"||this.name
    75. ==="計劃"||
    76. this.name==="計劃"||
    77. this.name==="badPlan"){   
    78.                 ctx.save();   
    79.                 ctx.translate(this.left, this.top);   
    80.                 ctx.rotate(this.rotateAngle);   
    81.                 this.painter.paint(this);   
    82.                 ctx.restore();   
    83.             }其他 {   
    84.                 this.painter.paint(this);   
    85.             }            }        },   
    86.     update:function(time){   
    87.         if(this.behaviors){   
    88.             for(var i=0;ithis.behaviors.length;i ){   
    89.                 this.behaviors[i].execute(this,time);   
    90.             }   
    91.         }   
    92.     }   
    93. }   


    寫出精靈類別後,就可以透過寫每個的painter以及behavior來產生不同的物件了。接下來就是寫painter了,painter分成兩種,一種是普通的painter,一種就是精靈表painter,因為像爆炸動畫,飛機開槍動畫,都不是一張圖片就能搞定的,所以就需要用到精靈表了:
    2015511181456172.png (168×24)

    2015511181533636.png (896×64)

    而繪製這些就要為他們定制一個精靈表繪製器,下面這個是最簡單的精靈表繪製器,針對遊戲的複雜性可以相對的修改精靈表寫法,直到合適,不過原理都大同小異,就是小修小改而已:

    XML/HTML Code複製內容到剪貼簿
    1. var SpriteSheetPainter = 函數(單元函數
    2. (單元 >             this.cells
    3.  = 細胞             this.cellIndex =         }   
    4.         
    5. SpriteSheetPainter.prototype
    6.  = {  =              提前:function(){   
    7.                 if(
    8. this.cellIndex === .                     this.cellIndex
    9.                 }                    其他 this.cellIndex ;                },   
    10.             繪畫:函數(精靈){   
    11.                 var 
    12. cell 🎜>
    13.                 context.drawImage(spritesheet , cell.x , cell.y ,spcell.p . .h);   
    14.             }            }     
    15. 而普通的器就更簡單了,直接寫一個畫家,把要畫的東西都寫進去就行了。
    16. 有了精靈類和精靈表較差器後,我們就可以把星星,飛機,子彈,爆炸對像都寫出來了:下面是整個allSprite.js的代碼:
    17. JavaScript 程式碼 將內容複製到剪切板
      1. (函數(W){   
      2.     「使用嚴格」  
      3.     var planWidth = 24,   
      4.         計畫高度= 24,   
      5.         missleWidth = 70,   
      6.         missleHeight = 70,   
      7.         boomWidth = 60;   
      8.     //精靈類別  
      9.     W.Sprite = 函數(姓名、畫家、行為、參數){   
      10.         if(name !== 未定義) 這個這個         
      11. if(畫家!==未定義) 畫家>         
      12. .top = 0;   
      13.         
      14. .left = 0;   
      15.         
      16. .width = 0;   
      17.         
      18. .height = 0;   
      19.         這個
      20. .velocityX = 3;   
      21.         
      22. .velocityY = 2;   
      23.         這個
      24. .visible = 
      25. true;         這個.animating = 
      26.         這個.behaviors = 行為;            
      27. .rotateAngle = 0;            
      28. .blood = 50;            
      29. .fullBlood = 50;            if
      30. (name==="計畫"             
      31. .rotateSpeed = 0.05;   .rotateSpeed = 0.05;                這個
      32. .rotateLeft = .rotateLeft =             
      33. 這個
      34. .rotateRight = .rotateRight =             這個.fire = 
      35. .fire = 
      36.             .firePerFrame = 10;   
      37. .firePerFrame = 10;   
      38.             
      39. .fireLevel = 1;   .fireLevel = 1;            }否則 if
      40.  
      41. if(nameif
      42. (name
      43. if(name>if ){                
      44. .width = Math.random              
      45. .speed = 1*.speed = 1*.speed = 1*這樣
      46.             
      47. .lightLength = 5;   .lightLength = 5;                .cacheCanvas = .T.createElement(" >
      48.             .cacheCtx = 這個>這個>這個>這個>這個>這個> );                .cacheCanvas.width = 
      49. 這樣🎜>.lightLength*2;                .cacheCanvas.height = .lightLength*2;   
      50.             
      51. .painter.cache(        }否則 
      52. if
      53.  if(nameif(nameif(name
      54. if
      55. (nameif(name
      56. if
      57. (name(name ){   
      58.             .badKind = 1;   
      59. .badKind = 1;   
      60.             .speed = 2;   .speed = 2;   
      61.             .rotateAngle = Math 
      62.         }否則 if if(name
    18. if
    19. (nameif ){   
    20.             這.width = missleWidth;           }否則 if if(nameif(name ){                這.width = boomWidth; 🎜         }其他 if(name==="食物"){ >
    21.             .width = 40;   .width = 40;   
    22.             
    23. .speed = 3;   .speed = 3;                這個
    24. .kind = 「升級」
    25. .kind = 
    26. 「升級」        }            這個
    27. .toLeft =          這個.toTop = 
    28.         
    29. 這個.toRight =          這個
    30. .toBottom = 
    31.            這個.outArcRadius = Math.sqrt((
    32. .width/2)*2);   
    33.            if(args){                
    34. for
    35. (
    36. var
    37. (var(
    38. var
    39. (var                 [arg]  
    40.             }            }   
    41.     }   
    42.     Sprite.prototype = {   
    43.         建構子:Sprite,   
    44.         繪製:函數
    45. (){   
    46.             如果(這個
    47. (這個(這個(這個.> > ){這個.update();}   
    48.   
    49.             if( .可見){                    if
    50. (if(if(if(這個計畫
    51. ) {                        
    52. update();這個 update();                 }  
    53.                 如果(如果(如果(如果這個計劃這個>||這個.name===“導彈”||
    54. 這個 .name===
    55. "壞計畫"){                        ctx.save();                        ctx.translate(
    56.                     ctx.rotate(
    57. 這個
    58.                                          ctx.restore();   
    59.                 }
    60. 其他
    61.  {                      
    62.                 }                }            },   
    63.         更新:
    64. 函數(時間){   
    65.             
    66. 如果(               
    67. 對於
    68. (((
    69. var
    70. 這個(var.behaviors.length;i ){                        這個.beofo[ 
    71.                 }                }            }   
    72.     }  
    73. // 精灵表绘制器
    74. W.SpriteSheetPainter = 関数(cells , isloop , endCallback , spritesheet){
    75. この.cells = cells || [];   
    76. この.cellIndex = 0;   
    77. this.dateCount = null;   
    78. この.isloop = isloop;   
    79. これ.endCallback = endCallback;   
    80. この.spritesheet = スプライトシート;   
    81. }
    82. SpriteSheetPainter.prototype = {
    83. advance:関数(){
    84. this.cellIndex = this.isloop?(this.cellIndex===この.cells.length-1?0:この.cellIndex 1):(この.cellIndex 1);   
    85. }、
    86. paint:関数(スプライト){
    87. if(this.dateCount===null){
    88. this.dateCount = new Date();   
    89. }else {
    90. var newd = new Date();   
    91. var tc = newd-this.dateCount;   
    92. if(tc>40){
    93. this.advance();   
    94. this.dateCount = newd;   
    95. }
    96. }  
    97. if(this.cellIndex<this。セル.長さ || この.isloop){
    98. var cell = this.cells[this .cellIndex];   
    99. ctx.drawImage(this.spritesheet , cell.x , cell.y , cell.w , cell.h , sprite.left-sprite.width/ 2、sprite.top-sprite.width/2、cell.w、cell.h);   
    100. } else if(this.endCallback) {
    101. この.endCallback.call(sprite);   
    102. この.cellIndex = 0;   
    103. }
    104. }
    105. }
    106. //特制飞机精灵表绘制器
    107. W.controllSpriteSheetPainter = 関数(セル, スプライトシート){
    108. この.cells = cells || [];   
    109. この.cellIndex = 0;   
    110. this.dateCount = null;   
    111. this.isActive = false;   
    112. this.derection = true;   
    113. この.spritesheet = スプライトシート;   
    114. }  
    115. controllSpriteSheetPainter.prototype = {
    116. advance:関数(){
    117. if(this.isActive){
    118. この.cellIndex ;   
    119. if(this.cellIndex === this.cells.length){
    120. この.cellIndex = 0;   
    121. this.isActive = false;   
    122. }
    123. }
    124. }、
    125. paint:関数(スプライト){
    126. if(this.dateCount===null){
    127. this.dateCount = new Date();   
    128. }else {
    129. var newd = new Date();   
    130. var tc = newd-this.dateCount;   
    131. if(tc>sprite.firePerFrame){
    132. this.advance();   
    133. this.dateCount = newd;   
    134. }
    135. }
    136. var cell = this.cells[this .cellIndex];   
    137. ctx.drawImage(this.spritesheet , cell.x , cell.y , cell.w , cell.h , -planWidth/2 , -planHeight/ 2、セル.w、セル.h);   
    138. }  
    139. }
    140. W.planBehavior = [
    141. {実行:関数(スプライト,時間){
    142. if(sprite.toTop){
    143. sprite.top = sprite.top
    144. }
    145. if(sprite.toLeft){
    146. sprite.left = sprite.left
    147. }
    148. if(sprite.toRight){
    149. sprite.left = sprite.left>canvas.width-planWidth/2? sprite.left : sprite.left sprite.velocityX;   
    150. }
    151. if(sprite.toBottom){
    152. sprite.top = sprite.top>canvas.height-planHeight/2? sprite.top : sprite.top sprite.velocityY;   
    153. }
    154. if(sprite.rotateLeft){
    155. sprite.rotateAngle -= sprite.rotateSpeed;   
    156. }
    157. if(sprite.rotateRight){
    158. sprite.rotateAngle = sprite.rotateSpeed;   スパン
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn