Одна проблема, которую я вижу с методом paintComponent (), - это место, где вы рисуете изображение. Насколько я понимаю, каждый спрайт в вашей игре - это отдельная JPanel. Поэтому объект Graphics (g), передаваемый в метод paintComponent, отличается для каждого спрайта. Вы можете представить объект Graphics как холст для живописи. Если у вас был только 1 графический объект для всей игры, и этот графический объект представлял все игровое окно, тогда ваша логика была бы правильной, и все должно работать.
Однако каждый Sprite здесь имеет свой собственный графический объект, предположительно с высотой и шириной, относящимися к спрайту. В этом случае ваш метод paintComponent, вероятно, будет выглядеть следующим образом:
public void paintComponent(Graphics g)
{
if (spriteImage != null)
g.drawImage(this.spriteImage, 0, 0, getWidth(), getHeight(); // always at (0,0)
}
Почему? Потому что с вашим дизайном вы перемещаете Sprite и его графический объект вокруг игрового окна! Координаты, которые вы передаете drawImage (), относятся к объекту Graphics; Вы всегда хотите начать рисовать в верхнем левом углу, (0,0), Sprite. Вы получаете только серый квадрат, потому что пытаетесь нарисовать изображение далеко за пределами объекта Graphics.
В долгосрочной перспективе я не думаю, что этот подход сработает, потому что не так просто перемещать JPanels внутри своих родительских контейнеров (если вы не используете абсолютное позиционирование). Это не очень масштабируемо, потому что JPanels довольно тяжеловесны и требуют много ресурсов для создания и отображения.
Вероятно, вам лучше иметь одну JPanel, которая представляет всю игровую область. Каждый Sprite не будет подклассом JPanel, поэтому у вас нет метода paintComponent. Вы могли бы сделать что-то вроде этого:
public class GameArea extends JPanel
{
private final Collection<Sprite> sprites; // sprites to draw
public void paintComponent(Graphics g)
{
for(Sprite sprite : sprites)
{
sprite.drawOnSurface(g);
}
}
}
public class Sprite // no need to extend anything
{
/* Your other code looks OK */
public void drawOnSurface(Graphics surface)
{
surface.drawImage(image, x, y, getWidth(), getHeight());
}
}