Egret社区

游戏--场景切换

2015-7-21 12:35
55335268
本帖最后由 xsstomy 于 2016-8-31 12:10 编辑

帖子不维护了,如果出问题了,需要自行处理,引擎版本使用的版本是2.0.5 最后感谢大家的支持。
1.
询问问题,请您说明具体情况,您需要实现什么样子的功能,遇到什么样子的困难,具体代码问题,请您贴具体代码。
2.如果您有任何吐槽或者建议,欢迎发帖跟我联系。

经常在群里看到有人说,如何切换场景,这里我就发一个帖子发布一下自己的经验,欢迎各位来讨论和吐槽。
egret引擎当中,有两个常用的显示容器SpriteDisplayObjectContainer(这里没有包括gui体系)。这里随大家喜好,我个人一般使用Sprite,这里我只是拿小游戏示例示范,讲一下简单的使用过程,复杂的这里不做陈述,欢迎留言讨论。
在一般的小游戏当中,一般分为三个界面,游戏开始界面,游戏界面,游戏结束界面
这里我们取名为GameStartPanel,GamePlayingPanel,GameEndPanel。创建三个类,同时创建一个管理类ViewManager
image1.png

首先我们来实现开始面板的内容。
[mw_shl_code=actionscript3,true]/**
*
* @author
* 游戏开始界面
*/
class GameStartPanel extends egret.Sprite {

    public static GAME_START: string = "gameStart";
    private bg: egret.Bitmap;// 背景
    private startBtn: egret.TextField;//这里我们使用textfield当做按钮
    public constructor() {
        super();
        this.init();
    }
        
    //开启监听
    public start() {
        this.startBtn.touchEnabled = true;
        this.startBtn.addEventListener(egret.TouchEvent.TOUCH_TAP,this.onTouchTab,this);
    }
    //初始化
    private init() {
        this.bg = new egret.Bitmap(RES.getRes('gameStartBgImage'));
        this.addChild(this.bg);

        this.startBtn = new egret.TextField();
        this.startBtn.text = '开始游戏';
        this.addChild(this.startBtn);
        this.startBtn.x = (480 - this.startBtn.width) * 0.5;
        this.startBtn.y = 400;
    }

    private onTouchTab(e: egret.TouchEvent) {
        this.dispatchEventWith(GameStartPanel.GAME_START);
    }
        
    //结束界面,释放监听
    public end() {
        this.startBtn.touchEnabled = false;
        if(this.startBtn.hasEventListener(egret.TouchEvent.TOUCH_TAP))
            this.startBtn.removeEventListener(egret.TouchEvent.TOUCH_TAP,this.onTouchTab,this);
    }
}
[/mw_shl_code]

这里面我们添加了背景,使用了一个TextField当做一个按钮,做事件监听。
游戏结束面板同游戏开始界面
这里使用了事件的监听和抛事件来实现消息的传递
在我们点击开始游戏的时候,进行了消息的传递,在viewManager中,我们做了监听处理,监听到gameStartPanel 自己抛的事件,然后在ViewManager中移除gameStartPanel,添加gamePlayingPanel,然后做同样的监听。
这里再看下gamePlayingPanel
[mw_shl_code=actionscript3,true]/**
*
* @author
* 游戏界面
*/
class GamePlayingPanel extends egret.Sprite {
    public static CHANGEPANEL: string = "changepanel";
    private bg: egret.Bitmap;// 背景
    private timeTitle: egret.TextField;//这里我们使用textfield当做开始按钮
    private timer: egret.Timer;//计时器
    private timeNumbers: number = 20;//计时的秒数
    public constructor() {
        super();
        this.init();
    }
            
    //开启监听
    public start() {
        this.timeNumbers = 20;
        this.timer.start();
        this.timer.addEventListener(egret.TimerEvent.TIMER,this.onTimer,this);
        this.timer.addEventListener(egret.TimerEvent.TIMER_COMPLETE,this.onTimerComplete,this);
    }
    //初始化
    private init() {
        this.bg = new egret.Bitmap(RES.getRes('gamePlayingBgImage'));
        this.addChild(this.bg);

        this.timeTitle = new egret.TextField();
        this.timeTitle.text = "剩余时间:"  + this.timeNumbers + " 秒";
        this.timeTitle.x = (480 - this.timeTitle.width) * 0.5;
        this.timeTitle.y = 400;
        this.addChild(this.timeTitle);
        this.timer = new egret.Timer(1000,this.timeNumbers);
        
    }

