1

好的,所以我已经搜索并搜索了我的问题的解决方案,但似乎没有解决它。

我需要制作一个带有旋转“大炮”的游戏,我的大炮是一个简单的矩形,放置在面板中间,我可以用键盘旋转它。它围绕一个边缘旋转。我想从另一边的边缘射出去。我通过以下方式找到了射击子弹的起点:

x = a + dia * (float)Math.Cos(angle);
y = b + dia * (float)Math.Sin(angle)

其中“a,b”是我旋转它的中心坐标,“dia”是矩形的对角线,“angle”是我的矩形一半的角度。

public float rotate = 0.0f; 
g.TranslateTransform(a , b);
        g.RotateTransform(rotate);

我有一个自己的子弹类,我把它放在一个列表中。到目前为止,一切都很好。但是当我旋转我的大炮时,子弹不再从尖端出来了......它们只是开始出现在我想要它们的地方很远的地方。这是因为这段代码:

x = (float)((x * Math.Cos(rotate)) - (y * Math.Sin(rotate)));
        y = (float)((x * Math.Sin(rotate)) + (y * Math.Cos(rotate)));

那应该更新大炮尖端的x,y坐标。如果我删除它,它只会从同一个地方触发(不废话)。有人可以向我解释一下我需要编写什么代码来更新 X、Y 以便它们从我的矩形边缘出来吗?这让我疯狂..

编辑:发现我的答案在清晨盯着屏幕。我不需要任何“查找新的 x,y 坐标”。我只是做了一个更新程序,用浮点数更新原始角度,每次旋转它时它需要移动一点。哈哈!如此简单,却又如此难看。

4

1 回答 1

0

首先,

x = (float)((x * Math.Cos(rotate)) - (y * Math.Sin(rotate)));
y = (float)((x * Math.Sin(rotate)) + (y * Math.Cos(rotate)));

需要是这样的:

float oldx = x;
float oldy = y; 
x = (float)((oldx * Math.Cos(rotate)) - (oldy * Math.Sin(rotate)));
y = (float)((oldx * Math.Sin(rotate)) + (oldy * Math.Cos(rotate)));

您的新价值观需要完全基于旧价值观..

如果修复后还有其他问题,可能与矩形在平面上的平移方式有关。

编辑:如果这是一次代码审查,我会说我刚刚给出的解决方案也不是最好的解决方案(它只是不会受到您通过使用 x 的新值来计算新值而引入的错误的影响y)。请参阅,与乘法和加法相比,Math.Cos 和 Math.Sin 通常是昂贵的运算。如果您有一堆需要以相同方式转换的点,最好计算一次Math.Sin(rotate)Math.Cos(rotate)为每个点使用这些值。这可能是使用享元模式并定义一个类的好地方,其中一个实例将保存给定对象/上下文的所有点,以便可以聚合完成操作。

于 2012-11-18T18:12:22.000 回答