Как я делал игру под KolibriOS

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



Как всё началось?


А началось всё с того, на igdc.ru появилось объявление от администрации KolibriOS о начале конкурса на создание игры под их операционную систему.

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

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

Инструменты


Подготовка к написанию игры началась с выбора языка и среды разработки. По началу взгляд пал на С, но отсутствие ООП делает меня грустным пандой. Вариант использовать Ассемблер… Не рассматривался. Довольно быстро был найден вариант написания «Hello World» на С++, и это меня вполне устраивало. Правда, немного мешала непереносимая ненависть к С++, но борьба с ней помогла таки понять тайну звездочек в языке.

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

Остановился на утилите автоматического создания проекта под Visual Studio под компилятором FASM — это один из самых простых способов, при котором компиляция из среды сразу же создавала запускаемый файл приложения для Kolibri. Указав путь компиляции на USB флешку, стало удобно запускать приложение на виртуалке. Способов проще не нашлось, общие папки не поддерживаются.

На сборку пустого проекта было потрачено около недели, поэтому, несмотря на то, что на конкурс давалось почти 2 месяца, на создание игры осталось всего 20 дней. Но всем известно — чем ближе дедлайн, тем выше продуктивность.

12-20 Декабря


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

struct RGB
{
	Byte b;
	Byte g;
	Byte r;
}
…
void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y);

Графика в игре будет спрайтовая, а значит, надо загрузить изображение из файла, но какой формат использовать? png, jpg или gif? Как всегда выбор пал на png, он бесплатный, довольно экономичный, не портит картинку сжатием и имеет возможность хранить альфа-канал. Поработав с чтением файлов в KolibriOS, я наступил на десятки граблей и решил использовать простой массив пикселей, занесенных в глобальную константу.

const RGB img_water[576] = {
	0x0B79BD, 0x0A6DAE, 0x0A69AA, 0x0A6EAD, 0x0B71B0, 0x0A65A8, 0x0A65A6, 0x0B75B4, 0x0B6DAD, 0x0B71B1, 0x0A6AAD, 0x0A6DAD, 0x0C7EBB, 0x0A66AB, 0x0B66AD, 0x0B6DB1, 0x0A61A3, 0x0B79B7, 0x0A72B1, 0x0A6AAD, 0x0C85C1, 0x0A6AAB, 0x0A62A3, 0x0B6EB2, 0x0B7ABC, 0x0B6BAC, 0x0C8BC3, 0x0C9BCE, 0x0C88C1, 0x0B75B4, 0x0B81BD, 0x0B89C1, 0x0B71B1, 0x0B7AB8, 0x0A74B1, 0x0B76B5, 0x0B86BF, 0x0B81BC, 0x0B81BC, 0x0A5B9F, 0x0B70AF, 0x0C86BE, 0x0B76B5, 0x0C94C6, 0x0D9DCB, 0x0A6EAF, 0x0B70B0, 0x0B70B4, 0x0B72B2, 0x0A6EAE, 0x0C8BC4, 0x0DA1D3, 0x0C8CC9, 0x0B7CB9, 0x0B7DBA, 0x0B70AF, 0x0B7CB9, 0x0B89C2, 0x0B80BB, 0x0B7AB9, 0x0B80BD, 0x0C9FCC, 0x0B8DC1, 0x0B73B3, 0x0B79B6, 0x0A61A4, 0x0B81BB, 0x0DAAD3, 0x0EB7D8, 0x0C86C4, 0x0B80BC, 0x0B79BA, 0x0A6EAD, 0x0B81BC, 0x0B8DC5, 0x0C94CA, 0x0C8AC8, 0x0C8DC4, 0x0E90C6, 0x0A64A5, 0x0B71B0, 0x0B81BD, 0x0B87C0, 0x0C8AC6, 0x0D90CB, 0x0D9FCC, 0x0B84BD, 0x0B77B7, 0x0B7DBA, 0x0B80BB, 0x0C97C8, 0x0DA6D3, 0x0EC8E0, 0x0D94CB, 0x0C8AC4, 0x0B79B9, 0x0A64A6, 0x0B7EBA, 0x0B86BF, 0x0B7EBA,
…
};

И вот, наконец, получилось вывести картинку в окне приложения.

Но оказалось, что в структуре пикселя отсутствует прозрачность. Это вставило ноги мне в рот, а в колёса палки. Возникла идея создания своего буфера кадра. Оказалось, что его использование довольно требовательно ресурсам системы и при выводе буфера возникает мерцание. Для борьбы с этими минусами было решено использовать RenderTarget, в которых фон попиксельно смешивался со спрайтом объекта, имеющего альфу.

alpha = (float)addPixel.a / 255.0f;
newPixel.r = pixel.r * (1 - alpha) + addPixel.r * alpha;
newPixel.g = pixel.g * (1 - alpha) + addPixel.g * alpha;
newPixel.b = pixel.b * (1 - alpha) + addPixel.b * alpha;

Но и тут было несколько проблем. Пришлось создать свою структуру пикселя ARGB (с прозрачностью) и ряд функций по работе с массивами изображений. Вывод спрайтов с альфой готов; но теперь я с ужасом осознал, что понятия не имею, что за игру буду делать.

21-22 Декабря


Сегодня мой взгляд упал на пункт правил конкурса об автосборке проекта. Прочитав пару статей на эту тему, я запутался и испугался еще больше, поэтому опять обратился к форуму за помощью. Но ответа ждать не стал и сразу приступил к разработке самой игры. Основа геймплея была взята из старого прототипа на конкурс IGDC.ru №94, в котором я участвовал пару лет назад. Как вспоминаю тот проект, так вырывается непроизвольная улыбка. В этой конкурсной работе был просто небольшой стёб над администрацией и конкурентами конкурса: я написал игру в Delphi кириллицей со всеми принципами хорошего тона при формировании кода. Но это совсем другая история.

Выглядело это как-то так:
type
  Логика = Boolean;
  Число = Integer;
  Дробь = Single;
  ТикТаймера = Double;
  Точка = TPoint;
  TСписок = TList;

const
  ПРАВДА: Логика = True;
  ЛОЖЬ: Логика = False;
…
type
  TЛазер = record
    X, Y, Угол, Тайл: Число;
  end;

  TИгрок = class(TОбычныйОбъект)
  strict private
    FЛазер: array of TЛазер;
    FКнопки: array[0..255] of Логика;
    procedure ДелаемЛазер(Время: ТикТаймера);
  public
    procedure Процесс(Время: ТикТаймера); override;
    procedure Рисуй(Слой: Число); override;
    procedure ЗажатаКнопка(Кнопка: Число);
    procedure ОтжатаКнопка(Кнопка: Число);
    function ПроверкаСмещения(X, Y: Число): Логика; override;
  end;
…
  while (Карта.Тип[Тчк.X, Тчк.Y] in [тмТрава, тмВода, тмЯщикВВоде]) do
  begin
…
      if (Карта.Объект[Тчк.X, Тчк.Y] is TЯщик) or (Карта.Объект[Тчк.X, Тчк.Y] is TПушка) then
      begin
        Карта.Объект[Тчк.X, Тчк.Y].СместитьПоВектору(Смещение.X, Смещение.Y);
        Конец := ПРАВДА;
      end


Но вернемся назад к нашим баранам.

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



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

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

Честно говоря, тут я решил немного сжульничать, внося изменения только при действиях игрока. Это значительно разгрузило систему и при отрисовке, и в моменты простоя. Для поворота танка было решено не делать заранее заготовленные изображения, а написать алгоритм для поворота изображения. Обычное отражение по горизонтали и вертикали с переменой координат дало простой поворот картинки на угол, кратный 90 градусов. Первое время этого хватало с лихвой. Но никак не стыковалось с плавностью движения самого танка. Чуть позже сделано будет и это, но сначала сделаем толкание ящиков и сбрасывание их в воду для создания моста. Это позволит заниматься не спецэффектами, а непосредственно механикой игры.



23-24 Декабря


Посмотрев на то, как выглядит игра, невольно пришла идея заменить графику неясного происхождения на свою, во избежание проблем с авторством. Пришлось искать художника (но, надо сказать, недолго) и заказывать у него графику. Взгляд пал на знакомого художника Weilard. Обсудив идею и показав прототип, мы договорились о цене и начали работу. (вы же не думаете, что профессионалы работают бесплатно?)

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



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



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

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

Следующим шагом был реализован лазер. Алгоритм прост — рекурсивно идем по клеточкам уровня по направлению вектора движения, пока не столкнемся с препятствием. Если препятствие — зеркало, проверяем его ориентацию и либо заканчиваем цикл (зеркало повернуто к нам стенкой), либо меняем вектор направления и идем дальше (попали в само зеркало).



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

25-26 декабря


После добавления разрушения кирпичной стены лазером проект стал компилироваться достаточно долго. Причина скрывалась в большом количестве глобальных констант, которыми были забиты в код текстуры. Сделав загрузку ресурсов из файла, я поборол эту проблему. Возится с загрузкой png-файлов не было времени и желания, так как формат с сжатием и требует приличного загрузчика. Поэтому пришлось быстренько переделать свою утилиту по созданию массива пикселей в файл. Я потратил уйму времени пока понял, что нужно указывать полный путь к файлу (относительные пути не поддерживаются), но совершенно случайным образом удалось это сделать. т.к. файл с текстурой был простым массивом RGB или ARGB структур, я решил не заморачиваться и сделал утилиту по упаковке всех файлов в один.



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

27 Декабря


