这是开始学习silverlight的第一个游戏
源码下载 https://files.cnblogs.com/hubj/Movebox.rar
感谢各位的关注,已增加重新开始功能! :)
click onto the red block with jump over it:
鼠标移动到红色部分。
move the red block avoiding crash with the blue ones
拖动红块,避免碰到蓝色部分。
don't touch the black edge.
不要碰到黑色区域。
if you can reach more than 18 seconds, you are a genius.
如果你能达到18秒以上,你算得上是个天才。
1、游戏管理类
GameManager.cs
Page.xaml.cs

Code
1
using System;
2
using System.Net;
3
using System.Windows;
4
using System.Windows.Controls;
5
using System.Windows.Documents;
6
using System.Windows.Ink;
7
using System.Windows.Input;
8
using System.Windows.Media;
9
using System.Windows.Media.Animation;
10
using System.Windows.Shapes;
11
using System.Windows.Threading;
12
using System.Collections.Generic;
13
14
namespace Movebox
15

{
16
public class GameManager
17
{
18
/**//// <summary>
19
/// 游戏状态(Ready, Play, Pause, Over)
20
/// </summary>
21
///
22
public GameStatus GameStatus
{ get; set; }
23
24
/**//// <summary>
25
/// 移动速度
26
/// </summary>
27
public double MoveSpeed
{ get; set; }
28
29
private double initSpeed = 13; // 初始速率(毫秒)
30
31
private DispatcherTimer timer;
32
33
public List<Enemy> enemies; //敌方
34
35
private Canvas layoutRoot;
36
private Owner owner; //玩家
37
Enemy enemy1;
38
Enemy enemy2;
39
Enemy enemy3;
40
Enemy enemy4;
41
42
public GameManager(Canvas _layoutRoot, Owner _owner)
43
{
44
enemies = new List<Enemy>();
45
this.layoutRoot = _layoutRoot;
46
this.owner = _owner;
47
48
timer = new DispatcherTimer();
49
timer.Interval = TimeSpan.FromMilliseconds(initSpeed);
50
timer.Tick += new EventHandler(timer_Tick);
51
52
enemy1 = new Enemy();
53
enemy2 = new Enemy();
54
enemy3 = new Enemy();
55
enemy4 = new Enemy();
56
57
enemies.Add(enemy1);
58
enemies.Add(enemy2);
59
enemies.Add(enemy3);
60
enemies.Add(enemy4);
61
62
InitEnemisPoint();
63
64
}
65
66
/**//// <summary>
67
/// 初始化位置
68
/// </summary>
69
/// <param name="_layoutRoot"></param>
70
private void InitEnemisPoint()
71
{
72
73
enemy1.X = 70; //初始化位置
74
enemy1.Y = 70;
75
enemy1.InitSpeedY = 2;
76
enemy1.InitSpeedX = 6;
77
enemy1.ContainerWidth = (int)layoutRoot.Width;
78
enemy1.ContainerHeight = (int)layoutRoot.Height;
79
80
enemy2.X = 270; //初始化位置
81
enemy2.Y = 60;
82
enemy2.InitSpeedY = 5;
83
enemy2.InitSpeedX = 3;
84
enemy2.Dimension(60, 50);
85
enemy2.ContainerWidth = (int)layoutRoot.Width;
86
enemy2.ContainerHeight = (int)layoutRoot.Height;
87
88
enemy3.X = 70; //初始化位置
89
enemy3.Y = 320;
90
enemy3.InitSpeedY = 3;
91
enemy3.InitSpeedX = 5;
92
enemy3.Dimension(30, 60);
93
enemy3.ContainerWidth = (int)layoutRoot.Width;
94
enemy3.ContainerHeight = (int)layoutRoot.Height;
95
96
enemy4.X = 300; //初始化位置
97
enemy4.Y = 330;
98
enemy4.InitSpeedY = 4;
99
enemy4.InitSpeedX = 4;
100
enemy4.Dimension(100, 20);
101
enemy4.ContainerWidth = (int)layoutRoot.Width;
102
enemy4.ContainerHeight = (int)layoutRoot.Height;
103
104
GameStatus = GameStatus.Ready;
105
}
106
107
/**//// <summary>
108
/// 开始游戏(启动计时器)
109
/// </summary>
110
public void Play()
111
{
112
GameStatus = GameStatus.Play;
113
timer.Start();
114
115
}
116
117
/**//// <summary>
118
/// 暂停游戏(停止计时器)
119
/// </summary>
120
public void Pause()
121
{
122
timer.Stop();
123
GameStatus = GameStatus.Pause;
124
125
}
126
127
/**//// <summary>
128
/// 重新开始
129
/// </summary>
130
public void Resart()
131
{
132
InitEnemisPoint();
133
}
134
135
/**//// <summary>
136
/// 开始运行
137
/// </summary>
138
/// <param name="sender"></param>
139
/// <param name="e"></param>
140
private void timer_Tick(object sender, EventArgs e)
141
{
142
OnGrameRun(null);
143
foreach (Enemy enemy in enemies)
144
MoveEnemy(enemy);
145
}
146
147
/**//// <summary>
148
/// 移动敌方
149
/// </summary>
150
public void MoveEnemy(Enemy enemy)
151
{
152
if (GameStatus != GameStatus.Play) return;
153
154
if (!IsBoundary(enemy))
155
{
156
enemy.Move = true;
157
enemy.Speed = MoveSpeed;
158
}
159
else
160
{
161
OnGameOver(null);
162
this.Pause();
163
}
164
}
165
166
/**//// <summary>
167
/// 是否敌方与玩家撞击
168
/// </summary>
169
/// <param name="x"></param>
170
/// <param name="y"></param>
171
/// <param name="xw"></param>
172
/// <param name="yh"></param>
173
/// <returns></returns>
174
private bool IsBoundaryForOwner(double x, double y, double xw, double yh)
175
{
176
bool bCollision = false;
177
double getpointx = owner.X - Convert.ToInt32(x + xw);
178
double getpointy = owner.Y - Convert.ToInt32(y + yh);
179
if ((getpointy <= 0 && y <= (owner.Y + owner.Height)) && (getpointx <= 0 && x <= (owner.X + owner.Width)))
180
{
181
bCollision = true;
182
}
183
return bCollision;
184
}
185
186
/**//// <summary>
187
/// 是否撞击
188
/// </summary>
189
/// <returns></returns>
190
private bool IsBoundary(Enemy enemy)
191
{
192
return IsBoundaryForOwner(enemy.X, enemy.Y, enemy.Width, enemy.Height);
193
}
194
195
196
public event EventHandler GameOver;
197
public event EventHandler GrameRun;
198
199
private void OnGrameRun(EventArgs e)
200
{
201
EventHandler handler = GrameRun;
202
if (handler != null)
203
handler(this, e);
204
}
205
206
/**//// <summary>
207
/// 游戏结束后所调用的方法,并触发游戏结束事件
208
/// </summary>
209
/// <param name="e"></param>
210
private void OnGameOver(EventArgs e)
211
{
212
GameStatus = GameStatus.Over;
213
timer.Interval = TimeSpan.FromMilliseconds(initSpeed);
214
timer.Stop();
215
216
EventHandler handler = GameOver;
217
if (handler != null)
218
handler(this, e);
219
}
220
221
}
222
}
223
DragManager.cs

