【轉載請註明出處】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(); } } })()