Html5 Egret游戏开发 成语大挑战(四)选关界面

通过前面的开始界面基本上了解了eui的使用方法,可以简单快速的制作一个UI界面,本篇使用第二界面选关界面展示更为难一点的代码控制,来展现关卡地图的内容,请确保素材和资源完整,可以在前面的教程中找到下载。

选关界面和开始界面不太一样,请参考开篇的结构图,需要一个推进式上下拉动的地图界面,创建基本的exml和开始界面是一样的,这里的名字叫“SceneLevelsSkin”,在组件库中把Scroller组件拖进去并给其下属内容命名group_levels,用来承载地图内容,最后加一个返回按钮。

<?xml version=‘1.0‘ encoding=‘utf-8‘?>
<e:Skin class="SceneLevelsSkin" width="720" height="1136" xmlns:e="http://ns.egret.com/eui" xmlns:w="http://ns.egret.com/wing" >
    <e:Scroller top="0" bottom="0" right="0" left="0">
        <e:Group id="group_levels"/>
    </e:Scroller>
    <e:Button id="btn_back" x="607" y="1047">
        <e:skinName>
            <e:Skin states="up,down,disabled">
                <e:Image width="100%" height="100%" source="BackBtn_png" source.down="BackBtn1_png"/>
                <e:Label id="labelDisplay" horizontalCenter="0" verticalCenter="0"/>
            </e:Skin>
        </e:skinName>
    </e:Button>
</e:Skin>

下面准备制作关卡图标,关卡图标对应的有主要的两种状态:开启和未开启,正好可以使用Button组件来实现,通过控制enabled实现开启和未开启状态对应,按照之前的做法拖拽的创建一个按钮,然后输入数字就可以当成关卡按钮了,可是问题来了,本游戏中有400多关,一个一个摆放累死不偿命的,所以,有几种做法是:分页、分组、用代码生成,分页的方式不能实现地图的拖拽效果,所以本项目中,我们用代码控制去管理创建按钮。

为了更快的控制和更好的理解教程,在这里,使用自定义的button皮肤来实现LevelIcon的效果,先创建一个基于eui.Button组件的LevelIconSkin皮肤,大小设置为77x77,

然后为各种状态添加图片和显示设置,在所有状态中增加一个Label用来显示关卡的数字,具体拖拽细节不再啰嗦,效果如下:

<?xml version=‘1.0‘ encoding=‘utf-8‘?>
<e:Skin class="LevelIconSkin" states="up,down,disabled" width="77" height="77"
        xmlns:e="http://ns.egret.com/eui" xmlns:w="http://ns.egret.com/wing">
    <e:Image source="gs_select_1_png" horizontalCenter="0" verticalCenter="0" includeIn="up,down"/>
    <e:Image source="gs_select_dis_png" includeIn="disabled" horizontalCenter="0" verticalCenter="0"/>
    <e:Label id="lb_level" text="100" horizontalCenter="0" verticalCenter="0"/>
</e:Skin>

保存一下,然后可以在界面中拖进去一个button组件,直接在皮肤中选择就可以看到显示效果了,

 

为了控制和便于操作,增加一个LevelIcon.ts  ,这里使用了get和set创建了一个属性来标记关卡数字

class LevelIcon extends eui.Button{
    private lb_level:eui.Label;
    public constructor() {
          super();
          this.skinName = "src/Game/LevelIconSkin.exml";
    }
    public get Level():number{
        return parseInt(this.lb_level.text);
    }
    public set Level(value:number){
        this.lb_level.text = value.toString();
    }
}

下面就是SceneLevels.ts的代码,会用上前面的SceneLevelsSkin.exml,请确保已经准备完成了SceneLevelsSkin.exml和LevelIcon:

