开发html5小游戏需要有JavaScript的基础。通过JavaScript生成画布,游戏循环来不停地绘制图形创建动画。
教程开始之前可以尝试游戏试玩,开发的是一个全屏手机游戏,在PC上打开可能不太适应。手机游戏地址:汽车游戏
教程开始:
1、创建画布var CANVAS_WIDTH = window.innerWidth;
var CANVAS_HEIGHT = window.innerHeight;
var canvasElement = $("");
var canvas = canvasElement.get(0).getContext("2d");
canvasElement.appendTo('body');
2、游戏循环:不停的绘图
为了游戏的连贯性实现动画等效果,需要对画布频繁的渲染(静态的页面就可以不用循环)。如下的代码会周期性的执行update和draw方法。var scale = CANVAS_WIDTH / 320, FPS =30; //通过scale计算出其他元素的宽高
setInterval(function() {
update();
draw();
}, 1000/FPS);
3、画布绘图
步骤2已经搭建起了一个循环的条件,在实现动画前我们可以在update和draw里将文字或者一张图片输出到画布上。
打印“www.songker.com”这几个黑色字体代码如下:function draw() {
canvas.fillStyle = "#000"; // 设置字体颜色
canvas.fillText("www.songker.com!", 50, 50);
}
4、道路的绘制:创建‘道路’元素
我们将上面的代码改掉,将道路绘制上去。创建一个包含道路的所有信息的一个对象,包含’道路‘的draw和run方法。代码://滚动的道路
var sight = {
speed: 10,
x: 0,
y: 0,
width: CANVAS_WIDTH,
height: 1126 * scale, //根据屏幕比例得出图片实际高度
run: function () {
this.y += this.speed;
if (this.y >= this.height) //第一张图已完毕
{
//console.log("road blank");
this.y = 0;
}
},
draw: function () {
var road_img = new Image();
road_img.src = "images/road.png";
canvas.drawImage(road_img, this.x, this.y, this.width, this.height);
canvas.drawImage(road_img, this.x, this.y - this.height, this.width, this.height);
}
};
然后在全局draw方法中执行sight.draw(),在update中执行sight.run()实现‘跑动’的道路。function draw() {
canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
sight.draw();
};
function update() {
sight.run();
};
每完成一次绘制需要将上次画布上的内容清除掉,清除代码就是canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)。
以上就完成了一个简单的'跑动的'道路。
5、绘制玩家的汽车
创建一个叫player对象,包含绘制、运动等所有玩家汽车的元素。//玩家的汽车
var player = {
width: 75 * scale,
height: 149 * scale,
x: CANVAS_WIDTH / 2 - (75 * scale) / 2,
y: CANVAS_HEIGHT - (149 * scale),
framePNG: new Array("images/car_1.png", "images/car_2.png"),
layer: 0, //当前一张图片
move: function () {
this.layer += 1;
if (this.layer > 3&&this.layer <= 30 && this.layer%2==1)
this.layer += 1;
if (this.layer > 30)
this.layer = 0;
},
draw: function () {
var car_img = new Image();
car_img.src = this.framePNG[this.layer % 2];
canvas.drawImage(car_img, this.x, this.y, this.width, this.height);
}
};
玩家的汽车有两张差异图片,循环绘制这两张图片产生汽车加速的效果。再次更新全局的draw和update方法,绘制玩家汽车:function draw() {
canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
sight.draw();
player.draw();
};
function update() {
sight.run();
player.move();
};
目前汽车还无法移动,我们可以给画布添加一个触摸移动事件,让汽车跟着我们手指的移动而移动。$("canvas").bind('touchmove',function (e) {
// 如果这个元素的位置内只有一个手指的话
if (e.originalEvent.targetTouches.length == 1) {
e.originalEvent.preventDefault();// 阻止浏览器默认事件,重要
var touch = e.originalEvent.targetTouches[0];
var PlayerX = touch.pageX
PlayerX = touch.pageX > CANVAS_WIDTH - player.width / 2 ? CANVAS_WIDTH - player.width : PlayerX;
var PlayerY = touch.pageY
PlayerY = touch.pageY > CANVAS_HEIGHT - player.height/2 ? CANVAS_HEIGHT - player.height : PlayerY;
// 把元素放在手指所在的位置
player.x = PlayerX;
player.y = PlayerY;
}
});
6、绘制其他的NPC汽车var NPC = {
meter: 0,
BlockCarCollet: [],
framePNG: Array(
{ width: 70, height: 120, xVelocity: 0, yVelocity: 2, src: "images/block_01.png" },
{ width: 50, height: 180, xVelocity: 0, yVelocity: 4, src: "images/block_02.png" },
{ width: 82, height: 141, xVelocity: 0, yVelocity: -4, src: "images/block_03.png" },
{ width: 50, height: 180, xVelocity: 0, yVelocity: 6, src: "images/block_02.png" }
),
BlockCar:function(I) {
I.active = true;
I.frameOBJ = this.framePNG[I.Num];
I.width = I.frameOBJ.width * scale;
I.height = I.frameOBJ.height * scale;
I.inScreen = function () {
return I.x > 0 && I.x -200 && I.y
};
I.draw = function () {
var imgOBJ = new Image();
imgOBJ.src = I.frameOBJ.src;
canvas.drawImage(imgOBJ, I.x, I.y, I.width, I.height);
};
I.update = function () {
I.x += I.frameOBJ.xVelocity;
I.y += I.frameOBJ.yVelocity;
I.active = I.active && I.inScreen();
}
return I;
},
draw: function () {
this.meter += 1;
if (this.meter > 2000) {
this.meter = 0;
}
if (this.meter % 50==0)
{
var index = GetRandomNum(1, this.framePNG.length) % this.framePNG.length;
var frameOBJ = this.framePNG[index];
this.BlockCarCollet.push(this.BlockCar({
x: GetRandomNum(15, CANVAS_WIDTH - frameOBJ.width-15),
y: frameOBJ.yVelocity
Num: index
}));
}
}
};
更新update和draw方法:function draw() {
canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
sight.draw();
player.draw();
NPC.draw();
NPC.BlockCarCollet.forEach(function (car) {
car.draw();
});
};
function update() {
sight.run();
player.move();
NPC.BlockCarCollet.forEach(function (car) {
car.update();
});
//handleCollisions();
NPC.BlockCarCollet = NPC.BlockCarCollet.filter(function (car) {return car.active});
};
游戏基本完成。出现的唯一问题是,汽车之间没有碰撞事件。在update里添加一个碰撞事件handleCollisions():function handleCollisions()
{
NPC.BlockCarCollet.forEach(function (CarA) {
NPC.BlockCarCollet.forEach(function (CarB) {
if (CarA != CarB && collides(CarA, CarB)) {
console.log("boom!!");
CarA.active = CarB.active = false;
}
});
if (collides(CarA, player))
{
console.log("gameover!!");
}
});
};function collides(a, b)
{
return (a.x + a.width > b.x &&
a.y + a.height > b.y &&
a.x
a.y
}
function GetRandomNum(Min, Max) {
var Range = Max - Min;
var Rand = Math.random();
return (Min + Math.round(Rand * Range));
}
我也是刚学习html5开发,有什么问题大家一起交流。