【转载请注明出处】html
紧接着上一篇文章createjs入门:http://www.cnblogs.com/beidan/p/7055422.htmlgit
这里来一篇小游戏实战篇。github
效果图:(录屏的时候有点卡)canvas

demo地址:https://github.com/beidan/canvas/tree/master/demo/car。若是对你有用,请点star~跨域
游戏总体思路实现数组
1. 实现一个无缝链接的背景图,模拟出汽车在加速的状态dom
this.backdrop = new createjs.Bitmap(bg); this.backdrop.x = 0; this.backdrop.y = 0; this.stage.addChild(that.backdrop); this.w = bg.width; this.h = bg.height; //建立一个背景副本,无缝链接 var copyy = -bg.height; this.copy = new createjs.Bitmap(bg); this.copy.x = 0; this.copy.y = copyy; //在画布上y轴的坐标为负的背景图长 //使用createjs的tick函数,逐帧刷新舞台 createjs.Ticker.addEventListener("tick", tick); function tick(e) { if (e.paused !== 1) { //舞台逐帧逻辑处理函数 that.backdrop.y = that.speed + that.backdrop.y; that.copy.y = that.speed + that.copy.y; if (that.copy.y > -40) { that.backdrop.y = that.copy.y + copyy; } if (that.copy.y > -copyy - 100) { that.copy.y = copyy + that.backdrop.y; } that.stage.update(e); } }
2. 随机绘制障碍物函数
因为一条跑道确定会有不少障碍物,对于超出屏幕的障碍物咱们要进行‘资源回收’,不然游戏到后面会愈来愈卡顿。ui
// 删除越界的元素 for (var i = 0, flag = true, len = that.props.length; i < len; flag ? i++ : i) { if (that.props[i]) { if (that.props[i].y > height + 300) { that.stage.removeChild(that.props[i]); that.props.splice(i, 1); flag = false; } else { flag = true; } } }
一共有3条赛道,咱们不能出现3个道具同时出如今水平线上,所以咱们会随机取1~2个值绘制障碍物。全部游戏咱们都应该有参数去控制它的难易程度,省得临上线的时候,老板体验以后以为游戏太难了……那就很是地尴尬了。 所以,咱们会设置加速物体,减速物体,炸弹出现的比例,后期能够调整这个比例来设置游戏的难易程度。this
var num = parseInt(2 * Math.random()) + 1, i; for (i = 0; i < num; i++) { var type = parseInt(10 * Math.random()) + 1; // 设置道具出现比例 if (type == 1) { /绘制炸弹 } else if ((type >= 2) && (type <= 5)) { //绘制加速道具 } else if ((type >= 6) && (type <= 10)) { //绘制减速道具 } }
第一次绘制完障碍物以后,会随机时间绘制下一次的障碍物。
var time = (parseInt(3 * Math.random()) + 1); //随机取1~3整数 // 随机时间绘制障碍物 setTimeout(function () { that.propsTmp = []; //清空 that.drawObstacle(obj); }, time * 400); //400ms ~ 1200ms
3.碰撞检测
咱们用一个数组来存放汽车占的矩形区域,障碍物占的矩形区域,在每一次tick的时候循环遍历数组,看是否有重叠的,如有重叠,则发生了碰撞。
createjs的一些小知识:
1. 暂停和恢复舞台渲染
createjs.Ticker.addEventListener(“tick”, tick); function tick(e) { if (e.paused === 1) { //处理 } } createjs.Ticker.paused = 1; //在函数任何地方调用这个,则会暂停tick里面的处理 createjs.Ticker.paused = 0; //恢复游戏
2. 因为汽车会有加速,减速,弹气泡的效果。所以咱们把这几个效果绘制在同一个container中,方便统一管理,对这些效果设置name属性,以后能够直接使用getChildByName获取到该对象。
container.name = ‘role’; //设置name值 car = this.stage.getChildByName(“role”); //使用name值方便获取到该对象
3. 预加载 preload (createjs 的 preload 很是的实用)
一开始是本身写的预加载,后来发现createjs里面对图片是有跨域处理的,本身处理跨域的img就比较麻烦,因此直接使用createjs的预加载。
//放置静态资源的数组
var manifest = [
{src: __uri('./images/car_prop2_tyre@2x.png'), id: 'tyre'} ]; var queue = new createjs.LoadQueue(); queue.on('complete', handleComplete, this); queue.loadManifest(manifest); //资源加载成功后,进行处理 function handleComplete() { var tyre = queue.getResult('tyre'); //拿到加载成功后的img }
通常作一个游戏,咱们正常都会构建一个游戏类来承载。 下面是一个游戏正常有的接口:
;(function () { function CarGame(){} CarGame.prototype = { init:function(manifest) { this.preLoad(manifest); //资源预加载 //时间倒计时 this.prepare(3, 3); //倒计时3秒 this.bindEvent(); }, render:function() { this.drawBg(bg1); this.drawRole(car, effbomb, effquick); this.drawObstacle(obj); }, //在游戏结束的时候批量销毁 destroy:function(){ //移除tick事件 createjs.Ticker.removeEventListener("tick", this.tick); //暂停里程,倒计时 clearInterval(this.changem); clearTimeout(this.gametime); }, //因为期间用户可能切出程序进行其余操做,所以都须要一个暂停的接口 pause:function() { //暂停里程,倒计时 clearInterval(this.changem); clearTimeout(this.gametime); //暂停页面滚动 createjs.Ticker.paused = 1; }, //从新开始游戏 reStart:function(){ this.destroy(); this.init(manifest); }, gameOver:function(){ //显示爆炸效果 var car = this.stage.getChildByName("role"); car.getChildByName('bomb').visible = true; car.getChildByName('quick').visible = false; this.destroy(); } } })()