SongKer 发布时间:2016-02-18 分类:Game 阅读:4909次 1 条评论
开发html5小游戏需要有JavaScript的基础。通过JavaScript生成画布,游戏循环来不停地绘制图形创建动画。

教程开始之前可以尝试游戏试玩,开发的是一个全屏手机游戏,在PC上打开可能不太适应。手机游戏地址:汽车游戏
教程开始:
1、创建画布
var CANVAS_WIDTH = window.innerWidth;
var CANVAS_HEIGHT = window.innerHeight;
var canvasElement = $("<canvas width='" + CANVAS_WIDTH + "' height='" + CANVAS_HEIGHT + "'></canvas>");
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 < player.width / 2 ? 0 : touch.pageX - player.width / 2;
PlayerX = touch.pageX > CANVAS_WIDTH - player.width / 2 ? CANVAS_WIDTH - player.width : PlayerX;
var PlayerY = touch.pageY < player.height / 2 ? 0 : touch.pageY - player.height / 2;
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 < CANVAS_WIDTH && I.y > -200 && I.y < CANVAS_HEIGHT + 200;
};
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 < 0 ? CANVAS_HEIGHT : -100,
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 < b.x + b.width &&
a.y < b.y + b.height);
}
function GetRandomNum(Min, Max) {
var Range = Max - Min;
var Rand = Math.random();
return (Min + Math.round(Rand * Range));
}以上是游戏的全部代码,测试的话请用手机端打开这个网址http://songker.com/Code/car/index.html
我也是刚学习html5开发,有什么问题大家一起交流。
上一篇:jQuery键盘按键监测键盘行为
下一篇:怎样在PC上调试手机网站
发布于 2016-02-20 18:28:15 回复该评论
发表评论:
◎欢迎您的参与讨论。