Silverlight:手把手教你写俄罗斯方块(五)(完)
/// <summary>
/// 构造固定砖块
/// </summary>
/// <param name="high">高度</param>
private void Paintguding(int high)
{
for (int h = 0; h < high; h++)
{
for (int i = 0; i < width; i++)
{
staticRect[i, height - 1 - h] = true;
}
Random rd = new Random();
int len = rd.Next(1, 5);
for (int l = 0; l < len; l++)
{
int ii = rd.Next(0, 9);
staticRect[ii, 19 - h] = false;
}
System.Threading.Thread.Sleep(20);
}
this.PaintBack();
}
原理就是,我们根据高度,先把指定高度的所有方块全部填满(即赋值为true),然后取1-4的随机数作为len的值,len表示一行中有几个方块被挖掉,也就是所谓的空白,然后遍历这个长度,在这一行中随机取len个方块,将它们挖掉(即赋值为false)。这里使线程暂停了20毫米,这样做可以防止随机数产生重复数的概率过高。然后绘制画板。
二.游戏开始的方法:
public void StartGame()
{
this.Clear();
this.Paintguding(12);
runBlock = GetBlock(4, 0);
runBlock.Show(board);
System.Threading.Thread.Sleep(200); //防止移动方块和准备方块一样
readyBlock = GetBlock(1, 1);
readyBlock.Show(readyBoard);
status = GameStatus.Ready;
}
Clear方法相当于把画板和积分全部清空,或许您觉得这个方法好像并没有必要,但是在游戏结束后,重新开始的时候,我们就需要执行这个方法重新初始化一遍了。具体代码如下:
private void Clear()
{
this.score.Text = "0"; //清空积分
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
staticRect[i, j] = false;
board[i, j].Color = null;
}
}
this.PaintReadyBack();
}
继续游戏与暂停游戏,代码如下:
/// <summary>
/// 继续游戏(启动计时器)
/// </summary>
public void Play()
{
status = GameStatus.Play;
timer.Start();
}
/// <summary>
/// 暂停游戏(停止计时器)
/// </summary>
public void Pause()
{
status = GameStatus.Pause;
timer.Stop();
}
游戏结束,我们采用的是.net的事件机制,这样的好处是,由UI层去捕获这个事件,然后决定做什么事情。上一节中,当游戏结束时,我们执行了这个OnGameOver方法,这个方法用于把GameOver事件fire出去,具体代码如下:
private void OnGameOver(EventArgs e)
{
//游戏结束
status = GameStatus.Over;
timer.Stop();
EventHandler handler = GameOver;
if (handler != null)
{
handler(this, e);
}
}
三.至此,Control类已经构建完毕,接下来我们打开MainPage.xaml,接着添加一个Canvas作为准备方块画板,添加TextBlock作为显示积分,添加一个Button,然后为UserControl添加一个x:Name属性,命名为“uc”,具体xaml代码如下:
<Border Width="95" Height="95" BorderThickness="2" BorderBrush="Black" Background="#FFFAF0F0" CornerRadius="10" Canvas.Left="380" Canvas.Top="83">
<Canvas x:Name="readyBoard" Height="80" Width="80" Background="Black" Canvas.Left="300" Canvas.Top="43"/>
</Border>
<Button x:Name="btnPlay" Content="开始游戏" Width="75" Click="Button_Click" Canvas.Left="394" Canvas.Top="241"/>
<TextBlock Text="你的积分:" TextWrapping="Wrap" Canvas.Left="390" Canvas.Top="200" Width="84" FontSize="14"/>
<TextBlock x:Name="txtScore" Width="40" Canvas.Left="460" Canvas.Top="200" FontSize="14" Text="0" TextWrapping="Wrap" Foreground="Red"/>
打开MainPage.xaml.cs,在load事件中,构建一个Control类,把Control类的board添加到我们的画板中:
private Control ctrl;
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
uc.Focus();
ctrl = new Control(this.txtScore);
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 20; j++)
{
this.playBoard.Children.Add(ctrl.board[i, j]);
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
this.readyBoard.Children.Add(ctrl.readyBoard[i, j]);
}
}
ctrl.GameOver += new EventHandler(ctrl_GameOver);
}
我们为uc的KeyDown事件添加如下代码:
private void uc_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Left)
{
ctrl.MoveLeft();
}
else if (e.Key == Key.Right)
{
ctrl.MoveRight();
}
else if (e.Key == Key.Up)
{
ctrl.Change();
}
else if (e.Key == Key.Down)
{
ctrl.CheckAndOverBlock();
ctrl.MoveDown();
}
else if (e.Key == Key.Ctrl)
{
ctrl.Drop();
}
}
通过方向键和Ctrl键来进行游戏。
为按钮添加点击事件:
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
string text = this.btnPlay.Content.ToString();
if (text == "开始游戏" || text == "重新开始")
{
ctrl.StartGame();
ctrl.Play();
this.btnPlay.Content = "暂停游戏";
}
else if (text == "暂停游戏")
{
ctrl.Pause();
this.btnPlay.Content = "继续游戏";
}
else if (text == "继续游戏")
{
ctrl.Play();
this.btnPlay.Content = "暂停游戏";
}
}
游戏结束事件:
void ctrl_GameOver(object sender, EventArgs e)
{
this.btnPlay.Content = "重新开始";
MessageBox.Show("游戏结束");
}
当然游戏结束后,您可以执行任何自定义代码。
好了,Ctrl+F5,一个单机版的俄罗斯方块游戏已经产生了,玩着自己写出的游戏,会不会有成就感呢?如果您还想了解silverlight与服务器通信的方式,实现英雄板的功能,请继续关注接下来的文章。

浙公网安备 33010602011771号