2d飞机上的弹丸问题

时间:2014-04-27 02:19:06

标签: java libgdx

我无法让我的子弹去他们想要的地方,我希望能得到一些帮助来确定我的计算结果。

基本上我做了一个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
    }
}

如果您需要澄清任何事情,请告诉我。谢谢。

1 个答案:

答案 0 :(得分:2)

我发现你还没有真正得到任何建议。有一段时间,所以我想我会鞭打一些东西。

您遇到的问题我可以使用您的代码重现。

  1. 子弹只向右射击 - 这是通过使用atan2(dy, dx)解决的。
  2. 它们应该是什么的相反角度 - 这是因为计算p.pos.y - Gdx.input.getY()确实应该被否定:Gdx.input.getY() - p.pos.y。只是一个简单的混合。当鼠标的y坐标大于玩家位置时,您希望y的变化为正。

  3. 关于申请的说明:

    帧大小调整的一些问题。倾向于在弹道中弹出子弹。

    我将时间变化除以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);
            }
    
        }
    
    }