Обновил "советы и секреты"

Добавил недокументированый режим сборщика мусора и пару подсказок про доступ к глобальным функциям через точку (наткнулся экспериментально в доках нигде не видел) и уменьшение утечек памяти.
Обновленная статья: http://blitzmax.3dn.ru/publ/3-1-0-8

Про игровые уровни

Написал статью про уровни в играх. В основном про то, как оформлять диалог выбора уровней и типичные ошибки. Но так-же и про то, как используются уровни для других задач игрового дизайна.
Статья тут: http://blitzmax.3dn.ru/publ/pro_igrovye_urovni/3-1-0-20

Blitzmax + Asm

Написал наконец-то статейку про то как прикрутить ассемблерный код к Blitzmax. Ознакомится можно по адресу: http://blitzmax.3dn.ru/publ/3-1-0-17
Статья не раскрывает разных тонкостей, но общая методика в ней показана. Надеюсь, она будет полезной.

Particles

По немногочисленным, но периодическим просьбам коллег выкладываю исходники своей сисчемы частиц с подгрузкой эффектов из скриптов.
Краткие характеристики:
  • загрузка эффектов из скриптов;
  • архитектура: эмиттер > группа > частица;
  • свойства и анимации: вращение, движение с ускорением и без, размеры, анимация цвета и спрайта, жизнь, период анимации, наложение (альфа или световое) и др.;
  • области эмиттера для появления новых частиц: прямоугольник, точка, окружность;
  • эффект следа или "хвоста" (group_trace)
Примеры скриптов прилагаются. В одном из скриптов есть описание синтаксиса.
Естественно, можно делать эффекты из кода в рантайме. В архиве есть пример в "particles.bmx" функция для эффекта взрыва PFX_Explode_1.

Скачать можно тут: http://blitzmax.3dn.ru/load/8-1-0-13

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

Индексный доступ к элементам строки для записи

Стандартно Blitzmax не позволяет записывать в строку, используя индексный доступ. Но с помощью небольшого трюка это можно забороть.
Вот исходник, показывающий подробно, как это делается:
Local str$ = "Hello"
Print str

Local
p:IntPtr = IntPtr(Varptr(str))
Local
pchar:ShortPtr = ShortPtr(p[0])
pchar :+ 6
'this offset depends on String structure

pchar[0]=
Asc("H")
pchar[1]=
Asc("e")
pchar[2]=
Asc(" ")
pchar[3]=
Asc("h")
pchar[4]=
Asc("e")

Print str
Или вот так в одну строку можно получить указатель на первый символ:
Local pchar:Short Ptr = Short Ptr(Int Ptr(Varptr(str))[0]) + 6
Как видно из примера, мы просто получаем указатель на первый элемент строки во внутренней структуре строкового типа языка.
Ссылка на статью с другими советами: http://blitzmax.3dn.ru/publ/3-1-0-8

Работа с многомерными массивами

Если мы объявили многомерный массив как массив значений (Local a[n,m]), а не массив массива (a[n][m]), то пройти весь массив можно не стандартным способом с вложенными циклами, а одним foreach:
Local a[2,2]
a[0,0]=1; a[0,1]=2; a[1,0]=3; a[1,1]=4
For Local i:Int = EachIn a; Print i; Next;
Обход выполняется сначала по последним индексам.

Перерыв

После бааальшога перерыва решил продолжить этот блог.
Приношу извинения за остывшиеся без ответов вопросы. Я перебрался на сайтик по БМ, который http://blitzmax.3dn.ru, а с этого почему-то не приходят извещения о коментах. Сейчас подправил настройки, должно работать, но лучше все-же постить на http://blitzmax.3dn.ru
А этот блог будет для повышения цитируемости.
Дизайн вот тут поменял.

Отрисовка куска изображения

