Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 球的弹性碰撞_Java - Fatal编程技术网

Java 球的弹性碰撞

Java 球的弹性碰撞,java,Java,我有一个我无法理解的错误。我尝试了很多次,碰撞检测和计算新的速度似乎很好,但有些球似乎彼此卡住了,我不知道为什么。你能帮我解决吗 import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.image.BufferStrategy; import java.util.Random; import javax.swing.JF

我有一个我无法理解的错误。我尝试了很多次,碰撞检测和计算新的速度似乎很好,但有些球似乎彼此卡住了,我不知道为什么。你能帮我解决吗

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.util.Random;

import javax.swing.JFrame;

public class ElasticCollision extends Canvas implements Runnable {

    private static final int WIDTH = 300;
    private static final int HEIGHT = WIDTH / 16 * 9;
    private static final int SCALE = 3;

    private static final String TITLE = "Elastic collision";

    private boolean running = false;

    private JFrame frame;
    private Thread thread;

    private Random random = new Random();
    private Color color;
    private int a, b, c;

    private Ball[] ball;
    private int x = 0, y = 0;
    private int radius = 0;
    private int speedX = 0, speedY = 0;

    private int noOfBalls = 25;

    private double newVelX1 = 0, newVelY1 = 0;
    private double newVelX2 = 0, newVelY2 = 0;

    private double angle1 = 0, angle2 = 0, angle3 = 0;
    private int x1 = 0, y1 = 0, x2 = 0, y2 = 0;

    public ElasticCollision() {

        Dimension size = new Dimension(WIDTH * SCALE, HEIGHT * SCALE);
        setPreferredSize(size);
        frame = new JFrame();
        ball = new Ball[noOfBalls];
    }

    public void start() {
        for (int i = 0; i < noOfBalls; i++) {
            x = random.nextInt(getWidth());
            y = random.nextInt(getHeight());
            radius = 25 + random.nextInt(25);
            speedX = 1 + random.nextInt(2);
            speedY = 1 + random.nextInt(2);
            ball[i] = new Ball(x, y, radius, speedX, speedY);
        }
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    public void stop() {
        running = false;
    }

    public void run() {

        long lastTime = System.nanoTime();
        double unprocessed = 0;
        double nsPerTick = 1000000000.0 / 60;
        int frames = 0;
        int ticks = 0;
        long lastTimer = System.currentTimeMillis();

        while (running) {
            long now = System.nanoTime();
            unprocessed += (now - lastTime) / nsPerTick;
            lastTime = now;
            while (unprocessed >= 1) {
                ticks++;
                update();

                unprocessed -= 1;
            }

            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int i = 0; i < noOfBalls; i++) {
                for (int j = i + 1; j < noOfBalls; j++) {
                    if (ball[i].inCollision != true
                            || ball[j].inCollision != true)
                        checkCollision(ball[i], ball[j]);
                }
            }
            frames++;
            render();
            if (System.currentTimeMillis() - lastTimer > 1000) {
                lastTimer += 1000;
                frame.setTitle(TITLE + " | " + ticks + " ticks, " + frames
                        + " fps");
                frames = 0;
                ticks = 0;
            }

        }
        stop();
    }

    public void update() {
        for (int i = 0; i < noOfBalls; i++) {
            ball[i].x += ball[i].speedX;
            ball[i].y += ball[i].speedY;

            if (ball[i].x >= getWidth() - ball[i].radius && ball[i].speedX > 0)
                ball[i].speedX = -ball[i].speedX;
            if (ball[i].x <= ball[i].radius && ball[i].speedX < 0)
                ball[i].speedX = -ball[i].speedX;
            if (ball[i].y >= getHeight() - ball[i].radius && ball[i].speedY > 0)
                ball[i].speedY = -ball[i].speedY;
            if (ball[i].y <= ball[i].radius && ball[i].speedY < 0)
                ball[i].speedY = -ball[i].speedY;
        }
    }

