Silverlight学习之贪吃蛇游戏

花了半天时间用Silverlight做了一个贪吃蛇游戏,从设计到编码完全原创。由于本人在界面美工方面相对较弱,所以界面相对比较单调。现在将源码拿出来分享,比较简单,非常适合初学者。
整个游戏页面展示如下图:

Silverlight学习之贪吃蛇游戏
首先,新建一个SilverlightApplication取名为SilverlightSnake,这边VS2010自带的是Silverlight3.0,我用了Silverlight4.0,读者建项目的时候用3.0运行我的程序我不知道会不会出问题,应该是不会有什么问题了。
然后分别打开MainPage.xaml和MainPage.xaml.cs
用如下代码覆盖这两个文件:

MainPage.xaml

 

代码
   
     
< UserControl x:Class = " SilverlightSnake.MainPage "
xmlns
= " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
xmlns:x
= " http://schemas.microsoft.com/winfx/2006/xaml "
xmlns:d
= " http://schemas.microsoft.com/expression/blend/2008 "
xmlns:mc
= " http://schemas.openxmlformats.org/markup-compatibility/2006 "
mc:Ignorable
= " d "
d:DesignHeight
= " 450 " d:DesignWidth = " 650 " >
< Grid Height = " 500 " Name = " grid1 " Width = " 800 " KeyUp = " grid1_KeyUp " >
< Grid Height = " 500 " HorizontalAlignment = " Left " Name = " grid2 " VerticalAlignment = " Top " Width = " 500 " Background = " Azure " >
</ Grid >
< StackPanel Height = " 500 " HorizontalAlignment = " Left " Margin = " 500,100,0,0 " Name = " stackPanel1 " VerticalAlignment = " Top " Width = " 100 " >
< Button Content = " start " Height = " 25 " Name = " button1 " Width = " 85 " Click = " button1_Click " Margin = " 0,10 " Background = " Red " />
< Button Content = " pause " Height = " 25 " Name = " button2 " Width = " 85 " Click = " button2_Click " Margin = " 0,10 " Background = " Red " />
< Button Content = " stop " Height = " 25 " Name = " button3 " Width = " 85 " Click = " button3_Click " Margin = " 0,10 " Background = " Red " />
</ StackPanel >
</ Grid >
</ UserControl >

MainPage.xaml.cs

代码
   
     
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using System.Windows.Navigation;
using System.Windows.Browser;

