You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:12:44