我想建立一個國際象棋應用程序。我有後臺邏輯(幾乎)。但我並沒有在UI上工作太多。我計劃使用C#,我聽說WPF是要走的路。WPF控件需要建立國際象棋應用程序
你能否給我指點一下如何構建UI界面和它的各種硬幣?我需要爲硬幣建立某種控制嗎?另外,我應該用什麼樣的控制來開發電路板?
我想建立一個國際象棋應用程序。我有後臺邏輯(幾乎)。但我並沒有在UI上工作太多。我計劃使用C#,我聽說WPF是要走的路。WPF控件需要建立國際象棋應用程序
你能否給我指點一下如何構建UI界面和它的各種硬幣?我需要爲硬幣建立某種控制嗎?另外,我應該用什麼樣的控制來開發電路板?
如果是2D,那麼Canvas是顯而易見的方法,您可以在其上放置圖像或任何其他您喜歡的圖像並將它們移動到任意位置。您也可以將其包裝在Viewbox中,以便它及其中的所有內容自動縮放到父窗口。
一般而言,您不需要進行任何用戶控制。 WPF對用戶控件的重視程度要低得多,一般而言,只有在需要添加非現有框架需要複製的特定行爲時,才需要它們。這在國際象棋應用中不太可能出現。
所以董事會必須是一個圖像,將被加載在畫布上?在那張紙上,所有的硬幣也將是獨立的圖像,必須疊加在紙板圖像上。是對的嗎? – Aadith
是的,沒錯。您可以將Canvas背景設置爲電路板的圖像,然後這些部分將成爲Canvas上獨立的圖像元素。這裏有很多變體,例如每個片可以是一個Button,並且該按鈕的背景被設置爲該片的位圖。並不是說這就是你必須做的事,WPF在如何做這樣的事情方面有很大的靈活性,但總的來說,你會從一個Canvas開始並從那裏開始。 –
ComponentOne有一個名爲跳棋的棋盤遊戲的Silverlight演示。您可以在線查看此演示,並且可以免費獲得源代碼。當然,它可以幫助你開始。請注意,移植到WPF會相當容易。
設計畫布上,並決定你需要多少尺寸給董事會或多少的得分區或球員姓名或任何其他其他信息你想在遊戲中展現。
2.設計硬幣的圖像,和董事會背景圖像
現在設置場景,你應該有圖形的一個類。更新它並處理它會更容易(它取決於你如何編寫它)。
4.爲動畫創建一個類,即圖像如何在特定動作上移動。
5.如果您打算使用,請爲聲音創建一個單獨的類。
6.創建一個包含遊戲邏輯
其他類7還有一類,你需要爲玩家
做他們,所有到您的邏輯之後如何你處理他們。
鏈接是here,它的vb.net但您可以瞭解如何設計用戶界面。
我會在這個問題上有另一個鏡頭,實際上告訴你如何正確使用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}
};
而這裏的結果:
這似乎是很多工作只是畫一個棋盤,但請記住,這是現在一個完全數據驅動的界面....如果您添加或刪除片段或更改任何的這些變化會立即傳播到前端。它也很容易擴展,修改和添加其他功能,如動畫,3D,反射等。但也許最令人印象深刻的是,我沒有必要創建任何自定義用戶控件爲了做到這一點,WPF數據綁定機制足夠強大,足以輕鬆支持這種開箱即用的東西。
如果您需要任何進一步的說明和/或希望看到一個獨立的項目,然後通過一切手段讓我知道。
哇!現在多數民衆贊成在一些答案..我試圖按照你的步驟..但我應該承認,你正在與一個總的WPF菜鳥談話......你能詳細說明在哪裏添加所有的XML內容?到目前爲止,我已經添加了MVVM包,並且添加cs代碼應該沒問題...我被困在XML中 – Aadith
@Aadith棋盤和圖像樣式應該放在Windows資源塊內(即
這是偉大的..感謝很多馬克!您能否告訴我需要添加移動硬幣的功能?事件處理程序將不得不觸發一次用戶嘗試移動硬幣..btw,你會考慮與我在項目上合作嗎? – Aadith
它是2D還是3D? – Shaharyar
它會是2d。 – Aadith
看看這個http://wpftutorial.net/Graphics2D.html這是一個非常有用的網站關於** WPF **控件和使用它們的技術 – Shaharyar