65.9K
CodeProject 正在变化。 阅读更多。
Home

Silverlight 中的 Breakout

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.61/5 (18投票s)

2010 年 4 月 9 日

CPOL

2分钟阅读

viewsIcon

35987

downloadIcon

2112

经典的 Breakout 游戏在 Silverlight 中的实现

BreakOut

介绍  

Silverlight 技术为编写基于 Web 的游戏提供了最佳平台之一。主要优势在于 Silverlight 中的形状会自动绘制,并且支持与其他元素相同的事件。因此,我们无需担心形状的绘制过程等。这个游戏也作为在 Silverlight 中开发游戏的基础。

游戏玩法

gamestart.png

在第一个屏幕上选择游戏模式后,您将看到游戏面板;游戏将使用“空格键”开始。使用左右箭头键移动挡板左右。

游戏组件

打砖块游戏的解决方案包含以下文件夹结构。

BreakOut

砖块组件

Brick.xaml 文件是游戏中砖块的表示。砖块使用其构造函数初始化,c 是一个画布,砖块在指定的位置和颜色上绘制。

public Brick(Canvas c, Point location, Color color)
{
    InitializeComponent();
    _color = color;
    brickColor.Color = _color;
    this.X = location.X;
    this.Y = location.Y;
    c.Children.Add(this);
}

当砖块被破坏时,会播放一个动画,使砖块的大小变为 0,并播放 Sounds\BrickDestroyed.mp3 音效。

<storyboard x:name="brickDestroyed">
    <doubleanimationusingkeyframes begintime="00:00:00" 
	storyboard.targetname="scaleTransform" storyboard.targetproperty="ScaleY">
        <splinedoublekeyframe keytime="00:00:01" value="0">
    </doubleanimationusingkeyframes>
    <doubleanimationusingkeyframes begintime="00:00:00" 
	storyboard.targetname="scaleTransform" storyboard.targetproperty="ScaleX">
        <splinedoublekeyframe keytime="00:00:01" value="0">
    </doubleanimationusingkeyframes>
</storyboard>

球组件

球在画布上使用指定的速度移动,球类中的 Move() 方法会将球移动到新的 X 和 Y 位置。

/// <summary>
/// This method will move ball according to its current speed and direction
/// </summary>
public void Move()
{
   X += ((_leftDirection) * SPEED);
   Y += ((_topDirection) * SPEED);
}

挡板组件

<Canvas Background="Transparent">
        <Rectangle x:Name="bar" Stroke="#FF000000" RadiusY="20" RadiusX="20">
            <Rectangle.Fill>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="Brown" Offset="0"/>
                    <GradientStop Color="Black" Offset="0.6"/>
                    <GradientStop Color="Maroon" Offset="0.7"/>
                    <GradientStop Color="Red" Offset="1"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
</Canvas>
/// <summary>
/// This function will move bar to right side according to its speed
/// </summary>
public void MoveRight()
{
    if ((X + SPEED) < Utility.PlayingAreaWidth - Bar.BarWidth)
    {
       X += SPEED;
    }
}

/// <summary>
/// This function will move bar to left side according to its speed
/// </summary>
public void MoveLeft()
{
    if ((X-SPEED) > 0)
    {
       X -= SPEED;
    }
}

游戏面板

游戏面板逻辑包含在 GameBoard.xamlGameBoard.xaml.cs 文件中。我使用了画布布局容器,因为该容器提供了 X 和 Y 轴坐标系来定位子元素。

<canvas x:name="mainArea" width="500" height="600"><canvas.background>
    <imagebrush imagesource="Images/background.jpg"></canvas.background>
    <mediaelement x:name="gameBackGroundSound" 
	source="Sounds/BackGroundSound.mp3" autoplay="True" volume="0.3"
                mediaended="gameBackGroundSound_MediaEnded">
    <mediaelement x:name="gameOver" source="Sounds/GameOver.mp3" autoplay="False">
</canvas>

此类包含 _mainTimer 成员变量,该变量将触发计时器滴答事件以执行某些任务,例如将球移动到其新位置、检查游戏是否结束、碰撞检测等。

DispatcherTimer _mainTimer = new DispatcherTimer();
/// <summary>
/// Main Game Loop
/// </summary>
void _mainTimer_Tick(object sender, EventArgs e)
{
   _ball.Move(); // move ball
   CheckGameOver(); // check game is over or not
   DetectCollision(); // collision detection
}

碰撞检测

DetectCollision() 方法检查球与砖块、面板侧面和挡板的碰撞。它使用实用程序类中的 Utility.GetDistance(Point point1, Point point2) 方法来计算两点之间的距离。

/// <summary>
/// Collision detection logic
/// </summary>
private void DetectCollision()
{   
   // Check collision with sides
   CheckCollisionWithSides();

   // Check collision with bar
   Point p1;
   Point p2;
   CheckCollisionWithBar(out p1, out p2);

   // Collision with Bricks
   Brick brickToRemove = null;
   CheckCollisionWithBricks(ref p1, ref p2, ref brickToRemove);

   if (brickToRemove != null)
   {
       _bricks.Remove(brickToRemove);
       score += 10;
   }
}
© . All rights reserved.