    private onTimer(e:egret.TimerEvent){
        this.timeNumbers -= 1;
        this.timeTitle.text = "剩余时间:"  + this.timeNumbers + " 秒";
    }
   
    private onTimerComplete(e: egret.TouchEvent) {
        this.dispatchEventWith(GamePlayingPanel.CHANGEPANEL);
    }
               
    //结束界面,释放监听
    public end() {
        
        if(this.timer.hasEventListener(egret.TimerEvent.TIMER))
            this.timer.removeEventListener(egret.TimerEvent.TIMER,this.onTimer,this);
        if(this.timer.hasEventListener(egret.TimerEvent.TIMER_COMPLETE))
            this.timer.removeEventListener(egret.TimerEvent.TIMER_COMPLETE,this.onTimerComplete,this);   
        this.timer.stop();
        this.timer.reset();
    }
}
[/mw_shl_code]

在这里面做了一个定时器来模拟,游戏中的一些操作过后,然后到游戏结束。同样使用的事件消息传递。dispatchEventWith

然后在ViewManager里面做界面切换处理,这里写的非常的繁琐,可以有更好的方式实现,自定义事件。有兴趣的可以自己思考一下。
或者您有更好的方式,欢迎留言,感谢。
[mw_shl_code=actionscript3,true]/**
*
* @author
* 主要控制三个界面的切换
*/
class ViewManager extends egret.Sprite {
    public constructor() {
        super();
        this.init();
    }

    private gameStartPanel: GameStartPanel; // 开始界面
    private gameEndPanel: GameEndPanel; //游戏结束界面
    private gamePlayingPanel: GamePlayingPanel; //游戏中界面
        /**
         * 这里初始化
         */
    private init() {
        this.gameStartPanel = new GameStartPanel();
        this.gameEndPanel = new GameEndPanel();
        this.gamePlayingPanel = new GamePlayingPanel();
    }

    //初始,添加游戏开始界面
    public start() {
   
        this.addChild(this.gameStartPanel);
        this.gameStartPanel.start();
        this.gameStartPanel.addEventListener(GameStartPanel.GAME_START,this.gamePlaying,this);
    }

    //切换界面,从游戏开始界面切换到游戏界面
    private gamePlaying() {
        this.gameStartPanel.end();
        this.removeChild(this.gameStartPanel);
        this.gameStartPanel.removeEventListener(GameStartPanel.GAME_START,this.gamePlaying,this);
        this.addChild(this.gamePlayingPanel);
        this.gamePlayingPanel.start();
        this.gamePlayingPanel.addEventListener(GamePlayingPanel.CHANGEPANEL,this.gameEnd,this);
    }

    //切换界面,由游戏界面切换到游戏结束界面
    private gameEnd() {
        this.gamePlayingPanel.end();
        this.removeChild(this.gamePlayingPanel);
        this.gamePlayingPanel.removeEventListener(GamePlayingPanel.CHANGEPANEL,this.gameEnd,this);
        this.addChild(this.gameEndPanel);
        this.gameEndPanel.start();
        this.gameEndPanel.addEventListener(GameEndPanel.GAME_END,this.gameStart,this);
    }
    //切换界面,从游戏结束界面又切回到游戏开始界面
    private gameStart(){
        this.gameEndPanel.end();
        this.removeChild(this.gameEndPanel);
        this.gameEndPanel.removeEventListener(GameEndPanel.GAME_END,this.gameStart,this);
        this.addChild(this.gameStartPanel);
        this.gameStartPanel.start();
        this.gameStartPanel.addEventListener(GameStartPanel.GAME_START,this.gamePlaying,this)
    }
}
[/mw_shl_code]
自定义事件代码事件[mw_shl_code=applescript,true]/**
* Created by xiashishi on 15/9/24.
*/
class ChangeSceneEvent extends egret.Event
{
    public static CHANGE_SCENE_EVENT:string = "changesceneevent";
    public eventType:any;//事件类型
    public obj:any;//对象
    public constructor(type:string, bubbles:boolean=false, cancelable:boolean=false){
        super(type,bubbles,cancelable);

    }
}[/mw_shl_code]

