danilaxxl danilaxxl

CollectableItemData.cs

[CreateMenuItem(fileName = "newItem", menuName = "Data/Items/Collectable", order = 51]

GoloGames GoloGames

vadya_ivan, рад, что вам игра показалась интересной : )

P.S. Кстати уже доступна бесплатная демо-версия в Steam

vadya_ivan vadya_ivan

Визуал, задумка, музыка , механики, все в цель

GoloGames GoloGames

Ato_Ome, спасибо за позитивные эмоции, будем стараться : )

Ato_Ome Ato_Ome

Потрясающий результат, все так четенько, плавненько)
То ли саунд, то ли плавность напомнили мне игрушку World of Goo, удачи вам в разработке и сил побольше дойти до релиза!)

Cute Fox Cute Fox

Graphics are a little cool, good HD content. But this game doesn't cause nary interest me.
However the game is well done.

GMSD3D GMSD3D

Почему действие после всех условий выполняется?
[step another object]

Zemlaynin Zemlaynin

Jusper, Везде, но наугад строить смысла нет. Нужно разведать сперва территорию на наличие ресурсов.

Jusper Jusper

Zemlaynin, а карьеры можно будет везде запихать?
Или под них "особые" зоны будут?

Zemlaynin Zemlaynin

Это так скажем тестовое строительство, а так да у города будет зона влияния которую нужно будет расширять.

Jusper Jusper

А ссылка есть?

Jusper Jusper

Я не оч понял из скриншота, как вообще работает стройка. У игрока будет как бы поле строительства?

split97 split97

в игру нужно добавить время песочные часы в инвентаре, пока бегаешь наберается усталость и ты очень тормозной мобильный враг просто убевает

split97 split97

в игру нужно добавить время песочные часы в инвентаре, пока бегаешь наберается усталость и ты очень тормозной мобильный враг просто убевает

ViktorJaguar ViktorJaguar

Почему я нигде не могу найти нормальный туториал, где покажут как экипировать предмет (например, меч) в определенную (выделенную под оружие) ячейку???

Логотип проекта Прочие движки

Разделяем игру на экраны

В этой короткой статье мы немного изменим примитивную одноэкранную игру из предыдущей статьи, добавив экран, который впоследствии станет главным меню нашей игрушки.

На данный момент у нас в подпроекте "core" всего один класс Drop:

public class Drop implements ApplicationListener {
   public void create() {...}

   public void render() {...}

   public void resize(int width, int height) {}

   public void pause() {}

   public void resume() {}

   public void dispose() {...}
}

Он расширен засчет интерфейса ApplicationListener, т.е. представляет из себя класс, который первым делом вызывается при запуске игры (из класса-лаунчера).

Для создания многоэкранных приложений в LibGDX существует класс Game. Это наследник ApplicationListener, в него добавлены всего лишь 2 метода:

public void setScreen (Screen screen)
public Screen getScreen ()

Как вы можете догадаться, они предназначены для работы с игровыми экранами.

Что же такое Screen? По факту это тот же самый ApplicationListener, но вызывается не классом-лаунчером, а классом-игрой. Класс Game позволяет переключаться с экрана на экран, благодаря чему можно сделать меню для игры, сплэш скрин, различные внутриигровые окна типа карты, окон торговли, разговора, миниигр.

Поскольку окон, в отличие от самой игры, может быть несколько и их можно создать одновременно, то метод create() заменён обычным конструктором класса. Второе отличие Screen от ApplicationListener - метод render(float delata). Класс Game вызывает метод render с аргументом времени, прошедшим с момента последнего вызова этого же метода. Т.е. окна всегда знают, когда обновлялись в предыдущий раз. И последнее отличие - наличие двух вспомогательных методов для работы экранов.

Создаём экран с игрой

Так как у нас уже есть готовая игра, то проще будет начать с игрового экрана, а потом уже добавить меню. Для этого нам необходимо скопировать класс Drop и назвать копию GameScreen. Класс Drop мы полностью изменим и превратим в обработчик экранов, а класс GameScreen подправим так, чтобы он стал игровым экраном. Последним сейчас и займёмся.
Для этого мы меняем класс-расширитель с ApplicationListener на Screen:

public class GameScreen implements ApplicationListener
public class GameScreen implements Screen

