Archive for the 'tothink' Category

Сущности покатят?

Я что-то в последнее время сидел думал над Component/Entity-based System применительно к разработке игр. Вот единственная вменяемая ссылка для тех, кто шпрехает на инглише. Если кратко резюмировать, то получается как-то так.

Есть у нас игра и какие-то Сущности в ней (entity — сущность поанглицки). Например, игрок и мобы. В терминах ооп есть цепочка наследования. Игрок и моб наследуются от каких-то классов в цепочке MovableObject, ControlledObject итд. Дальше от моба наследование идет в сторону FlyingMob, UndergroundMob итд. Какие-то типы мобов с разными особенностями и поведением. Очень вероятно, что когда-нибудь нам понадобится летающий, плавающий и одновременно с этим синий моб, а наша цепочка наследования такого не позволяет (привет множественное наследование). Теперь о component-based системах. В данном случае Сущность — это контейнер с уникальным ID для компонентов, которые описывают эту сущность. То есть, то что моб летающий, плавающий и синий мы говорим просто добавляя к нему FlyingComponent, SwimmingComponent и BlueComponent. Просмотрев несколько примеров, я увидел, что компоненты могут быть как пассивными хранилищами данных, так и большими кусочками логики. Но это не важно.

UI.

Так вот, забавно было бы применить такую же идею к UI. То есть вот есть Сущность, она кнопка. А я говорю — стань-ка ты List’ом, и кнопка становится листом с какими-то последствиями. В общем, я вскоре на это забил, потому что получается какая-то неведомая йухня. Для UI как нельзя хорошо работает старое доброе дерево наследования.

Data (Model).

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

Данные самопроизвольно принимают структуру ориентированного графа, где нодами являются объекты со своими свойствами, а стрелочки — отношения. Например, есть у нас Сущность user — некоторый игрок в системе. У него есть items, которыми он владеет и slots — слоты, куда можно эти итемы засунуть. Картинка снизу примерно это и показывает.

entities1

У сущности сверху есть свойство, что оно user. А также коллекция итемов и слотов. Сущность итема тоже говорит, что оно item, плюс к этому свойства owned (принадлежит) и equipped (надето, да, спелчекер подсказал, что пишется с двумя p, но я уже закрыл исходник картинки), которые ссылаются на соответствующие Сущности. Снизу slot (слоты), в одном из них есть ссылка equipment, то есть в него что-то положили. Если разделить взаимные ссылки (например, items и owned), то получается ориентированный граф.

Понятия.

Основные понятия получаются следующие:

  • Entity (сущность) — некий объект, который сам по себе. У сущностей есть id, я думаю уникальный в системе вообще, то есть любую сущность можно всегда найти по id.
  • Property (свойство) — то, что называют еще компонентом или тэгом. Свойство сущности, которое определяет ее как “является тем-то”.
  • Link (ссылка) — ссылка/ссылки на другие entity. По сути, ребра в графе. На самом деле являются частным случаем свойсв.

С ссылками не все так просто, они могут быть одновременно и коллекциями (много ссылок с одинаковыми названиями) или ребрами гиперграфа, но гиперграф не умещается в моем миниатюрном мозге. Могут быть следующие типы ссылок:

  • 1 .. много — в примере items –> item x *
  • много .. 1 — наоборот, item x * –> items
  • 1 .. 1 — equipment –> equiped
  • много .. много — если, например, может быть несколько хозяев у итема

Ссылки могут быть двусторонними, например items –> owned — двусторонняя ссылка. Проще говоря, если я делаю ссылку из user в некий item (добавляю item к юзеру), то на Сущности итема появляется свойство-ссылка owned. Если она там уже есть, то так как это ссылка типа 1 .. много, этот итем убирается из предыдущего хозяина и прицепляется к новому хозяину. Что-то напоминает? Да, частным случаем евляется отношение parent-child. Ссылка slots односторонняя, слоту в данном случае совершенно пофиг кому он принадлежит (как определять выполнимость 1 .. много в данном случае яхз).

Вроде бы должно быть все более-менее просто.

События.

