При добавлении в JPanel изображение выглядит как серый квадрат - PullRequest
1 голос
/ 21 марта 2009

Я работаю над проектом для университета, который по сути является переработкой игры Space Invaders с немного измененными правилами. Пока у меня есть основной JFrame, содержащий подкласс JPanel (для фонового изображения), который содержит другой подкласс JPanel, который я использую для спрайтов. Однако, когда я запускаю его, JFrame и фон JPanel работают нормально, но затем, когда я рисую спрайт, он просто генерирует серый квадрат, для которого я не могу изменить размер или положение. Вот код, который я получил для своего класса Sprite:

import java.awt.*;
import java.io.File;
import javax.swing.*;


public class Sprite extends JPanel
{
Image spriteImage;
int speedX;
int speedY;
Point pos;
final boolean MV_LEFT = false;
final boolean MV_RIGHT = true;

public Sprite(File _imageFile)
{
    try {
        spriteImage = javax.imageio.ImageIO.read(_imageFile);
    } catch (Exception e) {
        /* handled in paintComponent() */
    }
    speedX = 1;
    speedY = 1;
    pos = new Point(100,100);
}

@Override
protected void paintComponent(Graphics g)
{
    super.paintComponent(g);
    if (spriteImage != null)
        g.drawImage(this.spriteImage, this.pos.x, this.pos.y, this.getWidth(), this.getHeight(), this);
}

public void move(boolean direction)
{
    if (direction == true)
    {
        this.pos = new Point((pos.x + speedX), pos.y);
        repaint();
    }
    else
    {
        this.pos = new Point((pos.x - speedX), pos.y);
        repaint();
    }
}
}

Я уверен, что в этом есть несколько неправильных вещей, но для метода paintComponent () я только что попробывал все учебные пособия по обработке изображений, которые я нашел в интернете, но это все еще не работает. Есть что-то огромное, что я забыл?

1 Ответ

2 голосов
/ 21 марта 2009

Одна проблема, которую я вижу с методом 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());
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...