2D Java игра. Перемещение спрайта над плиточными изображениями - PullRequest
3 голосов
/ 16 ноября 2010

-> Краткое введение, вы можете пропустить эту часть

Я рад наконец опубликовать сообщение на этой платформепотому что я для себя получил столько знаний через это сообщество;просто читая.Поэтому я хотел сказать: «Привет всем, и спасибо!

Фактическое содержание (пролог):

Хотя я работаю в Objective-C в своей компании, я полностьюЯ заинтересован в разработке JAVA. Мне довольно комфортно с синтаксисом, но у меня есть некоторые серьезные проблемы с awt / swing / Graphics2D.

Концепция:

Приложение JAVA с фреймом 800 * 600.В кадре вы можете видеть 16 * 12 плиток (т.е. gras.jpg или tree.jpg) размером 50px². Над этим кадром движется .png «игрок». Поле генерируется с помощью двумерного массива int [16] [12], где 0 символизирует «гра», а 1 означает «дерево».

-> Это на самом деле «работает».

Первая попытка:

Добавление (фрейм.добавить (...)) 16 * 12 JLabels с imageIcon "gras" или "tree" в JLayeredPane
Добавление (frame.add (...)) класса "entityLayer", который обновляется через 5 мс с помощью paint (Graphics)g)
{
g.drawImage (imageIcon.getImage ());
}
Эта версия «работает», если я добавлю либо поле сh тайлы или слой сущности.В любом случае либо entityLayer накладывает поле на серый фон, либо под полем не отображается «player»;

Second Try:

Создание всех рисунков в рисовании entityLayer (Графика г) метод.Но это не то, что я хотел.Я хочу, чтобы поле было нарисовано один раз, а «игрок», как полупрозрачный фон, нарисовал над полем.

Вопрос:

Как я могу получить себяв состоянии фактически иметь два отдельных слоя, которые оба одинаково независимы без того, чтобы один перекрывал другой?Я почти на 99% уверен, что моя попытка в некотором роде неверна.

Спасибо тебе сразу.

1 Ответ

1 голос
/ 16 ноября 2010

Вместо добавления / рисования 16 * 12 JLabels, просто нарисуйте изображение плитки 16 * 12 раз?

Для подобных вещей я обычно добавляю один элемент JPanel в JFrame и переопределяю метод JPanel paint (). На самом деле я не добавляю JPanel, я добавляю созданный мной подкласс JPanel, вы должны сделать то же самое, так как я покажу, что вам нужно будет добавить поле в JPanel и переопределить метод рисования

Ваш код рисования фоновой плитки может выглядеть примерно так:

int tileWidth = 50;
int tileHeight = 50;
for ( int x = 0; x < 16; x++ )
{
    for ( int y = 0; y < 12; y++ )
    {
        Image tileImage;
        int tileType = fieldArray[x][y];

        switch ( tileType )
        {
            case 0:
            {
                tileImage = myGrassImage;
                break;
            }
            case 2:
            {
                tileImage = myTreeImage;
                break;
            }
        }

        Graphics2D g;
        g.drawImage(tileImage, x * tileWidth, y * tileHeight, null);
    }
}

Метод, который мне подходит, заключается в том, чтобы разделить логику рисования каждого слоя на отдельный класс, который реализует интерфейс Painter (или аналогичный интерфейс, который вы определили).

public class TilePainter implements Painter
{

    @Override
    public void paint( Graphics2D g, Object thePanel, int width, int height )
    {
        //The tile painting code I posted above would go here
        //Note you may need to add a constructor to this class
        //that provides references to the needed resources
        //Eg: images/arrays/etc
        //Or provides a reference to a object where those resources can be accessed
    }

}

Тогда для игрока художника:

public class EntityPainter implements Painter
{

    @Override
    public void paint( Graphics2D g, Object thePanel, int width, int height )
    {
        g.drawImage(player.getImage(), player.getX(), player.getY(), null);
    }

}

Если вам интересно, почему я передаю значения NULL в функцию g.drawImage (), то это потому, что для этого вызова перегруженной функции последний параметр является ImageObserver, который нам не нужен для этой цели.

Хорошо, поэтому, когда ваши художники разделены на разные классы, нам нужно сделать JPanel способным их использовать!

Это поле, которое нужно добавить в JPanel:

List<Painter> layerPainters;

Ваш конструктор должен выглядеть примерно так:

public MyExtendedJPanel()
    {
        //I use an ArrayList because it will keep the Painters in order
        List<Painter> layerPainters = new ArrayList<Painter>();

        TilePainter tilePainter = new TilePainter(Does,This,Need,Args);
        EntityPainter entityPainter = new EntityPainter(Does,This,Need,Args);

        //Layers will be painted IN THE ORDER THEY ARE ADDED
        layerPainters.add(tilePainter);
        layerPainters.add(entityPainter);

    }

Теперь о последней, но самой важной части:

@Override
public void paint( Graphics g )
{
    int width = getWidth();
    int height = getHeight();
    //Loops through all the layers in the order they were added
    //And tells them to paint onto this panels graphic context
    for(Painter painter : layerPainters)
    {
        painter.paint(g,this,width,height);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...