libGDX. Урок 7. Добавление фона, ям и расположение зомби

Добавление фона

Давайте быстренько добавим задний фон в нашу игру и приступим к реализации ям, откуда будут вылезать наши зомби. В классе GameManager нам нужно добавить переменные:

private static float ZOMBIE3_HORIZ_POSITION_FACTOR = 1.5f;
static Texture backgroundTexture; // текстурное изображение заднего фона
static Sprite backgroundSprite; // спрайт для заднего фона

В методе initialize() класса GameManager мы загружаем текстуру и инициализируем спрайт, который будет покрывать весь экран предполагаемого устройства:

zombieTexture = new Texture(Gdx.files.internal("zombie.png"));

backgroundTexture = new Texture(Gdx.files.internal("ground.jpg")); // загрузка текстуры
backgroundSprite = new Sprite(backgroundTexture); // установка текстуры в спрайт
// настройка размеров и позиции спрайта заднего фона
backgroundSprite.setSize(width, height);
backgroundSprite.setPosition(0,0f);

 
Отрисовываем получившийся спрайт в методе renderGame() перед отрисовкой всех остальных игровых объектов (чтобы не перекрыть их):

    public static void renderGame(SpriteBatch batch){

        backgroundSprite.draw(batch);
        // Нарисовать(отобразить) каждого зомби
        for(Zombie zombie : zombies)
            zombie.render(batch);
    }

После чего избавляемся от текстуры в методе dispose():

public static void dispose() {
    // утилизация текстуры крота, чтобы обеспечить отсутствие утечек памяти
    zombieTexture.dispose();
    backgroundTexture.dispose();
}

Теперь приложение будет выглядеть так:

background libgdx

Реализация ям

Для ям мы будем использовать новое изображение, но в отличие от заднего фона мы используем его несколько раз (в нашем случае 9). В классе GameManager объявим массив и текстуру для наших ям:

static Sprite backgroundSprite; // спрайт для заднего фона
static Texture holeTexture; // текстура для ямы
static Array<Sprite> holeSprites; // массив спрайтов ям
private static float HOLE_RESIZE_FACTOR = 1100f;

Теперь приступи к инициализации ям в методе initialize() (этот кусок кода нужно вставить до кода инициализации зомби):

holeTexture = new Texture(Gdx.files.internal("hole.png"));
holeSprites = new Array<Sprite>();
for(int i=0;i<3;i++){
    for(int j=0;j<3;j++){
        Sprite sprite = new Sprite(holeTexture);
        // подгоняем размер ям
        sprite.setSize(sprite.getWidth()* (width/HOLE_RESIZE_FACTOR), sprite.getHeight()* (width/HOLE_RESIZE_FACTOR ));
        // размещаем позиции ям
        sprite.setPosition(width*(j+1)/4f - sprite.getWidth()/2, height*(i+1)/4.4f - sprite.getHeight());
        holeSprites.add(sprite);
    }
}

Хотя мы и используем одномерный массив для хранения девяти экземпляров ям, расположены они будут в сетке 3х3. Мы располагаем их соответствующим образом и изменяем их размер так, чтобы они отображались в центре. Отрисовка ям будет происходить в методе renderGame() – после отрисовки заднего фона, но до зомби:

 

public static void renderGame(SpriteBatch batch){

    backgroundSprite.draw(batch);
    // Нарисовать(отобразить) каждую яму
    for(Sprite sprite : holeSprites)
        sprite.draw(batch);
    // Нарисовать(отобразить) каждого зомби
    for(Zombie zombie : zombies)
        zombie.render(batch);
}

И наконец избавляемся от текстуры ямы в методе dispose():

public static void dispose() {
    // утилизация текстуры крота, чтобы обеспечить отсутствие утечек памяти
    zombieTexture.dispose();
    backgroundTexture.dispose();
    holeTexture.dispose();
}

Должно получится это:

игра приложение android studio libgdx

Добавление зомби в ямы

Теперь нам нужно отобразить зомби вылезающих из ям. Каждый зомби должен вылезать из соответствующей ямы так, чтобы это выглядело более-менее реалистично. Сначала увеличим количество зомби до девяти в методе initialize() класса GameManager:

// создание новых зомби и добавление их в массив
for(int i = 0; i < 9 ; i++){
    zombies.add(new Zombie());
}

Теперь нужно расположить всех зомби. Перед этим добавим переменную scaleFactor в класс Zombie. Она нужна нам для масштабирования зомби относительно экрана устройства:

public float height,width; // размеры зомби
public float scaleFactor; // коэффициент масштабирования зомби

Теперь обновим код метода initialize() класса GameManager. Для начала удалите эти строки из метода initialize():

// установить позиции для каждого зомби
zombies.get(0).position.set(width/ZOMBIE1_HORIZ_POSITION_FACTOR,height/ZOMBIE_VERT_POSITION_FACTOR);
zombies.get(1).position.set(width/ZOMBIE2_HORIZ_POSITION_FACTOR,height/ZOMBIE_VERT_POSITION_FACTOR);
zombies.get(2).position.set(width/ZOMBIE3_HORIZ_POSITION_FACTOR,height/ZOMBIE_VERT_POSITION_FACTOR);
for(Zombie zombie : zombies){

// установить спрайт для зомби, используя текстуру
zombie.zombieSprite = new Sprite(zombieTexture);
// установка размеров зомби
zombie.width = zombie.zombieSprite.getWidth()* (width/ZOMBIE_RESIZE_FACTOR);
zombie.height = zombie.zombieSprite.getHeight()* (width/ZOMBIE_RESIZE_FACTOR);
zombie.zombieSprite.setSize(zombie.width, zombie.height);
zombie.zombieSprite.setPosition(zombie.position.x, zombie.position.y);
}

Вместо них введите следующий код:

    // установка позиций для зомби
    for(int i=0;i<9;i++){
        Zombie zombie = zombies.get(i);
        Sprite sprite = holeSprites.get(i);
        // установить спрайт для зомби, используя текстуру
        zombie.zombieSprite = new Sprite(zombieTexture);
        // установка размеров зомби
        float scaleFactor = width/600f;
        zombie.scaleFactor = scaleFactor;
        zombie.width = zombie.zombieSprite.getWidth()*(scaleFactor);
        zombie.height = zombie.zombieSprite.getHeight()*(scaleFactor);
        zombie.zombieSprite.setSize(zombie.width, zombie.height);
        // установка позиции зомби
        zombie.position.x=((sprite.getX() + (sprite.getX() + sprite.getWidth()))/2 - (zombie.zombieSprite.getWidth()/2));
        zombie.position.y=(sprite.getY() + sprite.getHeight()/5f);
        zombie.zombieSprite.setPosition(zombie.position.x, zombie.position.y);
    }

} // конец метода initialize()

Если у вас что-то не получится, вы можете сверить свой код с исходным, который можете скачать внизу урока.

 
В этом кусочке кода мы устанавливаем x и y координаты каждого зомби так, чтобы они находились в центре своей ямы. Обсудим получение x-координаты. Нам необходимо, чтобы оба центра: и спрайта ямы и спрайта зомби были приведены к одной точке. Сперва мы вычисляем центр ямы по горизонтали. Это будет центр между начальной и конечной точками спрайта ямы. Делаем это следующим образом:

(sprite.getX() + (sprite.getX() + sprite.getWidth()))/2

 

sprite.getX() – начальная координата x спрайта;

(sprite.getX() + sprite.getWidth()) – конечная координата x спрайте;

(sprite.getX() + (sprite.getX() + sprite.getWidth()))/2 – центр спрайта по оси x.

центр спрайта

После чего мы смещаем из полученной точки (центр спрайта ямы по оси x) половину спрайта нашего зомби и таким образом центр спрайта зомби будет совмещен с центром спрайта ямы:

- (zombie.zombieSprite.getWidth()/2))

И записываем получившийся результат, как начальную точку размещения спрайта зомби по оси x:

zombie.position.x=((sprite.getX() + (sprite.getX() + sprite.getWidth()))/2 - (zombie.zombieSprite.getWidth()/2));

центр спрайта sprite

С координатой y все проще. Нам нужно создать видимость того, что зомби вылезает из ямы. Поэтому мы устанавливаем начальное положение спрайта зомби по оси y в начальное положение спрайта ямы + 20% смещение и записываем как начальную точку размещения спрайта зомби по оси y:

zombie.position.y=(sprite.getY() + sprite.getHeight()/5f);

расположение спрайта по оси y

Теперь, запустив приложение у вас должно получится это:

игра приложение android

Если что-то не получилось, сверьте свой код с моим, который можно скачать внизу. Задавайте вопросы в комментариях если что-то непонятно. В следующем уроке оживим наших зомби путем анимации.

Скачать исходники