Используем SetViewport
Function DrawImageRect(img:TImage, x#, y#, rx#, ry#, rw#, rh#)
SetViewport x, y, rw, rh
DrawImage img, x - rx, x - ry
SetViewport(0, 0, GFX_WIDTH, GFX_HEIGHT)
EndFunction

Особенности: надо знать абсолютные координаты.
Недостатки: SetViewport не всеми картами поддерживается.

Моноширинный шрифт из внешнего изображения

Добавил исходник с примером реализации класса моноширинного шрифта для загрузки из картинки. Полностью совместимого со стандартными функциями отрисовки текста. Смотреть здесь: http://blitzmax.3dn.ru/publ/3-1-0-15

Нашел новый сайт по разработке игр. Новая статья.

Ползая по сети, наткнулся на этот сайт - http://www.casualgamesecrets.com
Он еще в разработке, но кое-какие материалы на нем уже есть. Наличие одного из них побудило меня написать статью, которую я уже месяца с два собираюсь написать. Это статья "Torque Game Builder для «Чайников»". Вообще я решил написать просто коментарий. Написал. Ответственно так подошел, что получилась статейка. Туда ее запостить в качестве комментария не удалось - очевидно что-то у них еще не настроено (к тому-же зачем вводить код подтверждения зарегистрированным пользователям? И зачем такооой длинный?). Поэтому размещаю ее на своем сайте. Хотя у себя я бы ее все равно разместил, но в более развернутом варианте. Пришлось разворачивать, раз уж начал и размещать. Итак: "Еще раз замолвлю слово за Blitzmax"

Обновления

Добавлен еще один совет.
Исправлены кое-какие неприятности Blitzmax с библиотеками. А именно: удален бывший п.2.14 - Нет команд для временной передачи лишнего времени системе. Такие команды есть (о отсутсвие вменяемой документации)! Найдены были широко известным и необычайно успешным (правда зачастую и опасным) методом "научного тыка". Подробности в той-же статье.

Реальный счетчик ФПС

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

Новая статья на http://blitzmax.3dn.ru: Советы по написанию и оптимизации кода

Начал новую статью, которая будет регулярно обновляться, в разделе Доки/Уроки. Статья с советами (хинтами) по оптимизации и написанию кода. Ее адрес: http://blitzmax.3dn.ru/publ/3-1-0-8. Пока два совета: некий аналог оператора Width и использование GCCollect.

Столкновения или коллизии по-ненашему

Добавил свою старую статью про колизии. С некоторыми изменениями и дополнениями. Читать здесь: Коллизии или столкновения по нашему, часть 1.
Поскольку обьем статьи принят не был, пришлось ее разделять на 2-е части.
Вторая тут: Коллизии или столкновения по нашему, часть 2.
Кто уже читал материал раньше, рекомендую переходить к части 2. Там исходник, показывающий ошибки с определением столкновений и несколько советов.

Обновления на сайте

Перенес статьи с этого блога о приятном и неприятном в Blitzmax. Внес новые изменения и дополнения:
Убрал из недостатков пункт про невозможность зацикливания музыки (ну не мог я додуматься, что этот флаг указывается при загрузке, а не при проигрывании, - спс за коммент). Зато добавил пару новых, вылезших недавно: 2.11 и 2.12 (в недостатках библиотек).
Совсем забыл о некоторых хороших вещах в Blitzmax. Вот так привыкаешь к хорошому и оно кажется незаметным. Добавил две приятности в описание.
Но равенства между плохим и хорошим сегодня не добиться (как и обычно, впрочем). Вспомнил про три косяка, вылезшие при разработке оптимальной синхронизации игрового цикла. Добавил их в недостатки библиотек.
Сделал новый раздел в файлах для темплейтов. Так его и назвал (только по-русски) - шаблоны кода. И сразу поместил в него шаблон из статьи про оптимальную синхронизацию игрового цикла. Только немного доработанный в плане вывода дополнительной тестовой информации.
Поменял линки наконец.

Утилитка для восстановления русского текста, который портят IDE Blitzmax.

Сегодня случилось страшное: мои коменты на русском попортило стандартное ИДЕ. Я обычно его не пользую, но вот решил написать пару небольших тестов, чтобы определиться с методами. И когда я открыл файлы снова, то был сильно огорчен подменой руссокого текста в комментариях со статистикой по быстродействию, несуразным набором символов. Ситуацию пришлось исправлять и писать преобразователь полученных в ИДЕ кракозябров обратно в русский текст. Тому, кто столкнулся с подобной проблемой, эта утилитка пригодится: http://blitzmax.3dn.ru/load/6-1-0-1

Новости 25-06-2006

Я таки решил не откладывать переход к сайту и сегодня попытался поработать с юкозом. Кое-что получилось. Правда с утра все жутко тормозило. Сначала админка, потом сам сайт. Так что пол дня я просто тупо провтыкал, наблюдая разные ошибки 505 и прочие и ожидая сообщений сервера. Правда после обеда вроде все наладилось. И я передумал забить на него сразу. Я добавил первую статью про главный игровой цикл, как обещал в предыдущем посте. Подправил недостатки в связи с комментом к предыдущему посту.
Теперь про новый сайт. Адрес: http://blitzmax.3dn.ru
Я сделал опрос, чтобы не занимать много вашего времени. Просто проголосуйте насколько хорошо работает юкоз. Если все нормально, то я продолжу на нем. Поскольку там возможностей и удобностей больше. От рейтинга и пользовательских аккаутнов, до новостей, файлов и форума. Если нет - буду продолжать здесь. Но, наверное, изменю формат постов или еще как-то извернусь. Я заметил, некоторые добавили блог в РСС, на юкозе не спешите - я подумаю как это лучше организовать. Скорее через ленту новостей - я постараюсь в ней отражать все изменения. Поскольку там несколько лент для каждой категории. Если есть еще какие пожелания - прошу высказываться. Также если не сильно лень - прошу зарегистрироваться на сайте, посмотреть возможности и отписаться с комментами и пожеланиями.
зы: если с юкозом все будет норм, то в течении недели я туда перенесу материалы.
ззы: тут пара людей спрашивала насчет партиклов. Я несколько морозился, сейчас скажу поточнее: старая система сильно интегрирована в двиг, вырезать ее оттуда нет ни времени, ни желания. Новая еще в стадии проектирования. Когда я ее допишу до приемлимого вида, то скажу как ее можно получить.

Изменения и дополнения

Добавил по пункту в приятное/неприятное. Все про звук. Из приятного, то что, звук 3Д. Из неприятного, то что нет простой команды для проигрывания звука в цикле.
Сейчас вожусь с главным игровым циклом - экспериментирую с использованием особенностей языка. Как закончу - выложу.
Еще есть такая мысль - может перенести блог на юкоз - там просто можно новости отдельно делать. А то это и постом то называть стыдно. И тормознуто сильно блоггер работает. - Как нибудь попоробую, потом сделаю или зеркало или перенесу совсем, если на юкозе понравится.

Неприятное в BlitzMax, ч.3 - разработка игр

3.1. Нет поддержки шрифтов с произвольной шириной и утилит для работы с ними. Моноширинные - это вчерашний день.

3.2. Нет зачатков даже движка как в Blitz3D. Есть просто набор либ для работы с сетью, звуком графикой и устройствами ввода (мышь, клавиатура, джойстик). Джентльменский набор, но "ни цента больше".

3.3. Нет и намека на партиклы. О редакторе молчу, хотя бы классы или либы для работы с ними были какие-то. А современный уровень игростроения их требует. Все надо делать самому - опять время/деньги. Хотя есть пара сторонних убогих движков частиц. И даже с редакторами.

3.4. ГУИ. Игровое конечно. Опять полное отсутствие. Хотя тут проще - есть сторонние библиотеки. И даже бесплатные.

3.5. Нет поддержки треккерных форматов звука. Но можно использовать сторонние библиотеки.

3.6. Нет физики. Есть сторонние модули.

Неприятное в BlitzMax, ч.2 - библиотеки

2.1. Нет списка со значениями, не являющимися объектами. Например, целыми - Int.

2.2. Списки не очень удобно реализованы. Было бы хорошо наличие у элементов списка TLink поля Parent, для ссылки на родительский список (И поля Child для многоуровневых древовидных списков). Это связано с менеджером памяти языка, который не в состоянии корректно удалять объекты с кросслинками.

2.3. Утечка памяти в функции LoadImage при загрузке *.png. Ее практически не заметно, т.к. вылазит она при особых случаях, например при перегрузке картинок, что обычно не требуется - они загружаются один раз обычно. Но, например, при отсутствии менеджера ресурсов, когда нам нужно перезагружать изображение (при обработке скриптов, например), то утечка становится заметной. Причем внутренний меденжер памяти утечку не показывает.
Прим.: при загрузке *.jpg утечки нет.

2.4. При создании нового pixmap, он не инициализируется. Т.е. мы создали новый pixmap, а там мешанина из пикселов, а не черный или белый или заданный программистом фон. Надо писать функции заполнения новообразованных пиксмапов, а это - время/деньги.

2.5. Неясности со шрифтами: LoadImageFont("Arial.ttf"…) не приводит к ожидаемому результату, а с полным путем LoadImageFont("C:\Windows\Fonts\Arial.ttf"…) все работает. Хотелось бы без указания путей. Хоть и есть фонт по умолчанию.

2.6. Отсутствие такого хорошего понятия как контекст устройства. Есть в вынь и в пурике ( StartDrawing(OutputID) ). На CreateGraphics(…) его заменить нельзя - если разрешение не поддерживается, контекст не создается. Это очень-очень плохо. Нельзя рисовать нормально в оффскрин окно. Другими словами рисовать в текстуру (спрайт) можно только ручками через массив пикселей, что медленно. Сторонние библиотеки для этого - платные.

2.7. Метод pixmap. Paste(…) не проверяет размеры - это приводит к глюкам с затиранием памяти и необходимостью писать много чего своими ручками. Это unsafe (при том, что полезные вещи в страхе этого самого unsafe не делаются), и время/деньги на дополнительный код.

2.8. Глючность идиотическая, надеялся, что такого не встречу. Пример: когда работа с пиксмапами формата PF_RGBA8888 проходит отлично, а смена формата на PF_BGRA8888 приводит к непонятным глюкам в официальных библиотечных функциях.

2.9. Глюки при работе с созданием пиксмапов, если их делаешь много, то возникает глюк. Этот глюк как-то связан с форматом картинки. При формате PF_BGRA8888 он возникает раньше. GCCollect() не помогает, дело не в переполнении, а хз в чем.

2.10. Звук: Полная распаковка/загрузка в память, потом проигрывание. Это приводит к тому, что мы в программе уже запустили звук на проигрывание, а оно начинается позже - после полной распаковки. Это заметно даже на не сильно больших звуках, не треках. Сначала было совсем жестко - распаковка была не в отдельном процессе и можно было нарваться на притормаживания при попытках проиграть звук. Сейчас сделали распаковку в фоне (отдельным процессом). Этим убрались притормаживания всего приложения при проигрывании. Но остались паузы между желаемым началом проигрывания (вызовом в коде) и реальным началом, когда уже слышен звук.
При этом фоновая распаковка породила другую проблему. Тормоза при не фоновой распаковке можно было обойти правильной организацией ресурсов. Загрузкой и распаковкой звуков в начале игры или уровня, когда можно и подождать. Таким образом, при самой игре звуки проигрывались уже распакованные из памяти, не вызывая никаких нареканий. Теперь при такой организации, если приложение загрузилось достаточно быстро, а звуки в фоне не распаковались, то опять есть паузы в начале работы, между тем, когда звук должен проиграться и когда он звучит на самом деле. Вылез теперь немного иной недостаток - невозможность узнать, когда звук распакован, чтобы дождаться полной загрузки ресурсов.
Правильнее бы делать блочную распаковку/загрузку и проигрывание. Как в винампе, например. Когда подгружается кусок и распаковывается быстро и играется сразу, незаметно для слуха. А потом в фоне догружаются остальные части.