修改ViewManager里面的代码:
[mw_shl_code=applescript,true]/**
*
* @author
* 主要控制三个界面的切换
*/
class ViewManager extends egret.Sprite {
    public constructor() {
        super();
        this.init();
    }

    private static instance:ViewManager;
    private gameStartPanel: GameStartPanel; // 开始界面
    private gameEndPanel: GameEndPanel; //游戏结束界面
    private gamePlayingPanel: GamePlayingPanel; //游戏中界面
        /**
         * 这里初始化
         */
    private init() {
        this.gameStartPanel = new GameStartPanel();
        this.gameEndPanel = new GameEndPanel();
        this.gamePlayingPanel = new GamePlayingPanel();
        this.addChild(this.gameStartPanel);
        this.gameStartPanel.start();
        this.addEventListener(ChangeSceneEvent.CHANGE_SCENE_EVENT,this.onChangeScene,this);

    }

    public start()
    {
        this.addEventListener(ChangeSceneEvent.CHANGE_SCENE_EVENT,this.onChangeScene,this);
    }
    public static getInstance():ViewManager
    {
        if(ViewManager.instance == null)
        {
            ViewManager.instance = new ViewManager();
        }

        return ViewManager.instance;
    }

    public onChangeScene(e:ChangeSceneEvent)
    {
        e.obj.end();
        this.removeChildren();

        switch (e.eventType)
        {
            case GameStartPanel.GAME_START:

                this.gameStartPanel.start();
                this.addChild(this.gameStartPanel);
                break;
            case GamePlayingPanel.CHANGEPANEL:
                this.gamePlayingPanel.start();
                this.addChild(this.gamePlayingPanel);
                break;
            case GameEndPanel.GAME_END:
                this.gameEndPanel.start();
                this.addChild(this.gameEndPanel);
                break;
            default :
                break;
        }
    }
}
[/mw_shl_code]


当页面超级多的时候,自定义事件处理也不是一个很好的版本。
可以使用一个全局的单例,来更新显示列表,会更加灵活。
最后上传一下源代码 场景切换.rar (773.34 KB, 下载次数: 496)

场景切换.zip

906.25 KB, 下载次数: 293, 下载积分: 银子 -1

分享到 :
18 人收藏
一天一小步,十天一大步。个人博客http://www.xsstomy.com/

268 个回复

倒序浏览
zhjabc  圆转纯熟 | 2015-7-22 22:13:02
学习了,很详细,正找这个呢
xsstomy  斑竹 | 2015-7-23 10:09:06
zhjabc 发表于 2015-7-22 22:13
学习了,很详细,正找这个呢

感谢顶帖,顶帖的人不多呀
cui_xiaorui  初窥堂奥 | 2015-7-23 18:04:44
顶顶顶~~~~~
xsstomy  斑竹 | 2015-7-23 18:21:42

感谢顶帖,顶帖的人不多呀
jolee2015  登堂入室 | 2015-7-24 16:55:58
不同的场景进入前要加载不同的资源,这个要怎么实现
nolar  初学乍练 | 2015-7-27 22:41:57
对新手相当有启发的教程啊,场景切换一般都这样写了吧,至于场景内的内容,那就根据自己的需求来写了
xsstomy  斑竹 | 2015-7-27 22:48:51
nolar 发表于 2015-7-27 22:41
对新手相当有启发的教程啊,场景切换一般都这样写了吧,至于场景内的内容,那就根据自己的需求来写了 ...

一般初级的是这样的,如果还想更好的效果,就添加过渡动画。那个复杂点
xsstomy  斑竹 | 2015-7-27 22:50:23
jolee2015 发表于 2015-7-24 16:55
不同的场景进入前要加载不同的资源,这个要怎么实现

这个把一个场景内需要的资源全部定为一组就好了,然后进入场景之前就加载这组资源,这样就需要一个加载资源的过程,即一个等待的动画。
jolee2015  登堂入室 | 2015-7-28 10:47:59
好的,谢谢
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|京网文[2014]0791-191号|京ICP证150115号|Egret社区 ( 京ICP备14025619号 )

Powered by Discuz! X3.4 © 2001-2019 Comsenz Inc.

返回顶部