【译】HTML5 游戏入门

原文连接javascript

译文来自个人博客html

简介

若是你想用canvas作个游戏,那么来对地方了。html5

可是可是你至少知道javascript怎么拼写(╯‵□′)╯︵┻━┻java

既然没问题,那先来一下或者下载jquery

建立canvas标签

废话很少说,咱们必须建立一个canvas标签,简单起见,用一下不喜欢的jQuerygit

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');

游戏循环

为了可以让游戏平滑动画,咱们用30帧的频率。github

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

如今咱们能够先给这两个函数放置play,重要的是setInterval函数会按期照顾他们的。canvas

hello world

如今咱们有了这个循环,让咱们开始画东西吧~数组

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

注意:确认修改以后刷新一下,万一哪里不对,代码变的少还能看出哪里不对。app

若是没错,那么显示的是静止的字母,虽然好看,但咱们已经有了动画循环,因此咱们应该很容易让他动起来。

var textX = 50;
var textY = 50;

function update() {
  textX += 1;
  textY += 1;
}

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

如今若是没出错,那么字母应该在移动,可是有残影出现。想一想为何会这样,由于咱们没有清除以前的画面呢,so 咱们加点清除画布的代码。

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

如今能够看到字母在屏幕上移动了,恭喜你,你已经快入门了。让咱们继续。

建立玩家

接下来建立一个物体用来给玩家控制,咱们建立了一个简单的object:

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);
  }
};

咱们简单地着色了这个物体,当咱们清除画布的时候,画上这个物体。

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

键盘控制

使用jQuery HotKeys

使用jQuery HotKeys,这个插件提供了简单的键盘输入检测
咱们能够这么绑定事件

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

不用想哪一个按键是哪一个号码真舒服,咱们刚才实现了“当玩家按上的时候,作一些事情”,碉堡的插件!

玩家的移动

键盘输入检测已经完成了,但咱们还要处理键盘输入以后要作什么。
你可能会想使用事件驱动的方式去处理键盘输入,可是这样作系统不一,按键效果不同,并且脱离了动画循环呢,这样作就能够跨系统了,保证了一致性,也让游戏更平滑了。

有一个好消息,咱们有一个key_status.js的文件,提供了相似keydown.left等等。去下载的文件里找

如今咱们能够去查询是否有按键了,而后咱们就这么写:

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

  if (keydown.right) {
    player.x += 2;
  }
}

这样玩家能够控制了。

你可能注意到玩家能够跑出屏幕,让咱们限制一下玩家的位置,并且彷佛控制速度有点慢,咱们顺便加加速。

function update() {
  if (keydown.left) {
    player.x -= 5;
  }

  if (keydown.right) {
    player.x += 5;
  }

  player.x = player.x.clamp(0, CANVAS_WIDTH - player.width);
}

clamp这个函数能够在下载的util.js里看到

而后咱们加点炮弹进去。

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...
};

添加更多物体

子弹
咱们须要一个数组放子弹

var playerBullets = [];

接下来咱们建立一个子弹原型

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;
}

但玩家射击时,咱们应该实例子弹,而后添加到子弹数组中.

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
  };
};

咱们须要把子弹的动画添加到没帧的动画里,为了能让子弹变成无限的效果,咱们过滤了子弹数组,只保留了激活的子弹.同时删除了已经撞到敌人的子弹.

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();
  });
}

加载和添加图片

虽然目前这些方块飞来飞去看起来很酷,但有图片就更酷了。咱们使用了一个叫sprite.js的文件,能够从下载的文件里看到。

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);
  };

  ...
}

碰撞检测

咱们已经有了不少敌人飞来飞去了,但他们没有交互呢mb打不到他们,咱们是时候加点碰撞检测了.
让咱们使用一个简单的方法检测:

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;
}

咱们须要检测以下两种碰撞:

  1. 玩家子弹和敌方飞船

  2. 玩家和敌方飞船

让咱们给update加入处理碰撞以后的处理

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
};

声音

为了可玩性,咱们将要添加声音效果进去,咱们用到sound.js这个文件,让事情变得很是简单。

player.shoot = function() {
  Sound.play("shoot");
  ...
}

function Enemy(I) {
  ...

  I.explode = function() {
    Sound.play("explode");
    ...
  }
}

使用这些API就能很快地完成一个简单的游戏.

告别

再说一下游戏地址,也能够下载

well,我但愿你开始喜欢用js和html5写简单的游戏,随着学习的深刻,未来会有更多地挑战呢.

参考文献

HTML5 Canvas Cheat Sheet

HTML5 Game EnginesSF怎么自动读取gist的信息。。我在SF删了这个连接

译后感

第一次完整的翻译一篇文章,真蛋疼有些句子感受很差翻,就随便糊弄一下,BTW,我也按这个教程写了例子,好像写完还有不少问题呢(逃

顺便吐槽一下,SF编辑器怎么没有删除线,╭(╯^╰)╮

相关文章
相关标签/搜索