class SceneLevels extends eui.Component {
    private btn_back: eui.Button;
    private group_levels:eui.Group;
    public constructor() {
        super();
        this.skinName = "src/Game/SceneLevelsSkin.exml";
        this.btn_back.addEventListener(egret.TouchEvent.TOUCH_TAP,this.onclick_back,this);
        //创建地图选项
        var row = 20;
        var col = 10;
        var spanx = 720 / col;      //计算行x间隔
        var spany = 1136 / row;     //计算列y间隔
        var group = new eui.Group();//地图背景
        group.width = 720;
        group.height = (spany * 400 );//算出最大尺寸
        //填充背景
        for(var i = 0;i <= (group.height / 1138) ;i++) {
            var img = new eui.Image();
            img.source = RES.getRes("GameBG2_jpg");
            img.y = i * 1138;
            img.touchEnabled = false;
            this.group_levels.addChildAt(img,0);
        }
        //以正弦曲线绘制关卡图标的路径
        for(var i = 0; i<400;i++){
            var icon = new LevelIcon();
            icon.Level = i + 1;
            icon.y = spany * i /2;
            icon.x = Math.sin(icon.y / 180 * Math.PI) * 200 + group.width / 2;
            icon.y += spany * i /2;
            icon.y = group.height - icon.y - spany;
            group.addChild(icon);
            icon.addEventListener(egret.TouchEvent.TOUCH_TAP,this.onclick_level,this);
        }
        //开启位图缓存模式
        group.cacheAsBitmap = true;
        this.group_levels.addChild(group);
        //卷动到最底层
        this.group_levels.scrollV = group.height - 1100;
    }
    private onclick_back() {

    }
    private onclick_level(e:egret.TouchEvent){
        var icon = <LevelIcon>e.currentTarget;
        console.log(icon.Level);
    }
}

为了看起来好看,上面代码中没有使用简单的代码排列关卡,而是使用了正弦曲线描绘,当然细节上仍需要调整,要知道另外一个《疯狂猜歌名》的关卡按钮可是一个一个摆放的,200多关呢。现在所有的按钮都是开启状态,点击一下输出里看到点到的按钮数字,上下可以拖动,已经达到了我们的目的

但是,细节上仍然可以再处理一下,当我们点击那个按钮时候,就会有个指示来标记当前的选定,在正式游戏中,都是 选定=>进入 这样的体验流程,所以,增加一个arrow,这里正好当初的素材中多了一个本来用来做关卡翻页效果的废弃资源,直接用它来做素材,声明类里一个对象:

private img_arrow:eui.Image;

在构造方法里增加:

//跟踪箭头
this.img_arrow = new eui.Image();
this.img_arrow.source = RES.getRes("PageDownBtn_png");
this.img_arrow.anchorOffsetX = 124 / 2 - group.getChildAt(0).width / 2;
this.img_arrow.anchorOffsetY = 76;
this.img_arrow.touchEnabled = false;
this.img_arrow.x = group.getChildAt(0).x;
this.img_arrow.y = group.getChildAt(0).y;
group.addChild(this.img_arrow);

在onclick_level方法里增加:

private onclick_level(e:egret.TouchEvent){
    var icon = <LevelIcon>e.currentTarget;
    console.log(icon.Level);
    this.img_arrow.x = icon.x;
    this.img_arrow.y = icon.y;
}

最后看看效果怎么样?打开Main.ts,在修改startCreateScene方法,然后运行看看吧。

/**
 * 创建场景界面
 * Create scene interface
 */
protected startCreateScene(): void {
    this.addChild(new SceneLevels());
}

本篇中使用了eui创建自定义按钮组件,卷动视图的应用,并通过代码方式来控制界面元素。

