На основе класса BasicGame можно создавать вполне успешные простые игры. Однако, в том случае, когда игра становится достаточно сложной, полезно разбивать её на отдельные части, поместив эти части в различные классы, разделив также логику и графику. Эти части называются состояниями игры.
Реализация этой концепции в библиотеке Slick находится к классе StateBasedGame. Состояния создаются с помощью реализации интерфейса GameState. Для удобства реализации этого интерфейса доступен класс BaseGameState (аналогично классу BasicGame для простых игр).
Интерфейс GameState обеспечивает простейший игровой интерфейс, а именно, имеет методы init, render и update. При этом, игры, основанные на состояниях могут иметь несколько различных реализаций состояний, между которыми есть возможность переключаться. Поэтому, логика и отрисовка, связанные с каждой частью игры могут быть оформлены разными классами, что упрощает разработку и отладку готовой программы.
Интересной особенностью данной реализации состояний является наличие различных визуальных эффектов, которые можно применять при переключении между состояниями. Эти визуальные эффекты объявлены и реализованы с помощью интерфейса Transitions.
Зачем?
Каждая игра обычно состоит из несколько раздельных частей. Каждый, кто когда-либо играл в компьютерные игры, знает, что после исчезновения заставки игры на экране появится приветствие или главное меню. Далее, если игрок нажимает кнопку "Играть" в главном меню, он знает, что после этого начнётся непосредственно сама игра.
Поэтому, по мере усложнения механизма игры, необходимо использовать механизм игровых состояний. Например, среднестатистическая игра содержит: заставку, игровое меню, меню настроек, введение, собственно сама игра, экран лучших результатов, и, наконец, экран или заставка, информирующая об окончании игры.
Если кто-либо попробует создать все эти состояния использую только класс BasicGame, ему придётся реализовывать эти состояния в методах update и render, что приведёт к чрезмерному разрастанию кода этих методов. Использование игровых состояний решает данную проблему путём деления игры на логические части. То есть, класс MainMenuState будет отвечать только за работу с меню, а класс GamePlayState будет содержать только игровую логику и будет рисовать на экране только игровое поле.
Или вот, например, в игре может содержаться внутренне меню для оперативного изменения настроек. При этом действие в игре должно быть приостановлено и на экране должно отобразиться меню настроек. Без использования состояний это бы пришлось делать в классе основной игры. А при использовании состояний игра просто передаёт управление другому состоянию (назовём его OptionsMenuState) которое содержит код и ресурсы, необходимые для реализации такого меню настроек. При этом пункт главного меню "Настройки" также будет ссылаться на это состояние.
Или, например, игры, где есть два разных игровых процесса (уровень с платформами и некоторый необычный бонусный уровень). Без использования состояний пришлось бы в одном классе совмещать логику двух, совершенно разных по виду игр. А с использованием состояний это легко сделать, создав два разных класса, которые реализуют состояния: PlatformGameplayState и BonusLevelGamePlayState.
В заключении, приведу пример простейшей реализации игровых состояний. Здесь использованы тестовые классы, реализующие три разных состояния:
Интересной особенностью данной реализации состояний является наличие различных визуальных эффектов, которые можно применять при переключении между состояниями. Эти визуальные эффекты объявлены и реализованы с помощью интерфейса Transitions.
Зачем?
Каждая игра обычно состоит из несколько раздельных частей. Каждый, кто когда-либо играл в компьютерные игры, знает, что после исчезновения заставки игры на экране появится приветствие или главное меню. Далее, если игрок нажимает кнопку "Играть" в главном меню, он знает, что после этого начнётся непосредственно сама игра.
Поэтому, по мере усложнения механизма игры, необходимо использовать механизм игровых состояний. Например, среднестатистическая игра содержит: заставку, игровое меню, меню настроек, введение, собственно сама игра, экран лучших результатов, и, наконец, экран или заставка, информирующая об окончании игры.
Если кто-либо попробует создать все эти состояния использую только класс BasicGame, ему придётся реализовывать эти состояния в методах update и render, что приведёт к чрезмерному разрастанию кода этих методов. Использование игровых состояний решает данную проблему путём деления игры на логические части. То есть, класс MainMenuState будет отвечать только за работу с меню, а класс GamePlayState будет содержать только игровую логику и будет рисовать на экране только игровое поле.
Или вот, например, в игре может содержаться внутренне меню для оперативного изменения настроек. При этом действие в игре должно быть приостановлено и на экране должно отобразиться меню настроек. Без использования состояний это бы пришлось делать в классе основной игры. А при использовании состояний игра просто передаёт управление другому состоянию (назовём его OptionsMenuState) которое содержит код и ресурсы, необходимые для реализации такого меню настроек. При этом пункт главного меню "Настройки" также будет ссылаться на это состояние.
Или, например, игры, где есть два разных игровых процесса (уровень с платформами и некоторый необычный бонусный уровень). Без использования состояний пришлось бы в одном классе совмещать логику двух, совершенно разных по виду игр. А с использованием состояний это легко сделать, создав два разных класса, которые реализуют состояния: PlatformGameplayState и BonusLevelGamePlayState.
В заключении, приведу пример простейшей реализации игровых состояний. Здесь использованы тестовые классы, реализующие три разных состояния:
package slicktemplate; import org.newdawn.slick.AppGameContainer; import org.newdawn.slick.GameContainer; import org.newdawn.slick.SlickException; import org.newdawn.slick.state.StateBasedGame; import org.newdawn.slick.tests.states.TestState1; import org.newdawn.slick.tests.states.TestState2; import org.newdawn.slick.tests.states.TestState3; public class Game extends StateBasedGame { static int height = 600; static int width = 800; static boolean fullscreen = false; static boolean showFPS = true; static String title = "Slick State Based Game Example"; static int fpslimit = 60; public Game(String title) { super(title); } @Override public void initStatesList(GameContainer gc) throws SlickException { addState(new TestState1()); addState(new TestState2()); addState(new TestState3()); } public static void main(String[] args) throws SlickException { try { AppGameContainer container = new AppGameContainer(new Game(title)); container.setDisplayMode(width, height, fullscreen); container.start(); } catch (SlickException e) { e.printStackTrace(); } } }
Источник: сайт Wiki-документации проекта Slick: http://slick.cokeandcode.com/wiki/doku.php?id=state_based_games
Комментариев нет:
Отправить комментарий