为扫雷游戏动态创建游戏板 [英] Dynamicly create a playboard for Minesweeper game

查看:29
本文介绍了为扫雷游戏动态创建游戏板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了学习 C#、XAML,尤其是 MVVM,我开始编写扫雷游戏的程序.我制作的第一个版本没有 MVVM 部分,我使用 C# 代码创建和添加按钮,而不是通过 MVVM 方式在 XAML 中进行.现在我尝试将 MVVM 模式应用到游戏中.

with the objective to learn C#, XAML and especially MVVM I started to program the Minesweeper game. First version I made was without the MVVM part, where I created and added the buttons with C# code instead of doing it in XAML via the MVVM way. Now I try to apply the MVVM pattern into the game.

我制作了一个自己的用户控件,其中包含一个代表雷区部分的按钮.这个控件还有一个 ViewModel 和一个 Model Class 来存储一些状态数据和处理一些命令.在一个测试项目中,我创建了 4 个自己的用户控件,并尝试将它们放在一个网格中,其中按钮形成一个 2 x 2 按钮的正方形.在后面的代码中,按钮被放在一个 ObservableCollection 对象中.我假设在这个对象中按钮被列出和索引如下:

I made an own User Control which contains a button representing a minefield part. This control also has a ViewModel and a Model Class to store some state data and handle some commands. In a test project I create 4 of those own User Controls and try to put them in a grid where the buttons forms a square of 2 by 2 buttons. In the code behind, the buttons are put in an ObservableCollection object. I assume that in this object the buttons are listed and indexed like:

Button1
Button2
Button3
Button4

但在演示文稿网格中我希望按钮显示为

but in the presentation grid I want the buttons to be shown like

Button1 | Button2
--------+--------
Button3 | Button4

问题是:我如何动态地做到这一点?因为在我的测试项目中我测试了 4 个按钮,但是在我想使用它的项目中,按钮的数量可能会根据玩家选择的游戏难度而有所不同.

The question is: how do I do that dynamicly? Cause in my test project I test with 4 buttons, but In the project I want to use this, the amount of buttons can be different depending on the difficulty of the game the player has chosen.

第二个问题是我如何弄清楚按钮的 neigbhours 是什么.因此,如果网格是包含 20 个按钮的 4 x 5.例如,我选择了按钮 8,它的邻居按钮编号为 2、3、4、7、9、12、13 和 14.当按钮被列出时,我怎样才能到达这些邻居按钮?

And a second question is how I can figure out what the neigbhours are of a button. So if the grid is 4 by 5 containing 20 buttons. And for example I pick button 8 which has as neighbour buttons number 2, 3, 4, 7, 9, 12, 13 and 14. How can I reach those neighbour buttons when the buttons are listed?

我希望我的问题足够清楚.

I hope my questions are clear enough.

先谢谢你!

推荐答案

您可以使用 ItemsControl 将它的 ItemsPanel 设置为 GridUniformGrid.我有一些 ItemsControl 示例 这里 这可能对您有所帮助,因为我认为 MDSN 的示例没有太大帮助.

You can display your collection using an ItemsControl that has it's ItemsPanel set to a Grid or UniformGrid. I have some ItemsControl examples here that may help you, as I don't find MDSN's examples very helpful.

UniformGrid 将是最简单的>,但是这要求所有单元格的大小都相同,我不记得属性 RowsColumns 是否是参与绑定系统的 DependencyProperties.

A UniformGrid would be easiest if you can bind your Rows and Columns properties to a property in your ViewModel, however that requires all your cells be the same size, and I can't remember if the properties Rows and Columns are DependencyProperties that participate in the binding system or not.

<ItemsControl ItemsSource="{Binding MyCollection}">
    <!-- ItemsPanelTemplate -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="{Binding ColumnCount}" 
                         Rows="{Binding RowCount}" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

如果这对您不起作用,您可以使用 Grid 作为 ItemsPanel 并设置 Grid.RowItemContainerStyle 中的 >Grid.Column 绑定.

If this doesn't work for you, you can use a Grid as the ItemsPanel and set the Grid.Row and Grid.Column bindings in the ItemContainerStyle.

这将要求您在 ObservableCollection 中的每个单元格对象上都有属性来说明该单元格所在的行/列,但是我怀疑您无论如何都需要这些来确定诸如相邻单击命令中的单元格.

This will require you have properties on each of your cell objects in the ObservableCollection to say what Row/Column that cell is in, however I suspect you'll need these anyways to determine things like adjacent cells in your click command.

此外,没有内置的方法来绑定Grid 中的行/列数,所以我倾向于使用一些自定义附加属性,将动态构建网格的 RowDefinitionsColumnDefinitions 基于绑定值.

In addition, there's no built-in way to bind the number of Rows/Columns in your Grid, so I tend to use some custom attached properties that will dynamically build the Grid's RowDefinitions and ColumnDefinitions based on a bound value.

因此,如果您使用网格,您的最终结果可能如下所示:

So your end result if you're using a Grid would probably look something like this:

<ItemsControl ItemsSource="{Binding Cells}">
    <!-- ItemsPanelTemplate -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <!-- This is assuming you use the attached properties linked above -->
            <Grid local:GridHelpers.RowCount="{Binding Height}"
                  local:GridHelpers.ColumnCount="{Binding Width}" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <!-- ItemContainerStyle -->
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Grid.Column" 
                    Value="{Binding ColumnIndex}" />
            <Setter Property="Grid.Row" 
                    Value="{Binding RowIndex}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

模型/视图模型看起来像这样

With a Model/ViewModel looking something like this

public class GameViewModel
{
    // These should be full properties w/ property change notification
    // but leaving that out for simplicity right now
    public int Height;
    public int Width;
    public ObservableCollection<CellModel> Cells;
}

public class CellModel
{
    // Same thing, full properties w/ property change notification
    public int ColumnIndex;
    public int RowIndex;
    public bool IsVisible;
    public bool IsMine;
    public int NumberAdjacentMines;
}

这篇关于为扫雷游戏动态创建游戏板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