Java 二维平面上的射弹问题

Java 二维平面上的射弹问题,java,libgdx,Java,Libgdx,我很难让我的子弹飞到他们想去的地方,我希望我能得到一些帮助来确定我的计算出了什么问题 基本上我是在做一个2d游戏,只要你点击屏幕,子弹就会射向你点击的位置,但问题是我的子弹没有射向我想要的地方。现在我相信我的问题出在checkScreenForTouch()方法的某个地方,以及我如何计算应该添加到项目符号位置的内容。我不擅长三角函数,但我确实理解它,因此,如果有人对如何修复以下代码有任何建议,那将非常酷:) private void updateBullets(float dt){ batch.

我很难让我的子弹飞到他们想去的地方,我希望我能得到一些帮助来确定我的计算出了什么问题

基本上我是在做一个2d游戏,只要你点击屏幕,子弹就会射向你点击的位置,但问题是我的子弹没有射向我想要的地方。现在我相信我的问题出在checkScreenForTouch()方法的某个地方,以及我如何计算应该添加到项目符号位置的内容。我不擅长三角函数,但我确实理解它,因此,如果有人对如何修复以下代码有任何建议,那将非常酷:)

private void updateBullets(float dt){
batch.begin();
对于(int i=0;isWidth | | b.position.y<0 | | b.position.y>sHeight){
删除(b);
继续;
}
}       
batch.end();
}
Creentouch(浮动dt)的专用无效支票{
if(Gdx.input.isTouched()){
项目符号b=新项目符号();
双角度=Math.atan((p.pos.y-Gdx.input.getY())/(p.pos.x-Gdx.input.getX());
b、 deltaX=数学cos(角度);
b、 deltaY=数学sin(角度);
b、 position.x=p.pos.x;//将项目符号的起始位置设置为与玩家相等
b、 位置y=位置y;
项目符号。添加(b);//项目符号数组列表
}
}

如果你需要澄清什么,请告诉我。谢谢

我知道你还没有得到任何建议。我有点时间,所以我想我应该做点什么

你遇到的问题我可以用你的代码重现

  • 子弹只射向右边-这是通过使用atan2(dy,dx)解决的
  • 它们应该是相反的角度-这是因为计算
    p.pos.y-Gdx.input.getY()
    实际上应该被否定:
    Gdx.input.getY()-p.pos.y
    。只是一个简单的错误。当鼠标的y坐标大于玩家位置时,您希望y坐标的变化为正值
    有关应用程序的说明:

    一些问题与帧大小调整。倾向于在弹道中间突然射出子弹

    我将时间变化除以
    1000
    ,表示我希望速度为
    像素/秒
    。只是物理学20中的一个习惯

    应用程序正在运行中。您真正需要的代码位于顶部的
    makeSproject
    函数中

    除此之外,我只是使用了一个同步列表来避免更新和渲染的并发性问题

    如果您有任何问题,请随时提问:)


    import javax.swing.*;
    导入java.awt.*;
    导入java.awt.event.ActionEvent;
    导入java.awt.event.ActionListener;
    导入java.awt.event.MouseAdapter;
    导入java.awt.event.MouseEvent;
    导入java.util.Collection;
    导入java.util.Collections;
    导入java.util.Iterator;
    导入java.util.LinkedList;
    /**
    *@author Obicere
    */
    公共类项目专家{
    //一个人去很危险!拿着这个。
    公共空间(最终鼠标事件e、最终整数宽度、最终整数高度){
    最终整数x=宽度/2;
    最终int y=高度/2;
    最终双角度=Math.atan2(e.getY()-y,e.getX()-x);
    最终双deltaX=数学cos(角度);
    最终双三角=数学sin(角度);
    射弹。添加(新射弹(x,y,deltaX,deltaY));
    }
    私有静态最终双投射速度=100;//像素/秒
    private final Collection Projectles=Collections.synchronizedCollection(新LinkedList());
    公共静态void main(最终字符串[]args){
    调用器(projectletest::new);
    }
    公共项目专家(){
    最终JFrame=新JFrame(“射弹试验”);
    最终JPanel内容=新JPanel(){
    专用最终尺寸=新尺寸(500500);
    @凌驾
    公共组件(最终图形g){
    超级组件(g);
    g、 设置颜色(颜色为黑色);
    g、 drawOval(getWidth()/2-2,getHeight()/2-2,4,4);
    射弹。forEach((e)->e.render(g));
    }
    @凌驾
    公共维度getPreferredSize(){
    返回大小;
    }
    };
    content.addMouseListener(新的MouseAdapter(){
    @凌驾
    公共无效鼠标按下(最终鼠标事件e){
    makeSproject(e,content.getWidth(),content.getHeight());
    }
    });
    content.addMouseMotionListener(新的MouseAdapter(){
    @凌驾
    公共无效鼠标标记(最终鼠标事件e){
    makeSproject(e,content.getWidth(),content.getHeight());
    }
    });
    最终计时器重新绘制=新计时器(10,新ActionListener(){
    @凌驾
    已执行的公共无效操作(操作事件e){
    最终迭代器iter=projectles.Iterator();
    while(iter.hasNext()){
    最终射弹next=iter.next();
    如果(!next.valid()){
    iter.remove();
    }
    下一步(content.getWidth(),content.getHeight());
    }
    frame.repaint();
    }
    });
    框架。添加(内容);
    frame.pack();
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(空);
    frame.setVisible(true);
    
    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
        }
    }
    
    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);
            }
    
        }
    
    }