简易版3D中国象棋
在前面几篇博客了简要的介绍了一下WPF相关的技术,其中主要是3D编程和鼠标事件在3D环境中的相关处理。通过上面的学习,我来讲一下基于上述技术做的一个没有AI的类3D中国象棋。
1. 游戏界面的编写,首先使用viewport3D这个控件来建立一个3D的场景,其中有camera,ModelVisual3D。然后在ModelVisual3D的content属性上使用了Model3DGroup,最后在这个group中加入一些3D模型,比如光源,一些GeometryModel3D(这个是有material和MeshGeometry3D组成的)。其实上面讲的这些是一颗树的关系,大家可以用笔画一下就知道了,其实在WPF中写界面程序,每个程序都是一个tree的概念,一层套一层。
2. 棋的规则的实现,这个问题是游戏的核心问题。我使用了一个二维matrix来代替棋盘,给每个棋子起了标示(比如一个正整数),在matrix中放上对应的数字就可以的。当有棋子移动的时候,在matrix上也相应的移动,如果它的移动式去吃棋子,这时候就会在matrix中原来的地方变为没棋的状态,而在它吃棋的地方放上他的标示,然后在棋盘上删去被吃的棋子;如果他只是移动的,就只要在matrix的原来的地方变为没棋的标示,在移动到的地方放上这个标示。这其中还有就是你移动棋子的合法性判断,这个也完全可以通过matrix来判断,比如说“车”,只要判断它到目的地之间没有其他棋子就好了,也就是只要判断matrix中间全部都是没棋的状态。
3. 联系界面和matrix的是鼠标事件,主要使用的技术就是hittest技术,可以在我们的前面的博客中知道怎么使用。鼠标事件主要分为三种.1)选中要移动的棋子,使用左键选择棋子,对其合法选中的棋子进行记录和改变其外观。2)取消刚才选中的棋子,使用右键取消刚才选中的棋,让其恢复到原来的样子。3)选要移动的目标,如果没有违反棋的规则,就移动到目的地。
我的游戏是在windows7和visual studio 2010上编译生成的。
程序很长:
1sing System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Windows;
6using System.Windows.Controls;
7using System.Windows.Data;
8using System.Windows.Documents;
9using System.Windows.Input;
10using System.Windows.Media;
11using System.Windows.Media.Imaging;
12using System.Windows.Navigation;
13using System.Windows.Shapes;
14using System.Windows.Media.Media3D;
15using System.Windows.Media.Animation;
16namespace WPF3D1
17{
18 /// <summary>
19 /// Interaction logic for MainWindow.xaml
20 /// </summary>
21 public partial class MainWindow : Window
22 {
23 Canvas Panel = new Canvas();
24 Viewport3D vp = new Viewport3D();
25 AxisAngleRotation3D rotation= new AxisAngleRotation3D();
26 Model3DGroup mg = new Model3DGroup();
27 const int BorderNum = 32; const int ChessHeight = 15; const double PanelHeight = 50;
28 const double radius = 19.125; const int red = 1; const int black = -1;
29 //const int RedPlayer = 1; const int BlackPlayer = -1;
30 const double Delta = 35.75;
31 String s = "rotation";
32 int RotationFlag = 0;
33 int[,] BoardMatrix = new int[10, 9];
34 List<string> ListForNmae = new List<string>();
35 //assume that the first player is red
36 int Player = red; bool FirstChoosing = true;
37 chess CurrentChess = new chess();
38 int FlagForClick = 0;
39 public MainWindow()
40 {
41 initBoardMatrix();
42 InitializeComponent();
43 this.Content = Panel;
44 DrawPanel();
45 Canvas.SetLeft(vp, 50); Canvas.SetTop(vp,50);
46 SetupCamera();
47 GetModelVisual3D();
48 DrawButton();
49 }
50 private void DrawPanel()
51 {
52 this.Width = 1000; this.Height = 750;
53 SolidColorBrush myBrush = new SolidColorBrush();
54 myBrush.Color = Colors.Black;
55 Panel.Background = myBrush;
56 }
57 private void SetupCamera()
58 {
59 vp.Width = 800; vp.Height = 600;
60 PerspectiveCamera camera = new PerspectiveCamera();
61 camera.Position = new Point3D(600, 0, 600);
62 camera.UpDirection = new Vector3D(0, 0, 1);
63 camera.LookDirection = new Vector3D(-6, 0, -6);
64 vp.Camera = camera ;
65 }
66 private void GetModelVisual3D()
67 {
68 ModelVisual3D mv = new ModelVisual3D();
69 mv.Content = GetModelGroup();
70 mv.Transform = GetRotation();
71 vp.Children.Add(mv);
72 vp.MouseLeftButtonDown += new MouseButtonEventHandler(vp_MouseLeftButtonDown);
73 vp.MouseRightButtonDown += new MouseButtonEventHandler(vp_MouseRightButtonDown);
74 Panel.Children.Add(vp);
75 }
76 void vp_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
77 {
78 if (!FirstChoosing)
79 {
80 FlagForClick = (FlagForClick + 1) % 2;
81 FirstChoosing = true;
82 Model3DCollection mc = mg.Children;
83 for (int i = 1; i < mc.Count; i++)
84 {
85 //MessageBox.Show("remove");
86 GeometryModel3D gm = mc.ElementAt(i) as GeometryModel3D;
87 MeshGeometry3D meshg = gm.Geometry as MeshGeometry3D;
88 if (clac(new Point3D(CurrentChess.GetPosition().X, CurrentChess.GetPosition().Y,ChessHeight), meshg.Positions.Last()) < radius)
89 {
90 //MessageBox.Show(ListForNmae.ElementAt(Math.Abs(BoardMatrix[x, y]) - 1));
91 DiffuseMaterial dm = new DiffuseMaterial();
92 ImageBrush imageBrush = new ImageBrush();
93 imageBrush.ImageSource =
94 new BitmapImage(
95 new Uri(CurrentChess.GetName()+ ".bmp", UriKind.Relative)
96 );
97 dm.Brush = imageBrush;
98 gm.Material = dm;
99 break;
100 }
101 }
102 }
103 }
104 void vp_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
105 {
106 FlagForClick = (FlagForClick+1) % 2;
107 Point mouseposition = e.GetPosition(vp);
108 Point3D testpoint3D = new Point3D(mouseposition.X, mouseposition.Y, 0);
109 Vector3D testdirection = new Vector3D(mouseposition.X, mouseposition.Y, 10);
110 PointHitTestParameters pointparams = new PointHitTestParameters(mouseposition);
111 RayHitTestParameters rayparams = new RayHitTestParameters(testpoint3D, testdirection);
112 VisualTreeHelper.HitTest(vp, null, HTResult, pointparams);
113 }
114 public HitTestResultBehavior HTResult(System.Windows.Media.HitTestResult rawresult)
115 {
116 RayHitTestResult rayResult = rawresult as RayHitTestResult;
117 if (rayResult != null)
118 {
119 RayMeshGeometry3DHitTestResult rayMeshResult = rayResult as RayMeshGeometry3DHitTestResult;
120 Point3D p = new Point3D();
121 if (rayMeshResult != null)
122 {
123 //this is the top geometrymodel3D to be clicked.
124 GeometryModel3D hitgeo = rayMeshResult.ModelHit as GeometryModel3D;
125 MeshGeometry3D mg = hitgeo.Geometry as MeshGeometry3D;
126 Point3D p1 = mg.Positions.ElementAt(rayMeshResult.VertexIndex1); double weight1 = rayMeshResult.VertexWeight1;
127 Point3D p2 = mg.Positions.ElementAt(rayMeshResult.VertexIndex2); double weight2 = rayMeshResult.VertexWeight2;
128 Point3D p3 = mg.Positions.ElementAt(rayMeshResult.VertexIndex3); double weight3 = rayMeshResult.VertexWeight3;
129 p = new Point3D(p1.X * weight1 + p2.X * weight2 + p3.X * weight3 ,p1.Y * weight1 + p2.Y * weight2 + p3.Y * weight3 , p1.Z * weight1 + p2.Z * weight2 + p3.Z * weight3);
130 if (FirstChoosing && p.Z > 0 && FlagForClick == 1)
131 {
132 if (GetChoosedChess(p, Player))
133 {
134 FirstChoosing = false;
135 }
136
137 }
138 else if (!FirstChoosing && FlagForClick==0)
139 {
140 if (IsLegal(p))
141 {
142 //MessageBox.Show(MoveChess(p).ToString());
143 if (MoveChess(p)==-5)
144 {
145 MessageBox.Show("game Over!");
146 }
147 FirstChoosing = true;
148 Player = - Player;
149 //AutoBeginAnimation();
150 }
151 }
152 }
153 }
154 return HitTestResultBehavior.Continue;
155 }
156 private Model3DGroup GetModelGroup()
157 {
158 //light source
159 DirectionalLight dl = new DirectionalLight();
160 dl.Color = Colors.White; dl.Direction = new Vector3D(0, 0, -1);
161 //3D model,contains material and mesh.
162 GeometryModel3D gm = new GeometryModel3D();
163 MeshGeometry3D meshg = new MeshGeometry3D();
164 Point3DCollection pc = new Point3DCollection();
165 pc.Add(new Point3D(203, 185, 0)); pc.Add(new Point3D(-225, 185, 0));
166 pc.Add(new Point3D(-225, -185, 0)); pc.Add(new Point3D(203, -185, 0));
167 pc.Add(new Point3D(203, 185, -PanelHeight)); pc.Add(new Point3D(-225, 185, -PanelHeight));
168 pc.Add(new Point3D(-225, -185, -PanelHeight)); pc.Add(new Point3D(203, -185, -PanelHeight));
169 meshg.Positions = pc;
170 Int32Collection ic = new Int32Collection();
171 ic.Add(0); ic.Add(1); ic.Add(2); ic.Add(0); ic.Add(2); ic.Add(3);
172 ic.Add(4); ic.Add(6); ic.Add(5); ic.Add(4); ic.Add(7); ic.Add(6);
173 ic.Add(0); ic.Add(5); ic.Add(1); ic.Add(0); ic.Add(4); ic.Add(5);
174 ic.Add(0); ic.Add(3); ic.Add(7); ic.Add(0); ic.Add(7); ic.Add(4);
175 ic.Add(3); ic.Add(6); ic.Add(7); ic.Add(3); ic.Add(2); ic.Add(6);
176 ic.Add(1); ic.Add(6); ic.Add(2); ic.Add(1); ic.Add(5); ic.Add(6);
177 meshg.TriangleIndices = ic;
178 PointCollection tpc = new PointCollection();
179 tpc.Add(new Point(1,1)); tpc.Add(new Point(1, 0));
180 tpc.Add(new Point(0, 0)); tpc.Add(new Point(0, 1));
181 meshg.TextureCoordinates = tpc;
182 DiffuseMaterial dm = new DiffuseMaterial();
183 ImageBrush imageBrush = new ImageBrush();
184 imageBrush.ImageSource =
185 new BitmapImage(
186 new Uri("board2.bmp", UriKind.Relative)
187 );
188 dm.Brush = imageBrush;
189 gm.Geometry = meshg;
190 gm.Material = dm;
191 mg.Children.Add(dl);
192 mg.Children.Add(gm);
193 List<chess> ListOfChess = GetAllPosition();
194 for (int i = 0; i < ListOfChess.Count; i++)
195 {
196 mg.Children.Add( GetChess(ListOfChess.ElementAt(i)));
197 }
198 return mg;
199 }
200 private RotateTransform3D GetRotation()
201 {
202 RotateTransform3D CCTransform = new RotateTransform3D();
203 this.RegisterName(s,rotation);
204 rotation.Axis = new Vector3D(0, 0, 1);
205 rotation.Angle = 0;
206 CCTransform.Rotation = rotation;
207 return CCTransform;
208 }
209 private List<chess> GetAllPosition()
210 {
211 List<chess> ListC = new List<chess>();
212 ListC.Add(new chess("Rrook", 1, new Point(162, 143), red)); ListC.Add(new chess("Rrook", 1, new Point(162, 143 - 8 * Delta), red));
213 ListC.Add(new chess("Rkngt", 2, new Point(162, 143 - Delta), red)); ListC.Add(new chess("Rkngt", 2, new Point(162, 143 - 7 * Delta), red));
214 ListC.Add(new chess("Rbishop", 3, new Point(162, 143 - Delta * 2), red)); ListC.Add(new chess("Rbishop", 3, new Point(162, 143 - Delta * 6), red));
215 ListC.Add(new chess("Rassist", 4, new Point(162, 143 - Delta * 3), red)); ListC.Add(new chess("Rassist", 4, new Point(162, 143 - Delta * 5), red));
216 ListC.Add(new chess("Rking", 5, new Point(162, 143 - Delta*4), red));
217 ListC.Add(new chess("Rgunner", 6, new Point(162 - Delta * 2, 143 - Delta), red)); ListC.Add(new chess("Rgunner", 6, new Point(162 - Delta * 2, 143 - Delta * 7), red));
218 ListC.Add(new chess("Rpawn", 7, new Point(162 - 3 * Delta, 143), red)); ListC.Add(new chess("Rpawn", 7, new Point(162 - 3 * Delta, 143 - 2 * Delta), red));
219 ListC.Add(new chess("Rpawn", 7, new Point(162 - 3 * Delta, 143 - 4 * Delta), red)); ListC.Add(new chess("Rpawn", 7, new Point(162 - 3 * Delta, 143 - 6 * Delta), red));
220 ListC.Add(new chess("Rpawn", 7, new Point(162 - 3 * Delta, 143-8 * Delta), red));
221 ListC.Add(new chess("Brook", 1, new Point(-162, 143), black)); ListC.Add(new chess("Brook", 1, new Point(-162, 143 - 8 * Delta), black));
222 ListC.Add(new chess("Bkngt", 2, new Point(-162, 143 - Delta), black)); ListC.Add(new chess("Bkngt", 2, new Point(-162, 143 - 7 * Delta), black));
223 ListC.Add(new chess("Bbishop", 3, new Point(-162, 143 - Delta * 2), black)); ListC.Add(new chess("Bbishop", 3, new Point(-162, 143 - Delta * 6), black));
224 ListC.Add(new chess("Bassist", 4, new Point(-162, 143 - Delta * 3), black)); ListC.Add(new chess("Bassist", 4, new Point(-162, 143 - Delta * 5), black));
225 ListC.Add(new chess("Bking", 5, new Point(-162, 143 - Delta * 4), black));
226 ListC.Add(new chess("Bgunner", 6, new Point(-162 + Delta * 2, 143 - Delta), black)); ListC.Add(new chess("Bgunner", 6, new Point(-162 + Delta * 2, 143 - Delta * 7), black));
227 ListC.Add(new chess("Bpawn", 7, new Point(-162 + 3 * Delta, 143), black)); ListC.Add(new chess("Bpawn", 7, new Point(-162 + 3 * Delta, 143 - 2 * Delta), black));
228 ListC.Add(new chess("Bpawn", 7, new Point(-162 + 3 * Delta, 143 - 4 * Delta), black)); ListC.Add(new chess("Bpawn", 7, new Point(-162 + 3 * Delta, 143 - 6 * Delta), black));
229 ListC.Add(new chess("Bpawn", 7, new Point(-162 + 3 * Delta, 143 - 8 * Delta), black));
230 return ListC;
231 }
232 private GeometryModel3D GetChess(chess c)
233 {
234 GeometryModel3D gm = new GeometryModel3D();
235 MeshGeometry3D meshg = new MeshGeometry3D();
236
237 Point3DCollection pc = new Point3DCollection();
238 Point3D center = new Point3D(c.GetPosition().X, c.GetPosition().Y, ChessHeight);
239 double ConstAngle = 360 / BorderNum;
240 for (int i = 0; i < BorderNum; i++)
241 {
242 pc.Add(new Point3D(radius * Math.Cos(i*ConstAngle*Math.PI/180) + center.X,radius * Math.Sin(i*ConstAngle*Math.PI/180)+center.Y,ChessHeight));
243 }
244 for (int i = 0; i < BorderNum; i++)
245 {
246 pc.Add(new Point3D(radius * Math.Cos(i * ConstAngle * Math.PI / 180) + center.X, radius * Math.Sin(i * ConstAngle * Math.PI / 180) + center.Y, 0));
247 }
248 pc.Add(center);
249 meshg.Positions = pc;
250 Int32Collection ic = new Int32Collection();
251 for (int i = 0; i < BorderNum-1; i = i+1)
252 {
253 ic.Add(2 * BorderNum); ic.Add(i); ic.Add(i + 1);
254 ic.Add(i); ic.Add(i + BorderNum); ic.Add(i + 1);
255 ic.Add(i+1); ic.Add(i + BorderNum); ic.Add(i + BorderNum + 1);
256 }
257 ic.Add(2 * BorderNum); ic.Add(BorderNum-1); ic.Add(0);
258 ic.Add(BorderNum-1); ic.Add(BorderNum); ic.Add(0);
259 ic.Add(BorderNum-1); ic.Add(2 * BorderNum-1); ic.Add(BorderNum);
260 meshg.TriangleIndices = ic;
261 PointCollection tpc = new PointCollection();
262 for (int i = 0; i < BorderNum; i = i + 1)
263 {
264 tpc.Add(new Point( 0.5+c.GetRedOrBlack()*0.5*Math.Sin(i*ConstAngle*Math.PI/180) ,0.5+c.GetRedOrBlack()*0.5*Math.Cos(i*ConstAngle*Math.PI/180) ) );
265 }
266 for (int i = 0; i < BorderNum; i = i + 1)
267 {
268 tpc.Add(new Point(0.5 + c.GetRedOrBlack() * 0.5 * Math.Sin(i * ConstAngle * Math.PI / 180), 0.5 + c.GetRedOrBlack() * 0.5 * Math.Cos(i * ConstAngle * Math.PI / 180)));
269 }
270 tpc.Add(new Point(0.5, 0.5));
271 meshg.TextureCoordinates = tpc;
272 DiffuseMaterial dm = new DiffuseMaterial();
273 ImageBrush imageBrush = new ImageBrush();
274 imageBrush.ImageSource =
275 new BitmapImage(
276 new Uri(c.GetName()+".bmp", UriKind.Relative)
277 );
278 dm.Brush = imageBrush;
279 gm.Geometry = meshg;
280 gm.Material = dm;
281 // use the imagebrush
282 return gm;
283 }
284 private void initBoardMatrix()
285 {
286 BoardMatrix[0, 0] = -1; BoardMatrix[0, 1] = -2; BoardMatrix[0, 2] = -3; BoardMatrix[0, 3] = -4; BoardMatrix[0, 4] = -5;
287 BoardMatrix[0, 5] = -4; BoardMatrix[0, 6] = -3; BoardMatrix[0, 7] = -2; BoardMatrix[0, 8] = -1;
288 //gunner for black
289 BoardMatrix[2, 1] = -6; BoardMatrix[2, 7] = -6;
290 //
291 BoardMatrix[3, 0] = -7; BoardMatrix[3, 2] = -7; BoardMatrix[3, 4] = -7; BoardMatrix[3, 6] = -7; BoardMatrix[3, 8] = -7;
292 //gunner for red
293 BoardMatrix[7, 1] = 6; BoardMatrix[7, 7] = 6;
294 //
295 BoardMatrix[6, 0] = 7; BoardMatrix[6, 2] = 7; BoardMatrix[6, 4] = 7; BoardMatrix[6, 6] = 7; BoardMatrix[6, 8] = 7;
296 BoardMatrix[9, 0] = 1; BoardMatrix[9, 1] = 2; BoardMatrix[9, 2] = 3; BoardMatrix[9, 3] = 4; BoardMatrix[9, 4] = 5;
297 BoardMatrix[9, 5] = 4; BoardMatrix[9, 6] = 3; BoardMatrix[9, 7] = 2; BoardMatrix[9, 8] = 1;
298 ListForNmae.Add("rook"); ListForNmae.Add("kngt"); ListForNmae.Add("bishop"); ListForNmae.Add("assist");
299 ListForNmae.Add("king"); ListForNmae.Add("gunner"); ListForNmae.Add("pawn");
300 }
301 private bool GetChoosedChess(Point3D p,int CurrentPlayer)
302 {
303 int x = (int)Math.Round((p.X + 162) / Delta); int y = (int)Math.Round((p.Y + 143) / Delta);
304 //MessageBox.Show(BoardMatrix[x, y].ToString());
305 if (BoardMatrix[x, y] * CurrentPlayer > 0)//it's ok
306 {
307 Point newp = new Point(Delta * x - 162, Delta * y - 143);
308 CurrentChess.SetFlag(Math.Abs(BoardMatrix[x, y]));
309 CurrentChess.SetPosition(newp);
310 CurrentChess.SetRedOrBlack(CurrentPlayer);
311 if (CurrentPlayer == red) { CurrentChess.SetName("R" + ListForNmae.ElementAt(BoardMatrix[x, y] - 1)); }
312 else { CurrentChess.SetName("B" + ListForNmae.ElementAt(-BoardMatrix[x, y] - 1)); }
313 Model3DCollection mc = mg.Children;
314 for (int i = 1; i < mc.Count; i++)
315 {
316 //MessageBox.Show("remove");
317 GeometryModel3D gm = mc.ElementAt(i) as GeometryModel3D;
318 MeshGeometry3D meshg = gm.Geometry as MeshGeometry3D;
319 if (clac(new Point3D(newp.X,newp.Y,p.Z), meshg.Positions.Last()) < radius)
320 {
321 //MessageBox.Show(ListForNmae.ElementAt(Math.Abs(BoardMatrix[x, y]) - 1));
322 DiffuseMaterial dm = new DiffuseMaterial();
323 ImageBrush imageBrush = new ImageBrush();
324 imageBrush.ImageSource =
325 new BitmapImage(
326 new Uri(ListForNmae.ElementAt(Math.Abs(BoardMatrix[x, y]) - 1)+".jpg", UriKind.Relative)
327 );
328
329 dm.Brush = imageBrush;
330 gm.Material = dm;
331 break;
332 }
333 }
334 return true;
335 }
336 else { MessageBox.Show("Please choose your own chess!"); return false; }
337 }
338 private bool IsLegal(Point3D p)
339 {
340 int x = (int)Math.Round((p.X + 162) / Delta); int y = (int)Math.Round((p.Y + 143) / Delta);
341 //MessageBox.Show(x.ToString()+y.ToString());
342 if (x>9 ||x<0 || y<0||y>8 || BoardMatrix[x, y] * CurrentChess.GetRedOrBlack() > 0)
343 {
344 //it says that you want move a chess to a your own chess.
345 //MessageBox.Show("illegal moving!");
346 return false;
347 }
348 int currentx = (int)((CurrentChess.GetPosition().X + 162)/ Delta); int currenty = (int)((CurrentChess.GetPosition().Y + 162)/ Delta);
349 switch(CurrentChess.GetFlag())
350 {//for different chess,the action is different
351 case 1://车
352 {//just moving or want to eat one chess
353 if (x == currentx)
354 {
355 int miny = y > currenty ? currenty : y; int maxy = y > currenty ? y : currenty;
356 for (int iy = miny + 1; iy < maxy; iy++) { if (BoardMatrix[x, iy] != 0) { MessageBox.Show("illegal moving!"); return false; } }
357 return true;
358 }
359 else if (y == currenty)
360 {
361 int minx = x > currentx ? currentx : x; int maxx = x > currentx ? x : currentx;
362 for (int ix = minx + 1; ix < maxx; ix++) { if (BoardMatrix[ix, y] != 0) { MessageBox.Show("illegal moving!"); return false; } }
363 return true;
364 }
365 else
366 { MessageBox.Show("illegal moving!"); return false; }
367 //break;
368 }
369 case 2://马
370 {
371 if (currenty - y == 2 && Math.Abs(currentx - x) == 1) { if (BoardMatrix[currentx, currenty - 1] == 0) return true; else { MessageBox.Show("illegal moving!"); return false; } }
372 if (currenty - y == -2 && Math.Abs(currentx - x) == 1) { if (BoardMatrix[currentx, currenty + 1] == 0) return true; else { MessageBox.Show("illegal moving!"); return false; } }
373 if (currentx - x == 2 && Math.Abs(currenty - y) == 1) { if (BoardMatrix[currentx-1, currenty ] == 0) return true; else { MessageBox.Show("illegal moving!"); return false; } }
374 if (currentx - x == -2 && Math.Abs(currenty - y) == 1) { if (BoardMatrix[currentx+1, currenty] == 0) return true; else { MessageBox.Show("illegal moving!"); return false; } }
375 MessageBox.Show("illegal moving!"); return false;
376 //break;
377 }
378 case 3://象
379 {
380 if (CurrentChess.GetRedOrBlack() == red) { if (x <5) { MessageBox.Show("illegal moving!"); return false; } }
381 else { if(x>4) { MessageBox.Show("illegal moving!"); return false; }}
382 if (currentx - x == 2 && currenty - y == 2) { if (BoardMatrix[currentx - 1, currenty - 1] == 0) return true; else { MessageBox.Show("illegal moving!"); return false; } }
383 if (currentx - x == 2 && currenty - y == -2) { if (BoardMatrix[currentx - 1, currenty + 1] == 0) return true; else { MessageBox.Show("illegal moving!"); return false; } }
384 if (currentx - x == -2 && currenty - y == -2) { if (BoardMatrix[currentx + 1, currenty + 1] == 0) return true; else { MessageBox.Show("illegal moving!"); return false; } }
385 if (currentx - x == -2 && currenty - y == 2) { if (BoardMatrix[currentx + 1, currenty - 1] == 0) return true; else { MessageBox.Show("illegal moving!"); return false; } }
386 MessageBox.Show("illegal moving!"); return false;
387 //break;
388 }
389 case 4://士
390 {
391 if (CurrentChess.GetRedOrBlack() == red) { if (x < 7 || y<3 || y>5) { MessageBox.Show("illegal moving!"); return false; } }
392 else { if (x > 2 || y<3|| y>5) { MessageBox.Show("illegal moving!"); return false; } }
393 if (currentx - x == 1 && currenty - y== 1) { return true; }
394 if (currentx - x == -1 && currenty - y == 1) { return true; }
395 if (currentx - x == -1 && currenty - y == -1) { return true; }
396 if (currentx - x == 1 && currenty - y == -1) { return true; }
397 MessageBox.Show("illegal moving!"); return false;
398 //break;
399 }
400 case 5://将
401 {
402 if (CurrentChess.GetRedOrBlack() == red) { if (x < 7 || y < 3 || y > 5) { MessageBox.Show("illegal moving!"); return false; } }
403 else { if (x > 2 || y < 3 || y > 5) { MessageBox.Show("illegal moving!"); return false; } }
404 if (currentx - x == 0 && currenty - y == 1) { return true; }
405 if (currentx - x == 0 && currenty - y == -1) { return true; }
406 if (currentx - x == -1 && currenty - y == 0) { return true; }
407 if (currentx - x == 1 && currenty - y == 0) { return true; }
408 MessageBox.Show("illegal moving!"); return false;
409 //break;
410 }
411 case 6://炮
412 {
413 if (BoardMatrix[x, y] == 0)
414 {
415 //MessageBox.Show(currentx.ToString() + x.ToString());
416 if (x == currentx)
417 {
418 int miny = y > currenty ? currenty : y; int maxy = y > currenty ? y : currenty;
419 //MessageBox.Show(y.ToString()+currenty.ToString());
420 for (int iy = miny + 1; iy < maxy; iy++) { if (BoardMatrix[x, iy] != 0) { MessageBox.Show("illegal moving!"); return false; } }
421 return true;
422 }
423 else if (y == currenty)
424 {
425 int minx = x > currentx ? currentx : x; int maxx = x > currentx ? x : currentx;
426 for (int ix = minx + 1; ix < maxx; ix++) { if (BoardMatrix[ix, y] != 0) { MessageBox.Show("illegal moving!"); return false; } }
427 return true;
428 }
429 }
430 else if(BoardMatrix[x, y]*CurrentChess.GetRedOrBlack() < 0)
431 {
432 //MessageBox.Show((BoardMatrix[x, y] * CurrentChess.GetRedOrBlack()).ToString());
433 if (x == currentx)
434 {
435 int miny = y > currenty ? currenty : y; int maxy = y > currenty ? y : currenty;
436 int count = 0;
437 for (int iy = miny + 1; iy < maxy; iy++) { if (BoardMatrix[x, iy] != 0) { count++; } }
438 if (count != 1) { MessageBox.Show("illegal moving!"); return false; }
439 return true;
440 }
441 else if (y == currenty)
442 {
443 int minx = x > currentx ? currentx : x; int maxx = x > currentx ? x : currentx;
444 int count = 0;
445 for (int ix = minx + 1; ix < maxx; ix++) { if (BoardMatrix[ix, y] != 0) { count++; } }
446 if (count != 1) { MessageBox.Show("illegal moving!"); return false; }
447 return true;
448 }
449 }
450 //MessageBox.Show( (BoardMatrix[x, y]*CurrentChess.GetRedOrBlack()).ToString());
451 MessageBox.Show("illegal moving!"); return false;
452 //break;
453 }
454 case 7://兵
455 {
456 if (CurrentChess.GetRedOrBlack() == red)
457 { if (x > currentx) { MessageBox.Show("illegal moving!"); return false; } if (currentx >= 5) { if (x == currentx) { MessageBox.Show("illegal moving!"); return false; } } }
458 else
459 { if (x < currentx) { MessageBox.Show("illegal moving!"); return false; } if (currentx <= 4) { if (x == currentx) { MessageBox.Show("illegal moving!"); return false; } } }
460 if (currentx == x && Math.Abs(y - currenty) == 1) { return true; }
461 if (currenty == y && Math.Abs(currentx - x) == 1) { return true; }
462 MessageBox.Show("illegal moving!"); return false;
463 //break;
464 }
465 }
466 return false;
467 }
468 private int MoveChess(Point3D p)
469 {
470 int x = (int)Math.Round((p.X + 162) / Delta); int y = (int)Math.Round((p.Y + 143) / Delta);
471 int currentx = (int)((CurrentChess.GetPosition().X + 162) / Delta); int currenty = (int)((CurrentChess.GetPosition().Y + 162) / Delta);
472 Point newp = new Point();
473 int IsKing = BoardMatrix[x, y];
474 if (BoardMatrix[x, y] != 0)
475 {
476 //MessageBox.Show("begin!:::"+p.X.ToString()+":::"+p.Y.ToString()+"::::"+p.Z.ToString());
477 //MessageBox.Show((x * Delta - 162).ToString() + "::::" + (y * Delta - 143).ToString());
478 BoardMatrix[x, y] = CurrentChess.GetFlag() * Player;
479 BoardMatrix[currentx, currenty] = 0;
480 Model3DCollection mc = mg.Children;
481 int len = mc.Count;
482 List<int> index = new List<int>();
483 for (int i = 2; i < len; i++)
484 {
485 GeometryModel3D gm = mc.ElementAt(i) as GeometryModel3D;
486 MeshGeometry3D meshg = gm.Geometry as MeshGeometry3D;
487 if (clac(p, meshg.Positions.Last()) < radius)
488 {
489 newp.X = meshg.Positions.Last().X; newp.Y = meshg.Positions.Last().Y;
490 //MessageBox.Show("remove1");
491 index.Add(i);
492 }
493 if (clac(new Point3D(CurrentChess.GetPosition().X, CurrentChess.GetPosition().Y, ChessHeight), meshg.Positions.Last()) < radius)
494 {
495 //MessageBox.Show("remove2");
496 index.Add(i);
497 }
498 if (index.Count== 2) { break; }
499 }
500 for (int i = 0; i < index.Count; i++)
501 {
502 mg.Children.RemoveAt(index.ElementAt(i)-i);
503 }
504 CurrentChess.SetPosition(newp);
505 mg.Children.Add(GetChess(CurrentChess));
506 }
507 else
508 {
509 BoardMatrix[x, y] = CurrentChess.GetFlag() *Player;
510 BoardMatrix[currentx, currenty] = 0;
511 Model3DCollection mc = mg.Children;
512 for (int i = 2; i < mc.Count; i++)
513 {
514 GeometryModel3D gm = mc.ElementAt(i) as GeometryModel3D;
515 MeshGeometry3D meshg = gm.Geometry as MeshGeometry3D;
516 if (clac(new Point3D(CurrentChess.GetPosition().X, CurrentChess.GetPosition().Y, ChessHeight), meshg.Positions.Last()) < radius)
517 {
518 //MessageBox.Show("remove");
519 mg.Children.RemoveAt(i);
520 break;
521 }
522 }
523 CurrentChess.SetPosition(new Point(x*Delta-162,y*Delta-143));
524 mg.Children.Add(GetChess(CurrentChess));
525 }
526 return (IsKing*Player);
527 }
528 private double clac(Point3D p1, Point3D p2)
529 {
530 return Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y) + (p1.Z - p2.Z) * (p1.Z - p2.Z));
531 }
532 private void DrawButton()
533 {
534 StackPanel rightPanel = new StackPanel();
535 rightPanel.Width=125;rightPanel.Height=600;
536 Canvas.SetLeft(rightPanel,850);Canvas.SetTop(rightPanel,50);
537 rightPanel.Background = Brushes.Black;
538 Button RotateHalf = new Button();
539 RotateHalf.Width = 70; RotateHalf.Height = 50;
540
541 RotateHalf.Background = Brushes.White;
542 string str = "Switch User!";
543 RotateHalf.Content = str;
544 RotateHalf.Name = "rotate180";
545 DoubleAnimation da = new DoubleAnimation();
546 //da.From = RotationFlag * 180; da.To = RotationFlag*180+180;
547 Duration duration = new Duration(TimeSpan.FromSeconds(2));
548 da.Duration = duration;
549 da.RepeatBehavior = new RepeatBehavior(1);
550 Storyboard.SetTargetName(da,s);
551 Storyboard.SetTargetProperty(da,new PropertyPath(AxisAngleRotation3D.AngleProperty));
552 Storyboard sb = new Storyboard();
553 sb.Children.Add(da);
554 RotateHalf.Click += delegate(object sender, RoutedEventArgs args)
555 {
556 da.From = RotationFlag * 180; da.To = RotationFlag * 180 + 180;
557 sb.Begin(RotateHalf);
558 if (RotationFlag == 0) { RotationFlag = 1; } else { RotationFlag = 0; }
559 rotation.Angle = rotation.Angle % 360;
560 };
561 rightPanel.Children.Add(RotateHalf);
562 Panel.Children.Add(rightPanel);
563 }
564 private void AutoBeginAnimation()
565 {
566 DoubleAnimation da = new DoubleAnimation();
567 //da.From = RotationFlag * 180; da.To = RotationFlag*180+180;
568 Duration duration = new Duration(TimeSpan.FromSeconds(2));
569 da.Duration = duration;
570 da.RepeatBehavior = new RepeatBehavior(1);
571 da.From = RotationFlag * 180; da.To = RotationFlag * 180 + 180;
572 Storyboard.SetTargetName(da, s);
573 Storyboard.SetTargetProperty(da, new PropertyPath(AxisAngleRotation3D.AngleProperty));
574 Storyboard sb = new Storyboard();
575 sb.Children.Add(da);
576
577 if (RotationFlag == 0) { RotationFlag = 1; } else { RotationFlag = 0; }
578 rotation.Angle = rotation.Angle % 360;
579 }
580 }
581 public class chess
582 {
583 private string name;
584 private int flag;
585 private Point position;
586 private int RedOrBlack;
587 public chess()
588 { }
589 public chess(string name,int flag,Point position,int RedOrBlack)
590 {
591 this.name = name; this.position = position;
592 this.flag = flag; this.RedOrBlack = RedOrBlack;
593 }
594 public string GetName()
595 {
596 return name;
597 }
598 public int GetFlag()
599 {
600 return flag;
601 }
602 public Point GetPosition()
603 {
604 return position;
605 }
606 public int GetRedOrBlack()
607 {
608 return RedOrBlack;
609 }
610 public void SetName(string name)
611 {
612 this.name = name ;
613 }
614 public void SetFlag(int flag)
615 {
616 this.flag = flag;
617 }
618 public void SetPosition(Point p)
619 {
620 this.position = p;
621 }
622 public void SetRedOrBlack(int RedOrBlack)
623 {
624 this.RedOrBlack = RedOrBlack;
625 }
626 }
627}
只要将上述代码贴到你的mainwindow,xmal,cs中就可以了。但是需要一些图片资源,那个我没法提供。
如果有需要可以联系fire_fuxm@hotmail.com.