Меню Рубрики

Как написать игру на языке c

Пишем игры на C++, Часть 1/3 — Написание мини-фреймворка

На хабре не очень много уроков по созданию игр, почему бы не поддержать отечественных девелоперов?
Представляю вам свои уроки, которые учат создавать игры на C++ с использованием SDL!

Что нужно знать

  • Хотя бы начальные знания C++ (использовать будем Visual Studio)
  • Терпение

О чем эта часть?

  • Мы создадим каркас для всех игр, в качестве отрисовщика будем использовать SDL. Это библиотека для графики.

В следующих постах будет больше экшена, это лишь подготовка 🙂

Почему SDL?

Я выбрал эту библиотеку как наиболее легкую и быструю в освоении. Действительно, от первой прочитанной статьи по OpenGL или DirectX до стотысячного переиздания змейки пройдет немало времени.

1.1. Начало начал

Скачиваем SDL с официального сайта.
Создаем проект Win32 в Visual Studio, подключаем lib’ы и includ’ы SDL (если вы не умеете этого делать, то гугл вам в помощь!)

Также необходимо использовать многобайтную кодировку символов. Для этого идем в Проект->Свойства->Свойства конфигурации->Набор символов->Использовать многобайтную кодировку.

Пока что он ничего не делает.

Царь и бог каркаса — класс Game
Game.h

Создаем файл Project.h, он нам очень пригодится в будущем

Уже чуточку получше, но все равно как-то не густо.

1.2. Графика

Создаем аж 2 класса — Graphics для отрисовки графики и Image для отрисовки картинок

SDL_Surface — класс из SDL для хранения информации об картинке
Рассмотрим Graphics
NewImage — есть 2 варианта загрузки картинки. Первый вариант просто грузит картинку, а второй после этого еще и дает прозрачность картинке. Если у нас красный фон в картинке, то вводим r=255,g=0,b=0
DrawImage — тоже 2 варианта отрисовки картинки. Первый рисует всю картинку целиком, второй только часть картинки. startX, startY — координаты начала части картинки. endX, endY — конечные координаты части картинки. Этот метод рисования применяется, если используются атласы картинок. Вот пример атласа:


(изображение взято из веб-ресурса interesnoe.info)

Рассмотрим Image
Он просто держит свой сурфейс и дает право доступа к своим закрытым членам классу Graphics, а он изменяет сурфейс.
По сути, это обертка над SDL_Surface. Также он дает размер картинки

В конструкторе инициализируется SDL и создается экран.
Функция Flip должна вызываться каждый раз после отрисовки картинок, она представляет получившееся на экран и чистит экран в черный цвет для дальнешней отрисовки.
Остальные функции малоинтересны, рекомендую разобраться в них самому

Нет, вы все правильно делаете, этот файл и должен быть таким 🙂

Надо изменить Game.h, Game.cpp и main.cpp
Game.h

Тут мы добавляем указатель на Graphics и в Execute добавляем размер экрана

Ничего особенного, разве что не пропустите функцию SDL_Quit для очистки SDL

Тут мы создаем экран размером 500 на 350.

1.3. Ввод

Надо поработать со вводом с клавиатуры

SDL_Event — класс какого-нибудь события, его мы держим в Input’е для того, чтобы не создавать объект этого класса каждый цикл
Ниже расположены методы, не представляющие особого интереса. Примечание: методы с окончанием Down вызываются, когда клавиша была нажата, а с окончанием Up — когда опущена.

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

Изменяем теперь Game.h и Game.cpp

Как видно, мы добавили указатель на Input и создали методы-возвращатели Graphics и Input

1.4. Итоги

Это был первый урок. Если вы дошли до этого места, я вас поздравляю! У вас есть воля, присущая программисту 🙂 Смотрите ссылки в начале статьи на последующие уроки для того, чтобы узнать еще много нового!

Источник статьи: http://habr.com/ru/post/197278/

Видеоуроки по созданию игры на C++

Видеоуроки по созданию игры на C++

Нашли для вас серию видео, в которой автор по шагам рассказывает, как написать свою игру на C++. Эти уроки не требуют каких-то продвинутых знаний, но базовые представления о программировании приветствуются.

