Egret初体验–躲避类小游戏
下面简单介绍一下我这个游戏:
基本上就3个画面(准备再添加一个胜利的界面)
开始画面,一个按钮,点击进入游戏
游戏画面,滚动的背景,触摸移动的老鹰,从天而降的翔,以及右上角的时间条
结束画面,显示结果,关注按钮和重玩一次按钮
游戏主文件:GameContainer.ts(游戏逻辑)
4个类文件:GameUtil.ts(功能集合),BgMap.ts(背景滚动),Shit.ts(翔的创建和回收),ScorePanel.ts(结果展示)
/**GameUtil.ts*/ /**基于圆心的碰撞检测*/ public static hitTestP(obj1:egret.DisplayObject,obj2:egret.DisplayObject):boolean { var rect2x:number; var rect2y:number; rect2x = obj2.x + obj2.width/2; rect2y = obj2.y + obj2.height/2; return obj1.hitTestPoint(rect2x, rect2y); } /**根据name关键字创建一个Bitmap对象。name属性请参考resources/resource.json配置文件的内容。*/ export function createBitmapByName(name:string):egret.Bitmap { var result:egret.Bitmap = new egret.Bitmap(); var texture:egret.Texture = RES.getRes(name); result.texture = texture; return result; }
/**BgMap.ts*/ /**可滚动的背景*/ export class BgMap extends egret.DisplayObjectContainer { /**图片引用*/ private bmpArr:egret.Bitmap[]; /**图片数量*/ private rowCount:number; /**stage宽*/ private stageW:number; /**stage高*/ private stageH:number; /**纹理本身的高度*/ private textureHeight:number; /**控制滚动速度*/ private speed:number = 4; public constructor() { super(); this.addEventListener(egret.Event.ADDED_TO_STAGE,this.onAddToStage,this); } /**初始化*/ private onAddToStage(event:egret.Event){ this.removeEventListener(egret.Event.ADDED_TO_STAGE,this.onAddToStage,this); this.stageW = this.stage.stageWidth; this.stageH = this.stage.stageHeight; var texture:egret.Texture = RES.getRes("bgImage"); this.textureHeight = texture.textureHeight;//保留原始纹理的高度,用于后续的计算 this.rowCount = Math.ceil(this.stageH/this.textureHeight)+1;//计算在当前屏幕中,需要的图片数量 this.bmpArr = []; //创建这些图片,并设置y坐标,让它们连接起来 for(var i:number=0;i<this.rowCount;i++) { var bgBmp:egret.Bitmap = AvoidShit.createBitmapByName("bgImage"); bgBmp.y = this.textureHeight*i-(this.textureHeight*this.rowCount-this.stageH); this.bmpArr.push(bgBmp); this.addChild(bgBmp); } } /**开始滚动*/ public start():void { this.removeEventListener(egret.Event.ENTER_FRAME,this.enterFrameHandler,this); this.addEventListener(egret.Event.ENTER_FRAME,this.enterFrameHandler,this); } /**逐帧运动*/ private enterFrameHandler(event:egret.Event):void { for(var i:number=0;i<this.rowCount;i++) { var bgBmp:egret.Bitmap = this.bmpArr[i]; bgBmp.y+=this.speed; //判断超出屏幕后,回到队首,这样来实现循环反复 if(bgBmp.y > this.stageH) { bgBmp.y = this.bmpArr[0].y-this.textureHeight; this.bmpArr.pop(); this.bmpArr.unshift(bgBmp); } } } /**暂停滚动*/ public pause():void { this.removeEventListener(egret.Event.ENTER_FRAME,this.enterFrameHandler,this); } }
/**Shit.ts*/ /**大便,利用对象池*/ export class Shit extends egret.Bitmap { private static cacheDict:Object = {}; /**生产*/ public static produce(textureName:string):AvoidShit.Shit { if(AvoidShit.Shit.cacheDict[textureName]==null) AvoidShit.Shit.cacheDict[textureName] = []; var dict:AvoidShit.Shit[] = AvoidShit.Shit.cacheDict[textureName]; var shit:AvoidShit.Shit; if(dict.length>0) { shit = dict.pop(); } else { shit = new AvoidShit.Shit(RES.getRes(textureName)); } shit.textureName = textureName; return shit; } /**回收*/ public static reclaim(shit:AvoidShit.Shit,textureName:string):void { if(AvoidShit.Shit.cacheDict[textureName]==null) AvoidShit.Shit.cacheDict[textureName] = []; var dict:AvoidShit.Shit[] = AvoidShit.Shit.cacheDict[textureName]; if(dict.indexOf(shit)==-1) dict.push(shit); } public textureName:string; public constructor(texture:egret.Texture) { super(texture); } }
/**ScorePanel.ts*/ /**成绩显示*/ export class ScorePanel extends egret.Sprite { private txt:egret.TextField; public constructor() { super(); var g:egret.Graphics = this.graphics; g.drawRect(0,0,100,100); g.endFill(); this.txt = new egret.TextField(); this.txt.width = 100; this.txt.height = 100; this.txt.textAlign = "center"; this.txt.textColor = 0x00dddd; this.txt.size = 24; this.txt.y = 60; this.addChild(this.txt); this.touchChildren = false; this.touchEnabled = false; } public showScore(value:number):void { var msg:string = value+""; this.txt.text = msg; } }
上面4个源码基本是基于官方的Demo而来,下面是游戏逻辑的代码:(这个代码太长就只贴主要部分)
游戏初始画面就是把标题,按钮都堆积在上面,比较简单,给按钮增加一个点击事件的监听就行了
this.icon.addEventListener(egret.TouchEvent.TOUCH_TAP, this.gameStart, this);
游戏进行界面,主要有三点:时间轴,翔,碰撞检测(GameUtil做了,直接用就行)
时间轴有三部分:背景框,中间的轴,遮罩层。
/**背景框*/ this.timelinebg = AvoidShit.createBitmapByName("tlbgImage"); this.timelinebg.x = this.stageW - this.timelinebg.width - 10; this.timelinebg.y = 10; this.addChild(this.timelinebg); /**中间的轴*/ this.timeline = AvoidShit.createBitmapByName("tlImage"); this.timeline.x = this.stageW - this.timeline.width - 13; this.timeline.y = 14; this.addChild(this.timeline); /**遮罩层*/ this.timelinemask = new egret.Rectangle(0, 0, this.timeline.width, this.timeline.height); this.timeline.mask = this.timelinemask; /*计时器增加遮罩层刷新的方法*/ this.gameTimer = new egret.Timer(this.timeDelay,this.timeCount); this.gameTimer.addEventListener(egret.TimerEvent.TIMER, this.timelineDown, this);
/**遮罩层移动*/ private timelineDown(evt:egret.TimerEvent):void { this.timelinemask.y += this.timeline.height/20; }
翔的产生和销毁都是调用Shit.ts中的方法
/**创建大便*/ private createShit(evt:egret.TimerEvent):void{ var shit:AvoidShit.Shit = AvoidShit.Shit.produce("shitImage"); shit.x = Math.random()*(this.stageW-shit.width); shit.y = -shit.height-Math.random()*300; this.addChildAt(shit,this.numChildren-1); this.shits.push(shit); }
//大便运动 var theShit:AvoidShit.Shit; var enemyFighterCount:number = this.shits.length; for(i=0;i<enemyFighterCount;i++) { theShit = this.shits[i]; theShit.y += this.downTimes * speedOffset; if(theShit.y>this.stageH) delArr.push(theShit); } for(i=0;i<delArr.length;i++) { theShit = delArr[i]; this.removeChild(theShit); AvoidShit.Shit.reclaim(theShit,"shitImage"); this.shits.splice(this.shits.indexOf(theShit),1); }
游戏结束有两个条件,一是时间到了,二是碰到翔
结束画面就是展示成绩和提供两个按钮
最主要的应该是微信分享功能:
需要用到两个文件libs/WeixinAPI.d.ts和launcher/WeixinAPI.js
并在html页面中增加调用
private doShare(n:number,m:number) { WeixinApi.ready(function(api:WeixinApi) { var info:WeixinShareInfo = new WeixinShareInfo(); info.title = "我本卖萌鸟,何处惹尘埃?"; if (m == 0) { info.desc = "我本卖萌鸟,何处惹尘埃?"; } else { info.desc = "我本卖萌鸟,何处惹尘埃?屎开,屎开~~我躲过了" + n + "坨大便,你行吗?"; } info.link = "http://games.11wj.com/fly/launcher/release.html"; info.imgUrl = "http://games.11wj.com/fly/resource/assets/icon.png"; api.shareToFriend(info); api.shareToTimeline(info); }) }