Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   редактор квестов (http://www.flasher.ru/forum/showthread.php?t=203376)

boyard 20.09.2013 02:49

редактор квестов
 
Доброе время суток, уважаемые форумчане. решил я тут собрать редактор квестов. при попытке связать область выполнения с менеджером кнопок, возникло пару вопросов(моя память говорит, что где-то я уже видел реализацию всего этого, но из-за разных мыслей не могу придумать толковое описание каждого из вопросов):
1) можно ли повесить внешнего(относительно класса) слушателя событий на изменение переменной без использования EnterFrame?{есть у меня менеджер кнопок, в зависимости от нажатой кнопки на цене выполняется действие. номер нажатой кнопки хранится во внутренней переменной(доступной внешне только для чтения) можно ли отслеживать изменение переменной с главной сцены, не добавляя обработчик EnterFrame?}
2) что менее нагрузит систему: HitTest или слушатель клика мыши?{на сцене, локации отображаются точками. что будет выигрышнее: 1-повесить на всю сцену слушателя клика мыши, и искать локацию, на которую кликнули hitTest ом или же повесить на каждую локацию свой собственный слушатель клика мыши?}

Akopalipsis 20.09.2013 02:57

Мне кажется, что для отслеживания изменения какой либо переменной есть только два способа - сделать сеттер и при его изменении посылать событие. И ещё есть биндинг http://blog.diestro.ru/binding-v-actionscript-1/
И наверное лучше повесить слушателя на мышь и там проверять target.

boyard 20.09.2013 10:41

Цитата:

Сообщение от Akopalipsis (Сообщение 1146513)
Мне кажется, что для отслеживания изменения какой либо переменной есть только два способа - сделать сеттер и при его изменении посылать событие. И ещё есть биндинг http://blog.diestro.ru/binding-v-actionscript-1/

dispatchEvent() уже побывал, у меня почему-то не хочет установить связь между 2 предками одного родителя...
Цитата:

Сообщение от Akopalipsis (Сообщение 1146513)
И наверное лучше повесить слушателя на мышь и там проверять target.

спасибо, совсем упустил из вида target(хотя буквально в соседнем классе активно его использую);

появился еще 1 вопрос: возможно ли использовать строку, как строку ввода логических условий?{есть 3 переменные: p1, p2, p3, и 2 строки: в первой строке пользователь задает условие((p1!=p2) and (p1>5)) во второй - действие (p3=p1*p2)}

AlexCooper 20.09.2013 12:23

Цитата:

Сообщение от boyard (Сообщение 1146521)
появился еще 1 вопрос: возможно ли использовать строку, как строку ввода логических условий?{есть 3 переменные: p1, p2, p3, и 2 строки: в первой строке пользователь задает условие((p1!=p2) and (p1>5)) во второй - действие (p3=p1*p2)}

можно но придется ручками написать парсер таких строк

Babylon 20.09.2013 14:54

Для ввода условий можно использовать булевы переменные и даже затолкать их в словарь

Akopalipsis 20.09.2013 16:28

Цитата:

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

AlexCooper 20.09.2013 16:45

На счёт событий

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

Добавлено через 5 минут
если это ДО
Код AS3:

import flash.display.Sprite;
import flash.events.Event;
 
var papa:Sprite = new Sprite();       
var child:Sprite = new Sprite();
 
papa.addChild(child);
 
papa.addEventListener('event', function(e:Event){ trace('papa')} );
child.addEventListener('event', function(e:Event){ trace('child')} );
 
child.parent.addEventListener('event', function(e:Event){ trace('papa child')} );
 
child.dispatchEvent(new Event('event')); // child
papa.dispatchEvent(new Event('event'));
// papa
// papa child


boyard 20.09.2013 18:07

Цитата:

Сообщение от AlexCooper (Сообщение 1146526)
можно но придется ручками написать парсер таких строк

думал что есть что-то встроенное... значит снова будем писать парсер.

AlexCooper 20.09.2013 19:23

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

Код AS3:

 
var fLib:Object = new Object();
        fLib['=='] = ravno;
        fLib['!='] = neravno;
        fLib['>'] = bolshe;
        fLib['<'] = menshe;
 
function bolshe(arg:Array):Boolean {
        return arg[0]>arg[1];
}
 
function menshe(arg:Array):Boolean {
        return arg[0]<arg[1];
}
 
function ravno(arg:Array):Boolean {
        return arg[0]==arg[1];
}
 
function neravno(arg:Array):Boolean {
        return arg[0]!=arg[1];
}
 