本篇项目源代码:源代码下载 (由于资源过大,没有resource文件夹,请参考之前的文章单独下载素材

时间: 2024-08-01 14:11:54

Html5 Egret游戏开发 成语大挑战(四)选关界面的相关文章

Html5 Egret游戏开发 成语大挑战(一)开篇

最近接触了Egret白鹭引擎,感觉非常好用,提供了各种各样的开发工具让开发者和设计者更加便捷,并且基于typescript语言开发省去了很多学习成本,对于我们这种掉微软坑许久的童鞋来说,确实很有吸引力,在开发中最浪费时间就是设计和调试的阶段,js的语言过于自由,自由到有时候写错了都不知道,但typescript可以使用开发IDE帮助排错和调试,不得不说确实很有效率,在这之前,我在egret论坛里发了几个小游戏做练手,最近的一个<疯狂猜歌名>在素材齐备的情况下,仅用了不到1天的时间完成了开发,以

Html5 Egret游戏开发 成语大挑战(二)干净的eui项目和资源准备

现在我们使用egret来起步开发一个名叫<成语大挑战>的小游戏,关于egret的开发环境就不在这里啰嗦了,直接去官方下载安装就可,egret是我见过开发环境部署最简单的解决方案,这个系列教程中,使用了egret的Wing和ResDepot,只需要安装这两个就行,首先打开EgretWing,选择创建项目,输入你想要的项目名称,项目类型为“Egret EUI项目”,然后下一步: 由于游戏设计的是竖屏,而素材的分辨率为720x1136,所以设置是如上的选择,然后选择完成,稍等就会构建一个模板项目出来

Html5 Egret游戏开发 成语大挑战(八)一般性二级页面处理

在游戏中,我们一般会有各种各样的二级页面,比如游戏暂停界面或者游戏结束界面,这些界面组成了对玩家交互主要手段,在游戏开发中,对于这些界面的coding组织是非常有学问的,如果倒退到十年前,游戏开发的老前辈们一定孜孜不倦的上课如何设计好“易读”“可维护”“逻辑清晰”的界面代码,本人曾深陷其中变得对代码抠抠索索,结果事倍功半,原因是什么?老前辈们的一个项目或一段代码可能是长期维护长期使用的,而现在的高速code和超短的产品生命周期,使得完全不用规划那么好的交互代码,有时候可能过几个月自己的代码都不认

Html5 Egret游戏开发 成语大挑战(九)设置界面和声音管理

在上一篇中,简单的使用界面元素快速实现了一个游戏中的二级页面,这种直接在游戏页面上做UI的做法并不太好,原因是,UI会让游戏的压力变大,即使它是隐蔽的,如果同样的功能在其它的地方也是一样的,那么就要写多个同样的逻辑吗?例如设置界面,游戏中的设置界面基本上功能都是一样,如果每个UI中都做一遍,是多么愚蠢的办法?在UI的代码设计中,一般来说,单独的功能不会在其它的地方用到,如GameOver,就直接写在UI里,而如果是通用功能,则最好的做法是做一个通用的单例类或者工厂类在需要的时候将它们初始化,在多

Html5 Egret游戏开发 成语大挑战(三)开始界面

本篇需要在前面的素材准备完毕,才可以开始,使用egret的eui结合代码编辑,快速完成基本的界面搭建,这里写的可能比较细,目的是减少大家对于其中一些操作疑问,我去掉了很多无用的步骤,以最精简的流程来完成,如果比较熟练的话,这些操作只需要不到15分钟就完全可以搞定. 特别说明:如果已经对EUI 有基础了解的童鞋,可以直接跳过这篇,因为实在是太简单了. 创建一个exml的皮肤,这里特别说一下,到现在仍然对于项目中的“包”和“目录”有什么具体区别仍然还是不是很清晰,反正对我来说就是一个目录,习惯性的会

Html5 Egret游戏开发 成语大挑战(七)游戏逻辑和数据处理

本篇在前面的基础上,将进行逻辑的编码开发让游戏能够正式的玩起来,这里没有注重太多的体验细节,而是直接实现游戏的规则逻辑,将分成两个部分说明:数据处理和游戏逻辑. 初始化游戏数据 在前面的第五篇中,我们通过数据的构建已经读取了所有的关卡数据在关卡选择界面中,LevelDataManager负责管理所有的关卡数据,在SceneLevels类中,当onclick_level触发时,就会切换到Game界面中,所以改造代码如下: private onclick_level(e:egret.TouchEve

Unity3D游戏开发从零单排(四) - 制作一个iOS游戏

提要 此篇是一个国外教程的翻译,虽然有点老,但是适合新手入门.自己去写代码,debug,布置场景,可以收获到很多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一篇中,我们学会了怎么在Unity中搭建游戏的场景,并且设置模型的物理属性. 在第二篇中,我们学会了怎么在unity中使用脚本,并且创建了大部分的游戏逻辑,包括投球和得分! 在这最后一节中,我们将会为用户创建一个菜单系统,并且和GameController进行交互,我们开始吧. 在设备上测试 到目前为止,

HTML5物理游戏开发 - 越野山地自行车(三)粉碎自行车

自上一章发布到现在已时隔四月,实在对不住大家,让大家久等了~话说不是我不关注我的博客,而是事情一多起来写博客的时间就少了.待到今日有空了,回头看了看自己以前写的文章,猛得发现已经四个月不曾写文章了,便只得叫声:"苦也~",我害怕本系列文章会拖得更久,于是立刻提笔,也好为本系列文章留个凤尾. 首先,大家来温习一下前面两篇里的内容吧: HTML5物理游戏开发 - 越野山地自行车(二)创建一辆可操控的自行车 http://blog.csdn.net/yorhomwang/article/de

Html5 移动游戏开发

有很多游戏采用H5技术开发,比如三国来了.巴哈姆特之怒.切绳子等.我们公司也有多款游戏用H5开发,H5开发成本低,效率高,方便做自动更新,可移植性好.受益于H5技术,我们公司的很多产品都很方便跨平台. 早在2012年,我就很荣幸负责技术攻关,把我们的游戏移植到win8和wp8平台,当时在国内的win8和wp8平台是领先的.我们的一款游戏,跨ios.android.win8.wp8和黑莓10五大移动平台,这在国内肯定是唯一的吧? <Infinity Lands>喜获黑莓优秀大奖 也得益于在win