    public void render() {

        BufferStrategy bs = getBufferStrategy();
        if (bs == null) {
            createBufferStrategy(3);
            return;
        }
        Graphics g = bs.getDrawGraphics();
        g.setColor(Color.yellow);
        g.fillRect(0, 0, getWidth(), getHeight());
        for (int i = 0; i < noOfBalls; i++)
            ball[i].paint(g);
        g.dispose();
        bs.show();
    }

    public void checkCollision(Ball ball1, Ball ball2) {
        double distance;

        if (ball1.x + ball1.radius + ball2.radius > ball2.x
                && ball1.x < ball1.x + ball1.radius + ball2.radius
                && ball1.y + ball1.radius + ball2.radius > ball2.y
                && ball1.y < ball2.y + ball1.radius + ball2.radius) {

            distance = Math.sqrt(((ball1.x - ball2.x) * (ball1.x - ball2.x))
                    + ((ball1.y - ball2.y) * (ball1.y - ball2.y)));
            if ((int) distance < ball1.radius + ball2.radius) {
                ball1.collision = true;
                ball2.collision = true;
                ball1.inCollision = true;
                ball2.inCollision = true;

                ball1.collisionX = ((ball1.x * ball2.radius) + (ball2.x * ball1.radius))
                        / (ball1.radius + ball2.radius) + ball1.radius;
                ball1.collisionY = ((ball1.y * ball2.radius) + (ball2.y * ball1.radius))
                        / (ball1.radius + ball2.radius) + ball1.radius;

                ball2.collisionX = ((ball1.x * ball2.radius) + (ball2.x * ball1.radius))
                        / (ball1.radius + ball2.radius) + ball2.radius;
                ball2.collisionY =

                ((ball1.y * ball2.radius) + (ball2.y * ball1.radius))
                        / (ball1.radius + ball2.radius) + ball2.radius;


                /*
                 * x1 = (ball1.x - getWidth()) / 2; y1 = (ball2.y - getHeight())
                 * / 2; angle1 = Math.toDegrees(Math.atan2(y1, x1));
                 * 
                 * x2 = (ball1.x - getWidth()) / 2; y2 = (ball2.y - getHeight())
                 * / 2; angle2 = Math.toDegrees(Math.atan2(y2, x2));
                 */
                double colision_angle = Math.toDegrees(Math.atan2(
                        (ball2.y - ball1.y), (ball2.x - ball1.x)));

                double speed1 = Math.sqrt(ball1.speedX * ball1.speedX
                        + ball1.speedY * ball1.speedY);
                double speed2 = Math.sqrt(ball2.speedX * ball2.speedX
                        + ball2.speedY * ball2.speedY);

                double direction1 = Math.atan2(ball1.speedY, ball1.speedX);
                double direction2 = Math.atan2(ball2.speedY, ball2.speedX);

                double vx_1 = speed1 * Math.cos(direction1 - colision_angle);
                double vy_1 = speed1 * Math.sin(direction1 - colision_angle);
                double vx_2 = speed2 * Math.cos(direction2 - colision_angle);
                double vy_2 = speed2 * Math.sin(direction2 - colision_angle);

                double final_vx_1 = ((ball1.radius - ball2.radius) * vx_1 + (ball2.radius + ball2.radius)
                        * vx_2)
                        / (ball1.radius + ball2.radius);
                double final_vx_2 = ((ball1.radius + ball1.radius) * vx_1 + (ball2.radius - ball1.radius)
                        * vx_2)
                        / (ball1.radius + ball2.radius);

                double final_vy_1 = vy_1;
                double final_vy_2 = vy_2;

                newVelX1 = (int) (Math.cos(colision_angle) * final_vx_1 + Math
                        .cos(colision_angle + Math.PI / 2) * final_vy_1);
                newVelY1 = (int) (Math.sin(colision_angle) * final_vx_1 + Math
                        .sin(colision_angle + Math.PI / 2) * final_vy_1);
                newVelX2 = (int) (Math.cos(colision_angle) * final_vx_2 + Math
                        .cos(colision_angle + Math.PI / 2) * final_vy_2);
                newVelY2 = (int) (Math.sin(colision_angle) * final_vx_2 + Math
                        .sin(colision_angle + Math.PI / 2) * final_vy_2);

                ball1.speedX = (int) newVelX1;
                ball1.speedY = (int) newVelY1;

                ball2.speedX = (int) newVelX2;
                ball2.speedY = (int) newVelY2;

                ball1.x = ball1.x + (int) newVelX1;
                ball1.y = ball1.y + (int) newVelY1;
                ball2.x = ball2.x + (int) newVelX2;
                ball2.y = ball2.y + (int) newVelY2;




            }

        }
    }

