2013-12-13 24 views
3

我想建立一个国际象棋应用程序。我有后台逻辑(几乎)。但我并没有在UI上工作太多。我计划使用C#,我听说WPF是要走的路。WPF控件需要建立国际象棋应用程序

你能否给我指点一下如何构建UI界面和它的各种硬币?我需要为硬币建立某种控制吗?另外,我应该用什么样的控制来开发电路板?

+0

它是2D还是3D? – Shaharyar

+0

它会是2d。 – Aadith

+1

看看这个http://wpftutorial.net/Graphics2D.html这是一个非常有用的网站关于** WPF **控件和使用它们的技术 – Shaharyar

回答

1

如果是2D,那么Canvas是显而易见的方法,您可以在其上放置图像或任何其他您喜欢的图像并将它们移动到任意位置。您也可以将其包装在Viewbox中,以便它及其中的所有内容自动缩放到父窗口。

一般而言,您不需要进行任何用户控制。 WPF对用户控件的重视程度要低得多,一般而言,只有在需要添加非现有框架需要复制的特定行为时,才需要它们。这在国际象棋应用中不太可能出现。

+0

所以董事会必须是一个图像,将被加载在画布上?在那张纸上,所有的硬币也将是独立的图像,必须叠加在纸板图像上。是对的吗? – Aadith

+0

是的,没错。您可以将Canvas背景设置为电路板的图像,然后这些部分将成为Canvas上独立的图像元素。这里有很多变体,例如每个片可以是一个Button,并且该按钮的背景被设置为该片的位图。并不是说这就是你必须做的事,WPF在如何做这样的事情方面有很大的灵活性,但总的来说,你会从一个Canvas开始并从那里开始。 –

1

ComponentOne有一个名为跳棋的棋盘游戏的Silverlight演示。您可以在线查看此演示,并且可以免费获得源代码。当然,它可以帮助你开始。请注意,移植到WPF会相当容易。

1

设计画布上,并决定你需要多少尺寸给董事会或多少的得分区球员姓名或任何其他其他信息你想在游戏中展现。

2.设计硬币的图像,和董事会背景图像

现在设置场景,你应该有图形的一个类。更新它并处理它会更容易(它取决于你如何编写它)。

4.为动画创建一个类,即图像如何在特定动作上移动。

5.如果您打算使用,请为声音创建一个单独的类。

6.创建一个包含游戏逻辑

其他类7还有一类,你需要为玩家

做他们,所有到您的逻辑之后如何你处理他们。

链接是here,它的vb.net但您可以了解如何设计用户界面。

20

我会在这个问题上有另一个镜头,实际上告诉你如何正确使用WPF来做到这一点。不过要注意的是,如果你之前从未做过任何WPF,那么开始时可能会有些压倒性,但是希望它能给出一些关于数据驱动的WPF的概念,以及一旦你掌握了WPF的强大功能它。

首先,您需要创建一个WPF项目并运行NuGet包管理器来添加MVVM Light包(或者如果您愿意,可以手动添加它)。接下来,您将要设置一对夫妇枚举来定义你的作品类型,一类代表在董事会一块的实际例子:

public enum PieceType 
{ 
    Pawn, 
    Rook, 
    Knight, 
    Bishop, 
    Queen, 
    King 
} 

public enum Player 
{ 
    White, 
    Black 
} 

public class ChessPiece : ViewModelBase 
{ 
    private Point _Pos; 
    public Point Pos 
    { 
     get { return this._Pos; } 
     set { this._Pos = value; RaisePropertyChanged(() => this.Pos); } 
    } 

    private PieceType _Type; 
    public PieceType Type 
    { 
     get { return this._Type; } 
     set { this._Type = value; RaisePropertyChanged(() => this.Type); } 
    } 

    private Player _Player; 
    public Player Player 
    { 
     get { return this._Player; } 
     set { this._Player = value; RaisePropertyChanged(() => this.Player); } 
    } 
} 

