在学习了一段时间egret时间后,今天来分享一个egret的实战项目,用egret框架来做一款很流行的黑白块游戏。
开发环境的搭建在这里就不在详细述说,以下项目默认你已经搭好开发环境和了解egret的API,如果还有不会的同学请移步白鹭官网
本项目使用的是白鹭的工具Egret wing 3 和 5.1.1的引擎版本
开启Egret项目之旅~
1.新建项目
新建一个Egret游戏项目 项目名称叫做black_white_block_chapter,因为这时候创建的项目是一个白鹭的模板项目,可以直接在这个项目上开发自己的项目。接下来打开src文件夹下面的Main.ts文件,把创建游戏场景的createGameScene这个方法里面自带的内容删掉,之后就可以直接在这里做自己想做的事情–游戏的业务逻辑。
每个程序员都是一个好的架构师(偷笑一秒钟),为了更好的管理项目,下面只在createGameScene这个方法里面作入口处理,其他的业务逻辑独立到其他的文件。
2.创建文件
在src下新建一个文件夹App把该项目的所有业务代码放在这里面,现在新建一个GameMain.ts文件,代码里面会有一些注释,里面的具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
class GameMain extends egret.DisplayObjectContainer{ public constructor(){ super();
this.addEventListener(egret.Event.ADDED_TO_STAGE, this.addToStage, this); } public addToStage(){ this.removeEventListener(egret.Event.ADDED_TO_STAGE, this.addToStage, this); console.log('TODO HERE'); } }
|
3.回到Main.ts在创建场景的时候新建这个类并添加到舞台,具体代码如下:
1 2 3 4 5 6 7 8
|
private createGameScene() { this.addChild(new GameMain()); }
|
4.在App下新建一个Rect.ts文件
既然是面向对象,而项目中方块就是主角色,所以下面就是封装一个有业务逻辑的方块类,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
class Rect extends egret.Sprite{ public constructor(){ super(); this.touchEnabled = true; this.draw(); } private _colors:Array<number> = [0x000000, 0xffffff, 0xff0000, 0x0000ff]; private _currentColor:number = 1; private draw(){ this.width = Data.getRectWidth(); this.height = Data.getRectWidth(); this.graphics.lineStyle(2, 0x000000); this.graphics.beginFill(this._colors[ this._currentColor ]); this.graphics.drawRect(0, 0, Data.getRectWidth(), Data.getRectWidth()); this.graphics.endFill(); } private _type:string = RectType.NONCLICKABLE; public get type():string{ return this._type; } public set type(val:string){ this._type = val; if(this._type == RectType.CLICKABLE){ this._currentColor = 0; }else{ this._currentColor = 1; } this.draw(); } public onRectClick(){ if(this._type == RectType.CLICKABLE){ this._currentColor = 3; }else{ this._currentColor = 2; } this.draw(); } }
|
5.在App下新建一个RectType.ts文件
定义方块的类型,两个静态变量,具体代码如下:
1 2 3 4 5
| class RectType{ public static CLICKABLE:string = 'clickable'; public static NONCLICKABLE:string = 'nonclickable'; }
|
6.在App下新建一个Data.ts文件
每个项目中都会有一些固定的配置信息,那么在这个项目中,将一些公用的数据在Data.ts中封装起来,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Data{ private static _rectWidth:number = 0; public static getRectWidth():number{ if(Data._rectWidth == 0){ Data._rectWidth = egret.MainContext.instance.stage.stageWidth/4; } return Data._rectWidth; } public static score:number = 0; public static _rectRow:number = 0; public static getRectRow():number{ if(Data._rectRow == 0){ Data._rectRow = Math.ceil(egret.MainContext.instance.stage.stageHeight/Data.getRectWidth()) + 1; } return Data._rectRow; } public static getStageHeight():number{ return egret.MainContext.instance.stage.stageHeight; } }
|
7.项目中是以一行为一个小组单元,每组当中由4个小方块组成,然后多组(行)拼成一整个舞台,所以接下来在App下新建一个GroupRect.ts,具体的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
class GroupRect extends egret.Sprite{ public constructor(){ super(); this.createRects(); } private _rects:Array<Rect>; private createRects(){ this._rects = []; for(var i = 0;i < 4;i++){ var rect:Rect = new Rect(); this._rects.push(rect); rect.x = rect.width*i; this.addChild(rect); rect.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onClickRect, this); } } public _currentRow:number = 0; private onClickRect(evt:egret.TouchEvent){ evt.target.onRectClick(); if(evt.target.type == RectType.NONCLICKABLE || this._currentRow != Data.getRectRow() - 2){ this.dispatchEventWith("gameOver"); }else{ this.dispatchEventWith("clickRight"); } } private _currentBlcakRectIndex:number = 0; public createBlackRect(){ this.init(); var n:number = Math.random(); if(n >= 0 && n < 0.25){ this._currentBlcakRectIndex = 0; }else if(n >= 0.25 && n < 0.5){ this._currentBlcakRectIndex = 1; }else if(n >= 0.5 && n < 0.75){ this._currentBlcakRectIndex = 2; }else if(n >= 0.75 && n <= 1){ this._currentBlcakRectIndex = 3; } this._rects[this._currentBlcakRectIndex].type = RectType.CLICKABLE; }
public init(){ for(var i = 0;i < 4;i++){ this._rects[i].type = RectType.NONCLICKABLE; } } public move(){ this._currentRow += 1; if(this._currentRow == Data.getRectRow()){ this._currentRow = 0; this.createBlackRect(); } this.y = this._currentRow*Data.getRectWidth(); } }
|
8.在App文件夹下新建一个项目的总控Game.ts,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
class Game{ private _root : egret.DisplayObjectContainer; public constructor(root:egret.DisplayObjectContainer){ this._root = root; this.createGroupsRect(); this.createTimer(); this.startGame(); } private _row:number; private _rectRoot:egret.Sprite; private _rectGroups:Array<GroupRect>; private createGroupsRect(){ this._rectRoot = new egret.Sprite(); this._root.addChild(this._rectRoot); this._rectGroups = []; this._row = Data.getRectRow();
var groupRect:GroupRect; console.log(this._row) for(var i = 0;i < this._row;i++){ groupRect = new GroupRect(); groupRect.addEventListener("gameOver", this.gameOver, this); groupRect.addEventListener("clickRight", this.newRow, this); this._rectGroups.push(groupRect); groupRect.y = Data.getRectWidth()*i; this._rectRoot.addChild(groupRect); } this._rectRoot.y = Data.getStageHeight() - this._rectRoot.height; } private newRow(){ for(var i =0;i < this._row;i++){ this._rectGroups[i].move(); } Data.score++; } private gameOverPanel:GameOverPanel; private gameOver(){ this._timerPanel.stop(); if(!this.gameOverPanel){ this.gameOverPanel = new GameOverPanel(); this.gameOverPanel.addEventListener('startGame', this.startGame, this); } this._root.addChild(this.gameOverPanel); } private _timerPanel:TimePanel; private createTimer(){ this._timerPanel = new TimePanel(); this._timerPanel.addEventListener('gameOver', this.gameOver, this); this._root.addChild(this._timerPanel); } private startGame(){ Data.score = 0; for(var i = 0;i < this._row;i++){ this._rectGroups[i].init(); this._rectGroups[i].y = Data.getRectWidth()*i; this._rectGroups[i]._currentRow = i; if(i != (this._row - 1)){ this._rectGroups[i].createBlackRect(); } } this._timerPanel.start(); } }
|
9.在App文件夹下新建一个项目的时间面板TimerPanel.ts,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
class TimePanel extends egret.Sprite{ constructor(){ super(); this.draw(); this.createTimer(); } private txt:egret.TextField; private draw(){ this.txt = new egret.TextField(); this.txt.width = egret.MainContext.instance.stage.stageWidth; this.txt.y = 200; this.txt.textColor = 0xff0000; this.txt.textAlign = egret.HorizontalAlign.CENTER; this.txt.text = "20'00''"; this.addChild(this.txt); } private _timer:egret.Timer; private _num:number = 20; private createTimer(){ this._timer = new egret.Timer(1000, this._num); this._timer.addEventListener(egret.TimerEvent.TIMER, this.onTimer, this); this._timer.addEventListener(egret.TimerEvent.TIMER_COMPLETE, this.onTimerCom, this); } private _timers = 20; private onTimer(){ this._timers -= 1; this.txt.text = this._timers + "'00''" } private onTimerCom(){ this.txt.text = "00'00''"; this.dispatchEventWith('gameOver'); } public start(){ this.txt.text = "20'00''"; this._timers = 20; this._timer.reset(); this._timer.start(); } public stop(){ this._timer.stop(); } }
|
10.在App文件夹下新建一个项目的结束GameOverPanel.ts,具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
class GameOverPanel extends egret.Sprite{ public constructor(){ super(); this.draw(); this.addEventListener(egret.Event.ADDED, this.showText, this); } private txt:egret.TextField; private draw(){ var w = egret.MainContext.instance.stage.stageWidth; var h = egret.MainContext.instance.stage.stageHeight;
this.graphics.beginFill(0x111111, 0.5); this.graphics.drawRect(0, 0, w, h); this.graphics.endFill();
this.txt = new egret.TextField(); this.txt.width = w; this.txt.y = 100; this.txt.textColor = 0xff0000; this.txt.textAlign = egret.HorizontalAlign.CENTER; this.addChild(this.txt);
var btn = new egret.Sprite(); btn.graphics.beginFill(0x0000ff); btn.graphics.drawRect(0, 0, 200, 100); btn.graphics.endFill(); btn.width = 200; btn.height = 100; btn.x = (w - 200)/2; btn.y = (h - 100)/2; this.addChild(btn); btn.touchEnabled = true; btn.addEventListener(egret.TouchEvent.TOUCH_TAP, this.startGame, this); } private showText(){ this.txt.text = '我努力点击了'+Data.score+'步'; } private startGame(){ this.parent.removeChild(this); this.dispatchEventWith('startGame') } }
|
到这里就写完了整个项目的逻辑了,篇幅比较长,在教程的过程中也没有每个阶段的给出效果图,看起来和学习起来是比较吃力,在这里建议可以跑起完整的项目,然后自己跟着思路一步一步去实现。如果学习过程中,有不正确的欢迎纠正。谢谢大家!
源码地址