我正在尝试制作游戏小行星。我现在的问题是,如果按下向上箭头键,它会将“船”向上移动10个像素。如果你按下LEFT箭头键,它会将“船”向左转5度,当你向左转或向右转时我就会发挥作用。然后尝试向上移动。它不会进入转向的方向。它只会将转向的“船”向Y方向移动10度。
我想要做的是使用一个名为direction的变量,将此变量视为360度的圆。我想要做的是每当我点击左箭头时,它将从方向减去5,从0开始并从360向后减去因此将其设置为355.然后我将355除以10得到35.5。然后我将10除以35.5得到.355。然后我会从10减去.355(在Y中向上移动)。并从0减去它(在X中向左移动)。因此,我将在Y中向上移动9.645并在X中向左移动0.355。
我遇到的问题是Asteroids中的“船”我有一个Graphics.FillPie,它需要Ints作为起始角度和扫掠角度,但是你可以看到我必须使用双打或漂浮。我很确定我过于复杂,我很确定有一些简单的东西,我正在思考Bresenham的线算法。如果有人可以通过建议更容易或修复我的问题来提供帮助,那将非常感激。提前谢谢。
答案 0 :(得分:13)
听起来您需要根据其当前的弧度方向计算船舶的航向矢量。例如:
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非常量(想象一下按下按键时加速,而不是按下按键移动固定距离)。
答案 1 :(得分:2)
你在想它。 ;>只需使用矩阵变换来旋转和移动船只。当船舶指向“西北”并且用户按下向上键时,您可以在船舶的Y轴上将船舶的平移矩阵调整10个单位。您应用旋转和平移矩阵将船舶的坐标系转换为屏幕坐标系。操作顺序至关重要 - 如果您在旋转前应用平移,船舶将围绕中心点摆动而不是围绕船舶原点旋转,然后转换到新的“向前”方向。
由于您可以使用相同的矩阵变换进行绘制,因此您可以相对于其局部坐标系以相同的固定方向(鼻子指向“正Y轴”)绘制船只。矩阵变换将处理图像的旋转。
答案 2 :(得分:1)
我不想带走你的乐趣,但你总是可以下载其他人的代码并查看它以找出如何在你自己的代码中完成它。您可以在此处获得一个实施:http://www.c-sharpcorner.com/UploadFile/dannaboneheart/Asteroids11292005064500AM/Asteroids.aspx
ans here:http://www.codeproject.com/KB/game/hucsharpasteroids.aspx
答案 3 :(得分:1)
当您需要以这种方式使用浮点数时,在内部使用浮点数并将其转换为整数是没有问题的:
double angle = ...;
int angleAsInt = (int)Math.Round(angle);
我建议你研究使用像sin
和cos
这样的三角函数来确定速度和加速度的X和Y分量。
答案 4 :(得分:0)
你还没有提到的一件事是,在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;
请注意,有些游戏只是将速度添加到余弦值/正弦值的常数。这样做将产生令人遗憾的结果,即如果玩家将他的船指向某个方向并开始连续推进,则每架船所经过的距离可能会增长到荒谬的极限。当船舶的速度渐近接近最大值时,所示的代码将导致加速度减小。