var variables:Object = new Object();
        variables['p1'] = 1;
        variables['p2'] = 2;
        variables['p3'] = 2;
 
var commandLine = '(p1!=p2) AND (p2==p3) AND (p1<2)';
 
var resultCommand:Boolean = interpretator(commandLine);
 
trace(resultCommand); // true
 
function interpretator(line:String):Boolean {
 
        var funcTemp:Array = new Array();
 
        var funcDump:Array;
 
        // разбиваем на логические И
        var ifDump:Array = line.split('AND');
 
        var resultDump:Array = new Array();
 
        var result:Array = new Array();
 
        // проходим по логическим составным
        for each( var subcommand:String in ifDump) {
 
                // ищем функции
                for ( var func:String in fLib) {
 
                        // разбиваем на элементы
                        funcDump = subcommand.split(func);
 
                        // если два и более элемента значит нужно выполнить эту логическую функцию
                        if (funcDump.length>1) {
 
 
                                if (!resultDump[func]) resultDump[func] = new Array();
 
                                // парсим переменные
                                variableParser(funcDump);
 
                                // результаты в массив
                                resultDump[func].push(funcDump);
                        }
                }
        }
 
        // выполняем функции
        for ( func in resultDump) {
 
                // пока есть элементы
                while (resultDump[func].length) {
 
                        // выбираем по парам и выполняем соответсвующию функцию
                        result.push(fLib[func]( resultDump[func].shift() ) );
                }
 
        }
 
        // только для условия И ( нужно доработать )
        var resultBoolean:Boolean = true;
 
        for each( var resB:Boolean in result ) {
 
                if (resultBoolean) resultBoolean = resB;
        }
 
        return resultBoolean;
}
 
function variableParser(arr:Array):void {
 
        // проходим все пары элементов
        for ( var i:uint = 0; i <arr.length ; i++) {
 
                var varIndex:String;
 
                var ind:Number;
 
                if (i%2) {
                        // если элемент после знака оператора то ищем дугу
                        ind = String(arr[i]).indexOf(')');
 
                        // режем текст до дуги
                        varIndex = String(arr[i]).substr(0,ind);
 
                } else {
                        // если элемент перед оператором
                        ind = String(arr[i]).lastIndexOf('(');
 
                        // режем текст с начала строки до дуги
                        varIndex = String(arr[i]).substr(ind+1,String(arr[i]).length);
                }
 
                // находим переменную и переопределяем массив
                arr[i] = (variables[varIndex]) ? variables[varIndex] : varIndex;
 
        }
 
}


MikroAcse 20.09.2013 21:10

Код AS3:

fLib['=='] = ravno;
        fLib['!='] = neravno;
        fLib['>'] = bolshe;
        fLib['<'] = menshe;

Мои глаза!!!

Akopalipsis 20.09.2013 21:16

Цитата:

Мои глаза!!!
Что с ними?)

MikroAcse 20.09.2013 22:42

Код AS3:

Что с ними?)

Все плохо :)

dimarik 20.09.2013 22:46

Красненький плохо видно

AlexCooper 20.09.2013 22:47

Цитата:

Сообщение от MikroAcse (Сообщение 1146551)
Мои глаза!!!

еще чёт наваять?)) сча я мигом)

AlexLucas 20.09.2013 22:56

Лицо покраснело ?

AlexCooper 20.09.2013 22:59

Кстати очень интересно посмотреть другие (ваши) реализации, интерпретаторов по данной задаче, весь полезная штука в принципе.

dimarik 20.09.2013 23:39

http://www.antlr.org/about.html
http://www.antlr.org/wiki/display/AN...onScriptTarget

Akopalipsis 21.09.2013 00:18

Смог..)

MikroAcse 21.09.2013 19:50

Цитата:

Лицо покраснело ?
Цвета 0xFF0000

Вот, кстати, делал тут довольно быстрый парсер математических выражений:
https://github.com/MikroAcse/MikroAc...ath/MParser.as
Поддержки переменных нету, но есть поддержка функций из класса Math.
Работает с выражениями любой сложности:
Код AS3:

12/12/2/2+0.75
12/2+3*2*4+(1+(1+5)/2)
(sin(asin(1))+sin(asin(1)))*2

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

UPD:
Ах, да. Тут не просто математические выражения нужны, тут еще и логические операторы. Тогда MParser не совсем подходит.

mikhailk 22.09.2013 02:18

