Leila Abirova Leila Abirova - 2 months ago 12
Java Question

Java: drawing multiple sprites in different threads at a time

I need to create a JPanel, where upon a mouse click a new Sprite must appear in a new thread. This is what I have:

public class BouncingSprites {

private JFrame frame;
private SpritePanel panel = new SpritePanel();
private Sprite ball;

public BouncingSprites() {
frame = new JFrame("Bouncing Sprite");
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setVisible(true);
}
public void start(){
panel.animate(); // never returns due to infinite loop in animate method
}

public static void main(String[] args) {
new BouncingSprites().start();
}
}


Class SpritePanel:

public class SpritePanel extends JPanel
{
Sprite sprite;

public SpritePanel()
{
addMouseListener(new Mouse());
}

//method for creating a new ball
private void newSprite (MouseEvent event)
{
sprite = new Sprite(this);
}

public void animate()
{
}

private class Mouse extends MouseAdapter
{
@Override
public void mousePressed( final MouseEvent event )
{
newSprite(event);
}
}


@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if (sprite != null)
{
sprite.draw(g);
}
}
}


Class Sprite :

public class Sprite implements Runnable
{
public final static Random random = new Random();
final static int SIZE = 10;
final static int MAX_SPEED = 5;
SpritePanel panel;
private int x;
private int y;
private int dx;
private int dy;
private Color color = Color.BLUE;
private Thread animation;

public Sprite (SpritePanel panel)
{
this.panel = panel;
x = random.nextInt(panel.getWidth());
y = random.nextInt(panel.getHeight());
dx = random.nextInt(2*MAX_SPEED) - MAX_SPEED;
dy = random.nextInt(2*MAX_SPEED) - MAX_SPEED;

animation = new Thread(this);
animation.start();
}

public void draw(Graphics g)
{
g.setColor(color);
g.fillOval(x, y, SIZE, SIZE);
}

public void move()
{

// check for bounce and make the ball bounce if necessary
//
if (x < 0 && dx < 0){
//bounce off the left wall
x = 0;
dx = -dx;
}
if (y < 0 && dy < 0){
//bounce off the top wall
y = 0;
dy = -dy;
}
if (x > panel.getWidth() - SIZE && dx > 0){
//bounce off the right wall
x = panel.getWidth() - SIZE;
dx = - dx;
}
if (y > panel.getHeight() - SIZE && dy > 0){
//bounce off the bottom wall
y = panel.getHeight() - SIZE;
dy = -dy;
}

//make the ball move
x += dx;
y += dy;
}

@Override
public void run()
{
while (Thread.currentThread() == animation)
{
move();
panel.repaint();

try
{
Thread.sleep(40);
}
catch ( InterruptedException exception )
{
exception.printStackTrace();
}
}
}
}


This code creates a new moving sprite. However, the previous sprite gets removed from the panel. What I need to do is to add a new sprite with a mouse click, so that the previous sprite is not removed. If I click three times, three sprites should be painted.

How do I change my code to implement that?

Many thanks!

Answer

You could replace Sprite sprite; in the SpritePanel class with List<Sprite> sprites = new ArrayList<>();. Then, when you make a new Sprite, add it to the list. Then in your paintComponent method, you could iterate through the list, drawing all of the sprites.