![]() |
|
||||||||||
|
|||||
|
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Собственно, делаю входного обучающего визарда для приложения (ну, это когда чучело при первой загрузке вылазит "здравствуй, дорогой друг, нажми на эту пимпочку, чтобы завертелась каруселька, а теперь вот на эту кнопочку..." и потом изредка уже по событиям - "поздравляю, ты собрал свои первые денежки, положи их вот в этот ящичек...").
Поймал себя на мысли, что фактически это квест. Т.е., лучше сразу писать класс квеста (с механизмом контроля событий, которые должны произойти), а потом уже на основе его вылепить обучающего визарда. Кто как этих обучающих визардов делает? |
|
|||||
|
Приходилось делать на не больших играх его только, поэтому хватало одного мувика, лежащего поверх всего, которого ставил на нужный кадр. Добавлял после того, как всё написано - так что синглтоном, за это меня можно бить по рукам =) Хотя, проект уже написан и расширению не подлежал - почему нет?..
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Уже слепил квестом )))
Расписал ожидаемые игровые события и реакцию на них в зависимости от состояния/этапа квеста. Немного запахло конечными автоматами, но в меру. ) Получилось, что каждый новый пользователь получает на входе стартовый квест, который должен пройти. Посмотрю теперь, как все это отработает на реальных пользователях... |
|
|||||
|
Регистрация: Jun 2007
Сообщений: 374
|
mikhailk, а как вы стрелочки привязваете к объектам? Ну т. е. примерно так "тыкни на эту кнопку", стрелочка, указывающая на кнопку.
|
|
|||||
|
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
примерно так (это описание одного шага)
<step stepNumber="0" mousePositionX="165" mousePositionY="215" action="viewImmediately" waitingAction="openObjectControlInterface" waitingParameter="Farm" > <stepTitle>Приветствуем Вас в игре "..."!!!</stepTitle> <stepText>Сейчас Вам нужно произвести первый товар. Нажмите здесь, чтобы запустить производство.</stepText> </step> |
|
|||||
|
Регистрация: Jun 2007
Сообщений: 374
|
Я еще встретился с проблемой, когда идет "откат" на шаг назад. Например - есть выпадающий список. Сначала стрелка должна показать на этот список, потом на элемент в нем.
Если вдруг игрок не нажал нужный элемент, и меню закрылось, то стрелка должна снова вернуться в состояние "показать на кнопку открывающую меню". В результате я запутался с событиями вьюверов. Когда именно они должны переключать состояния. Как вы такого рода конфликты решаете, можно поинтересоваться? Еще одна проблема - скрыть/показать элементы интерфейса в зависимости от состояния тутора. Чтобы описать это в общем, надо давать какие-то глобальные id вьюверам, чтобы в xml квестов прописать что-нибудь типа <hideElems>id1,id2,...</hideElems>. Но я эту задачу в общем так и не поборол... PS. На пользователях любой туториал работает более, чем хорошо ![]() |
|
|||||
|
mikhailk, поделитесь реализацией, интересно взглянуть.
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
Механизм в бета-тестировании, ногами не пинать ))
package main { import flash.display.*; import flash.text.*; import flash.events.*; import main.*; public class AppQuester extends Sprite { private var questStep; private var questContent:XMLList; private var questName:String; private var questWaitingAction:String; private var questWaitingParameter:String; private var questStepNumber:int; private var containers:Object; public function AppQuester(_containers,questInfo) { // Для последующей передачи ссылки на враппер при необходимости containers = _containers; // Получаем данные по квесту var questArr:Array = questInfo.split("|"); questName = questArr[0]; questStepNumber = int(questArr[1]); questContent = GlobalQuestData.elements(questName); // Если квест есть и шаг требует вывода на экран - выводим if (questContent!=null) { var action:String = questContent.step[questStepNumber].attribute("action"); switch(action) { case "viewImmediately": showQuestStep(); break; } } } public function checkEvent(eventData) { if (eventData.action.toString()==questWaitingAction && eventData.parameter.toString()==questWaitingParameter) { // получили ожидаемое действие пользователя // Если было открыто - убираем с экрана (позже поставим нормальное удаление) if (questStep) questStep.y = -2000; // Переходим к следующему шагу // и выполняем действие, заложенное на этом шаге questStepNumber++; showQuestStep(); } } private function showQuestStep() { // Запоминаем действие и параметр, который ждем questWaitingAction = questContent.step[questStepNumber].attribute("waitingAction"); questWaitingParameter = questContent.step[questStepNumber].attribute("waitingParameter"); // Если требуется закрыть все окна - закрываем if (questContent.step[questStepNumber].attribute("closeBefore").toString()=="closeAllComplexInterfaces") { var appEvent = new AppEvent("closeAllComplexInterfaces","",true) dispatchEvent(appEvent); } // Если требуется записать статус - записываем if (questContent.step[questStepNumber].attribute("saveStatus").toString()!="") { var requestData = { questStatus : questContent.step[questStepNumber].attribute("saveStatus") }; var connDB = new DataConnectorDB(containers.wrapper,"saveQuestStatus",requestData); } // Открываем лопух правильной формы и ориентации var windowsVariant:String = questContent.step[questStepNumber].attribute("windowVariant").toString(); switch(windowsVariant) { case "flipX" : questStep = new QuestStepFlipX(); break; case "info" : questStep = new QuestInfo(); break; case "title" : questStep = new QuestTitle(); break; default: questStep = new QuestStep(); } // Позиционируем лопух и заполняем контентом questStep.x = questContent.step[questStepNumber].attribute("mousePositionX"); questStep.y = questContent.step[questStepNumber].attribute("mousePositionY"); questStep.stepTitle.htmlText = "<b>" + questContent.step[questStepNumber].stepTitle + "</b>"; questStep.stepText.htmlText = questContent.step[questStepNumber].stepText; questStep.btnClose.addEventListener(MouseEvent.CLICK,closeStep); addChild(questStep); } private function closeStep(e:Event) { removeChild(e.target.parent); } } } package { public var GlobalQuestData:XML = <quests> <startQuest> <step stepNumber="0" mousePositionX="165" mousePositionY="215" action="viewImmediately" condition="noCondition" item="noItem" waitingAction="openObjectControlInterface" waitingParameter="Farm" > <stepTitle>Приветствуем Вас в игре "Поездатый товарняк"!!!</stepTitle> <stepText>Сейчас Вам нужно произвести первый товар. Нажмите здесь, чтобы запустить производство.</stepText> </step> <step stepNumber="1" mousePositionX="655" mousePositionY="220" windowVariant="flipX" waitingAction="startManufacture" waitingParameter="" > <stepTitle>Всю эту продукцию Вы можете производить</stepTitle> <stepText>Нажмите здесь, чтобы начать производство риса.</stepText> </step> ... </startQuest> </quests> ; } При загрузке приложения, смотрим, нет ли у пользователя активного квеста и на каком шаге. Если есть - порождаем объект класса AppQuester. В необходимых точках приложения, вызываем метод checkEvent, который проверяет, не ожидает ли квест этого события. Последний раз редактировалось mikhailk; 05.06.2010 в 14:31. |
|
|||||
|
Понятно, спасибо. Ещё бы взглянуть в действии
![]() И да, типизация явно хромает.
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
|
про типизацию - это да ))
не могу себя заставить, а IDE не требует. Кстати, специально не занимался, но какой тип правильнее установить для переменной questStep? Что касается наблюдения в действии - этот квестер стоит на входе в товарняке (ВК). Сейчас, правда, приложение не работает, там что-то с сервером. При создании профиля юзеру назначается квест "startQuest|0" и вперед. |
![]() |
![]() |
Часовой пояс GMT +4, время: 04:07. |
|
|
« Предыдущая тема | Следующая тема » |
|
|