Code
1
using System;
2
using System.Net;
3
using System.Windows;
4
using System.Windows.Controls;
5
using System.Windows.Documents;
6
using System.Windows.Ink;
7
using System.Windows.Input;
8
using System.Windows.Media;
9
using System.Windows.Media.Animation;
10
using System.Windows.Shapes;
11
using System.Collections.Generic;
12
13
namespace Movebox
14

{
15
public class DragManager
16
{
17
private bool isStartMove = true;
18
private bool isDragging = false;
19
private Point lastMousePosition;
20
private UIElement layoutRoot;
21
private UIElement elementToDrag;
22
23
/**//// <summary>
24
/// 碰撞事件(未用)
25
/// </summary>
26
public event EventHandler<CollisionEventArgs> OnCollision;
27
/**//// <summary>
28
/// 第一次移动触发事件
29
/// </summary>
30
public event EventHandler<EventArgs> OnFristTimeMove;
31
/**//// <summary>
32
/// 拖动事件
33
/// </summary>
34
public event EventHandler<EventArgs> OnDragMove;
35
36
public DragManager(UIElement layoutRoot)
37
{
38
this.layoutRoot = layoutRoot;
39
}
40
41
42
public void EnableDragableElement(UIElement elementToDrag)
43
{
44
this.elementToDrag = elementToDrag;
45
46
this.elementToDrag.MouseLeftButtonDown += element_MouseLeftButtonDown;
47
this.elementToDrag.MouseMove += elementToDrag_MouseMove;
48
this.elementToDrag.MouseLeftButtonUp += elementToDrag_MouseLeftButtonUp;
49
50
}
51
52
public void DisableDragableElement()
53
{
54
isDragging = false;
55
elementToDrag.MouseLeftButtonDown -= element_MouseLeftButtonDown;
56
elementToDrag.MouseMove -= elementToDrag_MouseMove;
57
elementToDrag.MouseLeftButtonUp -= elementToDrag_MouseLeftButtonUp;
58
isStartMove = true;
59
}
60
61
void elementToDrag_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
62
{
63
Owner element = (Owner)sender;
64
element.Cursor =null;
65
element.ReleaseMouseCapture();
66
isDragging = false;
67
}
68
69
void elementToDrag_MouseMove(object sender, MouseEventArgs e)
70
{
71
if (isDragging)
72
{
73
74
Owner element = (Owner)sender;
75
// TranslateTransform transform = GetTranslateTransform(element);
76
Point currentMousePosition = e.GetPosition(layoutRoot);
77
double mouseX = currentMousePosition.X - lastMousePosition.X;
78
double mouseY = currentMousePosition.Y - lastMousePosition.Y;
79
element.X += mouseX;
80
element.Y += mouseY;
81
82
if (OnCollision != null)
83
{
84
List<UIElement> collidedElements = VisualTreeHelper.FindElementsInHostCoordinates(currentMousePosition, layoutRoot) as List<UIElement>;
85
collidedElements.Remove(element);
86
collidedElements.Remove(layoutRoot);
87
88
if (collidedElements.Count > 0)
89
{
90
CollisionEventArgs args = new CollisionEventArgs()
{ Element = element, Position = currentMousePosition, CollidedElements = collidedElements };
91
OnCollision(this, args);
92
}
93
}
94
95
EventArgs moveagrs = new EventArgs();
96
OnDragMove(this, moveagrs);
97
98
lastMousePosition = currentMousePosition;
99
100
}
101
}
102
103
void element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
104
{
105
isDragging = true;
106
if (isStartMove)
107
{
108
EventArgs args = new EventArgs() ;
109
OnFristTimeMove(this, args);
110
isStartMove=false;
111
}
112
Owner element = (Owner)sender;
113
element.Cursor = Cursors.Hand;
114
115
lastMousePosition = e.GetPosition(layoutRoot);
116
((UIElement)sender).CaptureMouse();
117
}
118
119
private TranslateTransform GetTranslateTransform(UIElement element)
120
{
121
TranslateTransform translateTransform = null;
122
if (element.RenderTransform is TranslateTransform)
123
{
124
translateTransform = element.RenderTransform as TranslateTransform;
125
}
126
else if (element.RenderTransform is TransformGroup)
127
{
128
TransformGroup group = element.RenderTransform as TransformGroup;
129
foreach (GeneralTransform transform in group.Children)
130
{
131
if (transform is TranslateTransform)
132
{
133
translateTransform = transform as TranslateTransform;
134
}
135
}
136
}
137
else
138
{
139
translateTransform = new TranslateTransform();
140
element.RenderTransform = translateTransform;
141
}
142
return translateTransform;
143
}
144
145
}
146
147
public class CollisionEventArgs : EventArgs
148
{
149
150
public UIElement Element
{ get; set; }
151
public Point Position
{ get; set; }
152
public List<UIElement> CollidedElements
{ get; set; }
153
}
154
155
}
156
Enemy.xaml.cs

