C# 中的小行星游戏运动

发布于 2024-09-17 11:02:21 字数 567 浏览 12 评论 0原文

我正在尝试制作小行星游戏。我现在遇到的问题是,如果您按向上箭头键,它会将“船”向上移动 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。

我遇到的问题是小行星中的“船”是 Graphics.FillPie,它需要 Ints 用作起始角度和扫描然而,正如你所看到的,我必须使用双打或浮点数。我很确定我把这个问题复杂化了,而且很确定有比这简单 100 倍的东西,我正在思考布雷森汉姆直线算法的一些东西。如果有人可以通过提出更简单的建议或解决我的问题来提供帮助,我将不胜感激。提前致谢。

I am trying to make the game Asteroids. My issue I have right now, is if you press the UP Arrow key, it will move the "ship" 10 pixels up. And if you hit the LEFT Arrow key, it will turn the "ship" 5 degrees to the left, the issue I have comes into play when you turn left, or right. And then try to move up. It won't move into the turned direction. It will just move the turned "ship" 10 degrees in the Y direction.

What I am thinking of doing is having a variable called direction, think of this variable as a circle with 360 degrees. What I am trying to do is everytime I hit the Left Arrow, it will subtract 5 from direction, which started at 0 and goes backwards from 360 and thus set it to 355. I would then divide 355 by 10 and get 35.5. Then I would divide 10 by 35.5 and get .355. I would then subtract .355 from 10 (moving up in the Y). And subtract it from 0 (moving left in the X). So I would be moving 9.645 up in the Y and moving 0.355 left in the X.

The issue I'm having is the "ship" in Asteroids I have is a Graphics.FillPie, which needs Ints to use as the Start Angle and Sweep angle, However as you can see I would have to be working with doubles or floats. I'm pretty sure I'm overcomplicating this and am pretty sure there is something 100 times simpler, I'm thinking something along the lines of Bresenham's Line Algorithm. If anyone could help by suggesting something easier or a fix to my problem, it would be much appreciated. Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

鹿童谣 2024-09-24 11:02:33

您还没有提到的一件事是,在 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;

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

One thing you haven't yet mentioned is that in the Asteroids(R) brand arcade machine and video games derived therefrom, the player's ship has inertia. Consequently, you need to keep track of the ship's velocity. Each frame you should do something like:

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;

Note that some games simply add to the velocity some constant times the cosine/sine. Doing that will have the unfortunate consequence that if a player points his ship in some direction and starts thrusting continuously, the distance traversed by the ship each frame may grow to absurd limits. The code as shown will cause the acceleration to diminish as the ship's velocity asymptotically approaches the maximum.

深空失忆 2024-09-24 11:02:32

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

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

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

There is no problem using floats internally and converting them to ints when you need to use them that way:

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

I suggest you look into using trigonometric functions like sin and cos for determining the X and Y components of velocities and accelerations.

陈独秀 2024-09-24 11:02:30

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

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

You're over thinking it. ;> Just use matrix transforms to rotate and move the ship. When the ship is pointed "northwest" and the user pushes the UP key, you adjust the ship's translation matrix by 10 units in the ship's Y axis. You apply the rotation and translation matrixes to convert the ship's coordinate system to the screen coordinate system. Order of operations is critical - if you apply translation before rotation, the ship will go swinging around a center point instead of rotating around the ships origin and then translating to its new "forward" direction.

Since you can use the same matrix transforms for drawing, you can just draw the ship in the same fixed orientation (nose pointing "up" the positive Y axis) relative to its local coordinate system. The rotation of the image will be taken care of by the matrix transform.

歌入人心 2024-09-24 11:02:30

我不想剥夺您的乐趣,但您始终可以下载其他人的代码并查看它以了解如何在自己的代码中执行此操作。您可以在这里获得一种实现: http://www.c-sharpcorner .com/UploadFile/dannaboneheart/Asteroids11292005064500AM/Asteroids.aspx

此处:http ://www.codeproject.com/KB/game/hucsharpasteroids.aspx

I don't want to take your fun away, but you can always download someone else's code and look at it to figure out how to do it in your own. You can get one implementation here: http://www.c-sharpcorner.com/UploadFile/dannaboneheart/Asteroids11292005064500AM/Asteroids.aspx

ans here: http://www.codeproject.com/KB/game/hucsharpasteroids.aspx

梦中的蝴蝶 2024-09-24 11:02:28

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

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 个单位但仍指向船舶当前方向的矢量。接下来以位置 X 和位置 Y 作为当前坐标移动船舶。

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

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

It sounds like you need to calculate heading vectors for the ship based on the its current orientation in radians. For example:

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

Then use the left and right arrows to control the ship's current orientation. Once you have the vector you can calculate the location of the ship that is 10 units away from its current position along the heading vector. First you need to scale the vector to a unit (length of 1) vector.

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

Now you have a vector that is 1 unit long but still points in the ship's current orientation. Next move the ship with positionX and positionY as current its coordinates.

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

You'll want to track the ship's position and orientation with doubles or floats even if you end up rendering with a system that only allows ints. You shouldn't store the current position and orientation using the rendering engine's precision or you will start to see strange jumps and pauses as you move and rotate. Also, using the above you can make distanceToTravel non-constant (imagine accelerating while the key is pressed instead of moving a fixed distance from a key press).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文