    public static void main(String[] args) {

        ElasticCollision balls = new ElasticCollision();
        balls.frame.setResizable(false);
        balls.frame.add(balls);
        balls.frame.pack();
        balls.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        balls.frame.setVisible(true);

        balls.start();
    }

}

class Ball {

    protected int x = 0, y = 0;
    protected int radius;
    protected int speedX = 0, speedY = 0;
    protected boolean collision = false;

    protected int collisionX = 0, collisionY = 0;
    protected boolean inCollision = false;

    public Ball(int x, int y, int radius, int speedX, int speedY) {
        this.x = x + radius;
        this.y = y + radius;
        this.radius = radius;
        this.speedX = speedX;
        this.speedY = speedY;
    }

    public void paint(Graphics g) {
        if (!collision) {
            g.setColor(Color.red);
            g.fillOval(x - radius, y - radius, radius * 2, radius * 2);
        } else {
            g.setColor(Color.green);
            g.fillOval(x - radius, y - radius, radius * 2, radius * 2);
            g.setColor(Color.blue);
            g.fillOval(collisionX - radius, collisionY - radius, 20, 20);
            g.setColor(Color.black);
            g.drawOval(collisionX - radius, collisionY - radius, 20, 20);
            collision = false;
            inCollision = false;
        }
        g.setColor(Color.black);
        g.drawOval(x - radius, y - radius, radius * 2, radius * 2);
    }

}
导入java.awt.Canvas;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.image.BufferStrategy;
导入java.util.Random;
导入javax.swing.JFrame;
公共类ElasticCollision扩展画布实现Runnable{
专用静态最终整数宽度=300;
专用静态最终内部高度=宽度/16*9;
专用静态最终整数刻度=3;
私有静态最终字符串TITLE=“弹性碰撞”;
私有布尔运行=false;
私有JFrame;
私有线程;
私有随机=新随机();
私人色彩;
私人int a、b、c;
私人舞会[]舞会;
私有整数x=0,y=0;
私有整数半径=0;
私人整数速度x=0,速度=0;
私密网内无球=25;
私有双newVelX1=0,newVelY1=0;
私有双newVelX2=0,newVelY2=0;
私人双角度1=0,角度2=0,角度3=0;
私有整数x1=0,y1=0,x2=0,y2=0;
公共弹性碰撞(){
尺寸尺寸=新尺寸(宽度*比例,高度*比例);
设置首选大小(大小);
frame=新的JFrame();
球=新球[无球];
}
公开作废开始(){
for(int i=0;i=1){
ticks++;
更新();
未加工-=1;
}
试一试{
睡眠(2);
}捕捉(中断异常e){
e、 printStackTrace();
}
for(int i=0;i1000){
lastTimer+=1000;
frame.setTitle(TITLE+“|”+“ticks+”ticks,“+frames
+“fps”);
帧=0;
滴答声=0;
}
}
停止();
}
公共无效更新(){
for(int i=0;i=getWidth()-ball[i].radius&&ball[i].speedX>0)
ball[i].speedX=-ball[i].speedX;
if(ball[i].x=getHeight()-ball[i].radius&&ball[i].speedY>0)
球[i]。斯皮蒂=-球[i]。斯皮蒂;
if(ball[i].y ball2.x
&&ball1.xball2.y
&&ball1.y