И сразу же получаем 3 ошибки. Начнём исправлять с самого простого - добавим методу render() аргумент:

	public void render(float delta) {

Теперь изменим create() на конструктор.

	@Override
	public void GameScreen() {

Меняем на

	public GameScreen(final Drop game) {

В качестве аргумента экран получит ссылку на обработчик экранов. Чтобы её не потерять, нужно создать переменную в блоке переменных

	private Drop game;

Ну и конечно же необходимо присвоить полученное значение:

	public GameScreen(final Drop game) {
		this.game = game;

		...
	}

Для работоспособности экрана осталось лишь добавить отсутствующие методы

	@Override
	public void show() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void hide() {
		// TODO Auto-generated method stub
		
	}

Игровое окно готово, чуть позже мы его немножко оптимизируем, а сейчас займемся обработчиком окон.

Класс Drop

Первым делом меняем интерфейс ApplicationListener на класс-предок Game

public class Drop implements ApplicationListener {
public class Drop extends Game {

Поскольку теперь это не класс с игрой, а всего лишь связующее звено для экранов, то мы можем смело удалить весь игровой код и заменить этим:

package com.badlogic.drop;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;


public class Drop extends Game {

    public SpriteBatch batch;
    public BitmapFont font;

    public void create() {
        batch = new SpriteBatch();
        font = new BitmapFont();
        this.setScreen(new GameScreen(this));
    }

    public void render() {
        super.render(); // Архиважно! Иначе ничего не будет рисоваться.
    }

    public void dispose() {
        batch.dispose();
        font.dispose();
    }

}

Хорошим тоном в ООП считается реюзабельность объектов, в частности, в нашей игре мы будем использовать один и тот же батч для всех игровых экранов. Поэтому мы создаём публичные переменные

    public SpriteBatch batch;
    public BitmapFont font;

Для того, чтобы к ним могли все обращаться через вызов класса Drop из переменной game.

game.batch.draw(...);

Аналогично со шрифтом. При использовании пустого конструктора создаётся стандартный Arial шрифт.
В методе create() батч и фонт инициализируются, а также запускается акивный экран - тот экран, который игрок увидит первым делом.

Метод render() запускает отрисовку активного игрового экрана. Если вы перфекционист и вам не нравятся лишние процедурные вызовы, можете заменить вызов метода-предка на строку

if (screen != null) screen.render(Gdx.graphics.getDeltaTime());

Метод dispose(), разумеется, очищает глобальные переменные.

Зачаток главного меню

Сейчас мы не будем делать меню как таковое, привычное для нас. Оно будет без каких-либо кнопок, в нём будет лишь одна пояснительная строчка о том, что нужно тыкнуть мышью(пальцем) в любое место на экране, чтобы начать игру. Делать насстоящее меню мы будем в следующей статье.

Создайте третий класс, назовите его MainMenuScreen и расширьте интерфейсом Screen.

Создайте ему конструктор с аргументом Drop объявите соответствующую переменную:

public class MainMenuScreen implements Screen {

	private Drop game;
	
	public MainMenuScreen(final Drop game){
		this.game = game;
	}
	
	...
}

А теперь в методе render(float delta) выведем строчку текста.

public void render(float delta) {
	Gdx.gl.glClearColor(0, 0, 0.2f, 1);
	Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
	
	game.batch.begin();
	game.font.draw(game.batch, "Tap anywhere to begin!", 100, 100);
	game.batch.end();
	
	if (Gdx.input.isTouched()) {
		game.setScreen(new GameScreen(game));
		dispose();
	}

}

Сперва при помощи модуля gl очищаем экран. Затем испольуем глобальные батч и фонт для рисования строки. И в конце мы ловим клик и переключаемся на игровой экран.

Чтобы "включить" наше меню, необходимо исправить обработчик экранов. Помните, что там устанавливается сразу игровой экран? Заменяем игровой экран на экран меню.

this.setScreen(new GameScreen(this));
this.setScreen(new MainMenuScreen(this));

Теперь перед началом игры мы видим синий экран с белой надписью. Кликаем мышкой - и начинаем игру. Но это ещё не всё, нам нужно немножко оптимизировать GameScreen.

Исправляем GameScreen

В данный момент GameScreen использует свой собственный батч для прорисовки. Нам нужно убрать его.

Вернее, заменить глобальным, который хранится в обработчике экранов. Это значит, что нужно удалить переменную,

private SpriteBatch batch;

её инициализацию

// и батча
batch = new SpriteBatch();

и её очищение.

batch.dispose();

И заменить все вызовы на вызовы глобальной переменной

batch.end();
game.batch.end();

Разумеется, батч и фонт - не единственное, что стоит вынести из игрового экрана. Например, текстуры и звуки - ведь их можно использовать в других экранах. Запустить фоновую музыку в главном меню, пустить там же фоном капли и т.д.. Но это в качестве домашнего задания.

Также в качестве самостоятельной работы вы можете добавить счетчик в GameScreen, учитывать каждую пойманную каплю и выводить счёт на экран.

Смотрите также:


Комментарии

Здесь еще никто не оставил комментарий

Справка