子弹没有射出枪
Bullets not getting shot out of the gun
我正在制作一个小游戏只是为了好玩,但我在让子弹从枪中射出时遇到了困难。在下面的代码中,玩家的方向是一个角度,叫做 rot
.
float gunOffsetX = 106, gunOffsetY = 96;
double angle = Math.toRadians(rot); // convert direction of player from degrees to radians for sin and cos
x = getX(); // player X
y = getY(); // player Y
float bulletX = (float) (x + (gunOffsetX * Math.cos(angle) - gunOffsetY * Math.sin(angle)));
float bulletY = (float) (y + (gunOffsetX * Math.sin(angle) + gunOffsetY * Math.cos(angle)));
Instances.fire.add(new Fire(bulletX, bulletY, rot, weapon));
也尝试过:
bulletX = (float) (x + Math.cos(angle + Math.atan2(gunOffsetX, gunOffsetY)) * Point2D.distance(0, 0, gunOffsetX, gunOffsetY));
但结果相同
据说子弹应该在枪的末端产生,但事实并非如此,正如您在下面的 gif 中看到的那样..
感谢任何帮助
一个大问题(至少在我看来)是这个游戏如何像玩家一样处理 锚点 形状点。
我们可以通过在其位置绘制一个红色的小矩形来突出显示锚点:
g.setColor(Color.RED);
g.drawRect((int)player.getX() -5, (int)player.getY() -5, 10, 10);
这进入了 Draw#renderGame(Graphics2D)
方法,所以它看起来像:
private void renderGame(Graphics2D g) {
g.rotate(Math.toRadians(player.rot), player.getX()+64, player.getY()+64);
g.drawImage(player.getCurrentFrame(), (int)player.getX(), (int)player.getY(), player.getWidth(), player.getHeight(), null);
g.setColor(Color.RED);
g.drawRect((int)player.getX() -5, (int)player.getY() -5, 10, 10);
g.rotate(-Math.toRadians(player.rot), player.getX()+64, player.getY()+64);
//...
然后我们会看到锚点不在图像的中心:
如您所见,锚点(旋转前的原始(0,0)点)不在图像的中心,十字准线与其相关,而不是玩家的视图.
这是由于玩家旋转时的移位操作造成的:
g.rotate(Math.toRadians(player.rot), player.getX()+64, player.getY()+64);
//...
g.rotate(-Math.toRadians(player.rot), player.getX()+64, player.getY()+64);
您正在移动 +64
的位置。我建议删除它并将移动添加到 g.drawImage
调用中,这样锚点就正确地位于中心(请注意我避免了固定值 64):
g.rotate(Math.toRadians(player.rot), player.getX(), player.getY());
g.drawImage(player.getCurrentFrame(), (int)player.getX() - (player.getWidth() / 2), (int)player.getY() - (player.getHeight() / 2), player.getWidth(), player.getHeight(), null);
g.rotate(-Math.toRadians(player.rot), player.getX(), player.getY());
然后你现在开枪你会看到子弹总是从玩家的某个位置 "starts"。这里的问题是您使用的偏移量不正确。正确的值为:
float gunOffsetX = 35, gunOffsetY = 29;
(我是通过反复试验得到的,所以如果你愿意,可以再稍微调整一下)
现在看起来像这样:
如您所见,射击仍然有点错位,但这是由于子弹旋转不正确造成的(就像您对玩家形状所做的那样):
g.rotate(Math.toRadians(f.rot), f.getX()+f.getWidth()/2, f.getY()+f.getHeight()/2);
g.drawImage(f.img, (int)f.getX(), (int)f.getY(), f.getWidth(), f.getHeight(), null);
g.rotate(-Math.toRadians(f.rot), f.getX()+f.getWidth()/2, f.getY()+f.getHeight()/2);
它应该看起来像这样(没有任何 X 或 Y 调整):
g.rotate(Math.toRadians(f.rot), f.getX(), f.getY());
g.drawImage(f.img, (int)f.getX(), (int)f.getY(), f.getWidth(), f.getHeight(), null);
g.rotate(-Math.toRadians(f.rot), f.getX(), f.getY());
最终结果是:
玩家现在可以正确地注视十字准线并且射击位于枪的前方。
如果你喜欢直接从十字准线的中心开火,你只需要稍微调整一下玩家位置和子弹偏移量。
玩家(Draw#renderGame(Graphics2D)
):
g.drawImage(player.getCurrentFrame(), (int)player.getX() - (player.getWidth() / 2), (int)player.getY() - (player.getHeight() / 2) - 30, player.getWidth(), player.getHeight(), null);
(注意(int)player.getY() - (player.getHeight() / 2) - 30
中的-30
)
项目符号:
float gunOffsetX = 35, gunOffsetY = 0;
现在子弹正好穿过十字准线(注意红色矩形就在武器上):
(我有点笨,不会做GIF文件,所以只能提供图片)
现在您有了获得所需结果所需的偏移值,但您绝对应该尝试理解为什么这些值会像现在这样。您稍后需要用 dynamic 值替换它们,因为不同的武器需要不同的子弹偏移量,因为玩家图像不同。为每种武器类型提供某种 class 实例应该会有所帮助,其中包含图像和图像中武器枪管所在的坐标。然后你可以使用这些坐标来正确设置子弹图像的偏移量。
我正在制作一个小游戏只是为了好玩,但我在让子弹从枪中射出时遇到了困难。在下面的代码中,玩家的方向是一个角度,叫做 rot
.
float gunOffsetX = 106, gunOffsetY = 96;
double angle = Math.toRadians(rot); // convert direction of player from degrees to radians for sin and cos
x = getX(); // player X
y = getY(); // player Y
float bulletX = (float) (x + (gunOffsetX * Math.cos(angle) - gunOffsetY * Math.sin(angle)));
float bulletY = (float) (y + (gunOffsetX * Math.sin(angle) + gunOffsetY * Math.cos(angle)));
Instances.fire.add(new Fire(bulletX, bulletY, rot, weapon));
也尝试过:
bulletX = (float) (x + Math.cos(angle + Math.atan2(gunOffsetX, gunOffsetY)) * Point2D.distance(0, 0, gunOffsetX, gunOffsetY));
但结果相同
据说子弹应该在枪的末端产生,但事实并非如此,正如您在下面的 gif 中看到的那样..
感谢任何帮助
一个大问题(至少在我看来)是这个游戏如何像玩家一样处理 锚点 形状点。
我们可以通过在其位置绘制一个红色的小矩形来突出显示锚点:
g.setColor(Color.RED);
g.drawRect((int)player.getX() -5, (int)player.getY() -5, 10, 10);
这进入了 Draw#renderGame(Graphics2D)
方法,所以它看起来像:
private void renderGame(Graphics2D g) {
g.rotate(Math.toRadians(player.rot), player.getX()+64, player.getY()+64);
g.drawImage(player.getCurrentFrame(), (int)player.getX(), (int)player.getY(), player.getWidth(), player.getHeight(), null);
g.setColor(Color.RED);
g.drawRect((int)player.getX() -5, (int)player.getY() -5, 10, 10);
g.rotate(-Math.toRadians(player.rot), player.getX()+64, player.getY()+64);
//...
然后我们会看到锚点不在图像的中心:
如您所见,锚点(旋转前的原始(0,0)点)不在图像的中心,十字准线与其相关,而不是玩家的视图.
这是由于玩家旋转时的移位操作造成的:
g.rotate(Math.toRadians(player.rot), player.getX()+64, player.getY()+64);
//...
g.rotate(-Math.toRadians(player.rot), player.getX()+64, player.getY()+64);
您正在移动 +64
的位置。我建议删除它并将移动添加到 g.drawImage
调用中,这样锚点就正确地位于中心(请注意我避免了固定值 64):
g.rotate(Math.toRadians(player.rot), player.getX(), player.getY());
g.drawImage(player.getCurrentFrame(), (int)player.getX() - (player.getWidth() / 2), (int)player.getY() - (player.getHeight() / 2), player.getWidth(), player.getHeight(), null);
g.rotate(-Math.toRadians(player.rot), player.getX(), player.getY());
然后你现在开枪你会看到子弹总是从玩家的某个位置 "starts"。这里的问题是您使用的偏移量不正确。正确的值为:
float gunOffsetX = 35, gunOffsetY = 29;
(我是通过反复试验得到的,所以如果你愿意,可以再稍微调整一下)
现在看起来像这样:
如您所见,射击仍然有点错位,但这是由于子弹旋转不正确造成的(就像您对玩家形状所做的那样):
g.rotate(Math.toRadians(f.rot), f.getX()+f.getWidth()/2, f.getY()+f.getHeight()/2);
g.drawImage(f.img, (int)f.getX(), (int)f.getY(), f.getWidth(), f.getHeight(), null);
g.rotate(-Math.toRadians(f.rot), f.getX()+f.getWidth()/2, f.getY()+f.getHeight()/2);
它应该看起来像这样(没有任何 X 或 Y 调整):
g.rotate(Math.toRadians(f.rot), f.getX(), f.getY());
g.drawImage(f.img, (int)f.getX(), (int)f.getY(), f.getWidth(), f.getHeight(), null);
g.rotate(-Math.toRadians(f.rot), f.getX(), f.getY());
最终结果是:
玩家现在可以正确地注视十字准线并且射击位于枪的前方。
如果你喜欢直接从十字准线的中心开火,你只需要稍微调整一下玩家位置和子弹偏移量。
玩家(Draw#renderGame(Graphics2D)
):
g.drawImage(player.getCurrentFrame(), (int)player.getX() - (player.getWidth() / 2), (int)player.getY() - (player.getHeight() / 2) - 30, player.getWidth(), player.getHeight(), null);
(注意(int)player.getY() - (player.getHeight() / 2) - 30
中的-30
)
项目符号:
float gunOffsetX = 35, gunOffsetY = 0;
现在子弹正好穿过十字准线(注意红色矩形就在武器上):
(我有点笨,不会做GIF文件,所以只能提供图片)
现在您有了获得所需结果所需的偏移值,但您绝对应该尝试理解为什么这些值会像现在这样。您稍后需要用 dynamic 值替换它们,因为不同的武器需要不同的子弹偏移量,因为玩家图像不同。为每种武器类型提供某种 class 实例应该会有所帮助,其中包含图像和图像中武器枪管所在的坐标。然后你可以使用这些坐标来正确设置子弹图像的偏移量。