Code
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Net;
5
using System.Windows;
6
using System.Windows.Controls;
7
using System.Windows.Documents;
8
using System.Windows.Input;
9
using System.Windows.Media;
10
using System.Windows.Media.Animation;
11
using System.Windows.Shapes;
12
13
namespace Movebox
14

{
15
public partial class Enemy : UserControl
16
{
17
//容器宽度高度
18
public int ContainerWidth
{ get; set; }
19
public int ContainerHeight
{ get; set; }
20
21
public Enemy()
22
{
23
InitializeComponent();
24
this.Speed = 1.001;
25
26
}
27
28
public double X
29
{
30
set
31
{
32
rectangle_enemy1_point.X = value;
33
}
34
get
{ return rectangle_enemy1_point.X; }
35
}
36
37
public double Y
38
{
39
set
40
{
41
rectangle_enemy1_point.Y=value;
42
}
43
get
{ return rectangle_enemy1_point.Y; }
44
}
45
46
/**//// <summary>
47
/// 设置尺寸
48
/// </summary>
49
/// <param name="_w">宽</param>
50
/// <param name="_h">高</param>
51
public void Dimension(double _w, double _h)
52
{
53
this.Width = _w;
54
this.Height = _h;
55
rectangle_enemy1.Width = _w;
56
rectangle_enemy1.Height = _h;
57
}
58
59
public double Speed
{ get; set; }
60
61
private bool hDirect=true;
62
private bool wDirect=true;
63
64
/**//// <summary>
65
/// 初始化X,Y移动步长
66
/// </summary>
67
public double InitSpeedY
{ get; set; }
68
public double InitSpeedX
{ get; set; }
69
70
public bool Move
71
{
72
set
73
{
74
if (value)
75
{
76
if (this.Y <= 0) hDirect = true;
77
78
if (hDirect && (this.Y < (ContainerHeight - this.Height)))
79
{
80
this.Y += Speed * InitSpeedY;
81
82
}
83
else
84
{
85
this.Y -= Speed * InitSpeedY;
86
hDirect = false;
87
88
}
89
90
if (this.X <= 0) wDirect = true;
91
92
if (wDirect && (this.X < (ContainerWidth - this.Width)))
93
{
94
this.X += Speed * InitSpeedX;
95
96
}
97
else
98
{
99
this.X -= Speed * InitSpeedX;
100
wDirect = false;
101
102
}
103
104
}
105
106
}
107
}
108
109
110
}
111
}
112
Owner.xaml.cs

