Silverlight 中的 Breakout






4.61/5 (18投票s)
经典的 Breakout 游戏在 Silverlight 中的实现

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

在第一个屏幕上选择游戏模式后,您将看到游戏面板;游戏将使用“空格键”开始。使用左右箭头键移动挡板左右。
游戏组件
打砖块游戏的解决方案包含以下文件夹结构。

砖块组件
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.xaml 和 GameBoard.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;
}
}