摘要:這個類可以大大減少后期的代碼量,降低整體的耦合度。關(guān)鍵代碼是把位圖按照區(qū)域進(jìn)行分割,顯示對象的滾動矩形范圍。
這次給大家?guī)淼氖峭ㄟ^Egret實(shí)現(xiàn)密室逃生小游戲的教程。該游戲包括人物狀態(tài)機(jī)、MVC設(shè)計(jì)模式和單例模式,該游戲在1.5s內(nèi)通過玩家點(diǎn)擊操作尋找安全點(diǎn),方可進(jìn)入下一關(guān),關(guān)卡無限,分?jǐn)?shù)無限。下面是具體的模塊介紹和代碼實(shí)現(xiàn)。
該游戲主要內(nèi)容包括
**開始游戲場景
游戲場景
游戲結(jié)束結(jié)算場景
全局常量類
人物狀態(tài)機(jī)類**
游戲源碼素材下載:https://github.com/shenysun/R...
創(chuàng)建全局常量類
在所有舞臺搭建之前先寫一個全局的靜態(tài)方法類,取名為GameConst。這個類里面的方法和常量可以供全局使用,例如舞臺寬高、通過名字獲取位圖、通過名字獲取紋理集精靈等等。這個類可以大大減少后期的代碼量,降低整體的耦合度。
/**常用常量類 */ class GameConst { /**舞臺寬度 */ public static StageW:number; /**舞臺高度 */ public static StageH:number; /**根據(jù)名字創(chuàng)建位圖 */ public static CreateBitmapByName(name:string):egret.Bitmap { let texture:egret.Texture = RES.getRes(name); let bitmap:egret.Bitmap = new egret.Bitmap(texture); return bitmap; } /** * 根據(jù)name關(guān)鍵字創(chuàng)建一個Bitmap對象。此name 是根據(jù)TexturePacker 組合成的一張位圖 */ public static createBitmapFromSheet(name:string, sheetName:string):egret.Bitmap { let texture:egret.Texture = RES.getRes(`${sheetName}_json.${name}`); let result:egret.Bitmap = new egret.Bitmap(texture); return result; } public static getTextureFromSheet(name:string, sheetName:string):egret.Texture { let result:egret.Texture = RES.getRes(`${sheetName}_json.${name}`); return result; } /**移除子類方法 */ public static removeChild(child:egret.DisplayObject) { if(child && child.parent) { if((child.parent).removeElement) { ( child.parent).removeElement( (child)); } else { child.parent.removeChild(child); } } } }
如果游戲中設(shè)置圖片錨點(diǎn)較多也可以在這個類里面加一個設(shè)置錨點(diǎn)的方法,傳入對象,橫軸錨點(diǎn)和縱軸錨點(diǎn)坐標(biāo)三個參數(shù)。
開始場景
開始頁面比較簡潔,有一個LOGO和兩個按鈕分別是開始游戲,更多游戲。
/**游戲開始場景 */ class StartGameLayer extends egret.Sprite { /**開始按鈕 */ private startBtn:MyButton; /**更多按鈕 */ private moreBtn:MyButton; /**LOGO */ private titleImage:egret.Bitmap; public constructor() { super(); this.init(); } private init():void { /**添加游戲LOGO */ this.titleImage = GameConst.createBitmapFromSheet("logo_mishitaosheng", "ui"); this.titleImage.x = 51; this.titleImage.y = 161; this.addChild(this.titleImage); //開始按鈕設(shè)置 this.startBtn = new MyButton("btn_y", "btn_kaishi"); this.addChild(this.startBtn); this.startBtn.x = (GameConst.StageW - this.startBtn.width) / 2; this.startBtn.y = GameConst.StageH / 2 - 75; this.startBtn.setClick(this.onStartGameClick); //更多按鈕設(shè)置 this.moreBtn = new MyButton("btn_b", "btn_gengduo"); this.moreBtn.x = (GameConst.StageW - this.startBtn.width) / 2; this.moreBtn.y =GameConst.StageH / 2 + 75; this.addChild(this.moreBtn); this.moreBtn.setClick(this.onMoreBtnClick); //文本 let tex:egret.TextField = new egret.TextField(); tex.width = GameConst.StageW; tex.textAlign = egret.HorizontalAlign.CENTER; tex.strokeColor = 0x403e3e; tex.stroke = 1; tex.bold = true; tex.y = GameConst.StageH / 2 + 250; tex.text = "Powered By ShenYSun"; this.addChild(tex); } private onStartGameClick() { GameControl.Instance.onGameScenesHandler(); } private onMoreBtnClick() { console.log("更多游戲"); platform.GetInfo(); } }
點(diǎn)擊startBtn按鈕執(zhí)行GameControl類的切換場景方法。
場景控制類
/**游戲管理 */ class GameControl extends egret.Sprite { private static _instance:GameControl; public static get Instance() { if(!GameControl._instance) { GameControl._instance = new GameControl(); } return GameControl._instance; } /**當(dāng)前場景 */ private currentStage:egret.DisplayObjectContainer; //開始游戲 private startGame:StartGameLayer; /**游戲場景 */ private gameScenes:GameScenesLayer; /**結(jié)束場景 */ private overScenes:GameOverLayer; /**背景 */ private bgImg:egret.Bitmap; public constructor() { super(); this.startGame = new StartGameLayer(); this.gameScenes = new GameScenesLayer(); this.overScenes = new GameOverLayer(); } public setStageHandler(stage:egret.DisplayObjectContainer):void { /**設(shè)置當(dāng)前場景的背景 */ this.currentStage = stage; this.bgImg = GameConst.CreateBitmapByName("bg_jpg"); this.bgImg.width = GameConst.StageW; this.bgImg.height = GameConst.StageH; //把背景添加到當(dāng)期場景 this.currentStage.addChild(this.bgImg); } /**開始游戲的場景 */ public startGameHandler():void { if(this.gameScenes && this.gameScenes.parent) { GameConst.removeChild(this.gameScenes); } if(this.gameScenes && this.overScenes.parent) { GameConst.removeChild(this.overScenes); } this.currentStage.addChild(this.startGame); GameApp.xia.visible = true; } /**游戲場景 */ public onGameScenesHandler():void { if(this.startGame && this.startGame.parent) { GameConst.removeChild(this.startGame); } if(this.overScenes && this.overScenes.parent) { GameConst.removeChild(this.overScenes); } this.currentStage.addChild(this.gameScenes); GameApp.xia.visible = false; } /**游戲結(jié)束場景 */ public showGameOverSceneHandler():void{ if(this.startGame && this.startGame.parent){ GameConst.removeChild(this.startGame) } if(this.gameScenes && this.gameScenes.parent){ GameConst.removeChild(this.gameScenes) } this.currentStage.addChild(this.overScenes); GameApp.xia.visible = true; } public getGameOverDisplay():GameOverLayer { return this.overScenes; } }
場景切換貫穿游戲全局,封裝成類方便調(diào)用,以及后期擴(kuò)展只需要加上新場景類的實(shí)例,便可以切換自如。
自定義按鈕類
不難發(fā)現(xiàn)上面的開始游戲界面的按鈕是MyButton類型,在MyButton類的構(gòu)造函數(shù)中傳入背景圖和顯示文字,創(chuàng)建出一個按鈕。此類有一個設(shè)置點(diǎn)擊事件的方法,按鈕調(diào)用此公開方法傳入觸發(fā)事件即可設(shè)置點(diǎn)擊事件。
/**自定義按鈕類 */ class MyButton extends egret.Sprite { private _bg:egret.Bitmap; private title:egret.Bitmap; private onClick:Function; public constructor(bgName:string, titleName:string) { super(); this._bg = GameConst.createBitmapFromSheet(bgName, "ui"); this.addChild(this._bg); this.title = GameConst.createBitmapFromSheet(titleName, "ui"); this.title.x = (this._bg.width - this.title.width) >> 1; this.title.y = (this._bg.height - this.title.height) >> 1; this.addChild(this.title); } //設(shè)置點(diǎn)擊觸發(fā)事件 public setClick(func:Function):void { this.touchEnabled = true; this.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onClickEvent, this); this.onClick = func; } //點(diǎn)擊觸發(fā)的事件 private onClickEvent() { this.onClick(); } public setTitle(title:string):void { this.title = GameConst.CreateBitmapByName(title); } public get bg() { return this._bg; } public set bg(bg:egret.Bitmap) { this._bg = bg; } }
自定義特殊數(shù)字類
一般游戲中的分?jǐn)?shù)、時間等數(shù)字組成的UI為了美觀都會使用位圖文本,但是當(dāng)游戲邏輯跑起來需要不斷的刷新游戲的分?jǐn)?shù),每次改變分?jǐn)?shù)的時候都要從紋理集里面調(diào)用對應(yīng)位圖,在時間上是一個大大的浪費(fèi),所以創(chuàng)建一個特殊字符類SpecialNumber,讓這個類替我們實(shí)現(xiàn)轉(zhuǎn)換特殊字符。
具體代碼如下:
/**特殊字符數(shù)字類 */ class SpecialNumber extends egret.DisplayObjectContainer { public constructor() { super(); } public gap:number = 0; /**設(shè)置顯示的字符串 */ public setData(str:string):void { this.clear(); if(str == "" || str == null) { return; } //把所有數(shù)字每一個都存進(jìn)數(shù)組中 let chars:Array= str.split(""); let w:number = 0; //所有的長度 let length:number = chars.length; for(let i:number = 0; i < length; i++) { try { let image:egret.Bitmap = GameConst.createBitmapFromSheet(chars[i], "ui"); if(image) { image.x = w; w += image.width + this.gap; this.addChild(image); } } catch (error) { console.log(error); } } this.anchorOffsetX = this.width / 2; } public clear() { while(this.numChildren) { this.removeChildAt(0); } } }
在體驗(yàn)過游戲的時候會發(fā)現(xiàn)任務(wù)會根據(jù)不一樣的墻體高度擺不一樣的poss,這才poss全是來自于幀動畫紋理集,只需要把對應(yīng)一套的動畫解析出來人物就會跳起舞來。下面是人物狀態(tài)類。
狀態(tài)機(jī)類
人物共有五個狀態(tài),其中一個是默認(rèn)狀態(tài)state為跳舞狀態(tài)STAGE1,還有設(shè)置當(dāng)前狀態(tài)的方法setState
/**角色動作類 */ class Role extends egret.Sprite{ //狀態(tài) public static STATE1:number = 0; public static STATE2:number = 1; public static STATE3:number = 2; public static STATE4:number = 3; public static STATE5:number = 4; /**人物狀態(tài)集合 */ public static FRAMES:Array= [ ["0020003", "0020004", "0020005", "0020006","0020007"], ["0020008"], ["0020009", "0020010"], ["0020011", "0020012"], ["xue0001", "xue0002", "xue0003", "xue0004", "xue0005"] ] //身體 private Body:egret.Bitmap; private state:number; private currFrames:Array ; private currFramesIndex:number = 0; private runFlag:number; private isLoop:boolean; public constructor() { super(); this.Body = new egret.Bitmap; //人物初始狀態(tài) this.Body = GameConst.createBitmapFromSheet("Role.FRAMES[0][0]", "Sprites"); //設(shè)置錨點(diǎn) this.Body.anchorOffsetX = this.Body.width * 0.5; this.addChild(this.Body); } /**設(shè)置狀態(tài) */ public setState(state:number) :void { this.state = state; //死亡狀態(tài) if(this.state == Role.STATE5) { this.isLoop = false; this.Body.anchorOffsetY = this.Body.height * 0; }else{ this.isLoop = true; this.Body.anchorOffsetY = this.Body.height * 1; } if(this.state == Role.STATE3 || this.state == Role.STATE4){ this.currFrames = []; if(Math.random() > 0.5){ this.currFrames.push(Role.FRAMES[this.state][0]); }else{ this.currFrames.push(Role.FRAMES[this.state][3]); } }else{ this.currFrames = Role.FRAMES[this.state]; } this.currFramesIndex = 0; this.setBody(); } private setBody() { this.Body.texture = GameConst.getTextureFromSheet(this.currFrames[this.currFramesIndex], "Sprites"); this.Body.anchorOffsetX = this.Body.width * 0.5; if(this.state == Role.STATE5){ this.isLoop = false; this.Body.anchorOffsetY = this.Body.height * 0; }else{ this.isLoop = true; this.Body.anchorOffsetY = this.Body.height * 1; } } public run():boolean{ this.runFlag ++; if(this.runFlag > 4){ this.runFlag = 0; } if(this.runFlag != 0){ return; } var gotoFrameIndex:number = this.currFramesIndex + 1; if(gotoFrameIndex == this.currFrames.length){ if(this.isLoop){ gotoFrameIndex = 0; }else{ gotoFrameIndex = this.currFramesIndex; } } if(gotoFrameIndex != this.currFramesIndex){ this.currFramesIndex = gotoFrameIndex; this.setBody(); } return false; } public play():void{ egret.startTick(this.run,this); this.runFlag = 0; } public stop():void{ egret.stopTick(this.run,this); } }
游戲場景
一切工作準(zhǔn)備就緒,下面就是本文的重點(diǎn)-----游戲場景的搭建以及邏輯的實(shí)現(xiàn)。先看一下游戲內(nèi)的主要內(nèi)容
首先是藍(lán)色的游戲背景,和開始游戲界面背景如出一轍不用更換,在場景管理的時候注意背景保留一下繼續(xù)使用。
其次分?jǐn)?shù)、關(guān)卡、上背景圖等等這些只需要調(diào)用常量類的獲取紋理集圖片的方法調(diào)整位置即可實(shí)現(xiàn)。
最后重點(diǎn)介紹一下內(nèi)容:
墻體生成和運(yùn)動
人物運(yùn)動和狀態(tài)切換
分?jǐn)?shù)和關(guān)卡數(shù)改變并記錄最高分?jǐn)?shù)
下面是重要代碼片段
墻體生成和運(yùn)動
墻體分別包括上半部分和下半部分
/**上部分墻體容器 */ private topContianer:egret.Sprite; /**下部分墻體容器 */ private bottomContianer:egret.Sprite;
容器內(nèi)又包含了上下部分的墻體圖片,上下邊界線
/**上下墻體填充圖 */ private topSprite:egret.Sprite; private bottomSprite:egret.Sprite; /**上下邊界線 */ private topLine:egret.Shape; private bottomLine:egret.Shape;
把填充圖和邊界線加到容器內(nèi)(以上邊界為例)
this.topContianer = new egret.Sprite(); this.addChild(this.topContianer); this.topSprite = new egret.Sprite(); this.topContianer.addChild(this.topSprite); this.topContianer.addChild(this.topLine);
定義一個top和bottom范圍區(qū)間,隨機(jī)在舞臺范圍內(nèi)取值。
let min:number = 150; let flag:boolean = false; let len:number = 8; let w:number = GameConst.StageW / len; for(let i:number = 0; i < len; i++) { var h:number = min + Math.floor(Math.random() * 8) * 10; this.bottomRects.push(new egret.Rectangle(i * w, GameConst.StageH - h, w, h)); h = GameConst.StageH - h; if (Math.random() < 0.2 || (!flag && i == len - 1)) { var index:number = Math.floor(Math.random() * this.spaceArr.length); h -= this.spaceArr[index]; flag = true; } this.topRects.push(new egret.Rectangle(i * w, 0, w, h)); }
這是隨機(jī)取區(qū)域已經(jīng)完成,不過都是理想的區(qū)域,并沒有填充實(shí)際上的圖片,下面寫一個方法通過區(qū)域來填充背景墻。
private fullFront(bgSptite:egret.Sprite, rects:Array, isBottom:boolean = false):void { bgSptite.cacheAsBitmap = false; this.clearBg(bgSptite); var len:number = rects.length; for (var i:number = 0; i < len; i++) { var rec:egret.Rectangle = rects[i]; var bitmap:egret.Bitmap; if (this.bgBitmaps.length) { bitmap = this.bgBitmaps.pop(); } else { bitmap = new egret.Bitmap(); bitmap.texture = this.bg; } bitmap.scrollRect = rec; bitmap.x = rec.x; bitmap.y = rec.y; bgSptite.addChild(bitmap); } }
關(guān)鍵代碼bitmap.scrollRect = rec是把位圖按照區(qū)域進(jìn)行分割,顯示對象的滾動矩形范圍。顯示對象被裁切為矩形定義的大小,當(dāng)您更改 scrollRect 對象的 x 和 y 屬性時,它會在矩形內(nèi)滾動。
上下背景位圖填充完畢,下面可是畫上下邊界線,同樣是寫了一個方法(以上邊界為例),如下:
private drawLine():void { var lineH:number = 10; this.topLine.graphics.clear(); this.topLine.graphics.lineStyle(lineH, 0x33E7FE); this.bottomLine.graphics.clear(); this.bottomLine.graphics.lineStyle(lineH, 0x33E7FE); this.drawTopLine(lineH / 2); this.drawBottomLine(lineH / 2); this.topLine.graphics.endFill(); this.bottomLine.graphics.endFill(); } private drawTopLine(lineH:number):void { var len:number = this.topRects.length; for (var i:number = 0; i < len; i++) { var rec:egret.Rectangle = this.topRects[i]; if (i == 0) { this.topLine.graphics.moveTo(rec.x, rec.height); this.topLine.graphics.lineTo(rec.x + rec.width, rec.height); } else { this.topLine.graphics.lineTo(rec.x, rec.height); this.topLine.graphics.lineTo(rec.x + rec.width, rec.height); } } }
此時,背景填充完畢,但墻體還不能運(yùn)動。前面this.topContianer.y = -200;把上部分墻體的的縱軸設(shè)置在-200的位置,等到游戲開始執(zhí)行Tween動畫,使this.topContianer.y = 0,為了有更好的效果游戲開始延遲1.5s再調(diào)用墻體運(yùn)動,Tween動畫如下:
let self = this; setTimeout(function() { // self.shakeRun(); //上面的模塊往下運(yùn)動 egret.Tween.get(this.topContianer).to({"y":0}, 100).call(function():void { self.landOver(); }) }, 1500);
人物運(yùn)動和狀態(tài)切換
人物運(yùn)動:給舞臺添加點(diǎn)擊事件,判斷點(diǎn)擊位置并移動。
/**點(diǎn)擊事件 */ private onClick(e:egret.TouchEvent):void { let len:number = this.bottomRects.length; for(let i:number = 0; i < len; i++) { let rec:egret.Rectangle = this.bottomRects[i]; if(e.stageX > rec.x && e.stageX < rec.x + rec.width) { this.setRolePos(i); break; } } }
操作角色所在位置全部是根據(jù)上面定義的人物所在位置下標(biāo)rolePosIndex的相對位置來決定的。
private setRolePos(index:number, offY:number = 17, offX:number = 0, isInit:boolean = false):void { if (!isInit) { //人物每次移動一個格子 if (this.rolePosIndex > index) { index = this.rolePosIndex - 1; } else if (this.rolePosIndex < index) { index = this.rolePosIndex + 1; } } this.rolePosIndex = index; var rec:egret.Rectangle = this.bottomRects[index]; //一次只移動一格 this.role.x = rec.x + rec.width / 2 + offX; this.role.y = rec.y + offY; }
狀態(tài)切換:
墻體運(yùn)動完畢之后,通過人物所在位置下標(biāo)找到上半部分墻體和下半部分墻體對應(yīng)的位置的差值,并根據(jù)差值判斷人物是否存活,如果存活應(yīng)該表現(xiàn)出什么狀態(tài)。
獲取人物所在位置上下墻體的距離:
privategetSpace():number{ lettop:egret.Rectangle=this.topRects[this.rolePosIndex]; letbottom:egret.Rectangle=this.bottomRects[this.rolePosIndex]; returnGameConst.StageH-top.height-bottom.height; }
根據(jù)返回的距離差值判斷人物的狀態(tài):
privatecheckState() { letspace:number=this.getSpace(); if(space==0) { this.role.setState(Role.STATE5); } elseif(space==this.spaceArr[2]) { this.role.setState(Role.STATE4); } elseif(space==this.spaceArr[0]) { this.role.setState(Role.STATE3); } elseif(space==this.spaceArr[1]) { this.role.setState(Role.STATE2); } if(space==0) { this.setRolePos(this.rolePosIndex, -10, 4); } }
根據(jù)返回的距離判斷游戲狀態(tài),若返回值為0,游戲結(jié)束;不為0,進(jìn)入下一關(guān):
/**檢驗(yàn)這關(guān)結(jié)束主角是否存活 */ privatecheckResult() { letspace:number=this.getSpace(); letself=this; if(space==0) { this.dieNum++; if(this.dieNum==1) { this.role.stop(); setTimeout(function() { //游戲結(jié)束 GameControl.Instance.getGameOverDisplay().setGameOverDataHandler(self.score, self.curretMaxScore); GameControl.Instance.showGameOverSceneHandler(); }, 500); return; } } //進(jìn)入下一關(guān) else{ this.curretLevel++; this.score+=10; if(this.score>this.curretMaxScore) { this.curretMaxScore=this.score; } //刷新成績 this.refreshScore(); } setTimeout(function() { self.refurbish() }, 1000); }
分?jǐn)?shù)和關(guān)卡
接著上一步此時如果人物存活進(jìn)入下一關(guān),那么就要刷新游戲成績和關(guān)卡數(shù),并檢驗(yàn)此時是否為最高成績:
/**刷新成績數(shù)據(jù) */ privaterefreshScore() { this.LvNum.setData(this.curretLevel.toString()); this.recodeNum.setData(this.score.toString()); }
游戲進(jìn)入下一關(guān)卡:
/**刷新游戲關(guān)卡 */ privaterefreshPoint() { this.initData(); this.start(); }
游戲結(jié)算界面
游戲結(jié)算界面效果圖
和開始界面差不多,有所不同的是需要從游戲場景中傳入本局分?jǐn)?shù)和做高分?jǐn)?shù),在這個頁面寫一個公開的setGameOverDataHandler方法,游戲結(jié)束是調(diào)用此方法傳入數(shù)值。
/**游戲結(jié)束頁面分?jǐn)?shù)最高分?jǐn)?shù) */ publicsetGameOverDataHandler(score:number=0, maxScore:number=0):void{ this.scoreNum.setData(score.toString()); this.maxScore.setData(maxScore.toString()); }
擴(kuò)展
墻體晃動效果
游戲場景內(nèi)當(dāng)墻體要下落的時候墻體會晃動一下,晃動墻體不僅提醒玩家這個墻體即將下落,同時也增加了這個游戲的可玩性,下面是控制墻體晃動的Shake類。
/**墻體晃動 */ classShake{ privateinitY:number; privateshakeNum:number; privateoverFunc:Function; privateobj:egret.DisplayObject; privatenum:number; privateflag:number; ? publicrun(obj:egret.DisplayObject, shakeNum:number, overFunc:Function=null) { this.obj=obj; this.initY=obj.y; this.shakeNum=shakeNum; this.overFunc=overFunc; egret.startTick(this.loop, this); this.num=0; this.flag=0; } privateloop():boolean{ if(this.flag==0) { if(this.obj.y<=this.initY) { this.obj.y+=5; } else{ this.obj.y-=5; } if(this.obj.y==this.initY) { this.num++; if(this.num==this.shakeNum) { egret.stopTick(this.loop, this); if(this.overFunc) { this.overFunc(); } } } } this.flag++; if(this.flag==2) { this.flag=0; } returnfalse; } }
小結(jié)
本文通過對一個簡單小游戲進(jìn)行模塊化的分析,并介紹了模塊化的好處,降低這些模塊之間的耦合度,后期如果要加新功能對舊的代碼無需進(jìn)行大的修改。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/98106.html
摘要:今天我們分享的菜鳥文檔將介紹微信小游戲好友排行榜的制作過程,包括創(chuàng)建項(xiàng)目并發(fā)布微信開發(fā)者平臺添加小游戲打開開放域功能主域和開放域通訊,以及與原生的布局。 寫在前面:隨著越來越多的新人開始接觸白鷺引擎,創(chuàng)作屬于自己的游戲。考慮到初學(xué)者會遇到一些實(shí)際操作問題,我們近期整理推出菜鳥系列技術(shù)文檔,以便更好的讓這些開發(fā)者們快速上手,Egret大神們可以自動忽略此類內(nèi)容。 今天我們分享的菜鳥文檔將...
摘要:對的要求基本沒有,都能繪制出來,但是動畫制作方式存在不同,可能某些幀不能完全繪制出來。目前對是有要求的本身必須是個多幀,如果只作為容器嵌套其他子項(xiàng)的做法將不會被繪制。點(diǎn)擊播放按鈕可以預(yù)覽動畫,默認(rèn)幀率為。 Texture Merger 可將零散紋理拼合為整圖,同時也可以解析SWF、GIF動畫,制作Egret位圖文本,導(dǎo)出可供Egret使用的配置文件,其紋理集制作功能在小游戲開發(fā)中可以起...
摘要:為避免加載資源時游戲黑屏,導(dǎo)致玩家誤認(rèn)為游戲非正常運(yùn)行,界面起到至關(guān)重要的作用。今天就為大家?guī)碛弥谱黜撁婕胺植郊虞d資源的教程。在中測試分步加載資源,原有的頁面上加上一個按鈕,添加加載資源事件。 我們都知道,當(dāng)游戲越做越大,資源越來越多的時候,加載資源會造成大量時間的浪費(fèi)。為避免加載資源時游戲黑屏,導(dǎo)致玩家誤認(rèn)為游戲非正常運(yùn)行,Loading界面起到至關(guān)重要的作用。今天就為大家?guī)碛肊...
閱讀 2312·2021-11-17 09:33
閱讀 843·2021-10-13 09:40
閱讀 573·2019-08-30 15:54
閱讀 778·2019-08-29 15:38
閱讀 2417·2019-08-28 18:15
閱讀 2475·2019-08-26 13:38
閱讀 1841·2019-08-26 13:36
閱讀 2129·2019-08-26 11:36