Что-то я туплю, наверное, но зачем все эти пляски с бубнами?
Я еще понимаю, в туториале отслеживать, куда пользователь нажал, но в квестах-то зачем?

AlexCooper 22.09.2013 14:54

Цитата:

Сообщение от mikhailk (Сообщение 1146622)
Что-то я туплю, наверное, но зачем все эти пляски с бубнами?
Я еще понимаю, в туториале отслеживать, куда пользователь нажал, но в квестах-то зачем?

Дык где Вы увидели что клики отслеживаются? Я так понимаю эт для того что-бы создавать динамически квесты и не компилировать версию.

mikhailk 23.09.2013 01:08

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

Интересно, кто-то делает иначе? :)

AlexCooper 23.09.2013 12:59

Цитата:

Сообщение от mikhailk (Сообщение 1146683)
Интересно, кто-то делает иначе? :)

Я раньше так делал) Сейчас квесты передаю только в виде брифа, все просчёты ведутся на сервере.

p.s. смотря конечно какие квесты

mikhailk 23.09.2013 13:32

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

ЗЫ. Под постобработкой я в данном случае понимаю, что клиент производит изменения на своей модели пользователя, а потом с некоторым интервалом (например, раз в минуту или по достижению определенного количества изменений) пакетом сбрасывает их на сервер, тот прогоняет изменения по своей модели и, если все сошлось, то акцептует их, если не сошлось - отправляет клиента на релоад. Но я, кстати, до сих пор не уверен, что эта архитектура дает какие-то дополнительные бонусы. Кроме снижения нагрузки на БД, естественно.

Tails 23.09.2013 19:11

Тема очень интересная. Может знатоки приведут несколько ссылок для чтения? :)

Вот например, каким образом реализовать текстовое описание квеста? Сам квест, разумно хранить и передавать как id из таблицы всех квестов в игре. Эта таблица только на сервере. Цели и задачи тоже можно использовать как id'ы выполняемых действий, их можно описать на клиенте. Но вот как хранить и передавать текстовое описание, ведь его не передать в виде id, иначе придётся для каждого внесения/редактирования квеста обновлять весь клиент?

AlexCooper 23.09.2013 19:33

Бриф? А что мешает хранить бриф в базе данных и получать текст в соответствии с Ид?

Tails 23.09.2013 19:38

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

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

AlexCooper 23.09.2013 19:46

Дык нам нужна динамичность и гибкость. То-есть текст брифа может изменятся. Соответственно можно реализовать версии. То-есть хранить уже полученные данные ( бриф - хотя сколько там того текста ) локально и сверяться только с версией брифа конкретного квеста. Если версия изменилась, произвести апдейт локальной версии.

Tails 23.09.2013 19:55

А вот это уже хорошая идея :)

mikhailk 23.09.2013 21:26

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

Что касается описания непосредственно квеста, то мы использовали примерно такой формат и было достаточно удобно (на идеальный вариант не претендую):

Код:

<quest ID="123" sequenceID="567" numInSequence="2">
    <title>Собрать и продать яблоки<title>
    <info>Тебе надо собрать 20 зеленых яблок и 10 красных яблок, 10 зеленых потом продать.</info>
    <tasks>
      <task num="1" type="collect" targetID="456" count="20">
        <info>Собери 20 зеленых яблок.</info>
      </task>
      <task num="2" type="collect" targetID="765" count="10">
        <info>Собери 10 красных яблок.</info>
      </task>
      <task num="3" type="sell" targetID="456" count="10">
        <info>Продай 10 зеленых яблок.</info>
      </task>
    </tasks>
    <bonus xp="100" gold="10" />
</quest>


Akopalipsis 23.09.2013 21:56

Цитата:

то в итоге он садится в кеш браузера и мы еще и на трафике экономим.
Можно чуть-чуть поподробнее.. я некоторое время назад как раз на этом моменте остановился.
Сделал на сервере, чтобы при изменении нужных файлов создавался новый xml с датой изменения..
Тут нужно немного обьяснить - я прочел статью, где говорилось о том же о чем говорите Вы.
Файл с временем последнего изменения и что при загрузке флеш проверяет его и если что, то дакачивает, если время не поменялось, то берет из хеша.. И там говорилось, что этот файл в браузере оседает.
А что нужно сделать, чтобы он там осел? Не чего? Просто загрузить во флешь? Или как?)

MikroAcse 23.09.2013 22:11

Цитата:

А что нужно сделать, чтобы он там осел?
Загрузить, минуя кэш:
Код AS3:

urlLoader.load(new URLRequest("hello.png?" + (new Date()).getTime()));

Загрузить из кэша (только если до этого уже воспроизводилась загрузка файла):
Код AS3:

urlLoader.load(new URLRequest("hello.png"));


mikhailk 23.09.2013 22:39

Ну да. Это собственно не заслуга флеша. Это браузер кэширует. И браузер же проверяет, нужно закачивать файл или отдавать из кэша.

dimarik 23.09.2013 22:54

Цитата:

Сообщение от Tails (Сообщение 1146749)
Тема очень интересная. Может знатоки приведут несколько ссылок для чтения? :)

Вот например, каким образом реализовать текстовое описание квеста? Сам квест, разумно хранить и передавать как id из таблицы всех квестов в игре. Эта таблица только на сервере. Цели и задачи тоже можно использовать как id'ы выполняемых действий, их можно описать на клиенте. Но вот как хранить и передавать текстовое описание, ведь его не передать в виде id, иначе придётся для каждого внесения/редактирования квеста обновлять весь клиент?

Храните таблицы (редкоизменяемые части БД) на клиенте. В снапшотах, понятных клиенту (например, amf). При перегенерации серверной таблицы создавайте новый снапшот. Сообщите клиенту, что снапшот изменился, чтобы он мог воспользоваться новым. Это если у вас хорошо спроектированная система. Либо подождите перезагрузки клиента, он сам загрузит новый снапшот базы квестов, если у вас полумеры.

AlexCooper 23.09.2013 23:25

Цитата:

Сообщение от mikhailk (Сообщение 1146761)
Мне все-таки нравится отдавать условно статическую информацию файлом и не дергать базу по такому поводу. Ведем, конечно, в админке, и храним в базе, потом нажимает кнопку "Генерация applicationData" и генерим xml-файл. При загрузке клиента скармливаем ему ссылку на текущую версию applicationData.xml, клиент его прикрасно закачивает, а поскольку меняется applicationData.xml не каждый день, то в итоге он садится в кеш браузера и мы еще и на трафике экономим.

Я не использую xml. Он выглядит мне слишком избыточным, использую для передачи данных AMF. А вообще работаю на связке AS3 -> AMF -> AMFPHP -> MongoDB, пихаю целыми объектами из базы в клиент и обратно практически не трансформируя. Плюс AMF работает и на FMS, для меня это как стандарт.

Akopalipsis 23.09.2013 23:59

AlexCooper а MongoDB это БД которую как и обычную, можно ставить на любой сервер?

mikhailk 24.09.2013 02:13

Цитата:

MongoDB это БД которую как и обычную, можно ставить на любой сервер?
Монго - чудесная вещь, но надо понимать, что все чудесно, пока она вся сидит в памяти. Как только возникает своп - чудеса заканчиваются. :)


Цитата:

А вообще работаю на связке AS3 -> AMF -> AMFPHP -> MongoDB, пихаю целыми объектами из базы в клиент и обратно практически не трансформируя.
Читеры не беспокоят? Или протокол AMF обеспечивает защиту от подмены данных?

Akopalipsis 24.09.2013 02:20

mikhailk а что тогда лучше использовать?

mikhailk 24.09.2013 11:25

Насколько я понимаю, надо идти все-таки от функционала приложения. MongoDB - штука модная и эффективная, но документо-ориентированная. Очень удобно вместо 30-50 таблиц иметь 3-5 коллекций, в которых все это лежит достаточно естественным образом, но некоторые операции становятся сложнее, чем в обычной SQL-базе (например, передача айтема от одного перса другому - тут это корректировка двух профилей персов, а в SQL-базе - изменение значения одного поля в одной строке таблицы, где лежат все айтемы всех персов). И она жрет память, а память - это деньги за хостинг.

Если проект оффлайновый и малобюджетный, то пока еще ничего лучше связки PHP+MySQL+Memcache+Ngnx, на мой взгляд, не придумали. Поднимаем все справочники и классификаторы в мемкеш и работаем с базой только по данным пользователей. Если добавить постобработку, то можем тащить на одном сервере БД совершенно неприличное количество пользователей.

Если проект онлайновый, то мне лично нравится связка Node.js+Mongoose+MongoBD (ну и Ngnx, естественно, если отдаем много контента). Но нужно следить за размером бд и его соответствием ресурсу сервера по оперативной памяти.

Tails 24.09.2013 11:32

dimarik,
спс


Часовой пояс GMT +4, время: 18:20.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.