我无法让我的子弹去他们想要的地方,我希望能得到一些帮助来确定我的计算结果。
基本上我做了一个2D游戏,你在屏幕上点击一个子弹应该在你点击的那个位置拍摄,但问题是我的子弹不会去我想要的地方。现在我相信我的问题出在checkScreenForTouch()方法的某个地方,以及我如何计算应该添加到项目符号位置的内容。我不是三角测量学中最好的,但我确实理解它,所以如果任何人对如何修复以下代码有任何建议,那将是非常酷:)。
private void updateBullets(float dt){
batch.begin();
for(int i = 0; i < bullets.size(); i++){
Bullet b = bullets.get(i);
b.velocity.x += b.deltaX * b.speed;
b.velocity.y += b.deltaY * b.speed;
b.position.x += b.velocity.x * dt;
b.position.y += b.velocity.y * dt;
batch.draw(bullTex, b.position.x, b.position.y, bullTex.getWidth(), bullTex.getHeight());
if(b.position.x < 0 || b.position.x > sWidth || b.position.y < 0 || b.position.y > sHeight){
bullets.remove(b);
continue;
}
}
batch.end();
}
private void checkForScreenTouch(float dt){
if(Gdx.input.isTouched()){
Bullet b = new Bullet();
double angle = Math.atan((p.pos.y - Gdx.input.getY())/(p.pos.x - Gdx.input.getX()));
b.deltaX = Math.cos(angle);
b.deltaY = Math.sin(angle);
b.position.x = p.pos.x; //sets bullet start position equal to the players
b.position.y = p.pos.y;
bullets.add(b); // array list of bullets
}
}
如果您需要澄清任何事情,请告诉我。谢谢。
答案 0 :(得分:2)
我发现你还没有真正得到任何建议。有一段时间,所以我想我会鞭打一些东西。
您遇到的问题我可以使用您的代码重现。
atan2(dy, dx)
解决的。p.pos.y - Gdx.input.getY()
确实应该被否定:Gdx.input.getY() - p.pos.y
。只是一个简单的混合。当鼠标的y坐标大于玩家位置时,您希望y的变化为正。 关于申请的说明:
帧大小调整的一些问题。倾向于在弹道中弹出子弹。
我将时间变化除以1000
,表示我希望速度为pixels/second
。只是物理学中的习惯20。
申请正在进行中。您真正想要的代码位于顶部的makeProjectile
函数内。
除此之外,我只使用了同步列表来避免更新和呈现的并发问题。
如果您有任何疑问,请随时询问:)
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
/**
* @author Obicere
*/
public class ProjectileTest {
// It's dangerous to go alone! Take this.
public void makeProjectile(final MouseEvent e, final int width, final int height){
final int x = width / 2;
final int y = height / 2;
final double angle = Math.atan2(e.getY() - y, e.getX() - x);
final double deltaX = Math.cos(angle);
final double deltaY = Math.sin(angle);
projectiles.add(new Projectile(x, y, deltaX, deltaY));
}
private static final double PROJECTILE_VELOCITY = 100; // Pixels per second
private final Collection<Projectile> projectiles = Collections.synchronizedCollection(new LinkedList<>());
public static void main(final String[] args){
SwingUtilities.invokeLater(ProjectileTest::new);
}
public ProjectileTest(){
final JFrame frame = new JFrame("Projectile Test");
final JPanel content = new JPanel(){
private final Dimension size = new Dimension(500, 500);
@Override
public void paintComponent(final Graphics g){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawOval(getWidth() / 2 - 2, getHeight() / 2 - 2, 4, 4);
projectiles.forEach((e) -> e.render(g));
}
@Override
public Dimension getPreferredSize(){
return size;
}
};
content.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(final MouseEvent e) {
makeProjectile(e, content.getWidth(), content.getHeight());
}
});
content.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(final MouseEvent e) {
makeProjectile(e, content.getWidth(), content.getHeight());
}
});
final Timer repaint = new Timer(10, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final Iterator<Projectile> iter = projectiles.iterator();
while(iter.hasNext()){
final Projectile next = iter.next();
if(!next.valid()){
iter.remove();
}
next.step(content.getWidth(), content.getHeight());
}
frame.repaint();
}
});
frame.add(content);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
repaint.start();
}
public class Projectile {
private final double velocityX;
private final double velocityY;
private double x;
private double y;
private long lastUpdate;
private boolean valid = true;
public Projectile(final double x, final double y, final double vx, final double vy){
this.x = x;
this.y = y;
this.velocityX = vx;
this.velocityY = vy;
this.lastUpdate = System.currentTimeMillis();
}
public boolean valid(){
return valid;
}
public void destroy(){
this.valid = false;
}
public void step(final int width, final int height){
final long time = System.currentTimeMillis();
final long change = time - lastUpdate;
this.x += (change / 1000D) * (velocityX * PROJECTILE_VELOCITY);
this.y += (change / 1000D) * (velocityY * PROJECTILE_VELOCITY);
this.lastUpdate = time;
if(x < 0 || y < 0 || x > width || y > height){
destroy();
}
}
public void render(final Graphics g){
g.setColor(Color.RED);
g.drawOval((int) x - 2, (int) y - 2, 4, 4);
}
}
}