Первые эскизы
Недавно мы получили первые картинки от художника. Вот такой концепт на данный момент:
Абстрактный класс 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/
Добавить комментарий