namespace SilverlightSnake
{
public partial class MainPage : UserControl
{
// 定时器间隔时间
int time = 350 ;
// 判断是否该改变time,1是可以改变
int v = 0 ;
// 游戏是否已经开始
bool gameStart = false ;
// 定义图片的长和宽
int w = 25 ;
int h = 25 ;
// 定义图片
Image imageTemporary;
// 蛇身,用string表示,如"0,0"代表坐标为0,0
List < string > snake = new List < string > ();
// 用来标识食物坐标
int x, y;
// 蛇移动方向,0-右,1-下,2-左,3-上
int direction = 0 ;
// 用于grid2中的元素记录,删除grid2中元素时用它定位
int t = 0 ;
// 用于grid2中的蛇身记录
List < int > t1 = new List < int > ();
// 用于grid2中的食物记录
List < int > t2 = new List < int > ();
// 用于记录已经在grid2中被移除的个数,删除grid2中元素时用它定位
int p = 0 ;
// 定义定时器
DispatcherTimer dispatcherTimer = new DispatcherTimer();
BitmapImage bi;
Random rd1;
// 初始化食物的位置,即改变它可以改变页面初始时的食物位置,注意不要超过页面grid2
int wN = 5 ;
int hN = 2 ;
public MainPage()
{
InitializeComponent();
Initialize();
}
public void Initialize()
{
// 蛇头
bi = new BitmapImage();
bi.UriSource
= new Uri( " Image/11.png " , UriKind.Relative);
imageTemporary
= new Image();
imageTemporary.Width
= w;
imageTemporary.Height
= h;
imageTemporary.Margin
= new Thickness( 0 , 0 , grid2.Width - w, grid2.Height - h);
imageTemporary.Source
= bi;
grid2.Children.Add(imageTemporary);
snake.Add(
" 0,0 " );
t1.Add(t);
t
++ ;
// 固定生成第一个食物
bi = new BitmapImage();
bi.UriSource
= new Uri( " Image/22.png " , UriKind.Relative);
imageTemporary
= new Image();
imageTemporary.Width
= w;
imageTemporary.Height
= h;
imageTemporary.Margin
= new Thickness(wN * w, hN * h, grid2.Width - w - wN * w, grid2.Height - h - hN * h);
imageTemporary.Source
= bi;
grid2.Children.Add(imageTemporary);
t2.Add(t);
t
++ ;
x
= wN * w;
y
= hN * h;
}
/// <summary>
/// 开始游戏
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click( object sender, RoutedEventArgs e)
{
if (gameStart)
{
return ;
}
else
{
dispatcherTimer.Tick
+= new EventHandler(Timer_Tick);
dispatcherTimer.Interval
= TimeSpan.FromMilliseconds(time); // 重复间隔
dispatcherTimer.Start();
gameStart
= ! gameStart;
}
}
/// <summary>
/// 暂停或继续游戏
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click( object sender, RoutedEventArgs e)
{
if (gameStart)
{
if (button2.Content.ToString().Equals( " pause " ))
{
dispatcherTimer.Stop();
button2.Content
= " continue " ;
}
else
{
dispatcherTimer.Start();
button2.Content
= " pause " ;
}
}
else
{
return ;
}
}
/// <summary>
/// 结束游戏
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click( object sender, RoutedEventArgs e)
{
// 刷新一下页面
HtmlPage.Window.Eval( " location.reload(); " );
}
/// <summary>
/// 蛇身定时移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Timer_Tick( object sender, EventArgs e)
{
if (time > 100 && snake.Count % 3 == 0 && v == 1 )
{
time
= time - 30 ;
dispatcherTimer.Interval
= TimeSpan.FromMilliseconds(time);
v
= 0 ;
}
// 蛇头的XY坐标
int xx = int .Parse(snake[snake.Count - 1 ].Split( ' , ' )[ 0 ]);
int yy = int .Parse(snake[snake.Count - 1 ].Split( ' , ' )[ 1 ]);
if (direction == 0 ) //
{
if (xx == grid2.Width - w || snake.Contains((xx + w).ToString() + " , " + h.ToString()))
{
MessageBox.Show(
" Game Over! " );
HtmlPage.Window.Eval(
" location.reload(); " );
}
else
{
// 前方不是食物
if ( ! ((xx + w) == x && yy == y))
{
snake.Remove(snake[
0 ]);
snake.Add((xx
+ w).ToString() + " , " + yy.ToString());
RemoveBody1();
AddBody1(xx
+ w, yy);
}
// 前方是食物
else
{
snake.Add((xx
+ w).ToString() + " , " + yy.ToString());
AddBody1(xx
+ w, yy);
RemoveBody2();
DoRandom();
}
}
}
else if (direction == 1 ) //
{
if (yy == grid2.Height - h || snake.Contains(xx.ToString() + " , " + (yy + h).ToString()))
{
MessageBox.Show(
" Game Over! " );
HtmlPage.Window.Eval(
" location.reload(); " );
}
else
{
// 前方不是食物
if ( ! ((yy + h) == y && xx == x))
{
snake.Remove(snake[
0 ]);
snake.Add(xx.ToString()
+ " , " + (yy + h).ToString());
RemoveBody1();
AddBody1(xx, yy
+ h);
}
// 前方是食物
else
{
snake.Add(xx.ToString()
+ " , " + (yy + h).ToString());
AddBody1(xx, yy
+ h);
RemoveBody2();
DoRandom();
}
}
}
else if (direction == 2 ) //
{
if (xx == 0 || snake.Contains((xx - w).ToString() + " , " + yy.ToString()))
{
MessageBox.Show(
" Game Over! " );
HtmlPage.Window.Eval(
" location.reload(); " );
}
else
{
// 前方不是食物
if ( ! ((xx - w) == x && yy == y))
{
snake.Remove(snake[
0 ]);
snake.Add((xx
- w).ToString() + " , " + yy.ToString());
RemoveBody1();
AddBody1(xx
- w, yy);
}
// 前方是食物
else
{
AddBody1(xx
- w, yy);
snake.Add((xx
- w).ToString() + " , " + yy.ToString());
RemoveBody2();
DoRandom();
}
}
}
else if (direction == 3 ) //
{
if (yy == 0 || snake.Contains(xx.ToString() + " , " + (yy - h).ToString()))
{
MessageBox.Show(
" Game Over! " );
HtmlPage.Window.Eval(
" location.reload(); " );
}
else
{
// 前方不是食物
if ( ! ((yy - h) == y && xx == x))
{
snake.Remove(snake[
0 ]);
snake.Add(xx.ToString()
+ " , " + (yy - h).ToString());
AddBody1(xx, yy
- h);
RemoveBody1();
}
// 前方是食物
else
{
snake.Add(xx.ToString()
+ " , " + (yy - h).ToString());
AddBody1(xx, yy
- h);
RemoveBody2();
DoRandom();
}
}
}
}
/// <summary>
/// 响应键盘事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void grid1_KeyUp( object sender, KeyEventArgs e)
{
if (e.Key == Key.Right && direction != 2 )
{
direction
= 0 ;
}
else if (e.Key == Key.Down && direction != 3 )
{
direction
= 1 ;
}
else if (e.Key == Key.Left && direction != 0 )
{
direction
= 2 ;
}
else if (e.Key == Key.Up && direction != 1 )
{
direction
= 3 ;
}
else
{
return ;
}
}
// 随机生成食物坐标
private void DoRandom()
{
rd1
= new Random();
x
= rd1.Next( int .Parse((grid2.Width / w).ToString())) * w;
y
= rd1.Next( int .Parse((grid2.Height / h).ToString())) * h;
if (snake.Contains(x.ToString() + " , " + y.ToString()))
{
DoRandom();
}
else
{
AddBody2(x, y);
}
}
// 添加一个蛇身段
private void AddBody1( int a, int b)
{
bi
= new BitmapImage();
bi.UriSource
= new Uri( " Image/11.png " , UriKind.Relative);
imageTemporary
= new Image();
imageTemporary.Width
= w;
imageTemporary.Height
= h;
imageTemporary.Margin
= new Thickness(a, b, grid2.Width - w - a, grid2.Height - h - b);
imageTemporary.Source
= bi;
grid2.Children.Add(imageTemporary);
t1.Add(t);
t
++ ;
}
// 添加一个食物
private void AddBody2( int a, int b)
{
bi
= new BitmapImage();
bi.UriSource
= new Uri( " Image/22.png " , UriKind.Relative);
imageTemporary
= new Image();
imageTemporary.Width
= w;
imageTemporary.Height
= h;
imageTemporary.Margin
= new Thickness(a, b, grid2.Width - w - a, grid2.Height - h - b);
imageTemporary.Source
= bi;
grid2.Children.Add(imageTemporary);
t2.Add(t);
t
++ ;
v
= 1 ;
}
// 删除grid2的蛇身记录
private void RemoveBody1()
{
if (t1[ 0 ] < p)
{
grid2.Children.RemoveAt(
0 );
}
else
{
grid2.Children.RemoveAt(t1[
0 ] - p);
}
p
++ ;
t1.RemoveAt(
0 );
}
// 删除grid2的食物记录
private void RemoveBody2()
{
// 这里面的目的是判断一下蛇身长度和蛇吃上一个食物到吃当前食物所走的路程,如果路程小于蛇身长则走else流程,此处比较有深意,读者需要细细体会
if (t2[ 0 ] < p)
{
grid2.Children.RemoveAt(
0 );
}
else
{
grid2.Children.RemoveAt(t2[
0 ] - p);
}
p
++ ;
t2.RemoveAt(
0 );
}
}
}

程序中的蛇身和食物我分别用了两个小图11.png、22.png,如下

          Silverlight学习之贪吃蛇游戏

读者需将图片下载下来放到如下工程目录中

Silverlight学习之贪吃蛇游戏

接下来就可以Ctrl+F5了,如果程序没问题应该就可以开始Play Game了。
这边关于代码我就不解释了,程序中都加了注释,代码不多,但这里面的思想读者可能需要花一点时间理解。这个只是我的初级版本,主要是能让读者快速有感觉,不至于因为功能多代码多而让初学者望而却步,有兴趣的读者可以自己试着改进我的代码。言至于此,无限感慨!

你可能感兴趣的:(silverlight)