Во фреймворке компании TimeZero есть прикольная фишка, которая мне нравится — баблинг событий по дереву данных. Как в дереве дисплейлиста. То есть, я могу быть ленивой скотиной и не подписываться ко всякой милюзге, а тупо подписаться на событие где-то сильно выше у родителей. Нужное мне событие туда всплывет. Здесь можно сделать также, если считать, что ссылки (даже двусторонние) имеют начало и конец. То есть баблинг идет с конца. Иначе попадаем на движение событий по кругу в совершенно ненужные части, в идеале зацикливание гг.

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

Итог.

Получается забавно, во всяком случае, пока я не заметил существенных косяков. Собственно, хочется услышать кто что думает. Изобрел я велосипед? Слишком сложно?

Я уже вижу некоторые возможные забавные расширения.

Резюмируя флейм про #14

В коментах на номер 14 развернулся нешуточный флейм. Какбы я понимаю обе стороны. Тут вопрос чистоты и понимаемости vs. оптимизации и скорости. Ruby vs. Assembler. Чем более на низком уровне что-то пытаешься сделать, тем больше аккуратнее нужно быть и знать досконально свое окружение, чтоб ничего не сломать. Помните, наш флэш пишут такие же индусы, над кодом которых мы время от времени ржем.

Встреча BURAFPUG 6 февраля в Москве

Что-то я совершенно случайно об этом узнал. Кто туда идет-то вообще? Какие-то все незнакомые имена.

Мой левелап…

Итак, я только что поднялся до уровня 25 в этой ММО игре с названием Жизнь. Еще один день рождения, я уже так стар, что этот день все меньше и меньше кажется праздником. Я думаю, что это не очень хорошая идея, пытаться кратко написать что ты сделал за последний год. Возможно, потому, что обычно писать-то и нечего, но я попытаюсь.

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

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

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

~ Cheers.

Unity + Flash

На самом деле, ребята из Unity3d, о которых я уже писал, вполне могли бы сбацать свой Flash Player и использовать флэш объекты в качестве интерфейсов, миниигр или текстур. Как вот эти парни. Получилось бы сильно лучше чем есть сейчас. По крайней мере лучше, чем существующие попытки совместить Flash и Unity.

Главное замахнуться!

Человек пишет “Space-based MMO written in erlang” проект erleve, валяется на code.google.com. Расписано так все хорошо, в основном, конечно, скопировано с EVE Online, но он и не скрывает этого. Правда, последний (или первый и последний?) апдейт SVN датирован декабрем 2008. Посмотрел код — сделано процентов 5 от инфраструктуры сервера, что само по себе представляет процентов 10 от всей игровой серверной логики. Не говоря уже о клиенте.

А так хорошо все начиналось.

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

Немного об Adobe AIR 2.0

Как все уже знают, на прошедшем Adobe MAX был анонсирован AIR 2.0 с огромным количеством вкусных фич. Народ в основном тащится от нативного сапорта мультитач ввода плеером 10.1, об этом пишет Andrew Trice из Cynergy, которые на конференции показывали приложение, использующее возможности AIR 2.0.

В выше упомянутом посте исчерпывающая информация с примерами кода про реакцию на мультитач события. Рекомендую. Лично мне кажется, что половина жестов в этом календаре лишняя и удобнее просто ткнуть. Но я конечно же очень рад, что мультитач приложения на Flash теперь можно будет делать не через жопу.

Подробное и интересное описание новинок AIR на русском. Рекомендую.