Урок 0 — Введение и подготовка

В этом уроке автор расскажет, как пишутся игры. Также вы загрузите компилятор и напишите простой helloworld в Visual Studio, чтобы всё было готово для разработки игры.

Урок 1 — Окна и указатели

Здесь вы перейдёте к первому шагу на пути к игре: созданию окон. К концу урока у вас всё будет готово для отображения графики в окне.

Урок 2 — Графика

В этом уроке вы узнаете, как написать программу для отрисовки фигур на экране. Также по ходу дела автор объяснит некоторые важные вещи вроде того, что такое буфер и зачем он нужен, что есть куча и стек, как запросить у Windows больше памяти и не только.

Урок 3 — Ввод, движение и время

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

Урок 4 — Геймплей, столкновения, улучшение передвижения

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

Урок 5 — Вражеский ИИ, подсчёт очков, завершаем геймплей

Из этого урока вы узнаете, как создать систему подсчёта очков. Также вы создадите ИИ противника и узнаете некоторые важные вещи об ИИ в играх.

Урок 6 — Завершаем игру

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

Хинт для программистов: если зарегистрируетесь на соревнования Huawei Honor Cup, бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.

Перейти к регистрации

Источник статьи: http://tproger.ru/video/how-to-program-a-game-in-cpp/

Змейка на С++ : создаем первую игру.ЧАСТЬ 1.

Давайте подробно разберем создание простой консольной игры языке на Visual Studio 2019.

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

Для создания вам необходимы базовые знания языка. Однако, даже если вы имеете мало опыта программирования на C++, я постараюсь подробно описать основные моменты разработки.

Для работы с C++ вам нужно скачать Visual Studio — это среда , разработанная компанией Microsoft.

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

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

ЧАСТЬ 1:

Окей, для начала подключим к нашей программе основную библиотеку для ввода и вывода ( Вывод осуществляется, как правило, с помощью перегруженного оператора сдвига влево ( >)) Это основная библиотека, только благодаря в дальнейшем мы сможем отрисовать карту для игры, саму змейку и фрукты, появляющиеся на карте.

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

Так, функция Setup (англ.установить) будет содержать в себе переменные, благодаря которым мы зададим змейке начальное положение и настроим случайное появление фрукта на карте.
Функция Draw (англ.рисовать) будет отвечать за отрисовку карты, змейки и фрукта в консоли с ее постоянным обновлением(анимацией).

Функция Input (англ.ввод) будет отвечать за управление нашей змейкой, которое заключается в назначении клавиш, отвечающих за перемещение.

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

Ну и основная функция main будет включать в себя все функции для отображения игры на консоли до тех пор пока игра не завершена.

Как вы уже заметили мы ввели логическую переменную GameOver (конец игры), пока она принимает значения False(ложь) игра будет продолжаться, поэтому все функции будут выполняться.

Теперь нам надо заполнить каждую функцию, чтобы они имели смысл. Но перед тем, как заполнять одну из функций введем глобальные переменные:
const int width (ширина ) и (height) можно поставить любые значения, эти константы зададут размер игрового поля для змейки. При тесте игры мы сможем в любой момент изменить эти параметры не меняя логику и целостность игры.

Параметры x,y будут отвечать за положение змейки на горизонтали и вертикали ( т.к. змейка в двухмерном пространстве(на плоскости)) , аналогично параметры fruitX и fruitY будут отвечать за положение фрукта.
Дальше идет перечисление enum (англ. enumeration) / с помощью перечислений мы присвоим параметрам Stop, LEFT,RIGHT,UP,DOWN целые значения ( первому параметру Stop присвоится 0, второму LEFT — 1, и т.д. DOWN — 4)

