-1

Ok so I have looked around and I didn't find anything that helped me with this so I thought I would go ahead and ask here. I want to have a bunch of circles that collide bounce and generally interact with each other. The problem I am running into is that drawing a lot of circles eats away at the frame rate. So given an array of circles which I have to draw, all of them. Is the only way to draw them simply to draw them all using g.fillOval() in the paintComponent?

For example, in the paint component, I call a function drawBalls(Graphics2D g) that draws all the balls it contains. (that's how I draw stuff by passing it through to the object that draws I don't know if there is a better way)

    for(Ball ball:balls){
        ball.drawYourself(g) //g is the Graphics2D
    }

Thanks

Edit. Sorry if it was a bad question here is the code of my program. I hope it isn't too long.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*; 
import java.io.*; 
import javax.imageio.*; 
import java.util.*;
import javax.swing.Timer;
//###################################################\\
public class Game extends JFrame implements ActionListener{
    private Timer myTimer;   
    private GamePanel panel;

    public Game() {
        super("Things.py");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1000,800);
        panel = new GamePanel(this);
        add(panel);
        myTimer = new Timer(1, this);
        myTimer.start();

        setResizable(false);
        setVisible(true);
    }

    public void actionPerformed(ActionEvent evt){
        panel.repaint();        
    }
    public static void main(String[] arguments) {
        Game frame = new Game();        
    }
}
//###################################################\\
//###################################################\\
class GamePanel extends JPanel implements MouseMotionListener, MouseListener,KeyListener{
    // ------------ Variables ----------------------------------------------
    private int mx,my;//Mouse position x and y
    private boolean[]keys;//If the keys are pressed
    private Boolean mousepressed=false;//If the mouse is pressed down
    private Game mainframe;//The panel that created this GamePanel

    private Color backmenuc;
    private Color backcolor;

    private bounceBalls bballs;
    private bounceBalls bballs2;
    // ------------ Constructor --------------------------------------------
    public GamePanel(Game m){
        //----- Listeners -----
        addMouseMotionListener(this);//LISTEN TO ME!!!
        addMouseListener(this);//Listen to me!
        addKeyListener(this);//listen to me pls

        //----- Variables -----
        mainframe=m;
        keys=new boolean[KeyEvent.KEY_LAST+1];//creates the array for keys
        backcolor=new Color(0,0,0);
        backmenuc=new Color(255,255,255);
        bballs=new bounceBalls(this);
        bballs2=new bounceBalls(this);
        //----- Load Images -----

        //----- End -----
    }

    // ------------ Drawing ------------------------------------------------
    public void paintComponent(Graphics gg){
        Graphics2D g=(Graphics2D) gg;
        paint.drawRect(g,0,0,getWidth(),getHeight(),backcolor);
        if (mousepressed){
            bballs.addBall(mx,my,10);
            bballs2.addBall(mx+100,my,10);
        }
        bBallThreading b1=new bBallThreading(g,bballs,"B1");
        b1.start();
        bBallThreading b2=new bBallThreading(g,bballs2,"B1");
        b2.start();

        //bballs.update();
        //bballs2.update();
        bballs.draw(g);
        bballs2.draw(g);

        System.out.println(bballs.size());

    }
    // ------------ Misc ---------------------------------------------------
    public void addNotify() {
        super.addNotify();
    }
    // ------------ MouseListener ------------------------------------------
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {
        mousepressed=false;
    }    
    public void mouseClicked(MouseEvent e){
        }  

    public void mousePressed(MouseEvent e){ 
        mousepressed=true;
    }   
    // ---------- MouseMotionListener --------------------------------------
    public void mouseDragged(MouseEvent e){
        mx=e.getX();
        my=e.getY();
    }
    public void mouseMoved(MouseEvent e){
        mx=e.getX();
        my=e.getY();
        }
    // ---------- KeyListener -----------------------------------------------
    public void keyTyped(KeyEvent e) {}