几乎一切都从这里其他在XAML完成。首先,您需要为棋盘自己创建棋盘格刷子,如果您喜欢,可以使用位图,但我会继续创建几何图形。此代码需要放置在您的Window.Resources部分中:

<DrawingBrush x:Key="Checkerboard" Stretch="None" TileMode="Tile" Viewport="0,0,2,2" ViewportUnits="Absolute"> 
     <DrawingBrush.Drawing> 
      <DrawingGroup> 
       <GeometryDrawing Brush="Tan"> 
        <GeometryDrawing.Geometry> 
         <RectangleGeometry Rect="0,0,2,2" /> 
        </GeometryDrawing.Geometry> 
       </GeometryDrawing> 
       <GeometryDrawing Brush="Brown"> 
        <GeometryDrawing.Geometry> 
         <GeometryGroup> 
          <RectangleGeometry Rect="0,0,1,1" /> 
          <RectangleGeometry Rect="1,1,1,1" /> 
         </GeometryGroup> 
        </GeometryDrawing.Geometry> 
       </GeometryDrawing> 
      </DrawingGroup> 
     </DrawingBrush.Drawing> 
    </DrawingBrush> 

接下来,您需要一种方法来根据要渲染的图片选择图像。有很多方法可以做到这一点,但我要在这里做的方式是声明图像样式,然后使用触发器根据片类型和播放器选择适当的位图。在这个例子中,我只是热连接到wpclipart网站上的一些剪贴画。这个XAML块很长,但它只是为每件类型做同样的事情:

<Style x:Key="ChessPieceStyle" TargetType="{x:Type Image}"> 
     <Style.Triggers> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Pawn}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_pawn_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Rook}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_rook_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Knight}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_knight_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Bishop}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_bishop_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Queen}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_queen_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.King}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.White}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_white_king_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Pawn}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_pawn_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Rook}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_rook_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Knight}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_knight_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Bishop}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_bishop_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.Queen}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_queen_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
      <MultiDataTrigger> 
       <MultiDataTrigger.Conditions> 
        <Condition Binding="{Binding Type}" Value="{x:Static local:PieceType.King}"/> 
        <Condition Binding="{Binding Player}" Value="{x:Static local:Player.Black}"/> 
       </MultiDataTrigger.Conditions> 
       <MultiDataTrigger.Setters> 
        <Setter Property="Image.Source" Value="http://www.wpclipart.com/recreation/games/chess/chess_set_1/chess_piece_black_king_T.png" /> 
       </MultiDataTrigger.Setters> 
      </MultiDataTrigger> 
     </Style.Triggers> 
    </Style> 

而现在板子本身。通过上面的代码设置,这个位出奇的短,我们只是渲染一个ItemsControl(即项目列表),我们将容器设置为画布,我们将它设置为棋盘的背景,对于每一件我们都会根据Pos属性设置位置。很显然,我们也将使用我们设置了上述ChessPieceStyle影像风格来选择正确的图像来呈现:

<ItemsControl Name="ChessBoard"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas Width="8" Height="8" Background="{StaticResource Checkerboard}"/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Grid Width="1" Height="1"> 
        <Image Width="0.8" Height="0.8" Style="{StaticResource ChessPieceStyle}" />      
       </Grid> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
     <ItemsControl.ItemContainerStyle> 
      <Style> 
       <Setter Property="Canvas.Left" Value="{Binding Pos.X}" /> 
       <Setter Property="Canvas.Top" Value="{Binding Pos.Y}" /> 
      </Style> 
     </ItemsControl.ItemContainerStyle> 
    </ItemsControl> 

就是这样!我们现在拥有一切我们需要的棋子。剩下的工作就是创造我们的作品的数组,把它放在一个ObservableCollection(以便GUI得到更新时,片添加和删除),并将其绑定到我们的棋盘:

this.ChessBoard.ItemsSource = new ObservableCollection<ChessPiece> 
     { 
      new ChessPiece{Pos=new Point(0, 6), Type=PieceType.Pawn, Player=Player.White}, 
      new ChessPiece{Pos=new Point(1, 6), Type=PieceType.Pawn, Player=Player.White}, 
      new ChessPiece{Pos=new Point(2, 6), Type=PieceType.Pawn, Player=Player.White}, 
      new ChessPiece{Pos=new Point(3, 6), Type=PieceType.Pawn, Player=Player.White}, 
      new ChessPiece{Pos=new Point(4, 6), Type=PieceType.Pawn, Player=Player.White}, 
      new ChessPiece{Pos=new Point(5, 6), Type=PieceType.Pawn, Player=Player.White}, 
      new ChessPiece{Pos=new Point(6, 6), Type=PieceType.Pawn, Player=Player.White}, 
      new ChessPiece{Pos=new Point(7, 6), Type=PieceType.Pawn, Player=Player.White}, 
      new ChessPiece{Pos=new Point(0, 7), Type=PieceType.Rook, Player=Player.White}, 
      new ChessPiece{Pos=new Point(1, 7), Type=PieceType.Knight, Player=Player.White}, 
      new ChessPiece{Pos=new Point(2, 7), Type=PieceType.Bishop, Player=Player.White}, 
      new ChessPiece{Pos=new Point(3, 7), Type=PieceType.King, Player=Player.White}, 
      new ChessPiece{Pos=new Point(4, 7), Type=PieceType.Queen, Player=Player.White}, 
      new ChessPiece{Pos=new Point(5, 7), Type=PieceType.Bishop, Player=Player.White}, 
      new ChessPiece{Pos=new Point(6, 7), Type=PieceType.Knight, Player=Player.White}, 
      new ChessPiece{Pos=new Point(7, 7), Type=PieceType.Rook, Player=Player.White}, 
      new ChessPiece{Pos=new Point(0, 1), Type=PieceType.Pawn, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(1, 1), Type=PieceType.Pawn, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(2, 1), Type=PieceType.Pawn, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(3, 1), Type=PieceType.Pawn, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(4, 1), Type=PieceType.Pawn, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(5, 1), Type=PieceType.Pawn, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(6, 1), Type=PieceType.Pawn, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(7, 1), Type=PieceType.Pawn, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(0, 0), Type=PieceType.Rook, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(1, 0), Type=PieceType.Knight, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(2, 0), Type=PieceType.Bishop, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(3, 0), Type=PieceType.King, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(4, 0), Type=PieceType.Queen, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(5, 0), Type=PieceType.Bishop, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(6, 0), Type=PieceType.Knight, Player=Player.Black}, 
      new ChessPiece{Pos=new Point(7, 0), Type=PieceType.Rook, Player=Player.Black} 
     }; 

而这里的结果:

WPF chessboard

这似乎是很多工作只是画一个棋盘,但请记住,这是现在一个完全数据驱动的界面....如果您添加或删除片段或更改任何的这些变化会立即传播到前端。它也很容易扩展,修改和添加其他功能,如动画,3D,反射等。但也许最令人印象深刻的是,我没有必要创建任何自定义用户控件为了做到这一点,WPF数据绑定机制足够强大,足以轻松支持这种开箱即用的东西。

如果您需要任何进一步的说明和/或希望看到一个独立的项目,然后通过一切手段让我知道。

+0

哇!现在多数民众赞成在一些答案..我试图按照你的步骤..但我应该承认,你正在与一个总的WPF菜鸟谈话......你能详细说明在哪里添加所有的XML内容?到目前为止,我已经添加了MVVM包,并且添加cs代码应该没问题...我被困在XML中 – Aadith

+2

@Aadith棋盘和图像样式应该放在Windows资源块内(即 ...这里...)。 ItemsControl是内容,所以它取代了缺省添加的标签。如果我只是将你指向一个[你可以用作起点的项目](http://www.ppl-pilot.com/files/ChessDemo.zip),那么可能是最简单的。 –

+0

这是伟大的..感谢很多马克!您能否告诉我需要添加移动硬币的功能?事件处理程序将不得不触发一次用户尝试移动硬币..btw,你会考虑与我在项目上合作吗? – Aadith