第一次做h5游戏。使用egret wing2.5引擎,语言是typeScript。
如有问题。欢迎来邮:[email protected]
从头开始跟完一个项目花费了大半年的时间。从自己做的功能一点点说起。
1.新手引导,新手引导时对层级的一个控制,添加新的层级,新手引导层放在最上面。在这个层级上显示新手引导每一步的内容,同时能够保证点点击能够往下传递穿透本层。即设置本层的touchThrough,但是又要保证其他地方不能被点击穿透。解决方案一:在皮肤上创建一个点击的框框,根据这个框框在创建四块区域,其他四块区域不可点击,本层可以穿透即实现了这个效果。对于整理的流程需要一个计时器来控制,通过一些变量的状态控制每一步的流程。
2.半兽人界面,在做这个界面的时候自己写了halfAnimalSevice.ts 的一个管理类,其实这个可以写个halfAnimalManager.ts的,因为不同界面的数据要用到用一组数据,因此缓存至本地是非常重要的,这个界面是开始做的第一个ts界面,这个界面有三个控件支持不同的跳转,基本上都是scroller,item的创建,还有就是半兽人的界面显示问题,分页显示,左右滑动的效果,不同界面数据的处理,前后端交互界面刷新问题,这些当然是孰能生巧了。
3.聊天按钮的移动,主要还是在mouseDown,mouseUp里面做的判断。
this.chatBtn.addEventListener(egret.TouchEvent.TOUCH_BEGIN,this.mouseDown,this);
this.chatBtn.addEventListener(egret.TouchEvent.TOUCH_END,this.mouseUp,this);
private mouseDown(e:egret.TouchEvent):void{
this._touchStatus = true;
this.startPos = new egret.Point(this.chatBtn.x, this.chatBtn.y);
this._distance.x = e.stageX - this.chatBtn.x;
this._distance.y = e.stageY - this.chatBtn.y;
this.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE,this.mouseMove,this);
}
private mouseUp(e:egret.TouchEvent):void{
this._touchStatus = false;
if(this.chatBtn.x <= this.stage.stageWidth/2){
this.chatBtn.x = 0;
}else{
this.chatBtn.x = this.stage.stageWidth - this.chatBtn.width;
}
if(Math.abs(this.chatBtn.x - this.startPos.x) <=1 && Math.abs(this.chatBtn.y - this.startPos.y) <= 1){
//如果移动距离非常小,为点击,跳转到对话界面
Message.instance.send(MsgCMD.MODULE_SHOW,WindowName.CHAT_MAIN)
}
this.stage.removeEventListener(egret.TouchEvent.TOUCH_MOVE,this.mouseMove,this);
}
private mouseMove(e:egret.TouchEvent):void{
if(this._touchStatus){
this.chatBtn.x = e.stageX - this._distance.x;
this.chatBtn.y = e.stageY - this._distance.y;
if(this.chatBtn.y <= 200){
this.chatBtn.y = 200;
if(this.chatBtn.x <= this.stage.stageWidth / 2) {
this.chatBtn.x = 0;
} else {
this.chatBtn.x = this.stage.stageWidth - this.chatBtn.width;
}
}
if(this.chatBtn.y > this.stage.stageHeight - 200){
this.chatBtn.y = this.stage.stageHeight - 200;
if(this.chatBtn.x <= this.stage.stageWidth / 2) {
this.chatBtn.x = 0;
} else {
this.chatBtn.x = this.stage.stageWidth - this.chatBtn.width;
}
}
if(this.chatBtn.x < 0){
this.chatBtn.x = 0;
}
if(this.chatBtn.x > this.stage.stageWidth - this.chatBtn.width){
this.chatBtn.x = this.stage.stageWidth - this.chatBtn.width;
}
}
}
4.副本界面。界面的复用。设计模式也就是ts文件,皮肤都是一个。通过不同的变量类型控制从而达到不同道具副本的显示不同的boss,奖励。
5.寻宝界面。运用tween动画实现动画的效果。背景没有移动。使用定时器来显示控制精力恢复的时间显示
/**
* 播放寻宝动画
*/
private playAimation():void{
egret.Tween.get(this.mTree).to({ x: 16,y: 411,width: 112,height: 142 },2150);
egret.Tween.get(this.mBone).to({ x: 380,y: 364,width: 185,height: 92 },2150);
egret.Tween.get(this.mCloud1).to({ x: 290,y: 134,width: 104,height: 63 },2150);
egret.Tween.get(this.mCloud2).to({ x: -62,y: 110,width: 142,height: 102 },2150).call(this.callBack,this);
// egret.Tween.get(this.mMap).to({ width: 1144,height: 1058 },2150).call(this.callBack,this);
if (this.treasureRole)
this.treasureRole.changAction(EnumManager.ACTION_TYPE.ACTION_RUN,EnumManager.DIRECTION_ENUM.DIR_UP);
}
private callBack():void{
// this.mMap.width = 572;
// this.mMap.height = 529;
egret.Tween.get(this.mResult).to({ width: 120,height: 80, visible:true },80).wait(600).to({visible:false},100).call(this.callBack2,this).wait(500);
if(this.IsOneKey){
this.IsOneKey = !this.IsOneKey;
Message.instance.send(Code.ADVENTURE_ONE_KEY_C,HawkProtocolManager.emptyProtocol(),true);
}else{
Message.instance.send(Code.ADVENTURE_START_C,HawkProtocolManager.emptyProtocol(),true);
}
}
this.timer = new egret.Timer(1000);
this.timer.addEventListener(egret.TimerEvent.TIMER,this.upDate,this);
this.timer.start();
/**
* 每一帧都检查
*/
private upDate(e:egret.TimerEvent):void{
if(this.AdventureInfo != null && this.AdventureInfo.getNextRecoverTime() > 0){
this.refreshRecoverTime();
}
}
/**
* 时间
*/
private refreshRecoverTime():void{
//当前精力
this.mEnergyNum.text=this.AdventureInfo.getCurEnergy()+ "/20";
//恢复一点精力的时间倒计时,下次精力+1恢复的时间
var timeCount = this.AdventureInfo.getNextRecoverTime();//下次恢复精力的时间为 s
var currentTime = PlayerService.instance.sysTime/1000;//当前时间 s
timeCount = timeCount - currentTime;
var min = Math.floor(timeCount /60);
var sec = Math.floor(timeCount - min* 60);
if(sec == 60){
sec = 0;
}
this.mTime.text = min.toString() + "分" + sec.toString() + "秒";
}
5.套装界面。主要就是显示问题了。这个就是读取配置表然后显示。
6.boss界面。组队boss 和 行会Boss都是我做的。组队boss界面比较复杂。加上调试做了很久,大概20天全部调通。行会boss界面也还可以。主要还是动画的缓存,删除这些地方需要注意,还有就是界面显示,限制条件的添加比较麻烦。没有什么难度。关键还是在于前后端的调试,配合!!
7.勇气商店,商城界面,功勋商店。
8.每日必做:界面跳转。每个Item都是单独做的界面跳转,分了好多情况。
9.100级之前的提示按钮。自动挑战boss按钮。没有前后端协议,全部是前端变量的控制。
10.副本关卡。这个做的比较早。主要还是Item的复用问题困扰了好久。千万要注意对。item数组的refresh操作,和removeAll操作。
11.奖励界面。节日礼包:本界面主要是对时间的控制。只有节日当天才可以领取。已经领取过的和已经超过领取日期的全部不显示,前后端的数据,协议的制作麻烦,调了好多遍。等级礼包:没有难度。item的创建领取。累计登陆:一般吧。
12.幻境PK,蛋疼。现在改成只有VIP10才能进入去打。
13.熔炼,批量熔炼。数据格式的及时显示。数据刷新及时问题!
14.邮件。全部删除和一键领取。对数组的操作。千万注意遍历时的删除顺序。
15.神兵界面。这个做的时候很顺利,没有卡在什么地方。
16.翅膀界面。这个也很顺利。
17.装备提升。装备格子的操作,这个是优化。改变掉装备的宝石镶嵌和强化 与装备的关系。改为与装备格子的关系。简化玩家的操作,更换装备不用再重新强化新装备 的清华和宝石的重新镶嵌,只有有装备的时候才能生效格子的强化和宝石效果!
一键强化和一键卸载。
18.次日登陆领好礼。对时间的处理。千万注意获取的时间是1970年1月1日早上8点的时间。如果操作天数。一定要注意+8小时的操作!!
19.魂珠界面。很简单。label比较多!!
20.关于动画,tween动画,代码中没有使用dragonBones,对于有些特效的制作,比如金币的闪光,Boss来袭,都是用的tween动画,比较复杂,还有用到特效ease,官网上有很多的列子可以学习。主角,怪物,的动作都有八个方向,资源是做了四个方向,使用的是MovieClip序列帧动画,http://edn.egret.com/cn/docs/page/596,有相关的拓展工具TextureMerger,可以直接生成资源,在代码里直接使用。其实有些特效的制作,因为使用tween动画实现太复杂,项目时间紧,没有学习使用dragonbones动画,如果使用dragonBones效果会好很多。
21.数据交互请求使用的Http请求,webSocket,和普通的Socket,根据浏览时是否支持webSocket进行选择,代码中封装了Message.ts。基本山都是调用这个协议,本地协议也是这样使用。协议使用的是protoBuf,较为常见的协议格式。
22.资源加载也比较方便,使用相关的ResDEepot,可视化资源管理,方便简单易用,还可以检查资源的路径重复性。
23.后期优化,各种图片压缩,代码合成大文件,皮肤合成大文件,协议合成大文件,小图整合成大图。图片先缩小再放大,尽量让每一张大图的尺寸控制在512*512,图片尺寸的调整,尽量控制在2的幂进行处理。
24.SDK的接入。至少三层的地址处理。没有接触去做。。