Silverlight:手把手教你写俄罗斯方块(五)(完)

  一.接着上一节的Control.cs的内容,我们继续完善。为了增强俄罗斯方块的趣味性,我们在游戏一开始就增加一些静态方块,需要一个方法,我们只用定义静态方块的高度就可以实现了:
        /// <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与服务器通信的方式,实现英雄板的功能,请继续关注接下来的文章。

posted @ 2011-05-22 17:54  疯狂的戴夫  阅读(593)  评论(4编辑  收藏  举报