当前位置: 首页 > 知识库问答 >
问题:

java线程弹跳球

仲承福
2023-03-14

提前感谢帮助我创建了一个程序,使多个弹跳球当用户点击屏幕上一个新的球应该出现并在屏幕上移动。但是当我点击屏幕上一个球出现,根本不移动。当另一个点击发生时,以前创建的球立即跳到另一个位置。

这是ball类:用于创建球

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.util.Random;
import javax.swing.JComponent;

public class Ball extends JComponent implements Runnable{
    private final int DIAMETER = 25;
    private final int v1 = 5;
    private final int v2 = -5;
    private final Random rnd = new Random();
    private int posX;
    private int posY;
    private Color color;
    private int xVelocity;
    private int yVelocity;
    
    public Ball(int posX, int posY) {
        this.posX = posX;
        this.posY = posY;
        this.color = randomColor(); 
        this.xVelocity = rnd.nextBoolean()?v1:v2;
        this.yVelocity = rnd.nextBoolean()?v1:v2;
    }
    
    public void move() {
        if (posX < 15) {
            xVelocity = -xVelocity;
        } else if(posX > 475) {
            xVelocity = -xVelocity;
        }
        
        if (posY < 0) {
            yVelocity = -yVelocity;
        } else if(posY > 475) {
            yVelocity = -yVelocity;
        }
        posX +=xVelocity;
        posY +=yVelocity;

    }
    
    public void draw(Graphics2D g2) {
        g2.setColor(color);
        g2.fill(new Ellipse2D.Double(posX,posY,DIAMETER,DIAMETER));
    }
    
    private static Color randomColor() {
        int r = (int)(Math.random()*255);
        int g = (int)(Math.random()*255);
        int b = (int)(Math.random()*255);
        Color rColor = new Color(r,g,b);
        return rColor;
    }

    @Override
    public void run() {
            while(!Thread.interrupted()) {
            move();
            repaint();
            try {
                Thread.sleep(60);
            } catch (InterruptedException ex) {}
            }

        
    }
}

这是一个ball组件类:用于创建面板

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class BallComponent extends JPanel{
    private ArrayList<Ball> bList;
    
    public BallComponent() {
        bList = new ArrayList<Ball>();
        this.setPreferredSize(new Dimension(500,500));
        this.setBackground(Color.BLACK);
        this.addMouseListener(new ClickListener());
    }
    
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;
        super.paintComponent(g2);
        for (Ball a : bList) {
            a.draw(g2);
        }
    }
    
    private class ClickListener extends MouseAdapter{
        public void mouseClicked(MouseEvent e) {
            Ball a = new Ball(e.getX(),e.getY());
            bList.add(a);
            repaint();
            Thread gameThread = new Thread(a);
            gameThread.start();
        }
    }
    
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setTitle("Bouncing Balls");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new BallComponent());
        frame.pack();
        frame.setVisible(true);
    }
}

共有1个答案

长孙宜
2023-03-14

因为你有一堆线程在做随机的事情。你不妨让你的JPanel更新自己。

在你的主要方法的末尾。

new Thread( ()->{
    while(true){
        frame.repaint();
        try{
            Thread.sleep(60);
        } catch(Exception e){
            break;
        }
    }
}).start();

通常你会用一个定时器任务来完成这个任务,但既然你说你不能用定时器,我就写了一个线程版本。

我认为repaint()可以安全地从关闭EDT调用,因为它只是计划重新绘制。paintComponent方法和click方法将仅在EDT上调用。所以你不应该得到CCME。多线程有很多比赛条件,但唯一的问题似乎是球被拉离了位置。

 类似资料:
  • 我正在创建一个弹跳球项目,每次点击鼠标时,都会以随机的速度、随机的大小和随机的位置生成弹跳球,除了一件事,一切都很完美,当球从顶部和左侧撞击墙壁时,它会完全反弹,但是当球撞击窗户的底部和右侧时,它们也会反弹,但不是完全反弹,我的意思是,球在撞击墙壁之前会从窗户的右侧反弹,当球超过窗户的一半时,会从底部反弹。问题是什么,为什么要这样做? 下面是代码:

  • 问题内容: 因此,我只是想使屏幕周围的球弹起,该球应由于重力而减慢,并像普通球一样从墙壁反射(弹起)。有人可以给出一些基础知识并且非常简单地实现吗?其他示例似乎有些“过高”,似乎超出了我想要做的事情。我已经试过了: 这是我一个人得到的最接近的东西。顺便说一下,x和y值来自加速度计。任何帮助将不胜感激,谢谢! 问题答案: 我认为您将需要三件事,即力(您拥有的x和y),速度(分别称为xVel和yVel

  • 动画outputBounceBounce UpBounce UpBounce In LeftBounce In RightBounce UpBounce Out DownBounce UpBounce Out LeftBounce Out RightBounce Out Up

  • 我正在的上的上运行应用程序。对于那些不熟悉的人,每当发生SQS事件时,Amazon都会自动向我的Worker应用程序执行请求。我的应用程序然后处理请求并返回200(除非明显出错)。 我想在处理单个请求时使用并发。例如,假设我需要执行10种不同的昂贵计算。我希望使用让10个线程同时执行这项工作,而不是串行执行。 这是坏习惯吗?如果没有,以这种方式启动新线程是否存在性能危险 线程的分配实际上是如何工作

  • 问题内容: 看起来我已经搞砸了Java线程/ OS线程和解释性语言。 在开始之前,我确实了解绿色线程是Java线程,其中JVM处理线程,并且整个Java进程仅作为单个OS线程运行。因此,在多处理器系统上是没有用的。 现在我的问题是。我有两个线程A和B。每个线程都有10万行独立代码。我在多处理器系统上的Java程序中运行这些线程。每个线程都将被赋予一个本机OS线程来运行,该线程可以在不同的CPU上运

  • 每个人我对使用线程池有一个误解。实际结果与该类的API描述不同。当我在线程池中使用时,它不重用线程,线程池等待构造函数中设置的KeepAliveTime,然后杀死这个线程并创建一个新线程。当我将KeepAliveTime设置为较小值时,比如1秒或更短,它会删除一个线程并重新创建它,但如果我设置一分钟,则不会创建新线程,因为不允许创建,队列已经满,所以所有任务都会被拒绝,但KeepAliveTime