Code
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Net;
5
using System.Windows;
6
using System.Windows.Controls;
7
using System.Windows.Documents;
8
using System.Windows.Input;
9
using System.Windows.Media;
10
using System.Windows.Media.Animation;
11
using System.Windows.Shapes;
12
13
namespace Movebox
14

{
15
public partial class Owner : UserControl
16
{
17
public Owner()
18
{
19
InitializeComponent();
20
}
21
22
public double X
23
{
24
set
25
{
26
rectangle_owner_point.X = value;
27
}
28
get
{ return rectangle_owner_point.X; }
29
}
30
31
public double Y
32
{
33
set
34
{
35
rectangle_owner_point.Y = value;
36
}
37
get
{ return rectangle_owner_point.Y; }
38
}
39
}
40
}
Page.xaml.cs

Code
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Net;
5
using System.Windows;
6
using System.Windows.Controls;
7
using System.Windows.Documents;
8
using System.Windows.Input;
9
using System.Windows.Media;
10
using System.Windows.Media.Animation;
11
using System.Windows.Shapes;
12
13
namespace Movebox
14

{
15
public partial class Page : UserControl
16
{
17
GameManager gm;
18
Owner me;
19
DragManager dm;
20
DateTime startTime;
21
22
public Page()
23
{
24
InitializeComponent();
25
26
this.Loaded += new RoutedEventHandler(Page_Loaded);
27
}
28
29
void Page_Loaded(object sender, RoutedEventArgs e)
30
{
31
dm = new DragManager(layoutRoot);
32
33
me = new Owner();
34
35
layoutRoot.Children.Add(me);
36
37
gm = new GameManager(layoutRoot, me);
38
gm.GameOver += new EventHandler(gm_GameOver);
39
gm.GrameRun += new EventHandler(gm_GrameRun);
40
41
foreach (Enemy enemy in gm.enemies)
42
layoutRoot.Children.Add(enemy);
43
44
dm.OnCollision += dm_Collision;
45
46
47
owner_Init();
48
}
49
50
/**//// <summary>
51
/// 初始化Owner
52
/// </summary>
53
void owner_Init()
54
{
55
me.X = 205;
56
me.Y = 205;
57
gm.MoveSpeed = 0.9;
58
dm.EnableDragableElement(me);
59
dm.OnDragMove += dm_OnDragMove;
60
dm.OnFristTimeMove += dm_MoveEventArgs;
61
62
gm.MoveSpeed = 0.9;
63
levelName.Text = "菜鸟";
64
levelRect.Height = 1;
65
}
66
67
68
69
void gm_GrameRun(object sender, EventArgs e)
70
{
71
levelRect.Height+=.1;
72
double s=(DateTime.Now - this.startTime).TotalSeconds;
73
if (s > 10 && s <= 15)
74
{
75
levelName.Text = "老鸟";
76
gm.MoveSpeed = 1.1;
77
}
78
if (s > 15 && s <= 20)
79
{
80
levelName.Text = "高手";
81
gm.MoveSpeed = 1.3;
82
}
83
if (s > 20)
84
{
85
levelName.Text = "天才";
86
gm.MoveSpeed = 1.5;
87
}
88
if (s > 30)
89
{
90
levelName.Text = "无敌";
91
gm.MoveSpeed = 2;
92
}
93
runTime.Text = (string.Format("{0}秒", s));
94
}
95
96
/**//// <summary>
97
/// 拖动
98
/// </summary>
99
/// <param name="sender"></param>
100
/// <param name="e"></param>
101
void dm_OnDragMove(object sender, EventArgs e)
102
{
103
currentPointBox.Text = "x:" + me.X + " y:" + me.Y;
104
if (((me.X + me.Width >= 400)
105
||
106
(me.X <= 50)) || (((me.Y + me.Height >= 400)
107
||
108
(me.Y <= 50))))
109
{
110
gm_GameOver(sender, e);
111
currentPointBox.Text += " 撞上了";
112
113
114
}
115
}
116
117
/**//// <summary>
118
/// 游戏开始
119
/// </summary>
120
/// <param name="sender"></param>
121
/// <param name="e"></param>
122
123
void dm_MoveEventArgs(object sender, EventArgs e)
124
{
125
startTime = DateTime.Now;
126
gm.Play();
127
runTime.Text = "";
128
}
129
130
/**//// <summary>
131
/// 游戏结束
132
/// </summary>
133
/// <param name="sender"></param>
134
/// <param name="e"></param>
135
void gm_GameOver(object sender, EventArgs e)
136
{
137
dm.DisableDragableElement();
138
gm.Pause();
139
resultBtn.Visibility = Visibility.Visible;
140
resultBtn.Content = "您坚持了" + runTime.Text + ",级别:" + levelName.Text;
141
142
}
143
void dm_Collision(object sender, CollisionEventArgs e)
144
{
145
146
}
147
148
private void resultBtn_Click(object sender, RoutedEventArgs e)
149
{
150
resultBtn.Visibility = Visibility.Collapsed;
151
owner_Init();
152
gm.Resart();
153
runTime.Text = "";
154
currentPointBox.Text = "";
155
}
156
157
158
}
159
}
160