Далее, Christian Cantrell в своем блоге написал пост о всех новых фишках Adobe AIR. Я думаю, будет полезно скопировать его сюда.

  • Мультитач: События прикосновения работают так же, как и события мыши, но на устройствах поддерживающих мультитач, вы можете отслеживать одновременно несколько точек нажатия.
    • Поддержка мультитач:
      • Windows 7 и далее.
      • Необходимо устройство ввода поддерживающее мультитач (очевидно).
  • Жесты: Приложение может слушать мультитач события или события жестов (но не оба типа одновременно). Жест — это композиция мультитач события в одно событие.
    • Поддержка жестов:
      • Windows 7 и далее.
      • Маки с OS X 10.6 и далее с мультитач трэкпадами.
    • Типы поддерживаемых жестов:
      • GESTURE_TWO_FINGER_TAP (прикосновение сразу двумя пальцами)
      • GESTURE_PRESS_AND_TAP (прикосновение одним пальцем, в то время как уже касаемся вторым)
      • GESTURE_PAN
      • GESTURE_ROTATE
      • GESTURE_SWIPE
      • GESTURE_ZOOM
  • Открыть файл дефолтной программой: Новый File.openWithDefaultApplication API позволяет вам открыть файл той программой, которая настроена на открытие данного типа по умолчанию в системе. Это хороший кросплатформенный способ интеграции с другими приложениями, так как вам не нужно знать какие приложения и где установлены.
  • Диалог OS безопасности скачивания: Новое свойство File.downloaded позволяет указать, что файл был скачан из сети, и что OS хорошо бы спросить пользователя перед тем как открывать его.
    • Поддерживаемые платформы:
      • Windows XP SP2 и далее.
      • Mac OS 10.5 (Leopard) и далее.
      • Linux не поддерживается, потому что там отсутствует такая концепция в принципе.
  • Информация о дисках: Новый API информации о дисках позволяет слушать события добавления и удаления внешних накопителей, получать список доступных дисков, получать информацию о них, о файловой системе, внешний ли диск, можно ли на него писать, букву и метку тома.
  • Нативные процессы: Теперь вы сможете запускать и общаться с нативными для данной OS процессами. Вы сможете включать свои программы или использовать уже установленные. Для работы данной фичи, необходимо чтобы приложение было установлено с помощью нативного для данной системы инсталятора, а не привычного .AIR файла. Тулзы для создания таких инсталяторов прилагаются.
    • Типы инсталяторов:
      • OS X: DMG
      • Windows: EXE
      • Linux: Debian and Red Hat Package Manager
  • Обещанные файлы: Концепция “обещанных файлов” позволит пользователям перетаскивать файлы, которые либо еще ен существуют (потому что вы хотите создавать их по мере необходимости) или существуют но на удаленном сервере. Мы предоставляем вам способ, при котором удаленные файлы будут скачиваться автоматически и сохраняться туда, куда были перетащены. А также, мы даем вам интерфейс, который позволит генерировать файлы по мере необходимости.
  • Сокеты: Новый ServerSocket API позволяет приложению создавать и слушать сокеты, так что теперь возможны коммуникации между клиентами без участия сервера, что позволит писать, например, p2p приложения, работать с сетевыми протоколами, например FTP и тд.
  • UDP сокеты: В дополнение к TCP сокетам, AIR 2.0 поддерживает передачу данных с помощью UDP.
  • Зашифрованные сокетные соединения: Данные передаваемые через сокетные соединения, теперь могут быть защищены с помощью TLS/SSL.
  • Поддержка IPv6.
  • Доступ к низкоуровневой сетевой информации: Объект NetworkInfo позволяет смотреть сетевые интерфейсы компьютера и их свойства, например активность, IP адрес и название.
  • Bind Sockets to Specific Network Interfaces: The new Socket.bind function can be used to bind to a specific network interface (discovered through the NetworkInfo API) rather than always binding to the default. This can allow you to pick the best network connection for your particular application. (вот это я как-то не понял)
  • Работа с DNS: DNSResolver позволяет смотреть следующие типы записей:
    • ARecord (IPv4 address for a host)
    • AAAARecord (IPv6 address for a host)
    • MXRecord: mail exchange record for a host
    • PTRRecord: host name for an IP address
    • SRVRecord: service record for a service
  • Настраиваемый HTTP Idle Timeout. URLRequest.idleTimeout и URLRequestDefaults.idleTimeout позволяет указать в миллисекундах время, в течение которого соединение остается открытым до того, как будут получены данные. Полезно, например для long polling.
  • Локальная работа со звуком: Появилась возможность доступа к аудио данным непосредственно с микрофона, больше не придется задействовать сервер и пересылать данные туда-сюда.
  • Глобальный Error Handling: Глобальный error handling позволет поймать все непойманные ошибки (синхронные и асинхронные) в одном месте в коде. (More information on Global Error Handling.)
  • Accessibility: В AIR 2.0 будет такая же поддержка аудио интерфейсов для слепых, как и во Flash. (More information on accessibility in AIR 2.0.)
  • Увеличение размеров NativeWindow и Bitmap: Раньше максимальный размер NativeWindow и Bitmap был 2880×2880. В AIR 2.0 он будет 4094×4094.
  • Улучшенная печать.
    • Векторная печать на Mac (уже в FP 10).
    • Поддержка сложной прозрачности.
  • Вложенные транзакции. SQLite теперь поддерживает вложенные транзакции.
  • Событие Exiting при выключении компьютера. В AIR 2.0 появится событие Event.EXITING, которое диспатчится, когда компьютер выключается. У вас будет время сохранить несохраненные данные.
  • WebKit Upgrades:
    • Nitro JavaScript Engine (SquirrelFish Extreme).
    • CSS3 Module support (2D transformations, transitions, animations, etc.).
    • Scrollbar styling.
    • Break up text across columns.
    • Latest Canvas enhancements.
  • Оптимизация:
    • Меньше ест CPU в режиме ожидания.
    • Меньше ест память.

