SongKer 发布时间:2016-02-18 分类:Game 阅读:4187次 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 回复该评论
发表评论:
◎欢迎您的参与讨论。