Переходим в функцию Setup.
Изначально игра не окончена, поэтому GameOver = false; , иначе при запуске консоли программа завершит процесс выполнения. eDirection или dir (направление при запуске игры будет 0, то есть змейка будет стоять на месте, 0 в перечислениях принимал параметр Stop. x,y отвечают за положение змейки, при делении высоты и ширины пополам мы получим, что змейка будет находиться в центре игрового поля при запуске. Положение фрукта же случайно , поэтому приплетаем функцию rand() с остатком от деления на высоту вертикальной составляющей и с остатком от деления на ширину горизонтальной составляющей, так фрукт будет появляться в случайном месте на карте. Score( счетчик очков ) изначально равен нулю. Тут все ясно.

Сразу перейдем к функции Draw для отрисовки карты и объектов на консоли. Пожалуй, это самая сложная и интересная функция. Для того, чтобы картинка стала обновляться и создалась анимация движения нам необходимо прописать команду system(«cls») ; Дальше заполняем первую верхнюю строчку(верхний край) нашего игрового поля. Это можно реализовать с помощью цикла for. Верхний край заполнится дефисами и будет символизировать стенку шириной width. По окончании цикла переходим на вторую строку консоли с помощью cout for вложен в for ) вложенный цикл отрисует змейку( решетка ), фрукт ( F ), и левую и правую стенку ( | ). Суть в том, что в каждой строке левая стенка находится на первой позиции(нулевой элемент строки), а правая на позиции ширина — 1(элемент равный ширине строки).
На позиции x,y находится змейка , рисуем любой элемент, я использовал решетку, на позиции fruitX,fruitY рисуем фрукт , я использовал букву F . Строки №40-45 отрисуют нижнюю границу поля, аналогично верхней, только ниже на расстоянии height (высоты).

На этом этапе, если вы все правильно усвоили и безошибочно написали вы увидите следующую картинку в консоли:

Теперь у нас имеется шаблон змейки , остается настроить управление и логику игры. О следующих функциях я расскажу во второй части 😉
Полный код игры я выложу в последней статье, вы сможете скопировать его, но я все же советую вам прописывать все самостоятельно , так процесс вашего обучения будет в разы продуктивнее.
И помните, ваши лайки — моя мотивация =)

Источник статьи: http://zen.yandex.ru/media/id/5e467af8cc6d233fd0f684fd/zmeika-na-s—sozdaem-pervuiu-igruchast-1-5e6ffb56441c2a3038399939

Пишем игровую логику на C#. Часть 1/2

Всем привет. В связи с выходом моей игры SpaceLab на GreenLight я решил начать серию статей о разработке игры на C#/Unity. Она будет основываться на реальном опыте её разработки и немного отличаться от стандартных гайдов для новичков:

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

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

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

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

Кого заинтересовало узнать, что за игра — внизу есть видео и ссылка на бесплатное скачивание.

Сразу предупрежу — у меня нету цели идеально применить огромное количество паттернов или описать подход к методологии TTD. В статье я стараюсь писать читабельный, поддерживаемый и безбажный код, как он писался бы в жизни. Возможно, людям имеющим огромный скилл в C# и написании игр данная статья покажется очевидной. Тем не менее, вопрос о том, как писать гейм-логику я слышал довольно часто и эта статья прекрасно подойдет и тем, кому интересно написание сервера и тем, кому интересно написание клиента на Unity.

Краткое описание GD, которого мы хотим достичь

1. Игрок управляет кораблем. В корабле можно выстраивать комнаты, в комнатах можно добавлять в слоты модули.

2. Для постройки чего-либо необходимо потратить ресурсы и подождать время.

Через полгода разработки результат должен выглядеть как-то так)

План работы

1. Настраиваем проекты
2. Создаем ядро — базовые сооружения
3. Добавляем и тестируем первые команды — построить строение и модуль
4. Выносим настройки строений и модулей в отдельный файл
5. Добавляем течение времени
6. Добавляем Constructible, строения теперь строятся некоторое время
7. Добавляем ресурсы, для постройки необходимы ресурсы
8. Добавляем цикл производства — модуль потребляет и выдает ресурсы

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

1. Настраиваем проекты

На первых порах Unity Editor нам не понадобится — мы пишем ГеймЛогику. Открываем VS и создаем два проекта: GаameLogic и LogicTests (Unit Tests Project). В первом мы будем писать собственно логику игры на чистом C# не используя namespace Unity, второй будет тестить нашу логику встроенной тест-тулзой. Добавим в GameLogic первый класс Core и напишем первый тест, чтобы проверить нашу связку:

2. Создаем ядро — базовые сооружения

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

Итак, разберемся с нашим гейм-дизайном. У нас есть корабль (Ship), в нем комнаты (Room), в каждую комнату может быть построено строение (Building), а в каждом строении могут быть модули (Module). Конечно, Room и Building можно было бы объединить в одну сущность, но далее такое разделение нам только поможет.

Для всех этих сооружений я создам отдельный namespace Architecture и базовые классы. А так же enum для индексов комнат. Многие вещи, которые мы сейчас делаем — временные и необходимы, чтобы запустить первый тест гейм-логики.

3. Добавляем и тестируем первые команды — построить строение и модуль

Теперь мы сможем написать первую «фичу» — постройка строения и постройка модуля в нем. Все подобные действия я буду описывать отдельным классом, который будет наследоваться от класса Command:

И хотя сейчас даже такая маленькая структура излишня — чуть позже благодаря ей мы прикрутим необходимые нам события. А существование каждого атомарного действия в отдельной команде позволит нам их комбинировать. Напишем наши первые два действия:

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

4. Выносим настройки строений и модулей в отдельный файл

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

  1. Создать конфигурацию для строений и модулей — » class BuildingConfig » и » class ModuleConfig «, именно они будут хранить все настройки наших сооружений.
  2. Building и Module при создании должны принимать соответствующие настройки
  3. Сделать фабрику для создания модулей и строений
  4. Добавить настройки для нескольких строений и модулей
  5. Адаптировать существующий код под новые входные данные

Как можно понять, теперь наш код нерабочий. Для того, чтобы не таскать каждый раз с собой конфиги создадим фабрику, которая будет выпускать наши сооружения зная только их тип. Я знаю, что название пока слишком общее, но мы всегда с легкостью можем его переименовать благодаря IDE, так же, как и разделить на две фабрики:

И хотя сейчас код корректен — при запуске наших тестов мы словим «Not implemented yet» . Для этого вернемся к нашей фабрике и реализуем несколько строений и модулей.

Я сразу добавил несколько строений и модулей, чтобы можно было покрыть тестами. И сразу скажу — да, хранить все эти настройки в фабрике нету никакого смысла. Они будут лежать отдельно в JSON файлах, по одному на структуру, парсится и передаваться в фабрику. К счастью, у нас движок даже не заметит этого изменения. Ну а пока нам не так критично вынести их в ЖСОНы, как запустить тесты и проверить все ли корректно работает. К счастью, да. Заодно допишем тесты, что нельзя построить модуль не в той комнате, например, Furnace в PowerPlant.

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

Что ж, теперь все корректно. Заодно добавим тесты на корректную работу лимитов и пойдем дальше.

5. Добавляем течение времени

Компьютеры дискретны. И все игры дискретны. Если говорить просто, то представим, что все игры — пошаговые. У большинства игр шаги пропускаются автоматически и 60 раз в секунду. Такие игры называются риалтайм. Я понимаю, что это очень грубо, но для реализации гейм-логики довольно удобно представлять, что ваша игра — пошаговая и мыслить такими категориями. А потом уже на клиенте можно запустить tween между двумя состояниями и юзеру будет красиво и игра будет работать быстро. Для начала введем понятие хода:

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

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

Теперь в Unity достаточно будет подвесится на любой Update и передавать дельта время в наш TimeWarp:

Продолжение следует.

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

6. Добавляем Constructible, строения теперь строятся некоторое время
7. Добавляем ресурсы, для постройки необходимы ресурсы
8. Добавляем цикл производства — модуль потребляет и выдает ресурсы

Для тех, кто просто любит код — есть отдельный репозиторий на ГитХаб

Кроме этого, если вас интересуют вопросы по разработке SpaceLab — задавайте, отвечу на них в комментариях или в отдельной статье

Скачать для Windows, Linux, Mac бесплатно и без СМС можно со страницы SpaceLab на GreenLight

Редакторский дайджест

Присылаем лучшие статьи раз в месяц

Скоро на этот адрес придет письмо. Подтвердите подписку, если всё в силе.

Похожие публикации

Первые шаги в оптимизации и полировке игры на Unity3d

