我正在做一个坦克游戏。我已经找到了如何使我的敌人朝着玩家的方向移动,但我不太确定如何让它在玩家方向上射击。坦克的射手也必须朝着敌人射击方向旋转。 (子弹必须“射出”射手)
这个必须旋转,我已经编写了代码,让玩家的射手跟随鼠标的位置
我把射手放在坦克的身上
作为子弹我们使用黑圈:(ObjWH
是ObjectWidhtHeight
)
`public void draw(Graphics2D g)
{
g.setColor(Color.BLACK);
g.fillOval((int) (x_pos - objWH), (int) (y_pos - objWH), (int) objWH,
(int) objWH);
}`
我想在ArrayLists中存储来自敌人的子弹,每个敌人都需要自己的ArrayList。
`package tanks;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.Timer;
import menu.PlayPanel;
import menu.Tanks;
public class Enemy extends Game_Object {
private static final Timer shootTimer = null;
private PlayPanel panel;
int launchPosition;
double distance;
double deltaX, deltaY;
private ArrayList<EnemyBullet> enemyBullets;
public Enemy(PlayPanel panel)
{
this.panel = panel;
speed = 3 + rand.nextInt(5);
maxHP = 80 + rand.nextInt(40);
HP = maxHP;
angle = 0;
angleCannon = 0;
objWH = 65;
}
public void launch()
{
launchPosition = rand.nextInt(3);
switch(launchPosition){
case 0: //up
x_pos = rand.nextInt(Tanks.getSchermBreedte());
y_pos = 0;
break;
case 1: //left
x_pos = 0;
y_pos = rand.nextInt(Tanks.getSchermHoogte());
break;
case 2: //downside
x_pos = rand.nextInt(Tanks.getSchermBreedte());
y_pos = Tanks.getSchermHoogte();
break;
case 3: //right
x_pos = Tanks.getSchermBreedte();
y_pos = rand.nextInt(Tanks.getSchermHoogte());
break;
}
}
public void move()
{
if (Player.get_x_pos() >= Enemy.get_x_pos())
{
deltaX = Player.get_x_pos() - Enemy.get_x_pos();
}
else //if(Player.get_x_pos() <= Enemy.get_x_pos())
{
deltaX = Enemy.get_x_pos() - Player.get_x_pos();
}
if(Player.get_y_pos() >= Enemy.get_y_pos())
{
deltaY = Player.get_y_pos() - Enemy.get_y_pos();
}
else //if(Player.get_y_pos() <= Enemy.get_y_pos())
{
deltaY = Enemy.get_y_pos() - Player.get_y_pos();
}
distance = Math.pow(Math.pow(deltaX, deltaX) + Math.pow(deltaY,
deltaY), 1/2);
x_move = speed*(deltaX/distance);
y_move = speed*(deltaY/distance);
x_pos += x_move;
y_pos += y_move;
}
private static double get_x_pos()
{
return Enemy.x_pos;
}
private static double get_y_pos()
{
return Enemy.y_pos;
}
public void shoot()
{
enemyBullets = new ArrayList<EnemyBullet>();
}
public void touched()
{
if(HP>0)
HP -= (5 + rand.nextInt(10));
if(HP <= 0)
dood = true;
}
public void draw(Graphics2D g2d)
{
body = new ImageIcon(getClass().getResource("/objects/enemy
tank.png")).getImage();
shooter = new ImageIcon(getClass().getResource("/objects/enemy
shooter.png")).getImage();
}
}`
答案 0 :(得分:3)
嗯,其实质是“基本几何”,特别是函数ATAN2
。 (Google it ...)
想象一下,有一个右三角形,你的坦克在一个顶点,而敌人在斜边的另一端。 ATAN2
可以告诉你该向量的角度(以及它所在的“象限”)。通常,计算以弧度为单位,而不是度数。
为了实现逼真的动作,你的坦克的逻辑必须定期计算这个角度,然后转向朝向。如果角度现在足够小,子弹将击中目标,坦克会发射。
我不打算给你提供“代码编写服务”,但这是它的基本数学。
答案 1 :(得分:0)
我建议你查看一些如何用2D矢量计算的例子。我不太确定你正在使用哪个框架。通常游戏引擎或框架都有矢量类。
矢量看起来像这样(x,y)。所以你有两个你需要的坐标。如果你从你应该到达的位置(v2)中减去你的子弹必须开始的位置(v1),你会得到一个方向向量。 计算看起来像这样。
v3.x = v2.x - v1.x. v3.y = v2.y - v1.y
此向量可以乘以速度因子。然后你只需添加子弹的位置矢量。
在方法之间插入的常用方法是lerp(http://en.wikipedia.org/wiki/Linear_interpolation)或slerp。这些是算法。您可以将其用于轮换。
这有用还是完全没用?我很乐意尽我所能帮助你。
答案 2 :(得分:0)
物体朝某个方向旋转的基本逻辑,主要是使物体朝向那个方向,可以表示如下:
private double calculateAngle(double vecX, double vecY) {
double angle = Math.toDegrees(Math.atan(vecY / vecX));
return vecX > 0 ? angle : 180 + angle;
}
其中vecX
和vecY
是向量的x
和y
值(方向)。这可以通过从“射手”的x, y
值中减去敌人的x, y
值来获得。最后,只需将旋转变换与从方法返回的角度应用到“射手”对象