C# UWP游戏:如何在游戏逻辑类中触发结束界面的页面导航
这问题我之前做UWP小游戏的时候也碰到过,核心是要把游戏逻辑和UI导航解耦,同时在逻辑触发时通知UI层做出响应。给你个最稳妥的方案,用事件委托来实现,既符合解耦原则,又能轻松触发页面跳转:
第一步:给Manager类添加游戏结束事件
首先,我们先定义一个枚举表示游戏结果,然后在Manager里加一个事件,用来通知外部游戏结束了:
// 先定义游戏结果的枚举,方便传递信息 public enum GameResult { Win, Lose } class Manager { // 定义游戏结束事件,参数是游戏结果 public event Action<GameResult> GameEnded; // 你的现有代码... int x, y, t, l, width, height; public void baddiesCollision(Baddies[] baddiesArr) { for (int i = 0; i < baddiesArr.Length; i++) { // 你的碰撞检测逻辑保持不变... x = (int)baddiesArr[i].ImgLeft; y = (int)baddiesArr[i].ImgTop; width = baddiesArr[i].PlayerWidth; height = baddiesArr[i].PlayerHeight; for(int j=i+1; j<=baddiesArr.Length-1; j++) { t = (int)baddiesArr[j].ImgLeft; l = (int)baddiesArr[j].ImgTop; // 你的碰撞判断逻辑... if (x <= t && t < x + width && y <= l && l <= y + height) { baddiesArr[j].badPlayer.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } // 其他碰撞判断分支... } // 统计存活敌人数量 int aliveCount = baddiesArr.Count(b => b.badPlayer.Visibility == Windows.UI.Xaml.Visibility.Visible); if(aliveCount == 1) { // 触发胜利事件,用?.避免空引用 GameEnded?.Invoke(GameResult.Win); return; // 可以提前退出,避免后续不必要的计算 } } } // 另外,你需要在检测玩家被敌人抓住的方法里也触发失败事件 public void CheckPlayerCaught(Player player, Baddies[] baddiesArr) { // 这里写玩家和敌人的碰撞检测逻辑 bool isCaught = baddiesArr.Any(b => b.badPlayer.Visibility == Windows.UI.Xaml.Visibility.Visible && player.ImgLeft < b.ImgLeft + b.PlayerWidth && player.ImgLeft + player.PlayerWidth > b.ImgLeft && player.ImgTop < b.ImgTop + b.PlayerHeight && player.ImgTop + player.PlayerHeight > b.ImgTop); if(isCaught) { GameEnded?.Invoke(GameResult.Lose); } } }
第二步:在游戏主页面订阅事件,处理导航
在你的游戏主页面(比如MainPage.xaml.cs)里,实例化Manager的时候订阅它的GameEnded事件,然后在事件回调里跳转到结束页面:
public sealed partial class MainPage : Page { private Manager _gameManager; public MainPage() { this.InitializeComponent(); _gameManager = new Manager(); // 订阅游戏结束事件 _gameManager.GameEnded += OnGameEnded; } private async void OnGameEnded(GameResult result) { // 注意:游戏逻辑可能在非UI线程运行,必须切回UI线程导航 await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { // 导航到结束页面,同时传递游戏结果参数 Frame.Navigate(typeof(EndPage), result); }); } // 你的其他页面逻辑,比如定时调用碰撞检测方法 // 比如在游戏循环里调用:_gameManager.baddiesCollision(baddiesArr); // 还有调用_checkPlayerCaught方法检测玩家是否被抓 }
第三步:结束页面接收结果并展示
最后,在你的结束页面(EndPage.xaml.cs)里,接收传递的游戏结果,显示对应的提示:
public sealed partial class EndPage : Page { public EndPage() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); if(e.Parameter is GameResult result) { // 假设你有一个TextBlock叫ResultText ResultText.Text = result == GameResult.Win ? "恭喜你!只剩最后一个敌人,你赢了!" : "糟糕,你被敌人抓住了,游戏失败!"; } } }
为什么推荐用事件?
这种方式把游戏逻辑(Manager)和UI导航完全解耦了——Manager只负责判断游戏是否结束,不需要知道怎么跳页面;UI层负责处理导航,不需要关心逻辑细节。这样不仅代码更清晰,以后要修改逻辑或者UI都更方便,也更容易测试。
如果实在不想用事件,也可以在Manager的构造函数里传入Frame的引用,但这种方式耦合度太高,不推荐——万一以后换了导航方式,或者要复用Manager,就会很麻烦。
内容的提问来源于stack exchange,提问作者Inbar Manor
相关产品推荐
相关产品推荐