Анализируем ошибки в открытых компонентах Unity3D

Unity3D + C#, или как переводить скрипты

Заказы

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Комментарии 51

А при реальной разработке игр (на Unity и вообще) тоже используется такой подход, когда логика пишется отдельным, абстрактным модулем и потом подключается к игровому движку, или это просто пример для статьи?

Нет. Так работает только какой-нибудь очень далекий от движка объект, например UI или дизайнерские задвики по AI. Вообще желательно всё писать поближе к движку, чтобы потом не оказаться с 1.5 fps. Иначе графику, физику, анимацию предеться очень оптимизировать и упрощать. Вообще даже бывает, что следят за ms, которые тратятся на обработку скриптов. И операции с матрицами и векторами в скрипты стараются не выносить.

На уровне проекта с игровой логикой — нету. Конечно, от завязки на View не обойтись. Но стараюсь просто создать абстрактный эвент в том месте, где необходимо запустить анимацию. Например, у меня есть какая-то комплексная команда и в определенном случае в опреленном месте этой команды необходимо запустить анимацию. Я делаю в этом месте что-то вроде:

А в коде вьюшки что-то вроде:

Таким образом у меня модель ничего не знает про рендер.

Это не подход вообще это очень низкий ентри левел. Писать код чтобы просто заработало.

В своем обучающем pet project на unity3d тоже думаю о выносе логики в отдельную сборку, благо четко отделены неймспейсы Core и UnityLogic (по сути — модель и представление, как бы странно в контексте юнити это не звучало) и в Core от юнити только вектора да Assert’ы используются.

Вот только редактор имеет обыкновение пересоздавать файлы .sln и .csproj, поэтому добавить в решение отдельную сборку довольно сложно (хотя, вроде если сильно исхитриться, то можно), а значит скорее всего придется делать их вообще разными solution’ами, что слегка неудобно — одновременно редактировать и ядро и юнити логику не получится, возможны проблемы с подключением какого-нибудь Vector2 от юнити в этот внешний проект (не проверял, т.ч. может быть тут проблем нет).

Кроме того, не очень понятно, как не устроить в VCS спам обновлениями какого-нибудь Plugins/Core.dll, да и вручную постоянным копированием перекомпилированного Core заниматься не очень хочется.

Т.ч. пока активных действий не предпринимаю и Core внутри основного .csproj. Чтобы жить было веселее, встроил известный плагин/хак, позволяющий использовать сахар из C# 6, а для тестов воспользовался Unity Test Tools.