Макросы компилятора ActionScript

Честно скажу, сам не знал. Прочитал только сегодня тут.

Значит, оказывается, для компилятора можно указывать константы в специальном неймспейсе ( по крайней мере выглядит так ), и потом использовать их для условной компиляции в зависимости от значения. Например, для отладки можно использовать следующий код:

function log( message:String ):void
{
 	CONFIG::Debug {
  		trace( message );
  	}
}

Который, если CONFIG::Debug == true, вкомпилит этот trace, в противном же случае нет.

Константы определяются следующим образом:

  • Flash. В File > Publish Settings, кнопка Settings. Добавить имя и значение в Config constants.
  • Flex Ant Task.
    <mxmlc ... >
        <define name="CONFIG::Debug" value="false"/>
    </mxmlc>
  • Flex-config.xml
    <compiler>
            <define>
                    <name>CONFIG::Debug</name>
                    <value>false</value>
            </define>
    </compiler>
  • mxmlc -define=CONFIG::Debug,false

Получается очень интересная штука. Дебаг и релиз версии лично у меня отличаются наличием всяких внешних вызовов дебагеров, например Alcon, которые совершенно не нужны в релизе. Проблема лишь в том, что мало кто эту фишку знает и, если отсутствуют объявления этих констант (мало ли, скопипастили код), то скомпилить становится нетривиально.

Prolog на Mac

Допустим, вам понадобился Prolog на OS X. Если вы все еще читатете, то идем дальше.

Вообще, проглядев книгу восемдесятбородатого года про Пролог, мне он показался довольно забавным, и я решил попробовать какие-нибудь простенькие штуковины пописать. Только, как это сделать без идиотских эмуляторов на Mac. Значит, что мне понадобилось.

  • Кроссплатформенные решения я нашел в виде плагинов для Eclipse, соответственно сперва нужен сам Eclipse. Версий там вагон, я выбрал где меньше всего всякой ненужной мне фигни, так как на Java я не разрабатываю.
  • Первый плагин я пробовал PDT, он уж очень старый и на 3.5 не работает, 3.1 я скачал, но так и не установил, потому что нашел второй плагин ProDT. Он заработал нормально, и для моих простых тестов вполне достаточен. В Downloads нужно качать самый мелкий файлик.
  • Для ProDT нужен SWI-Prolog — некоторая кросплатформенная opensource имплементация языка. Качаем, ставим.
  • SWI-Prolog требует или нет MacPorts, но в любом случае, он у меня был и штука весьма полезная.
  • Распаковываем ProDT в eclipse/dropins/prodt/eclipse/plugins, запускаем eclipse и он сам все устанавливает.
  • Теперь в свойствах ProDT ( Eclipse -> Preferences -> Prolog -> Compilers -> Swi Compiler ) нужно прописать путь до компилятора, который по умолчанию ставится в /opt/local/bin/swipl.
  • Переключаем вид Window -> Show Perspective -> Other… -> Prolog.

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

da( one ).
da( two ).

Запустить, и в консоли написать

da(X).
x = one ;
x = two.

Башорг отжег

<@Monster> Мне люди на работе сказали, что я зря обозвал функцию DrawChildren
<@Monster> ибо, когда быстро произносишь…

Не, честно, я чуть не умер под столом от смеха (((8