    public void keyPressed(KeyEvent e) {
        keys[e.getKeyCode()] = true;
    }
    public void keyReleased(KeyEvent e) {
        keys[e.getKeyCode()] = false;
    }
}
//###################################################\\
class bounceBall{
    private double bx,by;
    private int br;
    private double vx,vy;
    public bounceBall(int x,int y,int radius){
        bx=(double)x;
        by=(double)y;
        br=radius;
        vx=0;
        vy=0;
    }
    public void move(){
        if((by+vy)>800){
            vy*=-.9;
        }
        bx+=vx;
        by+=vy;
    }
    public void addV(double x, double y){
        vx+=x;
        vy+=y;
    }
    public void draw(Graphics2D g){
        g.setColor(new Color(255,0,0));
        g.fillOval((int)bx-br,(int)by-br,br*2,br*2);
    }
}
class bounceBalls{
    GamePanel gp;
    ArrayList<bounceBall> balls;
    double gravity;
    public bounceBalls(GamePanel gamep){
        gp=gamep;
        gravity=.1;
        balls=new ArrayList<bounceBall>();

    }
    public void draw(Graphics2D g){
        //paint.setAA(g,true);
        paint.setAlpha(g,.1f);
        for(bounceBall ball:balls.toArray(new bounceBall[balls.size()])){
            ball.draw(g);
        }
        paint.setAlpha(g,1f);
        //paint.setAA(g,false);
    }
    public void setGravity(double g){
        gravity=g;
    }
    public void update(){
        for(bounceBall ball:balls.toArray(new bounceBall[balls.size()])){
            ball.addV(0,gravity);
            ball.move();
        }
    }
    public void addBall(int x, int y, int radius){
        balls.add(new bounceBall(x,y,radius));
    }
    public int size(){
        return balls.size();
    }
}
class bBallThreading implements Runnable{
    private Thread t;
    private String threadname;
    Graphics2D g;
    private bounceBalls bballs;
    public bBallThreading(Graphics2D g, bounceBalls bballs,String s){
        this.g=g;
        this.bballs=bballs;
        threadname=s;
    }
    public void run(){
        bballs.update();
    }
    public void start(){
        if (t == null)
      {
         t = new Thread (this, threadname);
         t.start ();
      }
    }
}
//###################################################\\

When I run this I get 4000 circles at 30 fps

Tiago Mussi
  • 801
  • 3
  • 13
  • 20
Tristhal
  • 110
  • 8
  • 1
    Generally speaking, I've had +10, 000 "objects" painting and animating through Swing/`paintComponent` with little issues (it's not as great as 1, but it's not a significant issue). Problem areas I've found are in object creation, especially for short lived objects. Consider providing a [runnable example](https://stackoverflow.com/help/mcve) which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses – MadProgrammer Apr 16 '15 at 00:38
  • 1
    For [example](http://stackoverflow.com/questions/23417786/rotating-multiple-images-causing-flickering-java-graphics2d/23419824#23419824), [example](http://stackoverflow.com/questions/14886232/swing-animation-running-extremely-slow/14902184#14902184) and [example](http://stackoverflow.com/questions/27681998/smooth-animation-in-java-for-fast-moving-objects) – MadProgrammer Apr 16 '15 at 00:58

1 Answers1

0
    bBallThreading b1=new bBallThreading(g,bballs,"B1");
    b1.start();
    bBallThreading b2=new bBallThreading(g,bballs2,"B1");
    b2.start();

The paintComponent() method is for painting. That is all is should do.

You should NOT be starting a Thread in a painting method. Every time Swing paints the component you will be starting two more Threads.

Add a System.out.println(...) statement to that method to see how many times that method is executed.

You should start the Thread when you start the animation.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • 1
    So where should i put it? Im not sure what the thread does i thought that it starts the thread, finishes the 2 threads and continues is it not so? Do they just keep going alongside the main thread until they finish? Thanks. – Tristhal Apr 16 '15 at 20:26
  • Actually you don't event need the Thread. You already use a Timer. The Timer should be responsible for doing the animation. MadProgrammer gave you 3 examples to look at. I would suggest you look at the "BouncingBalls" from the 3rd examples link. – camickr Apr 16 '15 at 20:38