Но как-то костыльно это все( Все таки хочется выделить ядро в отдельный «чистый» проект, чтобы еще меньше зависеть от движка/удобнее тестировать и т.д. А у юнити проекта создать свои тесты и свои правила.
Но нужно, по крайней мере, автоматизировать сборку Plugins/Core.dll, причем кроссплатформенно. Хотя, вероятно это очень просто решить банальным output directory в проект юнити.

Вот только редактор имеет обыкновение пересоздавать файлы .sln и .csproj, поэтому добавить в решение отдельную сборку довольно сложно (хотя, вроде если сильно исхитриться, то можно), а значит скорее всего придется делать их вообще разными solution’ами, что слегка неудобно — одновременно редактировать и ядро и юнити логику не получится,

Я недавно придумал использовать для этого символические ссылки.

Создаёшь отдельный солюшен (CoreSolution) и проект (CoreProject) в Студии. Внутри CoreProject делаешь папочку Core и весь код хранишь в ней. А в проекте Unity в папку Assets кидаешь символическую ссылку на папку Core. В результате, писать и редактировать код можно и в CoreSolution, и в солюшене Unity, и даже одновременно.

Косяков такого подхода пока не заметил. Единственная неприятность ― если забыться и создать новый cs-файл в Unity внутри папки Core , то в CoreProject его потом надо будет добавлять вручную через Add -> Existing Item. Этот момент несколько раздражает.

Для удобной работы со ссылками есть расширение к Проводнику ― Shell Link Extension.

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

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

Вот такая конструкция добавит все файлы из поддерева в проект:

Необязательно, кстати, симолические ссылки использовать — в проект можно и какой-нибудь ..\..\Core\**\*.cs добавить.

У меня изначальная задумка была не столько для отделения «core-кода» от «не-core-кода», а скорее для того, чтобы вынести код, который я использую в каждом проекте Unity, куда-нибудь в одно место. Чтобы не хранить в десяти Unity-проектах десять копий одних и тех же, но чуть-чуть отличающихся исходников; потому что со временем перестаёшь понимать, где лежит более свежая версия, где более старая, и чем они отличаются.

Пробовал заводить для такого кода отдельный проект и билдить его dll в папку Assets текущего проекта Unity, но это неудобно. Оказалось проще кидать в Unity-проект линк на общую папку. В неё же можно положить какие-нибудь общие часто используемые ассеты, типа текстур в сеточку, в шахматную клеточку, в сеточку с пронумерованными ячейками для отладки uv-координат у геометрии.

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

Кстати, насколько я знаю, для подобных целей git submodule обычно используют. А чтобы не привязываться к структуре каталогов подмодуля можно объединиит подходы — в каком-нибудь ThirdParty хранить подмодуль и на него делать симлинк (или что-то другое, не знаю точно через что относительные ссылки делаются) в проект. По крайней мере, после клонирования на другую машину не потребуется доп. действий и вообще думать о зависимости.

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

Чтобы жить было веселее, встроил известный плагин/хак, позволяющий использовать сахар из C# 6

Решарпер не так давно начал понимать туплы. Теперь можно жить ещё веселее и потихоньку начинать применять C# 7. Правда всерьёз только на Windows.

Вообще, ИМХО, вот именно так и надо писать правильную архитекутру (не вседа правда получается). Все слои программы должны быть максимально абстрагированы друг от друга: UI ничего не знает о бизнес логике, внутри бизнес-логики сущности ничего не подозревают друг о друге, если мы исключим из программы UI, то она должна скомпилироваться и работать, ну и т.д.

Это удобно, модульно, масштабируемо и конфигируруемо.

В противном же случае мы получим настоящий ад зависимостей и хрупки классы. Начнем что-нибудь исправлять и получим по лбу. В Unity3D собственно старая-новая система анимации (Меканим что ли она называется) вот прям ИМХО яркий пример того как не надо делать: если все делать как по учебнику, то анимация и игровая логика будут прибиты друг к другу гвоздями, фиг потом отдерешь.

Вся проблема только в том, как только продумать такую архитектуру.

Assert.IsInstanceOfType(new Core(), typeof(Core));

А делать Assert.IsEqual(2*2, 4) вы не пробовали? Или там Assert.IsNotEqual(true, false) ?

Всегда начинаю писать тесты с assert true .

Это же стандартная практика — проверить, что сам тестировочный фреймворк работает, проект корректно настроен и нужные классы импортируются.

Только для начальной проверки или тест отсается?

Если первое, то можно и сразу тест на логику писать. если прошел — все работает, все подгружено.
Если второе, то в каком классе лежит такой тест и один ли он там?
А если третье, то это тесты самого фреймвека и они должны лежать в проекте с ним и скорее всего они там и так есть.

Отличная игра для тех, кому понравилась экономическая часть XCOM: Enemy Unknown, но показалась маленькой, относительно остальной игры.

Кто-нибудь знает наподобие игры, помимо Fallout Shelter?

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

Есть парочка советов:
1) Словарь, где ключом является enum — это плохо. Лучше заменить на int, по необходимости этот enum приводить к int, это исключит ненужный боксинг/анбоксинг.
2) Не знаю, как часто вы используете LINQ, но от таких штук лучше отказаться. Лишние аллокации.
3) foreach для List лучше не использовать, опять же, лишние аллокации. Если редко вызывается, то ещё ладно, если +- каждый кадр, то плохо.

ЕМНИП, там какой-то баг в рантайме, который давным-давно исправили в Mono, но никак не сольют в Unity.

3) На дворе Unity 5.5 и другой компилятор C#. Он в foreach на списках не аллоцирует.

К тому же, раз ядро в статье пишется в отдельном проекте вне Unity, то и компилируется оно, скорее всего, тоже вне Unity.

Поправка: в Unity под капотом старый Mono. В новом используется реализация из referencesource и такой проблемы там нет.