И опять эта автосборка… Автосборка получилась не сразу. Благо добрые люди на форуме помогли избавить проект от ошибок и собрать дистрибутив KolibriOS с вшитой игрой. Тем же днем художник наконец-таки скинул фоны для меню, окна выбора уровней и дополнительные текстуры объектов. Если раньше в игре была только одна сцена (разумеется, речь о режиме игры), то для внедрения меню, паузы и выбора уровня в проект пришлось добавлять еще сцены. Сперва появилось меню с кнопками начала игры и выхода. При создании перехода между сценами пришлось сперва реализовать события победы и поражения, но тут встала проблема: уровень был только один, и тот хранился в константе глобального массива.

Как всегда, пришла на помощь Delphi, которая помогла, быстро, накидать скромный редактор уровней:



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



28-29 Декабря


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

Уничтожение пушки было возможно только при попадании лазером ей в дуло, но простое визуальное исчезновение мне не нравилось. Взяв в руки Magic Particles, я сделал кадровую развертку анимации взрыва и еще раз доработал отрисовку спрайта в буфер. Теперь уже с учетом номера кадра, которых можно стало хранить в текстуре несколько.



Также заказал художнику нарисовать еще один тайл, пятно от взрыва (декаль).

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

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



30 Декабря


Ну вот и пришло время для создания сцены с выбором уровня. Я не мог не учесть тот момент, что редактором карт любой желающий может добавить или удалить уровень. Поэтому сделал постраничную навигацию по всем уровням в файле, тридцать уровней на странице. На данный момент в игре есть лимит на количество уровней. Меньше тысячи уровней, и то, только из-за того, что четырехзначное число не влезает в квадратик с кнопкой :D.

Наступила ночь на 31 число и почти все баги уже превратились в фичи. Как хорошо, что я взял отпуск на 3 последних дня, это позволило пройтись рубанком и напильником по проекту. Кстати, один из забавных багов: после лазера под зеркалами менялась почва, на ту, что под танком (вторая гифка).

31 Декабря


Решил посвятить весь день созданию уровней, ведь геймплейная часть уже была вполне готова. Это оказалось самым сложным во всей разработке. На создание 48 уровней было потрачено около 9 часов.

До конца сдачи остаётся три часа, я делаю коммит и успокаиваю нервы. Всё, успел!

Исходники


Исходники на SVN: LaserTank, ресурсы
Обсуждение игры на форуме: board.kolibrios.org/viewtopic.php?f=41&t=2934

Голосование


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

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

Комментарии 93
    0
    А png чем декодировали?
      +3
      Png — очень простой формат. Я однажды декодировал его на js для смены цветов палитры в разных уровнях.
        +3
        Ну я бы не сказал что прям простой. Вот классы для работы с ним на Delphi. Там и сохранение тоже, конечно, много отжирает, но загрузка большая и сложная. Всё-таки формат со сжатием.
          0
          Действительно, я же там только с палитрой играл, а не с самим сжатием и картинкой.
        +1
        Открывал файл при помощи TPNGImage в Delphi XE6 и попиксельно из Picture.Canvas.pixel[x, y] сохранял цвет в файл. Какая реализация внутри, не знаю.
        +3
        Собирается ли игра под linux? И если нет, то будет ли?
          +2
          Собирал только на KolibriOS и другие системы не рассматривал. Linux никогда не использовал и видел его только один раз. Так что вероятность очень мала.
            +1
            Там же компилятор MSVC (VS 2013) используется — какой Linux?
              +2
              Но сурсы на С++, значит можно попробовать собрать и под Linux с минимальными переделками же. Или я не прав?
                +1
                Ну, с переделками любая программа на C++ соберётся под Linux. Только я не знаю, сколько именно нужно будет переделывать конкретно в случае LaserTank. Изменять нужно будет 2 вещи:
                • Код, специфический для MSVC (VS 2013) — менять на GCC или другой компилятор, который есть под Linux
                • Код обёрток функций для KolibriOS нужно будет переписать под API Linux
            +1
            В целом собрать можно, но нужно реализовать API для работы с графикой и т.п:

            kos_PutImage(RGB*, short, short, short, short)
            kos_WindowRedrawStatus(long)
            kos_DefineAndDrawWindow(short, short, short, short, signed char, long, signed char, long, long)
            kos_WriteTextToWindow(short, short, signed char, long, char const*, long)
            kos_SetMaskForEvents(long)
            kos_WaitForEvent()
            kos_GetMouseState(long&, int&, int&)
            +1
            Дядько, щупай: github.com/h4tr3d/laser-tank/
              0
              Привет, спасибо!

              Скомпилил под арчиком и запустил, теперь надо в AUR опакетить.
                0
                Смотри, я не пытался отходить от канонической работы с ресурсами: они ищутся только рядом с бинарником, не в текущей директории. Т.е. если опакечивать, то использовать примерно такой подход:
                /usr/share/laser-tank/ — бинарник, ресурсы
                /usr/bin/laser-tank или любой другой скрипт, примерно такого содержимого:
                ~~~
                #!/bin/sh
                cd /usr/share/laser-tank
                ./LaserTank
                ~~~

                Да, кстати, отстройку для KolibriOS если кто может проверить — проверьте. Я попытался сделать так, что бы и для того и для другого собиралось. Там были минорные испрвления, может, теоретически, что-то поломаться.
                  0
                  Да это понятно, я всё в /opt засуну и сприптом запускать буду
            +7
            Была версия меню, которая смотрелась несколько живее за счет дополнительной пост-обработки. Разного рода блички и другие мелкие детальки. В качестве некоей демонстрации разработки «за кадром». Что в результате попадает в игру, а что нет.


              +4
              Господи, я так спешил с разработкой, что забыл заменить фон, печаль. Спасибо, что напомнил, после голосования заменю.
                +3
                У меня есть одна черта. Вредная для фрилансера. Привязываться к некоторым заказам. Теоретически самый лучший подход — выполнил задачу и вычеркнул из памяти. Хотя бы потому, что это уже не твоя графика, но контент заказанный заказчиком и сданный ему. Тем не менее периодически это происходит.

                  +1
                  Для меня, как заказчика, это большой плюс. Очень надеюсь, что поработаем еще вместе.
                    +7
                    Как уже говорил ранее — всегда пожалуйста. К Инди, и любым разработчикам исповедующим независимую деятельность я питаю слабость, будучи Инди сам. Поэтому порой предпочитаю их компаниям толстым, серьезным и денежным.

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



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

                    Релиз игры произошел в 2003, разработка была длительной учитывая нехватку свободного времени и опыта и началась ориентировочно в 2001 году. Стало быть прошло от 12 до 14 лет.
                      +1
                      Посмотрел, подумал. А ведь и правда уже просто столько лет. Ёмоё. И я (несмотря на ужаснейший код игры) всеравно считаю её практически лучшим что делал. Возможно из-за законченности, конечно. Надо бы её пересобрать под quad-engine.
                    0
                    А расскажи, почему такие старнные блоки и странный танк в итоге получился. Посмотрел и даже не поверил — после всех твоих крутых постов.
                      0
                      Как по мне — вполне нормальный танк и вполне нормальные блоки. Не говоря уже о том, что контент, вообще-то, имеет разную цену и как следствие разное качество. Это вообще частенько происходит.
                        0
                        Я очень надеюсь, что цена хотя бы была ниже $1,000 (суммы приза за 1 место) :-)
                          +3
                          Не самая лучшая черта считать чужие деньги, но вам не стоит переживать. Автор в любом случае уйдет в плюс.
                            +3
                            Я уже в плюсе, ведь мне дали стимул изучить что-то новое. Я впервые писал на С++, познал тайну звездочек и получил удовольствие в конце концов.
                              +1
                              Это самый лучший плюс. Двойной. И делом любимым занимались, и достигли им результатов. К примеру, разрабатывать игры и не иметь с них дохода не так весело. Или иметь доход, но не разрабатывать игры. Второй вариант и вовсе скука смертная.
                                +2
                                Не самая лучшая черта считать чужие деньги, но вам не стоит переживать. Автор в любом случае уйдет в плюс
                                Weilard — Я наоборот, за ZblCoder переживал — было бы жаль, если бы он остался в проигрыше, даже если работа займёт первое место. Очень рад, что это не так! Я же не спросил, сколько именно (с точностью до рубля) это стоило.

                                Я впервые писал на С++
                                Это самый лучший плюс. Двойной.
                                Прямо игра слов получилась :-)
                                  +1
                                  Понял yogev_ezra. Забираю свои слова обратно. Мне тоже хотелось чтобы он победил. Причем победил в любом случае, вне зависимости от места. Первого, второго или третьего — не суть.

                                  Главное чтобы гейм-плей был подчеркнут более или менее неплохой графикой. Которую, как верно было подмечено, мы делали аккурат под Новый Год, когда другие бегали по магазинам (нам тоже очень хотелось, но случились дела).

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

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

                                    +1
                                    Графику [...], как верно было подмечено, мы делали аккурат под Новый Год, когда другие бегали по магазинам (нам тоже очень хотелось, но случились дела).
                                    Вам ещё повезло: у нас «Новый Год» вообще в сентябре, а на мой родной советский Новый Год приходится идти на работу, как в обычный день. И это при том, что во время основной работы нужно было следить за конкурсом, и помогать участникам с проблемами авто-сборки, а все, как всегда, ждут до последнего момента :-)

                                    А на следующий день у меня ещё День Рождения (да, в моём профиле на Хабре «Дата рождения» заполнена правильно — у меня на самом деле он 1 января), который тоже хочется отметить. Но зато получил море позитива и персональный подарок на День Рождения — целых 10 новых игр для KolibriOS :-)
                                +1
                                Да что за звездочки?
                                  0
                                  Указатели в С++. В данном языке всегда пугало огромное количество * в коде. И поэтому я начинал писать на Delphi, он дался проще, я же самоучка.
                                    0
                                    Ну, я так и подумал. Просто такой синтаксис указателей — это специфика c, а не c++.
                                    Я, кстати, такой же путь прошел от Delphi к плюсам и дальше)
                                      0
                                      Ну если чесnно, я начинал с Web'a, делал сайты, потом это все наскучило, нет реалтайма, и я пошел играть в ActionScript, но он мне не понравился. Тут я нашел Delphi, и это растопило мне сердце. С++ ковырял, в Borlond, 97 года, но особо ничего не сделал.
                                    • НЛО прилетело и опубликовало эту надпись здесь
                                        0
                                        Соглашусь с ZblCoder'ом, прошел тот же путь.

                                        Нет, синтаксис все же разный. Такие вещи, как объявление указателя, указатель на указатель, работа с указателем на массив указателей записываются иначе. Мне точно так же было непривычно и неудобно. В Паскале и Дельфи указатели записывались так, что интуитивно понятно, что к чему. Понять же, почему, например, принят вот такой синтаксис объявления указателей (мнемоника) я смог только после КиР. И точно так же изучение Си и плюсов было отложено «из-за звездочек», хотя на тот момент я много писал на ассемблере, и указатели были естественным делом для меня. А вот синтакс не пошел, невкусно было.
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                            +3
                                            а в Паскале и Дельфи как встретишь '^', так впадаешь в ступор на пару секунд «а что же тут такое имеется в виду, что такое делается и зачем?

                                            В простом случае никакой разницы — что *abc, что abc^.
                                            Почему вы считаете, что звездочка интуитивно понятнее каретки? Правильно, потому что вы привыкли. Другие привыкли к другому. Дело даже не во вкусе, кмк.

                                            А уж указатели на указатели в Паскале выглядят вообще как тихий ужас

                                            Отлично выглядят: понятно. Тяжеловесно, ага. Зато не приходится составлять правила «как читать C type declaration»
                                            И вот таких сайтов по Паскалю/Дельфи не встретишь.
                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                –1
                                                Точно так же начинал с ассемблера.
                                                Не вижу, где подобное по ссылке выше char *(*(**foo[][8])())[] «прям чистые и естественные [bx][si][di]». То, что [bx] то же что и *abc, то же что и abc^, ничего не значит, это примитивные примеры.

                                                Наверное можно как-то, сначала наопределяв кучу новых type, но это получится такой огород, в котором сам чёрт ногу сломает.

                                                Именно. Это получится четкая и понятная запись с последовательным уточнением типов, а не мешанина, как в примере чуть выше.

                                                Так что не изменяю своё мнение, на вкус и цвет все фломастеры разные

                                                Бесспорно.
                            +3
                            У художника был очень срочный заказ, ведь на всю работу у него было буквально пару дней. Я написал ему за 7 дней до Нового Года, да и дела могут уже быть у человека. Первые переговоры были около 5 часов утра. В общем не очень благоприятные условия для творческой работы, но мастер показал себя с хорошей стороны.
                              +4
                              Вы зря это написали (смеется). Лишняя почва. В каждой второй или третьей конторе с которой я работал всегда находился человек, который говорил «да у нас есть человек, который за два часа подобные вещи делает», и самый лучший ответ из имевшихся у меня был «вот пусть он и делает, к чему вам я?».

                              Критиковать всегда легче, осуждать и порицать — тоже. Для этого всего-то нужно набрать пару строчек с ошибками и дело в шляпе. Мнение оформлено. Занимает секунд двадцать. Выяснять почему что-то сделано так, а не иначе, какие были условия разработки, какие сроки, какие инвестиции — зачем?

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

                              И ради бога… завязывайте с «мастером» (смеется). Я не он. Просто более или менее подкованный крендель.
                                +2
                                О! Подкованный крендель это то самое определение, что я искал последние пару недель. Шикарно!
                                  0
                                  Как бы эта формулировка не прилепилась, как это часто бывает. Ну да ладно. Я переживу.
                                  +2
                                  И ради бога… завязывайте с «мастером» (смеется). Я не он. Просто более или менее подкованный крендель.
                                  Ну я всегда стараюсь сравнивать с собой, а я рисовать никак не умею, даже цвета подобрать не могу. Поэтому, мастер, но больше не буду.
                                    +1
                                    Если уж на то пошло, то раскрою один небольшой секрет: за видео-обзор игр для конкурса я тоже немного заплатил блоггеру. Не вижу ничего постыдного в том, чтобы заплатить кому-то, кто может сделать лучше тебя (а сам я могу снимать видео-обзоры только так — т.е. грубо говоря «никак»).

                                    P.S. И рисовать тоже не умею никак. Вот понадобится нарисовать графику для игры или баннер — теперь буду знать, к кому можно обращаться :-)
                        +1
                        Исходников графики нет в svn? Что с лицензией на код и графику?
                        Есть желание сделать пару портов.
                          +1
                          Лицензия GPL. Файл лицензии добавлю в SVN после голосования. Но есть одно но, в данный момент я изучаю Unity3D и делаю эту же игру в ней. Там можно будет портировать на многие устройства. Рад, что игра на столько понравилась.
                            0
                            Unity overkill тут по моему :)
                            А вот кросс-платформу под *nix было бы интересно сделать.
                            После этого портировать можно будет куда угодно.
                              0
                              Под Windows уже портировали (правда, по словам самого автора порта, "Порт сделан быстро, грязно и на куче костылей").
                          +6
                          Читается захватывающе, как детектив! :)
                          Отличная вышла игра (и художнику отдельный респект), кроме неё в конкурсе понравился только «21days», уж больно задумка хороша.
                          Из багов, не описанных на форуме KolibriOS, заметил такой: если выйти из уровня, не доигрывая его, и выбрать другой, то танчик остаётся на том же месте, где был на прошлом уровне. Может оказаться где угодно: на воде, внутри стенки и т.д.
                            +1
                            Спасибо, забавный баг, после голосования внесу изменения.
                              +1
                              Погонял про разным уровням, проявляется при переходе с любого недоигранного на 15 уровень. На другие вроде нормально.
                                +1
                                Да, причина очень простая, я забыл на 15 уровне поставить стартовую позицию. Редактор доступен тут, вместе со старой версией игры.
                            +1
                            Здорово.
                            Остановился на утилите автоматического создания проекта под Visual Studio под компилятором FASM — это один из самых простых способов, при котором компиляция из среды сразу же создавала запускаемый файл приложения для Kolibri.

                            Не затруднит пояснить процесс, как происходит компиляция? Из плюсов в асм, потом FASMом в исполняемый файл Колибри? (у нее свой формат ведь?)
                              0
                              Я выбрал этот способ из-за того, что не нужно знать принципа компиляции.
                              Просто в утилите, нужно указать название проекта и путь к Fasm, и рядом в папке создается новый проект для VS в котором все настроено. Его открываешь и сразу делаешь билд, сразу появится запускаемый файл для KolibriOS с надписью «Hello World».
                                0
                                Все же — Студия генерирует листинг, который потом транслируется Fasm'ом?
                                  0
                                  Вопрос не по адресу — ZblCoder всего лишь пользователь. Нужно спрашивать CleverMouse — это её разработка.
                                    0
                                    Кто-то ведь знает в общих чертах, как оно работает, кроме автора?
                                      0
                                      По исходникам понятно. Изначально добавляется заголовок, потом постпроцессинг с копированием информации из секций.
                                      Не думал, что Fasm так разрастется. Очень гибкий инструмент получается, если такие конструкции позволяет:

                                      if CurRelocType=0
                                      else if CurRelocType=3
                                      load z dword from RelocItem-TextRVA
                                      store dword z-(TextRVA+ImageBase) at RelocItem-TextRVA

                                      в .asm файле

                                      или из документации:
                                      repeat $-$$
                                      load a byte from $$+%-1
                                      store byte a xor c at $$+%-1
                                      end repeat
                                      кодирование на лету.
                                    0
                                    Судя по создаваемым файлам, сначала среда делает билд и собирает exe файл, после, по прописанной в настройках проекта команде, идет запуск FASM с параметрами, тот создает (видимо из exe) файл для KolibriOS.
                                +1
                                >немного мешала непереносимая ненависть к С++, но борьба с ней помогла таки понять тайну звездочек в языке

                                Это не абсолютно универсальное правило, но по большей части в современной программе на С++, написанной с использованием стандартной библиотеки С++ 11 (14), вообще не должно быть звёздочек в смысле работы с сырыми указателями (кроме как для разыменования this). ИМХО.
                                  0
                                  Ну ненависть не только из-за звездочек. После длительного использования Delphi сложно переключится на С++. Хоть они и одинаковые по возможностям, но мелочи различия очень мешают переходу.

                                  На работе я пишу на Delphi + SQL и постоянно комментирую код в SQL через "//", в Delphi через "--". Хоть нужно наоборот, беда прям какая-то.
                                  0
                                  А где файлы data01.pak, data02.pak?
                                    +2
                                    Ресурсы тут, спасибо за подсказку, добавил в статью.
                                      0
                                      Спасибо, попробую запустить в Linux.
                                        +1
                                        Кто хочет под Linux пощупать: github.com/h4tr3d/laser-tank/

                                        сборку проверял на Min 17.1, нужно доставить пакеты: libsdl2-dev, libsdl2-ttf-dev ну и cmake (хотя можно собрать и просто командой make).

                                        Код не супер, плюс SDL2 чисто по докам прикручивал :)
                                          +1
                                          Спасибо за труды, но увы, проверить не смогу, не знаю Linux, вообще.

                                          Отписался на форумах IGDC и KolibriOS
                                            +2
                                            Ага, ну как минимум overmind86 оказался заинтересован и уже опробовал. Для себя сделал just for fun. Плюс сохранил возможность сборки и для KolibriOS, по Windows тоже можно будет собрать, но у меня пока нет SDL собранного под Mingw32 (по сути, все ifdef __linux__ поменять на __linux__ || WIN32).

                                            Понравилось, что здраво были сделаны абстракции, по сути, я просто подсунул свою реализацию нужных колбеков. Если постараться, то кроссплатформенность можно было бы сделать ещё более бесшовно. Но развернуться, по настоящему, можно только в платформенно-зависимом коде /как понимаю STL для Kolibri нет?/

                                            Непонравилось, что не зная ассемблера, бывает трудно :) Смутили команды FPU.

                                            Код, конечно, причёсывать и причёсывать :) Я вам пару слов отпишу, вдруг опять судьба с С++ сведёт ;-)
                                              0
                                              Сделал быстрый порт на MacOS X (проверял 10.10).
                                              Код все так же грязный, нужно много чего переписывать.

                                              github.com/dlancer/laser-tank/tree/dev
                                                0
                                                Ох, круто… Может всё же оставить перевод строки как в оригинальном проекте? Вроде же современные редакторы умеют «Automatic detect line end». А то дельта очень уж объёмная получается.

                                                Кстати, а где вы нашли __kolibrios__? гугл сходу ответ не дал
                                                  0
                                                  __kolibrios__ это чисто грязный хак (я там еще все дефайны вынес в LaserTank.h), чтобы заменить __linux проверки :)
                                                  Но по другому и не сделаешь, в стандартах его все равно нет.
                                                  Я пока убил эту ветку, попробуем мелкими коммитами нарастить, чтобы объединять проще было.
                                                  Нужно что-то другое для обсуждения придумать, мне тут сегодня слили карму, отвечать раз в час могу.
                                                  0
                                                  Для тех кто будет искать: порт под MacOS X живет в отдельной ветке: github.com/dlancer/laser-tank/tree/macosx
                                                  Под Linux из этой ветки также можно собирать (только cmake), если есть такая необходимость.
                                                  Новых изменений в этой ветке я не планирую.
                                                  Будем плавно переписывать основную ветку в сторону большего охвата платформ.
                                                0
                                                Опередили :)
                                                Я начинал двигаться в том же направления, но отложил на неделю. Думаю есть смысл править уже вашу версию.
                                                Отправил pull request на пару фиксов.
                                                Кстати я не заметил мерцания танка, или оно уже исправлено?
                                                  0
                                                  Проявляется когда зажимаешь клавишу движения и не отпускаешь. Но может что-то уже полечилось: немного тюнил отрисовку и обработку клавиатуры.

                                                  Кстати, от вас там был запрос про SDL_RENDERER_ACCELERATED? Можете подробнее рассказать?
                                                    0
                                                    В MacOS X  10.10 если включить SDL_RENDERER_ACCELERATED, то при движении все окно мерцает и
                                                    через раз выводит поверх картинку с экрана выбора уровня.
                                                    В общем где-то баг с отрисовкой текстур или что-то в этом роде…
                                                    Из похоже по описанию находил, что такой эффект бывает когда смешаны софтовый вывод и аппаратно ускоренный.
                                                    В Ubuntu 14.04 (AMD свежие драйвера) с отрисовкой вроде все нормально.

                                                    И еще где-то по моему перепутан цвет (или нет красного канала), т.к. картинка не соответствует скриншотам из статьи.
                                                      0
                                                      Понял. Протестировать на MacOSX нет возможности, так что если поборете — велком.

                                                      По цветам: habrahabr.ru/post/248001/#comment_8229179 уже на гитхабе.
                                                  0
                                                  Собрал в openSUSE, всё работает, только что-то с цветами.

                                                  Аналогичные пакеты у нас называются libSDL2-devel и libSDL2_ttf-devel, можете добавить в инструкцию.
                                                    0
                                                    Я добавил полностью команду для установки пакетов, проверьте, я не спец по OpenSUSE, вроде там yast2 для установки, хотя слышал про какой-то zypper :-)

                                                    А с цветами, покажите скрин? Возможно из-за RGB/BGR.

                                                      0
                                                      Всё, понял :) я сразу не обратил внимание, что у меня меню синие вместо коричневых, танк синий вместо красного. Действительно RGB/BGR. В одну строчку — поменять в kos_PutImage() SDL_PIXELFORMAT_RGB24 на SDL_PIXELFORMAT_BGR24, тогда цвета станут такими же как на ролике у автора. А так, пока не скажу где корень проблемы: в том виде как хранится пиксель в ресурсах или некорректно распаковывается в конструкторе RGB/ARGB классов.
                                                        0
                                                        > хотя слышал про какой-то zypper
                                                        Да, из командной строки зиппером ставится. Пульнул на гитхабе правку.
                                              0
                                              Вы никогда не видели такую игру как сокобан? (ни слова не нашёл в статье)
                                              Очень много похожего в геймплее, только лазеров не хватало. Вряд ли будут проблемы с авторскими правами (всё ж у вас совершенно другая игра), но явное сходство просто бросается в глаза.
                                                +3
                                                Классический сокобан предполагает манипуляцию с ящиками в одной плоскости. Эту игрушку можно считать развитием идей. Есть второе измерение (вода), есть лазер. Этого достаточно чтобы она не считалась клоном. Это комбинация танка и сокобана, ко всему прочему.

                                                Взгляните на то, что предлагает рынок сейчас. Многочисленные «рескины» даже без изменений. А все почему? Потому что привычное легче продать, и мало что нужно делать. А вот новое никому не нужно. Тут не авторских правах дело, к сожалению. А в том, что сегодняшнему игроку новое не нужно, в принципе. Ну стонет некоторое количество игроков. Да хоть десять тысяч из них. Не они делают кассу и прибыль.

                                                Хотя, конечно, странно. что не был упомянут такой именитый папа. Я о сокобане, конечно. Ведь базовая механика пришла именно из него.
                                                  0
                                                  Открыв глубины своей памяти я обнаружил сайт на котором играл много лет назад, и откуда тогда стырил графику. Лазертанк на сайте old.pig.ru. Геймплей содран в принципе с неё, надо было сказать об этом с статье, но указал на старую свою наработку, хотя она тоже была не первой версией данной игры. Также есть еще одна игра, точная копия по геймплею, LaserTank. Так что я не первый, кто сделал такую игру.
                                                  +1
                                                  По поводу сходства, и настоящего копирования воистину наполеоновских масштабов, можно вспомнить историю игры, которая сейчас известна многим. Обычно никто не акцентирует внимание на том, что Angry Birds, столь успешный и прибыль приносящий был скопирован с Crush the Castle. Если я не ошибаюсь, факт этого заимствования даже упомянут в википедии. Там сказано что разработчики из Rovio вдохновлялись CtC, ну а если не использовать это благозвучное слово, но просто заменить, на вполне обычный термин «содрали», то все встанет на свои места.

                                                  Флеш-рынок не более, чем экспериментальная площадка для коршунов (помимо бесплатной развлекательной платформы), что высматривают себе идеи для развития. Потом меняют у них шкурки, и продают. И это политика крупных контор. Ничего не делая получать готовые прототипы для игр. Вполне по человечески.
                                                    +1
                                                    Ну помню что в игре LaserTank, что я играл, был очень большой раздражительный минус. При стрельбе, летел кусок лазера, как в звездных воинах, пиу-пиу-пиу. И пока он долетит по всем зеркалам, устанешь ждать, а если надо было стрелять несколько раз, вообще забиваешь на игру, после пары попыток.
                                                  0
                                                  Вообще Lazer tank уже лет 100. И различных портов — килограммы. perso.cgocable.ca/lasertank/ltank_en.html
                                                    0
                                                    Тут вообще речь шла не о ремейках, а именно о портах. Не путайте.
                                                    Если игра старая, Вы сели и сделали похожую, или даже аналогичную, но с нуля — ремейк.
                                                    Если Вы взяли код старый и перенесли на другую платформу — порт.
                                                      0
                                                      И портов и ремейков килограммы. Более того в ремейках большая проблема сохранения различных фичей из-за чего оригинальные уровни не работают, например в ремейке под андроид. Сделали бы совместимый современный ремейк — было бы дело.
                                                        0
                                                        Это было бы здорово. Я, кстати, за. Стилизовав его, к примеру, под известный в прошлом (и не только в нем) стиль от Bitmap Brothers. Но совместный современный ремейк ради фана — дорогое удовольствие. А вот если нацелить этот ремейк на прибыль дело другое.
                                                          0
                                                          Ну автор статьи не утверждал, что он изобрёл паровоз эту игру. Он написал, что он сделал эту игру для конкурса KolibriOS на основе игры, которую он сделал для конкурса IGDC. Здесь всё верно. Правила конкурса не нарушены.

                                                          И в KolibriOS уже был Sokoban, но именно такой игры не было, так что наш проект получил новую игру в свою коллекцию. И мы, и автор «римейка» довольны.

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

                                                    Самое читаемое