UWP跳棋开发:检测点击棋子相邻网格是否包含椭圆棋子
嘿,针对你在UWP开发Peg Solitaire(跳棋)游戏时遇到的相邻网格检测问题,我来给你梳理几个实用的解决方案:
第一步:给棋盘和棋子建立数据驱动模型
直接在UI层面硬编码棋盘和棋子会让后续的相邻检测逻辑变得混乱,建议先定义一个网格单元格的模型类,把每个格子的状态(是否有棋子)、坐标信息封装起来:
public class GridCell : INotifyPropertyChanged { private bool _hasPeg; // 标记当前格子是否有棋子 public bool HasPeg { get => _hasPeg; set { _hasPeg = value; OnPropertyChanged(nameof(HasPeg)); } } // 格子所在的行、列坐标 public int Row { get; set; } public int Column { get; set; } // 实现INotifyPropertyChanged接口,确保UI能响应数据变化 public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
接着用二维集合管理整个棋盘,比如用ObservableCollection<ObservableCollection<GridCell>>,这样既方便绑定到XAML显示,也能快速访问任意格子:
// 假设你的棋盘是5x5的,可根据实际布局调整 public ObservableCollection<ObservableCollection<GridCell>> BoardGrid { get; set; } private void InitializeBoard() { BoardGrid = new ObservableCollection<ObservableCollection<GridCell>>(); for (int row = 0; row < 5; row++) { var rowCells = new ObservableCollection<GridCell>(); for (int col = 0; col < 5; col++) { // 初始化时默认给部分格子放置棋子,可根据游戏规则调整 rowCells.Add(new GridCell { Row = row, Column = col, HasPeg = row != 2 || col != 2 // 中间格子初始为空 }); } BoardGrid.Add(rowCells); } }
第二步:处理点击事件,检测相邻格子
当用户点击某个棋子时,先获取对应的GridCell实例,然后计算四个方向(上、下、左、右)的相邻格子坐标,同时做边界判断避免越界,最后检查相邻格子是否有棋子:
private void OnCellClicked(GridCell selectedCell) { // 定义四个相邻方向的偏移量 var adjacentOffsets = new[] { (-1, 0), (1, 0), (0, -1), (0, 1) }; foreach (var (rowOffset, colOffset) in adjacentOffsets) { int adjacentRow = selectedCell.Row + rowOffset; int adjacentCol = selectedCell.Column + colOffset; // 检查相邻坐标是否在棋盘范围内 if (adjacentRow >= 0 && adjacentRow < BoardGrid.Count && adjacentCol >= 0 && adjacentCol < BoardGrid[adjacentRow].Count) { var adjacentCell = BoardGrid[adjacentRow][adjacentCol]; // 判断相邻格子是否有棋子 if (adjacentCell.HasPeg) { // 这里可以添加你需要的逻辑,比如标记可跳跃的目标格子 Debug.WriteLine($"相邻格子({adjacentRow},{adjacentCol})存在棋子"); } } } }
第三步:XAML绑定与点击关联
在XAML中用ItemsControl嵌套绑定棋盘数据,把每个格子的点击事件绑定到上面的处理方法,同时可以保留你的网格高亮测试样式:
<ItemsControl ItemsSource="{Binding BoardGrid}"> <ItemsControl.ItemTemplate> <DataTemplate> <ItemsControl ItemsSource="{Binding}"> <ItemsControl.ItemTemplate> <DataTemplate> <Button Width="50" Height="50" Margin="2" Command="{Binding DataContext.CheckAdjacentCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" CommandParameter="{Binding}"> <!-- 用转换器根据HasPeg显示椭圆棋子或空样式 --> <Button.Content> <Ellipse Width="40" Height="40" Fill="DarkRed" Visibility="{Binding HasPeg, Converter={StaticResource BooleanToVisibilityConverter}}"/> </Button.Content> <!-- 你的网格高亮测试样式,后续可以直接移除 --> <Button.Style> <Style TargetType="Button"> <Style.Triggers> <Trigger Property="IsPressed" Value="True"> <Setter Property="Background" Value="LightBlue"/> </Trigger> </Style.Triggers> </Style> </Button.Style> </Button> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
这里的CheckAdjacentCommand是一个ICommand实现,用来把点击事件关联到OnCellClicked方法,你可以用RelayCommand之类的实现类来简化代码。
等相邻检测逻辑验证没问题后,只需要移除XAML中按钮的高亮Style部分即可。
内容的提问来源于stack exchange,提问作者user2963022
相关产品推荐
相关产品推荐