Я так понимаю, в среднесрочной перспективе будут существовать три платформы: .Net Framework для Windows, .Net Core для трёх основных платформ и Mono для всего.

Фишка .Net Framework ― богатство функционала.
Фишка Mono ― встраиваемость и работа на всём, что движется.
Фишка .Net Core ― автономность, платформа идёт вместе с приложением.

В краткосрочной перспективе Mono переходит со своего компилятора на Roslyn, и все три ветви унифицируют свои библиотеки под флагом .Net Standard.

Примерно так я себе это представляю, но могу ошибаться.

1) В родной среде исполнения вроде бы будет все норм, а вот в Mono были времена когда начинался боксинг-анбоксинг. Сам удивился когда обнаружил.

2) За LINQ-сахаром будет скрыт тот же for на самом деле: иного пути в поиске просто нет — надо перебирать элементы коллекции, разве что можно извратиться и сделать, например, бинарный поиск (сложность которого логарифмическая, а не линейная, т.е. работать он будет быстрее) или еще чего.

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

3) for Добавлю еще, что foreach не совсем таки безопасный, я бы сказал, что он совсем не безопасный. Enumerator не отслеживает состояние родительской коллекции после своего создания и может вернуть (при перечислении) объекты, которых там уже нет. О чем собственно упоминается в msdn. Исключения вылетающие на foreach — наверное самые частые которые мне приходилось разгребать в чужом коде и заменять foreach на for в таких ситуациях.
Ну и да, применение foreach подразумевает, что:

  • создается новый объект — итератор;
  • на каждой итерации идет вызов метода MoveNext;
  • на каждой итерации идет обращение к свойству Current, что равносильно вызову метода;

Конечно же родной JIT компиляторе в родной среде исполнения вумный и попытается соптимизировать. Но получается не всегда, а уж Mono так вообще такое не гарантирует (хотя последние версии пытаются), а древний Mono (вроде бы 2-ой) работающий под капотом Unity3D так вообще даже не попытается этого сделать. Хотя буквально пару месяцев назад вот наталкивался на ситуацию, когда foreach натурально сводил сума GC, который начинал молотить как сумашедший и всем становилось хорошо. И это было в .NET 4.6 под родимой виндой

В то время как глупый for просто обращается по индексу и все. Никаких премудростей и работать он будет везде одинаково, независимо от платформы, версии .NET, положения звезд, фазы Луны и т.д.

4) Я еще добавлю про var. Во-первых, опять таки это делает код трудно читаемым
натыкаешься на:

И сидишь и думаешь, а это что вообще такое? Строка, циферка или какой-то класс, а может структура? Лезешь внутрь метода, а там снова Var на Var’e и Var’ом погоняет. Так и сидишь, ковыряешься в чужих потрохах.

Реально, var оправдан только тогда, когда нужно работать со всякими анонимнымными типами и прочих лямбда-ситуациях, т.е. тогда, когда частота порождения говнокода выше чем обычно. Вес остальное от лени, а поощрение лени плохо сочетается с самодисциплиной => говнокод. Я вот var обычно по пятницам использую, потом в понедельник что-нибудь ломается…

Хорошо шо хоть var проверяется еще на этапе компиляции. Правда тоже на умность компилятор надеется не стоит, напишите var i = 5 — и компилятор подставит int32, а на переполнения из-за Var я уже тоже натыкался. А вот dynamic… а применение динамических типов ОТКРЫВАЕТ ДВЕРИ АДА. То есть, оно говорит компилятору, что это динамический ВЫЗОВ АДСКОГО СОТОНЫ, и надо перенести все проверки типа (и ошибки соответственно) на время выполнения(с). Правда к Unity3D это вроде бы еще пока отношение не имеет

Не для того Хейлсберг создал строго-типизируемый язык программирования, что бы потом на нем пытаться писать «как буд-то это ЖабаСкрипт».

В общем когда сахара много, наступает момент когда код и его исполнение становится трудно предсказуемым

Источник статьи: http://habr.com/ru/post/322258/


0 0 голоса
Article Rating
Подписаться
Уведомить о
guest

0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии