<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      HTML5游戲制作完全指南

      2011-12-08 18:28  【當(dāng)耐特】  閱讀(19246)  評(píng)論(10)    收藏  舉報(bào)

      簡(jiǎn)介

      創(chuàng)建畫布

      游戲循環(huán)

      Hello world

      創(chuàng)建player

      鍵盤控制

               a:使用jQuery Hotkeys

               b:移動(dòng)player

      添加更多游戲元素

      炮彈

      敵人

      使用圖片

      碰撞檢測(cè)

      聲音

       

       

      簡(jiǎn)介

      你想使用HTML5的Canvas制作一款游戲嗎?跟著這個(gè)教程,你將立刻上道兒。

      閱讀該教程需要至少熟悉javascript相關(guān)知識(shí)。

      你可以先玩這款游戲或者直接閱讀文章并且下載游戲源碼

       

      創(chuàng)建畫布

      在畫任何東西之前,我們必須創(chuàng)建一個(gè)畫布。因?yàn)檫@是完全指南,并且我們將用到j(luò)Query.

      var CANVAS_WIDTH = 480;
      var CANVAS_HEIGHT = 320;
      
      var canvasElement = $("<canvas width='" + CANVAS_WIDTH + 
                            "' height='" + CANVAS_HEIGHT + "'></canvas>");
      var canvas = canvasElement.get(0).getContext("2d");
      canvasElement.appendTo('body');

       

      游戲循環(huán)

      為了呈現(xiàn)給玩家連貫流暢的游戲動(dòng)畫,我們要頻繁地渲染畫布來欺騙玩家的眼睛。

      var FPS = 30;
      setInterval(function() {
        update();
        draw();
      }, 1000/FPS);

      現(xiàn)在我們先不管update和draw里面的實(shí)現(xiàn),重要的是我們要知道setInterval()會(huì)周期性的執(zhí)行update和draw

       

      Hello world

      現(xiàn)在我們已經(jīng)搭建好了一個(gè)循環(huán)的架子,我們?nèi)バ薷膗pdate和draw方法來寫一些文字到屏幕。

      function draw() {
        canvas.fillStyle = "#000"; // Set color to black
        canvas.fillText("Sup Bro!", 50, 50);
      }

      專家提醒: 當(dāng)你稍微更改了一些代碼的時(shí)候就執(zhí)行一下程序,這樣可以更快的找到程序出錯(cuò)地方。

      靜止文字正常的顯示出來了。因?yàn)槲覀円呀?jīng)有了循環(huán),所以我們可以很容易地讓文字動(dòng)起來~~~

      var textX = 50;
      var textY = 50;
      
      function update() {
        textX += 1;
        textY += 1;
      }
      
      function draw() {
        canvas.fillStyle = "#000";
        canvas.fillText("Sup Bro!", textX, textY);
      }

      執(zhí)行程序。如果你一步一步照著上面做下來,可以看到文字移動(dòng)。但是上一次的文字卻還留在屏幕上,因?yàn)槲覀儧]有擦除畫布。現(xiàn)在我們?cè)赿raw方法中加入擦除方法。

      function draw() {
        canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
        canvas.fillStyle = "#000";
        canvas.fillText("Sup Bro!", textX, textY);
      }

      現(xiàn)在你可以看到文字在屏幕上移動(dòng)了,它已經(jīng)算是一個(gè)真正意義上的游戲,只不過是個(gè)半成品。

       

      創(chuàng)建player

      創(chuàng)建一個(gè)包含player所有信息的對(duì)象,并且要有draw方法。這里創(chuàng)建了一個(gè)簡(jiǎn)單的對(duì)象包含了所有的player信息。

      var player = {
        color: "#00A",
        x: 220,
        y: 270,
        width: 32,
        height: 32,
        draw: function() {
          canvas.fillStyle = this.color;
          canvas.fillRect(this.x, this.y, this.width, this.height);
        }
      };

      我們現(xiàn)在用一個(gè)純色的矩形來代表player.當(dāng)我們把它加入游戲當(dāng)中的時(shí)候,我們需要清除畫布并且畫上player.

      function draw() {
        canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
        player.draw();
      }

       

      鍵盤控制

      使用jQuery Hotkeys

      jQuery Hotkeys plugin在處理鍵盤行為的時(shí)候,可以更加容易的兼容不同的瀏覽器。讓開發(fā)者不用因?yàn)椴煌瑸g覽器之間的keyCode andcharCode不同而苦惱,我們這樣綁定事件:

      $(document).bind("keydown", "left", function() { ... });

      移動(dòng)player

      function update() {
        if (keydown.left) {
          player.x -= 2;
        }
      
        if (keydown.right) {
          player.x += 2;
        }
      }

      是不是感覺移動(dòng)不夠快?那么我們來提高它的移動(dòng)速度。

      function update() {
        if (keydown.left) {
          player.x -= 5;
        }
      
        if (keydown.right) {
          player.x += 5;
        }
      
        player.x = player.x.clamp(0, CANVAS_WIDTH - player.width);
      }

      我們可以很容易的添加其他元素,比如炮彈:

      function update() {
        if (keydown.space) {
          player.shoot();
        }
      
        if (keydown.left) {
          player.x -= 5;
        }
      
        if (keydown.right) {
          player.x += 5;
        }
      
        player.x = player.x.clamp(0, CANVAS_WIDTH - player.width);
      }
      
      player.shoot = function() {
        console.log("Pew pew");
        // :) Well at least adding the key binding was easy...
      };

       

      添加更多游戲元素

      炮彈

      我們開始真正意義上的添加炮彈,首先,我們需要一個(gè)集合來存儲(chǔ)它:

      var playerBullets = [];

      然后,我們需要一個(gè)構(gòu)造器來創(chuàng)建炮彈:

      function Bullet(I) {
        I.active = true;
      
        I.xVelocity = 0;
        I.yVelocity = -I.speed;
        I.width = 3;
        I.height = 3;
        I.color = "#000";
      
        I.inBounds = function() {
          return I.x >= 0 && I.x <= CANVAS_WIDTH &&
            I.y >= 0 && I.y <= CANVAS_HEIGHT;
        };
      
        I.draw = function() {
          canvas.fillStyle = this.color;
          canvas.fillRect(this.x, this.y, this.width, this.height);
        };
      
        I.update = function() {
          I.x += I.xVelocity;
          I.y += I.yVelocity;
      
          I.active = I.active && I.inBounds();
        };
      
        return I;
      }

      當(dāng)玩家開火,我們需要向集合中添加炮彈:

      player.shoot = function() {
        var bulletPosition = this.midpoint();
      
        playerBullets.push(Bullet({
          speed: 5,
          x: bulletPosition.x,
          y: bulletPosition.y
        }));
      };
      
      player.midpoint = function() {
        return {
          x: this.x + this.width/2,
          y: this.y + this.height/2
        };
      };

      修改update和draw方法,實(shí)現(xiàn)開火:

      function update() {
        ...
        playerBullets.forEach(function(bullet) {
          bullet.update();
        });
      
        playerBullets = playerBullets.filter(function(bullet) {
          return bullet.active;
        });
      }
      function draw() {
        ...
        playerBullets.forEach(function(bullet) {
          bullet.draw();
        });
      }

      敵人

        enemies = [];
      
      function Enemy(I) {
        I = I || {};
      
        I.active = true;
        I.age = Math.floor(Math.random() * 128);
      
        I.color = "#A2B";
      
        I.x = CANVAS_WIDTH / 4 + Math.random() * CANVAS_WIDTH / 2;
        I.y = 0;
        I.xVelocity = 0
        I.yVelocity = 2;
      
        I.width = 32;
        I.height = 32;
      
        I.inBounds = function() {
          return I.x >= 0 && I.x <= CANVAS_WIDTH &&
            I.y >= 0 && I.y <= CANVAS_HEIGHT;
        };
      
        I.draw = function() {
          canvas.fillStyle = this.color;
          canvas.fillRect(this.x, this.y, this.width, this.height);
        };
      
        I.update = function() {
          I.x += I.xVelocity;
          I.y += I.yVelocity;
      
          I.xVelocity = 3 * Math.sin(I.age * Math.PI / 64);
      
          I.age++;
      
          I.active = I.active && I.inBounds();
        };
      
        return I;
      };
      
      function update() {
        ...
      
        enemies.forEach(function(enemy) {
          enemy.update();
        });
      
        enemies = enemies.filter(function(enemy) {
          return enemy.active;
        });
      
        if(Math.random() < 0.1) {
          enemies.push(Enemy());
        }
      };
      
      function draw() {
        ...
      
        enemies.forEach(function(enemy) {
          enemy.draw();
        });
      }

       

      使用圖片

      player.sprite = Sprite("player");
      
      player.draw = function() {
        this.sprite.draw(canvas, this.x, this.y);
      };
      
      function Enemy(I) {
        ...
      
        I.sprite = Sprite("enemy");
      
        I.draw = function() {
          this.sprite.draw(canvas, this.x, this.y);
        };
      
        ...
      }

       

      碰撞檢測(cè)

      function collides(a, b) {
        return a.x < b.x + b.width &&
               a.x + a.width > b.x &&
               a.y < b.y + b.height &&
               a.y + a.height > b.y;
      }
      function handleCollisions() {
        playerBullets.forEach(function(bullet) {
          enemies.forEach(function(enemy) {
            if (collides(bullet, enemy)) {
              enemy.explode();
              bullet.active = false;
            }
          });
        });
      
        enemies.forEach(function(enemy) {
          if (collides(enemy, player)) {
            enemy.explode();
            player.explode();
          }
        });
      }
      
      function update() {
        ...
        handleCollisions();
      }
      function Enemy(I) {
        ...
      
        I.explode = function() {
          this.active = false;
          // Extra Credit: Add an explosion graphic
        };
      
        return I;
      };
      
      player.explode = function() {
        this.active = false;
        // Extra Credit: Add an explosion graphic and then end the game
      };

       

      加入聲音

      function Enemy(I) {
        ...
      
        I.explode = function() {
          this.active = false;
          // Extra Credit: Add an explosion graphic
        };
      
        return I;
      };
      
      player.explode = function() {
        this.active = false;
        // Extra Credit: Add an explosion graphic and then end the game
      };

      DNT磚家提醒: 跟著上面的步驟,大概讓大家了解了一款游戲的各種元素的制作過程,這類游戲做一遍就夠,沒有必要做第二遍,沒有很難的算法,全是流程和經(jīng)驗(yàn)性質(zhì)的東西,倘若想做好看,做炫一點(diǎn),那就是美工拼了老命切圖的事情,或者開發(fā)人員介入做一些性能優(yōu)化和碰撞優(yōu)化。最后重復(fù)一遍----看過就好,不要當(dāng)寶。

      原文鏈接http://www.html5rocks.com/en/tutorials/canvas/notearsgame/#toc-player-movement

      你可能還喜歡:http://www.rzrgm.cn/iamzhanglei/archive/2011/11/06/2237870.html

      主站蜘蛛池模板: 国产一区二区三区精品综合| 国产乱子伦农村xxxx| 边添小泬边狠狠躁视频| 久热这里有精品免费视频| 99亚洲男女激情在线观看| 亚洲乱码国产乱码精品精大量 | 亚洲国产成人极品综合| 蜜臀av一区二区三区精品| 无码人妻丝袜在线视频| 忘忧草社区在线www| 国产午夜精品福利免费不| 国产一区二区三区禁18| 欧美成人免费一区二区三区视频 | 亚洲中文字字幕精品乱码| 露脸国产精品自产拍在线观看| 亚洲人成网网址在线看| 国产精品日本一区二区不卡视频| 97人妻蜜臀中文字幕| 少妇上班人妻精品偷人| 国产偷国产偷亚洲高清人| 熟妇人妻av中文字幕老熟妇 | 久久精品麻豆日日躁夜夜躁| 少妇和邻居做不戴套视频| 马关县| 亚洲av色香蕉一区二区| 亚洲精品成人福利网站| 国产成人高清亚洲综合| 久久AV中文综合一区二区| 亚洲精品第一国产综合精品| 国内精品久久久久影院网站 | 亚洲精品在线二区三区| 女人被狂c躁到高潮视频| 国产成人卡2卡3卡4乱码| 2019久久久高清日本道| 亚洲av无码之国产精品网址蜜芽| 亚洲av无码专区在线亚| 50路熟女| 武装少女在线观看高清完整版免费| 激情的视频一区二区三区| 亚洲久悠悠色悠在线播放| 无码人妻一区二区三区线|