5

我正在尝试制作游戏小行星。我现在遇到的问题是,如果您按向上箭头键,它会将“船”向上移动 10 个像素。如果你按下左箭头键,它会将“船”向左转 5 度,当你向左或向右转时,我遇到的问题就会发挥作用。然后尝试向上移动。它不会向转向的方向移动。它只会将转动的“船”沿 Y 方向移动 10 度。

我想做的是有一个名为方向的变量,把这个变量想象成一个 360 度的圆。我想要做的是每次我击中左箭头时,它会从方向中减去 5,它从 0 开始并从 360 向后退,因此将其设置为 355。然后我将 355 除以 10 并得到 35.5。然后我将 10 除以 35.5 得到 0.355。然后我会从 10 中减去 0.355(在 Y 轴上向上移动)。并从 0 中减去它(在 X 中向左移动)。所以我会在 Y 线向上移动 9.645,在 X 线向左移动 0.355。

我遇到的问题是我拥有的 Asteroids 中的“船”是 Graphics.FillPie,它需要 Ints 用作起始角和扫角,但是如您所见,我必须使用双精度或浮点数。我很确定我把它复杂化了,而且我很确定有些东西要简单 100 倍,我在想一些类似于 Bresenham 线算法的东西。如果有人可以通过建议更简单的方法或解决我的问题来提供帮助,将不胜感激。提前致谢。

4

5 回答 5

14

听起来您需要根据船的当前方向(以弧度为单位)计算船的航向矢量。例如:

double xVector = Math.Sin(orientationInRadians);
double yVector = Math.Cos(orientationInRadians);

然后使用左右箭头来控制船的当前方向。一旦你有了这个向量,你就可以计算出船的位置,它沿着航向向量距离其当前位置 10 个单位。首先,您需要将向量缩放为单位(长度为 1)向量。

double magnitude = sqrt(xVector*xVector + yVector*yVector);
double unitVectorX = xVector/magnitude;
double unitVectorY = yVector/magnitude;

现在你有一个长度为 1 个单位的向量,但仍然指向船的当前方向。接下来以 positionX 和 positionY 作为当前坐标移动船。

double distanceToTravel = 10;
double newPositionX = positionX + unitVectorX*distanceToTravel;
double newPositionY = positionY + unitVectorY*distanceToTravel;

即使您最终使用仅允许整数的系统进行渲染,您也需要使用双精度或浮点数来跟踪船的位置和方向。您不应该使用渲染引擎的精度来存储当前位置和方向,否则您会在移动和旋转时开始看到奇怪的跳跃和暂停。此外,使用上述方法,您可以使 distanceToTravel 非常量(想象在按下键时加速,而不是从按键移动固定距离)。

于 2010-09-03T19:38:14.300 回答
2

你想多了。;> 只需使用矩阵变换来旋转和移动船。当船指向“西北”并且用户按下 UP 键时,您将船的平移矩阵在船的 Y 轴上调整 10 个单位。您应用旋转和平移矩阵将船的坐标系转换为屏幕坐标系。操作顺序很关键——如果你在旋转之前应用平移,船将围绕中心点摆动,而不是围绕船的原点旋转,然后平移到新的“前进”方向。

由于您可以使用相同的矩阵变换进行绘图,因此您可以相对于其局部坐标系以相同的固定方向(鼻子指向“向上”正 Y 轴)绘制船。图像的旋转将由矩阵变换处理。

于 2010-09-03T19:37:33.110 回答
1

你还没有提到的一件事是,在 Asteroids(R) 品牌的街机和由此衍生的视频游戏中,玩家的飞船具有惯性。因此,您需要跟踪船舶的速度。您应该在每一帧中执行以下操作:

if (thrusting)
{
  XVelocity += (XVelocity - Math.Cos(Heading)*MAX_SPEED) * (1/INERTIA_CONSTANT);
  YVelocity += (YVelocity - Math.Sin(Heading)*MAX_SPEED) * (1/INERTIA_CONSTANT);
}
else
{
  XVelocity -= XVelocity * (1/FRICTION_CONSTANT);
  YVelocity -= YVelocity * (1/FRICTION_CONSTANT);
}

XPosition += XVelocity; // Do twice--once before and once after speed adjust
YPosition += YVelocity;

请注意,有些游戏只是将速度添加到余弦/正弦的常数倍。这样做会带来不幸的后果,如果玩家将他的船指向某个方向并开始连续推进,那么船每帧经过的距离可能会增长到荒谬的极限。所示代码将导致加速度随着船舶速度渐近接近最大值而减小。

于 2013-03-14T18:21:51.407 回答
1

在内部使用浮点数并在需要以这种方式使用它们时将它们转换为整数没有问题:

double angle = ...;
int angleAsInt = (int)Math.Round(angle);

我建议您考虑使用三角函数,例如sincos来确定速度和加速度的 X 和 Y 分量。

于 2010-09-03T19:36:04.113 回答
1

我不想带走你的乐趣,但你总是可以下载别人的代码并查看它以弄清楚如何用你自己的方式来做。你可以在这里得到一个实现:http ://www.c-sharpcorner.com/UploadFile/dannaboneheart/Asteroids11292005064500AM/Asteroids.aspx

在这里回答:http: //www.codeproject.com/KB/game/hucsharpasteroids.aspx

于 2010-09-03T19:31:48.327 回答