用cocos2d-x做一个简单的windows phone 7游戏:墓碑机制和收尾工作(完)

经过了前面3节的教程,现在我们已经拥有了一个不错的游戏,但是,有没发现,其实还有一些问题的。比如,背景音乐,即使回到了菜单,那背景音乐依然在播放。这个体验不友好,应该算是BUG了。

那么来修改一下吧。打开GamePlayScene类。在里面重装父类的两个方法,OnEnter和OnExit。把原来在GamePlayLayer的Init里面的播放背景音乐移到OnEnter里面播放背景音乐,并且设置为重复播放。在OnExit里面停止背景音乐的播放。具体代码如下:

        public override void onExit()
        {
            base.onExit();
            SimpleAudioEngine.sharedEngine().stopBackgroundMusic();
        }

        public override void onEnter()
        {
            base.onEnter();
            SimpleAudioEngine.sharedEngine().playBackgroundMusic(@"resource/backgroundmusic",true);
        }

这样,我们一旦不在游戏场景,背景音乐就自然停止了。回到游戏场景,背景音乐也能开始播放了。

现在游戏还有一个问题。就是按开始菜单,回到桌面后,按返回键无法返回到游戏中。细心的朋友就会发现,Debug窗口里面显示有异常,并且线程退出了。线程退出了,我们自然无法回到游戏中去了。

那么是什么原因呢,因为我们把一个场景的引用---GamePlayScene的引用放在了PhoneApplicationService里面。这个又黄又暴力的行为微软是认定为不安全的。所以有一个安全异常。这个异常导致线程直接退出了。那么怎么解决呢,我又舍不得不用这个引用。。虽然认为是不安全的。那么就来曲线救国一把。

打开Game1.cs,往Game1这个类里面添加一个声明

IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;


然后在Game1的构造函数里面增加程序的Deactived和Actived的注册。

            PhoneApplicationService.Current.Deactivated += new EventHandler<DeactivatedEventArgs>(Current_Deactivated);
            PhoneApplicationService.Current.Activated += new EventHandler<ActivatedEventArgs>(Current_Activated);


然后在Deactived时候把GamePlayScene存到IsolatedStorage里面。并且在PhoneApplicationService里面删除,在Actived的时候再把他取出来。其实把这东西存到IsolatedStorage里面也是引发安全异常的。但是经过测试能用。。

void Current_Activated(object sender, ActivatedEventArgs e)
        {
            Debug.WriteLine("Activated");
            GamePlayScene temp;
            if (settings.TryGetValue("PlayScene", out temp))
            {
                PhoneApplicationService.Current.State["PlayScene"] = temp;
                settings.Remove("PlayScene");
            }
        }

        void Current_Deactivated(object sender, DeactivatedEventArgs e)
        {
            CCScene currentScene = CCDirector.sharedDirector().runningScene;
            string currentSceneName = currentScene.GetType().ToString();
            if (currentSceneName == "cocos2dSimpleGame.Classes.GamePlayScene" || currentSceneName == "cocos2dSimpleGame.Classes.GameOverScene")
            {
                if (PhoneApplicationService.Current.State.ContainsKey("PlayScene"))
                {
                    GamePlayScene pScene = (GamePlayScene)PhoneApplicationService.Current.State["PlayScene"];
                    settings["PlayScene"] = pScene;
                    PhoneApplicationService.Current.State.Remove("PlayScene");
                }
            }
            else
            {
                if (PhoneApplicationService.Current.State.ContainsKey("PlayScene"))
                    PhoneApplicationService.Current.State.Remove("PlayScene");
            }
            Debug.WriteLine("Deactived");
        }


测试成功,能用返回键返回程序了。

关于这两个事件我就不多说了。不懂的去了解程序的生命周期的相关资料。

 

现在说下墓碑机制的问题。现在我用的是7.1的SDK,不是最新的SDK。最新的是7.11,现在我这里的问题就是XNA程序如果重新部署的话,IsolatedStorage就会清空,但是XAML程序就不会。经过多次折腾,还是无法折腾出在程序后台运行后,从启动器启动能返回到以前运行的界面。经过我多次尝试,发现的问题是在Deactived中保存到IsolatedStorage里面的值,在Actived里面能够取到,但是在Launching里面就取不到了。显示特征为压根IsolatedStorage里面压根就没有这个值。由于重新部署IsolatedStorage会清空,所以无法调试。(奇怪的是我用小程序测试还是可以存储的。)。所以进入后台后从启动器恢复程序没有完成。这个很具有WP7的特点的东西,没做好。

现在就这样吧,原来设想是用暴力点的方法直接把场景保存,如果是进入后台从启动器进入,直接暴力转到保存的这个场景。其实也有没那么暴力的方法,就是把游戏场景的游戏层里面增加两个方法,用来设置和获取需要存储的相关变量以便保存和恢复。不过这个相对麻烦多了。

现在想想,我手机上的游戏程序基本没有能进入后台后从启动器能够恢复的。或许也是XNA的局限性吧。毕竟那么多的精灵需要恢复很麻烦不说。还很慢。

到这里,不管怎么说,我们有一个非常不错的游戏了----一个旋转的炮塔,成千上万的不同类型的敌人,多个关卡,win/lose场景,菜单界面,about的声明,当然,还有很棒的音效!

工程下载:http://dl.dbank.com/c0h47u84l3

posted on 2012-04-23 19:53  fengyun1989  阅读(722)  评论(1编辑  收藏  举报