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

碰撞 - C# 游戏,第二部分:跟踪游戏元素并添加交互

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (17投票s)

2002年4月17日

3分钟阅读

viewsIcon

64899

downloadIcon

863

继续我用C#编写简单游戏的尝试。

Sample Image - Collision2.jpg

目标

在确定我最初的设计过于雄心勃勃之后,现在的想法是简化绘制过程,同时添加一些游戏元素 - 不以重复模式出现的行星,随着游戏进行数量增加,以及我们可以控制的飞船。

绘制背景

我保留了每次都使星空不同的代码,但现在星空不再滚动。这使得生活变得更加轻松,因为现在所有绘图都发生在 OnPaint 方法中。由于我们在启动代码中将 DoubleBuffering 设置为打开,因此我们以零成本(就工作量而言)获得了无闪烁的绘图,这使得所有这些都更加简单。

计时器代码现在重新定位飞船和陨石,并添加/删除它们,但行星和飞船直接在 OnPaint 方法中绘制到屏幕上。这类似于在 GDI+ 中实现橡皮筋效果的方式 - 我们保留不改变的部分,并将任何将要改变的东西直接绘制到屏幕上,因此它既不存储,也不影响我们的背景位图。

添加行星和计分

为了以半随机的方式添加行星,我使用了 Random 类,它有一个 Next 方法,该方法接受一个值,该值是随机数生成器返回的最大值。我为通过的每个行星获得 10 分,并且我根据分数增加添加行星的可能性。计数器的初始值设置为负数,以强制行星之间的最小间隙。代码如下所示

++m_nAddPlanet;

Random r = new Random();

if (m_nAddPlanet > r.Next(Math.Max(300 - m_nScore, 2)))
{
    m_nAddPlanet = - 10;

    bool b = true;
    Rectangle rcDest = new Rectangle();
    while (b)
    {
        b = false;
        rcDest = new Rectangle(640, r.Next(280), 87, 87);

        for (int i = 0; i < m_arAsteroids.Count; ++i)
        {
            Asteroid arTemp = (Asteroid)m_arAsteroids[i];

            if (rcDest.IntersectsWith(arTemp.rcAsteroid))
                b = true;
        }
    }

    Asteroid arAdd;
    arAdd.rcAsteroid = rcDest;
    arAdd.nBitmap = r.Next(8);

    m_arAsteroids.Add(arAdd);
}

跟踪行星

行星(由于最初的设计,在代码中仍然称为 Asteroid)在如下的 struct 中定义

    public struct Asteroid
    {
        public Rectangle rcAsteroid;
        public int       nBitmap;
    }

因为它是一个 struct,所以它是按值传递的。它存储将绘制到的 Rectangle,以及绘制它的 bitmap 的索引。我最初打算逐步旋转一个 asteroid,但是在使用了行星之后,我就没有它们的旋转视图了。您可以在添加代码中看到,行星以随机的 Y 值定位在屏幕之外。它们在 paint 方法中绘制时被移动,如下所示

for (int i = 0; i < m_arAsteroids.Count; ++i)
{
   Asteroid arTemp = (Asteroid)m_arAsteroids[i];

   arTemp.rcAsteroid.X -= 5;

   m_arAsteroids[i] = arTemp;

   if (arTemp.rcAsteroid.X < -87)
   {
      m_arAsteroids.RemoveAt(i);
      --i;
      m_nScore += 10;
   }

   e.Graphics.DrawImage(m_bmPlanets, arTemp.rcAsteroid, 
                          87 * arTemp.nBitmap, 0, 87, 87, 
                          GraphicsUnit.Pixel, iattrib);
}

请记住,增加分数会增加添加行星的速度,从而使游戏难度增加。

飞船

飞船是非常基本的东西 - 我们创建两个变量来存储在 xy 方向上移动飞船的值,并在按下箭头时将它们设置为 1-1,并在释放时将其设置回 0。可以很容易地更改代码,以便多次按下会加速/减速飞船。飞船的 rect 被存储,并由这些值改变,然后用于绘制它。

下一步是什么?

该代码仍然不使用任何时间同步代码,因为它在我的 700 MHz 机器上仍然以全速运行良好。接下来的想法是检查碰撞,我们将使其以像素完美的方式工作,同时希望保持可玩的速度,并且下次我们决定编写动作游戏时,我们将使用 C++ 和 DirectX。随着添加的行星数量增加,游戏肯定会变慢,如果我们关闭颜色键控,情况会稍微好一些(尽管看起来很糟糕)。如果我们使用 MakeTransparent 函数并恢复为(更大的)位图资源而不是 jpg,则可能会提高一些速度。

历史

  • 2002 年 4 月 17 日:初始版本

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.