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

C# 小行星大战

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.41/5 (10投票s)

2004年6月15日

3分钟阅读

viewsIcon

104558

downloadIcon

5398

一篇关于用 C# 编写简单游戏的文章

引言

这是我自己实现的小行星游戏。 它是基于向量模拟的,并使用 GDI 进行图形绘制。 游戏本身是相当面向对象的,应该很容易理解。 代码中仍然存在一些问题,我希望有人可以帮忙解决。

背景

很久以前,我最初在 Windows 3.1 上用 VB 编写了一个小行星游戏。 这本质上是该版本的移植。 该版本只有基本的游戏玩法,但没有声音。

Using the Code

由于此游戏是基于向量的,因此它基于一个非常大的空间。 所有对象都表示在这个较大的空间中,然后缩小到显示器的分辨率。 这似乎工作得相当好,并允许在任何大小的窗口中缩放相同的游戏。 游戏场拥有所有对象,并且基本上循环绘制每个对象。

该游戏具有精美的标题画面显示和暂停功能。 实现暂停非常简单 - 我不知道为什么所有游戏都没有包含这样的功能。

声音通过 DirectX 播放。 图形使用 GDI 绘制。 DirectX 或其他某种形式的显示可能会大大改善效果。

每个对象都负责自己。 这使得动画变得非常简单,因为对象本质上可以免费处理此操作。 在一些独特的情况下,事物的绘制方式略有不同。 例如,太空飞船负责绘制其推进器。

推进器、子弹和爆炸会产生令人惊讶的好效果。 这是通过在绘制时随机循环浏览颜色列表来完成的。 这创造了令人眼花缭乱的效果。

碰撞检测目前很简单。 由于小行星都是圆形的(见下文),因此只需检查任何点到小行星中心的距离即可。 当 UFO 出现(见下文)并且小行星具有独特的形状时,此方法将不起作用 - 但可以很好地查看两个对象是否足够接近以保证进行更完整的检查。

物体旋转

 protected void Rotate(double degrees)
 {
    double radiansAdjust = degrees * 0.0174532925;
    radians += radiansAdjust/FPS;
    double SinVal = Math.Sin(radians);
    double CosVal = Math.Cos(radians);

    pointsTransformed.Clear();
    Point ptTransformed = new Point(0,0);
    for (int i=0; i<points.Count; i++)
    {
       Point pt = ((Point)points[i]);
       ptTransformed.X = (int)(pt.X * CosVal + pt.Y * SinVal);
       ptTransformed.Y = (int)(pt.X * SinVal - pt.Y * CosVal);
       pointsTransformed.Add(ptTransformed);
    }
 }

绘制一个物体(在本例中,是ship

 public new void Draw(ScreenCanvas sc, int iPictX, int iPictY)
 {
    switch (state)
    {
       case SHIP_STATE.ALIVE:
          base.Draw(sc, iPictX, iPictY);
          if (bThrustOn)
          {
              //We have points transformed
              //so...  we know where the bottom of the ship is
             ArrayList alPoly = new ArrayList();
             alPoly.Capacity = 3;
             alPoly.Add(pointsTransformed[iPointThrust1]);
             alPoly.Add(pointsTransformed[iPointThrust2]);
             int iThrustSize = rndGen.Next(200) + 100;  random thrust effect
             alPoly.Add(new Point((((Point)pointsTransformed[iPointThrust1]).X + 
               ((Point)pointsTransformed[iPointThrust2]).X) / 2 + 
               (int)(iThrustSize*Math.Sin(radians)),
               (((Point)pointsTransformed[iPointThrust1]).Y + 
               ((Point)pointsTransformed[iPointThrust2]).Y) / 2 + 
               (int)(-iThrustSize*Math.Cos(radians))));
              //Draw thrust directly to ScreenCanvas
              //it's not really part of the ship object
             DrawPolyToSC(alPoly, sc, iPictX, iPictY, GetRandomFireColor());
          }
          break;
    }

关注点

控件

  • 推进 - 向上箭头
  • 向右旋转 - 向右箭头
  • 向左旋转 - 向左箭头
  • 超空间 - 向下箭头(重新进入时有爆炸的风险)
  • 射击 - 空格键
  • 暂停 - P 键。

这个游戏有几个有点烦人或不完整的地方。 它们是

  • 有时,游戏完全冻结。 我认为这是由于声音引起的。
  • 该游戏似乎在 1024x768 以上的分辨率下工作正常。 我确信这是由于我愚蠢的绘制和页面翻转算法造成的。 令人惊讶的是,在这方面,该游戏的性能并不比我的旧 VB 版本更好。
  • 有时,游戏在推进时会慢得像爬一样。 释放推进后就好了。
  • 有时,在游戏关闭时会抛出异常。
  • 没有 UFO - 尚未。 我需要一些关于智能子弹射击逻辑的帮助。
  • 小行星都是圆形的。 它们会旋转。 我想获得像街机游戏那样的凹凸不平的小行星。 这应该很简单,但会使碰撞检测变得稍微困难一些。
  • 当越过屏幕边缘时,对象会跳跃。 这可能会产生这样一种可能性,即看起来应该发生碰撞的东西会消失,并且除非它发生在对象翻转到的位置,否则不会发生碰撞。
  • 声音在一个目录中 - 我不知道如何将它们嵌入到可执行文件中,那样会好得多。

历史

  • 2004 年 6 月 15 日 - 首次发布

许可证

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

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

© . All rights reserved.