經過了前面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