When I add to the GameScreen more than one Object of class Duck only one appears on the screen. When I add Duck outside constructor in GameScreen class I have many Object of Duck but then the mouseClicked method doesn't work on Duck.
public class GameScreen extends JPanel{
public GameScreen(){
JPanel bottompanel = new JPanel();
Duck duck1 = new Duck("/red-duck.png", 200, 70, 70, 40);
Duck duck2 = new Duck("/blue-duck.png", 50, 70, 70, 5);
this.setLayout(new BorderLayout());
bottompanel.add(labelTime);
this.add(bottompanel, BorderLayout.SOUTH);
this.add(duck1);
this.add(duck2);
new Thread(
() -> {
while (!Thread.currentThread().isInterrupted()) {
labelTime.setText(String.valueOf(start));
repaint();
}
}
).start();
/////////////////////////////////////////////////////////////////////////
public class Duck extends JPanel implements ImageObserver, MouseListener {
private BufferedImage image;
private String pathname;
private int distance;
private int speed;
public int x;
private int y;
private int width;
private int hight;
private int lives;
public Duck(String pathname, int y, int width, int hight, int speed) {
super();
this.pathname = pathname;
this.speed = speed;
this.distance = 1 (int)(Math.random()*speed);
this.x = 0;
this.y = y;
this.width = width;
this.hight = hight;
this.lives = duckColor();
this.addMouseListener(this);
System.out.println("make duck" lives);
timer.start();
File imageFile = new File(pathname);
try {
image = ImageIO.read(imageFile);
} catch (IOException e) {
System.err.println("Blad odczytu obrazka");
e.printStackTrace();
}
}
ActionListener al=new ActionListener() {
public void actionPerformed(ActionEvent ae) {
x = distance;
}
};
Timer timer=new Timer(100,al);
public void paintComponent(Graphics g) {
// super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(image, x, y, width, hight, this);
}
@Override
public void mouseClicked(MouseEvent e) {
lives--;
}
CodePudding user response:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
BufferedImage img = ImageIO.read(getClass().getResource("/images/Duck.png"));
List<Duck> ducks = new ArrayList<>();
ducks.add(new Duck(img));
ducks.add(new Duck(img));
JFrame frame = new JFrame();
frame.add(new GamePane(ducks));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class Duck {
private BufferedImage image;
private int x;
private int y;
private int xDelta = 0;
private int yDelta = 0;
public Duck(BufferedImage image) {
this.image = image;
}
public BufferedImage getImage() {
return image;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setLocation(int x, int y) {
setX(x);
setY(y);
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return image == null ? 0 : image.getWidth();
}
public int getHeight() {
return image == null ? 0 : image.getHeight();
}
public void setDelta(int x, int y) {
xDelta = x;
yDelta = y;
}
public int getXDelta() {
return xDelta;
}
public int getYDelta() {
return yDelta;
}
public void move(Rectangle bounds) {
int xDelta = getXDelta();
int yDelta = getYDelta();
int x = getX() xDelta;
int y = getY() yDelta;
if (x < bounds.x) {
x = bounds.x;
xDelta *= -1;
} else if (x getWidth() >= bounds.x bounds.width) {
x = (bounds.x bounds.width) - getWidth();
xDelta *= -1;
}
if (y < bounds.y) {
y = bounds.y;
yDelta *= -1;
} else if (y getWidth() >= bounds.y bounds.height) {
y = (bounds.y bounds.height) - getHeight();
yDelta *= -1;
}
setDelta(xDelta, yDelta);
setLocation(x, y);
}
public void paint(Graphics2D g2d, ImageObserver observer) {
g2d.drawImage(getImage(), getX(), getY(), observer);
}
}
public class GamePane extends JPanel {
private List<Duck> ducks;
public GamePane(List<Duck> ducks) {
this.ducks = ducks;
Random rnd = new Random();
for (Duck duck : ducks) {
int width = 400 - duck.getWidth();
int height = 400 - duck.getHeight();
int x = rnd.nextInt(width);
int y = rnd.nextInt(height);
int xDelta = rnd.nextBoolean() ? 1 : -1;
int yDelta = rnd.nextBoolean() ? 1 : -1;
duck.setLocation(x, y);
duck.setDelta(xDelta, yDelta);
}
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Rectangle bounds = new Rectangle(getSize());
for (Duck duck : ducks) {
duck.move(bounds);
}
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Duck duck : ducks) {
Graphics2D g2d = (Graphics2D) g.create();
duck.paint(g2d, this);
g2d.dispose();
}
}
}
}
From this, you can start adding more entities as needed, for example, I can modify the Main
method to include LOTs of ducks...
BufferedImage img = ImageIO.read(getClass().getResource("/images/Duck.png"));
List<Duck> ducks = new ArrayList<>(100);
for (int index = 0; index < 100; index ) {
ducks.add(new Duck(img));
}
This is obviously and overly simplified example intended only as a demonstration of core concept, you'll need to do more research into basic game development and 2D graphics.