Колобок в гостях у Windows 8: дневники разработки (часть 1)

от автора

Пару недель назад мы опубликовали наш первый материал "Колобок в гостях у Windows 8: дневники разработки (введение)", сегодня мы продолжаем эту тему и рассказываем более детально структуру абстрактного уровня нашей архитектуры, в том виде как мы ее на сегодня организовали.

Первые эскизы

Недавно мы получили первые картинки от художника. Вот такой концепт на данный момент:

Абстрактный класс BaseGame

Этот класс берет на себя обязанности по управлению основным жизненным циклом игры, а также включает в себя логику и физику игры.

/// <summary>  /// Describes an abstract game  /// </summary>  public abstract class BaseGame:DisposeSupport     {         /// <summary>         /// The game Logic         /// </summary>         protected abstract ILogic Logic { get; }         /// <summary>         /// The game Physics         /// </summary>         protected abstract IPhysics Physics { get; }         /// <summary>         /// Initialize the game         /// </summary>         public void Initialize(){}         /// <summary>         /// Start the new game         /// </summary>         public void StartNewGame(){}         /// <summary>         /// Activate the game         /// </summary>         public void ActivateGame(){}         /// <summary>         /// Pause on game         /// </summary>         public void Pause(){}         /// <summary>         /// Restart the game         /// </summary>         public void Restart(){}         /// <summary>         /// Resume the game         /// </summary>         public void Resume(){}         /// <summary>         /// Exit the game         /// </summary>         public void Exit(){}         public event Action Win;         public event Action GameOver;         public event Action Lose;       } 

Жизненный цикл можно представить так:

Визуализация

Визуализация на верхнем уровне не привязана к игре. Связь с рендерингом происходит только в конкретной реализации игры.
За визуализацию отвечает интерфейс IRenderer, который обеспечивает реализацию трех методов:

  • Initialize выполняется во время инициализации устройства,
  • Render вызывается при отрисовке каждого кадра,
  • SizeChanged вызывается во время смены размеров экрана, и в этот момент возможна инициализация.
/// <summary>     /// Describes a renderer class     /// </summary>     /// <typeparam name="TInit">Type that used for method Initialize parameter</typeparam>     /// <typeparam name="TRender">Type that used for methods Render and ScreenSizeChanged parameters</typeparam>     public interface IRenderer<TInit, TRender>: IDisposable     {         /// <summary>         /// On initialize a device         /// </summary>         /// <param name="initParameter">Initialize parameter</param>         void Initialize(TInit initParameter);         /// <summary>         /// On render per frame         /// </summary>         /// <param name="renderParameter">Render parameter</param>         void Render(TRender renderParameter);         /// <summary>         /// On screen size changed         /// </summary>         /// <param name="renderParameter">Render parameter</param>         void ScreenSizeChanged(TRender renderParameter);     } 

Цикл визуализации:

IRenderer также наследует интерфейс IDisposable, что обеспечивает реализацию комплектом методов по детерминированному уничтожению объектов. В нашей реализации объекты по рисованию также наследуются от класса Component из библиотеки SharpDX, у которого можно использовать методы связанные с помещением ресурсов в список удаления, по которому проходит объект перед уничтожением, и мы получаем готовую реализацию IDisposable.

Логика

В нашей игре представлена интерфейсом ILogic

/// <summary>     /// Describes a game logic     /// </summary>     public interface ILogic     {         /// <summary>         /// Start game          /// </summary>         void StartGame();         /// <summary>         /// Stop game          /// </summary>         void StopGame();         /// <summary>         /// Pause game          /// </summary>         void PauseGame();         /// <summary>         /// Resume game          /// </summary>         void ResumeGame();         /// <summary>         /// Fire game event          /// </summary>         void FireEvent(IGameEvent @event);         /// <summary>         /// Win game event          /// </summary>         event Action Win;         /// <summary>         /// Lose game event          /// </summary>         event Action Lose;         /// <summary>         /// Delete game object event          /// </summary>         event Action<string> ObjectDeleted;         /// <summary>         ///Character moved event          /// </summary>         event Action<string,float,float,float> CharacterMoved;         /// <summary>         ///Character moved by path event          /// </summary>         event Action<string, IList<PathData>> CharacterMovedPath;         /// <summary>         ///Character patrol by path event          /// </summary>         event Action<string, IList<PathData>> CharacterPatrolPath;         /// <summary>         ///Character patrol event         /// </summary>         event Action<string, float, float, float> CharacterPatrol;         /// <summary>         ///Character moved to object event         /// </summary>         event Action<string, string, float> CharacterMovedToObject;         /// <summary>         ///Character in chase for object event         /// </summary>         event Action<string, string, float> CharacterChase;         /// <summary>         /// watch if the one object look at another;         /// </summary>         event Action<string, string> WatchedLook;          /// <summary>         /// watch the distance between two objects;         /// </summary>         event Action<string, string, float> WatchedDistance;         /// <summary>         /// character stop;         /// </summary>         event Action<string> ActionStopped;         /// <summary>         ///The rules factory         /// </summary>         IRuleFactory RuleFactory { get; }      } 

При возникновении игрового события логика обрабатывает набор правил, проверяет условия и возможность их выполнения, и потом инициирует события Win, Lose или Game Over, которые передаются в игру.

Рабочий цикл логики игры:

Физика

Интерфейс IPhysics

public interface IPhysics     {         /// <summary>         /// add object to simulation         /// </summary>         /// <param name="obj">object</param>         void AddObject(IObject obj);         /// <summary>         /// remove object from simulation         /// </summary>         /// <param name="obj">object</param>         void RemoveObject(IObject obj);         /// <summary>         /// simulate world on specified time after start         /// </summary>         /// <param name="time">seconds</param>         void Simulate(float time);         /// <summary>         /// signal that initialization starts         /// </summary>         void BeginInitialization();         /// <summary>         /// signal that initialization included adding of objects is finished         /// </summary>         void EndInitialization();         /// <summary>         /// getting movement observer for observing different events related to movement of  objects         /// </summary>         /// <returns>moevement observer</returns>         IMovementObserver GetMovementObserver();         /// <summary>         /// get object factory         /// </summary>         /// <returns>getting object factory</returns>         IObjectFactory GetObjectFactory();          } 

Интерфейс для физики предоставляет методы для добавления, удаления физических объектов,
симуляции мира на определенное время, получение фабрики объектов и слушателя событий
касаемых передвижения объектов. Интерфейс физического объекта представлен ниже

public interface IObject     {         /// <summary>         /// getting transformation matrix of object         /// </summary>         /// <returns>matrix</returns>         Matrix GetTransform();         float X { get; set; }         float Y { get; set; }         float Z { get; set; }     } 

С помощью данного интерфейс можно задать и получить начальные координаты объекта, а также
матрицу преобразования в результате симуляции мира.

Выводы:

Хотим сказать, что знакомство с DirectX и самой разработкой игр — это очень интересная и новая для нас сфера.

По C# 5.0 и разработке под Windows Store хотим выделить такие вот особенности:

  • очень много изменений в .Net;
  • нет синхронных операций чтения файлов, теперь все асинхронное (тут нету ничего плохого, иногда такой дизайн не подходит и приходится превращать асинхронный код в синхронный);
  • нет многих стандартных для .Net 4.0 классов;
  • внесены изменения в работу с метаданными типов и рефлексией;
  • немного отличается Xaml набором полезных классов от WPF;
  • чтобы писать под Windows Store нужно обязательно работать в среде Windows 8.

ссылка на оригинал статьи http://habrahabr.ru/post/169981/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *