Проблемы с графикой Java при стрельбе из нескольких пуль
Поэтому я пытаюсь создать эту Java-игру о стрельбе по самолетам инопланетян и прочее. Самолет стреляет пулей при каждом щелчке мышью. Это означает, что самолет может стрелять 10 или 20 или более пуль одновременно. Чтобы продемонстрировать движение пули, я попробовал Thread и Timer, но реальная проблема заключается в том, что если я выстрелил 1 пулю, это означает, что я создал новую Thread(или Timer) и это заставляет игру работать очень медленно. Есть ли способ, как я могу решить эту проблему? Вот мой код для перемещения пули
public class Bullet extends JComponent implements Runnable {
int x;//coordinates
int y;
BufferedImage img = null;
Thread thr;
public Bullet(int a, int b) {
x = a;
y = b;
thr = new Thread(this);
thr.start();
}
protected void paintComponent(Graphics g) {
// TODO Auto-generated method stub
try {
img = ImageIO.read(new File("bullet.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// g.drawImage(resizeImage(img, 2), x, y, this);
g.drawImage(Plane.scale(img, 2, img.getWidth(), img.getHeight(), 0.125, 0.125), x, y, this);
width = img.getWidth() / 8;
height = img.getHeight() / 8;
super.paintComponent(g);
}
public void run() {
while(true)
{
if(y<-50)break;//if the bullet isnt out of the frame yet
y-=5;//move up
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
1 ответ
Пуля не должна быть на собственной нити. Для этого есть несколько причин, одна из которых упомянута вами - она сделает вашу игру очень медленной.
Попробуйте использовать один главный поток, который обновляет все маркеры. Вам понадобится функция обновления в вашей пуле:
public class Bullet extends JComponent {
public void update() {
if(y<-50)return; //if the bullet isnt out of the frame yet
y-=5; //move up
}
//all your other code for your bullet
}
Тогда в вашей главной ветке есть список пуль:
LinkedList<Bullet> bullets = new LinkedList<>();
В методе выполнения этого потока вы можете постоянно обновлять ВСЕ маркеры:
public void run() {
while(true)
{
for (Bullet b : bullets) {
b.update();
}
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Вам понадобится метод в вашем основном потоке, который позволит вам добавить новый маркер:
public void addBullet(Bullet b) {
bullets.add(b);
}
Затем вы можете вызвать это, чтобы добавить новый маркер, и главный поток обновит этот маркер вместе со всеми остальными.