Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 02.01.2019, 11:37
Жень Шень вне форума Посмотреть профиль Отправить личное сообщение для Жень Шень Найти все сообщения от Жень Шень
  № 21  
Ответить с цитированием
Жень Шень
 
Аватар для Жень Шень

блогер
Регистрация: Feb 2004
Адрес: Украина
Сообщений: 1,180
Записей в блоге: 3
Отправить сообщение для Жень Шень с помощью ICQ
Мне кажется дело в методе appendText. Он обрабатывает стринговый аргумент и стыкует его к уже имеющемуся тексту. Когда же ему скармливают символ "Возврат каретки", то он его внутри себя выполняет и в результате получается пустая строка. Когда же методу передают строковую переменную с символом 13 внутри текста, то он таки делает перенос строки, по сути вставляя и "возврат каретки" и "перевод каретки".
Попробуйте "допечатывать" по два символа за раз и код символа 13 не пропадает!
Другого объяснения не могу дать. Может гуру флеша прольют свет на сие.

Старый 02.01.2019, 12:50
RedHead90 вне форума Посмотреть профиль Отправить личное сообщение для RedHead90 Найти все сообщения от RedHead90
  № 22  
Ответить с цитированием
RedHead90

Регистрация: Apr 2018
Сообщений: 42
Что-то вы тут перемудрили.
1. Зачем таймер стартует сразу же, если при первом же срабатывании он останавливается?
2. Зачем таймер останавливается в начале слушателя on_keyDown? (попробуйте нажать любую не назначенную клавишу во время анимации печати)
3. Опять же, к чему эта копи-паста внутри if else if? К тому же в конце проверка кода клавиши дублируется. У вас на 4 кнопки одно действие, значит и проверка должна быть только одна.


Я бы сделал как-то так

Код AS3:
import flash.ui.Keyboard;
 
stop();
 
var keysMap:Object = {}; //код клавиши : номер кадра;
keysMap[Keyboard.NUMBER_1] = 1;
keysMap[Keyboard.NUMBER_2] = 2;
keysMap[Keyboard.NUMBER_3] = 3;
keysMap[Keyboard.NUMBER_4] = 4;
 
var timer1:Timer=new Timer(20);
timer1.addEventListener(TimerEvent.TIMER, frameLooper);
 
stage.addEventListener(KeyboardEvent.KEY_DOWN, on_keyDown);
 
var text:String = "";
var currentSymbol:int = 0;
var pattern:RegExp = new RegExp(String.fromCharCode(13), "g"); //регулярка, ищущая все возвраты каретки в строке
var repl:String = String.fromCharCode(10); //символ переноса \n
 
function frameLooper(event:TimerEvent):void {
    if (currentSymbol < text.length) {
        answer_tf.appendText(text.charAt(currentSymbol++));
    } else {
        timer1.stop();
    }
}
 
function on_keyDown(e:KeyboardEvent):void {
	if (keysMap.hasOwnProperty(e.keyCode)) {
		answer_tf.text="";
		dialogs.gotoAndStop(keysMap[e.keyCode]);
		text = dialogs.tf.text.replace(pattern, repl);
		currentSymbol = 0;
        timer1.start();
	}
}
А вообще это все баловство и ничего вменяемого с таким подходом не получиться.

Старый 02.01.2019, 13:56
Жень Шень вне форума Посмотреть профиль Отправить личное сообщение для Жень Шень Найти все сообщения от Жень Шень
  № 23  
Ответить с цитированием
Жень Шень
 
Аватар для Жень Шень

блогер
Регистрация: Feb 2004
Адрес: Украина
Сообщений: 1,180
Записей в блоге: 3
Отправить сообщение для Жень Шень с помощью ICQ
По первому пункту - в начальной версии у автора печатался какой-то текст (не помню уже что, но типа "нажмите клавишу А,B,C,D). Так и остался старт таймера. Замечание принимается.
По второму пункту - тоже принимается замечание. В моей редакции просто проверку на используемые клавиши надо перенести повыше и удалить повторяющий код. Результат должен быть таким:
Код AS3:
function on_keyDown(e:KeyboardEvent):void {
    if (e.keyCode==49||e.keyCode==50||e.keyCode==51||e.keyCode==52) {
        timer1.stop();
        if (e.keyCode==49) {
            delay=10;
            dialogs.gotoAndStop(1);
        } else if (e.keyCode == 50) {
            delay=15;
            dialogs.gotoAndStop(2);
        } else if (e.keyCode == 51) {
            delay=20;
            dialogs.gotoAndStop(3);
        } else if (e.keyCode == 52) {
            delay=25;
            dialogs.gotoAndStop(4);
        }
        answer_tf.text="";
        myString=dialogs.tf.text;
        myArray=myString.split("");
        timer1.delay=delay;
        timer1.start();
    }
}
По-третьему пункту - автор хотел чтобы скорость таймера была разной в зависимости от нажатой клавиши (delay=20;//скорость печати). Просто в последних редакций кода на этом не заостряли внимание и delay была одинаковой. Поэтому был оставлен ранее используемый блок "if else if". В вашем случае к объекту keysMap надо добавить ещё одно свойство и устанавливать delay для каждой из назначенных клавиш.
В целом ваши замечания правильные и рациональны, но учитывая, что автор в АС3 плохо ещё разбирается, то логика работы "его замыслов" для него более понятна в данном изложении. Впрочем это ему судить и принимать решение.

Старый 02.01.2019, 15:16
RedHead90 вне форума Посмотреть профиль Отправить личное сообщение для RedHead90 Найти все сообщения от RedHead90
  № 24  
Ответить с цитированием
RedHead90

Регистрация: Apr 2018
Сообщений: 42
@Жень Шень, то, что автор плохо разбирается как раз и стало причиной, почему я "докопался" до его кода. Лучше уж сразу указать на эти типичные ошибки, чтобы в будущем ему было проще обходить такие грабли стороной.

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

Ну и по поводу
Цитата:
Сообщение от Жень Шень Посмотреть сообщение
удалить повторяющий код.
То, что значения в каждом условном блоке подставляются разные не отменяет того, что код в каждом блоке повторяется. Если записать все это дело простым абстрактным языком, то получится что-то вроде

Код:
если (нажата нужная клавиша) {
    изменить задержку;
    перейти в соответствующий кадр.
} иначе если (нажата другая нужная клавиша) {
    изменить задержку;
    перейти в соответствующий кадр.
} иначе если (нажата другая нужная клавиша) {
    изменить задержку;
    перейти в соответствующий кадр.
} иначе если (нажата другая нужная клавиша) {
    изменить задержку;
    перейти в соответствующий кадр.
}
Повторение на лицо. А если вариантов будет не 4, а хотя бы 10? Тут каждый блок выполняет одну и туже функцию, а-ля
Код:
setDelayAndFrame(delay:Int, frame:Int):Void;
поэтому можно и нужно избавляться от всей этой кучи проверок.

Лучше уж, как ты и заметил, держать все это дело в keysMap
Код AS3:
keysMap[Keyboard.NUMBER_1] = {frame:1, delay:20};
Код AS3:
dialogs.gotoAndStop(keysMap[e.keyCode]['frame']);
timer1.delay = keysMap[e.keyCode]['delay'];

Старый 02.01.2019, 19:14
Жень Шень вне форума Посмотреть профиль Отправить личное сообщение для Жень Шень Найти все сообщения от Жень Шень
  № 25  
Ответить с цитированием
Жень Шень
 
Аватар для Жень Шень

блогер
Регистрация: Feb 2004
Адрес: Украина
Сообщений: 1,180
Записей в блоге: 3
Отправить сообщение для Жень Шень с помощью ICQ
@RedHead90, повторюсь: "замечания правильные и рациональны". Осталось автору досконально разобраться с объектом, ну и заодно с регуляркой. Лично я вник и воспользовался ей на втором году пользования АС. Регулярные выражения удобная вещь, недаром им посвящены целые книги.

Старый 04.01.2019, 17:33
deepNoise вне форума Посмотреть профиль Отправить личное сообщение для deepNoise Найти все сообщения от deepNoise
  № 26  
Ответить с цитированием
deepNoise

Регистрация: May 2018
Сообщений: 27
Код AS3:
import flash.ui.Keyboard;
 
stop();
 
var keysMap:Object = {};//код клавиши : номер кадра;
keysMap[Keyboard.NUMBER_1] = 1;
keysMap[Keyboard.NUMBER_2] = 2;
keysMap[Keyboard.NUMBER_3] = 3;
keysMap[Keyboard.NUMBER_4] = 4;
 
var timer1:Timer = new Timer(delay);
timer1.addEventListener(TimerEvent.TIMER, frameLooper);
 
stage.addEventListener(KeyboardEvent.KEY_DOWN, on_keyDown);
 
var text:String = "";
var currentSymbol:int = 0;
var pattern:RegExp = new RegExp(String.fromCharCode(13),"g");//регулярка, ищущая все возвраты каретки в строке
var repl:String = String.fromCharCode(10);//символ переноса \n
var way = "1";//переменная порядка ветки событий
var wayX = way;//переменная текущего значения ветки
var delay:int = 100; //скорость печати
 
 
timer1.start();
 
function frameLooper(event:TimerEvent):void
{
	if (currentSymbol < text.length)
	{
		answer_tf.appendText(text.charAt(currentSymbol++));
	}
	else
	{
		timer1.stop();
	}
}
 
function on_keyDown(e:KeyboardEvent):void
{
		if (way == wayX)
	{//назначения порядкого номера ветки событий
		if (e.keyCode == 49)
		{//1
			way = wayX+"-1";
		}
		else if (e.keyCode == 50)
		{//2
			way = wayX+"-2";
		}
		else if (e.keyCode == 51)
		{//3
			way = wayX+"-3";
		}
		else if (e.keyCode == 52)
		{//4
			way = wayX+"-4";
		}
		wayX=way;
		trace("way="+way);
	}
 
	if(way == "1-1"){
		delay=20;
	}else if(way == "1-2"){
		delay=40;
	}else if(way == "1-3"){
		delay=60;
	}else if(way == "1-4"){
		delay=80;
	}
 
	if (keysMap.hasOwnProperty(e.keyCode))
	{
		answer_tf.text = "";
		way1.gotoAndStop(keysMap[e.keyCode]);
		text = way1.tf.text.replace(pattern,repl);
		currentSymbol = 0;
		timer1.delay = delay;
		timer1.start();
	}
 
}
В общем я задал переменную way, которая отслеживает текущую ветку события в игре.
Для каждой ветки я задал свою скорость печати.
Клип dialogs переименовал в way1. Теперь буду плодить клипы с названиями текущих веток событий:
way1-1, way1-2, way1-3 и т.д., в которых будут по кадрам выставлены варианты для переходов к последующим веткам. Таким образом собираюсь сделать разветвлённую сеть дерева событий для игры.

Сейчас скорость печати задаётся конкретно для каждой ветки. А можно как то задать скорость печати и время паузы с помощью символов в тексте, как это делалось ранее для переносов символом /n? Например, если будет написано:
Цитата:
/sВы пошли налево./speed=40/pause=1,5 /sКуда теперь?/speed=20

/s1. Пойти налево. 3. Пойти вверх.
2. Пойти направо. 4. Пойти вниз. /speed=0
то это будет означать, что "Вы пошли налево" будет печататься с delay=40, "Куда теперь?" c delay=20, а после "Вы пошли налево" будет пауза 1,5 секунды.

"1. Пойти налево. 3. Пойти вверх. 2. Пойти направо. 4. Пойти вниз." соответственно будут печататься без задержки, то есть моментально. Как это можно реализовать?

Старый 04.01.2019, 20:18
RedHead90 вне форума Посмотреть профиль Отправить личное сообщение для RedHead90 Найти все сообщения от RedHead90
  № 27  
Ответить с цитированием
RedHead90

Регистрация: Apr 2018
Сообщений: 42
@deepNoise,
1. Тебе нужно написать парсер строк. В кадрах такие вещи не делают.
2. Тебе нужна вменяемая система, управляющая вариантами дейтсвий. Сейчас все построено так, что для каждого вопроса должно быть задано 4 варианта ответов - ни больше ни меньше. Захочешь сделать больше или меньше и все сразу пойдет по... В общем, в кадрах такие вещи не делают.
3. Брать текст из клипов - это вообще бред. И это бред вдвойне, учитывая, что сами клипы вообще по сути не используются.
4. Даже для самого простейшего текстового квеста тебе нужно иметь хотя бы начальный багаж знаний в используемом языке и ООП. С наскоку такие вещи не делают. Прочти хотя бы руководство по AS3 Колина Мука. После него и сам язык поймешь и в ООП вникнешь и тебе уже не захочется возвращаться к коду в кадрах. Даже учитывая то, что flash похоронили (это не точно), AS3 как ЯП очень хорош для новичков. После него легко сможешь изучить любой другой ООП язык.


P.S. Чисто из спортивного интереса на коленке набросал, но далее развиваться тем же путем не рекомендую
Код AS3:
 
var SPEED_TAG:String = 'speed';
var PAUSE_TAG:String = 'pause';
 
var pauseTimer:Timer=new Timer(20, 1);
pauseTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onPauseComplete);
 
function frameLooper(event:TimerEvent = null):void {
    if (currentSymbol < text.length) {
		var tag:Array = getTag(text, currentSymbol);
 
		while (tag != null) {
			execTag(tag);
			currentSymbol += tag[2];
			tag = getTag(text, currentSymbol);
		}
 
		var symbol:String = text.charAt(currentSymbol++);
        answer_tf.appendText(symbol);
 
		//тупо костыль, вызывающий слушатель frameLooper повторно, если текст надо вывести без задержек
		if (timer1.delay == 0) {
			frameLooper();
		}
 
    } else {
        timer1.stop();
    }
}
 
function onPauseComplete(event:TimerEvent):void {
	if (currentSymbol < text.length) {
		timer1.start();
	}
}
 
//если в указанной позиции установлен тэг, вернет массив [имя тэга, значение, кол-во непечатаемых символов]
//массив передается как есть в метод execTag
//если тэга в позиции нет, вернет null
function getTag(text:String, pos:int):Array {
	if (text.charAt(pos) == '<') {
		var endIdx:int = text.indexOf('/>', pos);
		var tag:String = text.substring(pos + 1, endIdx);
		var tagLenght:int = tag.length + 3;
		var removeWhitespacesRex:RegExp =  /[\s\r\n\u00A0]+/gim;//регулярка для удаления всего лишнего из строки тега(пробелы, переносы)
		tag = tag.replace(removeWhitespacesRex, '');
		var result:Array = tag.split('=');
		result.push(tagLenght);
		return result;
	}
	return null;
}
 
 
function execTag(tag:Array):void {
	switch (tag[0]) {
		case SPEED_TAG : {
			timer1.delay = tag[1];
			break;
		}
		case PAUSE_TAG : {
			timer1.stop();
			pauseTimer.delay = tag[1];
			pauseTimer.start();
			break;
		}
		default : throw 'Неизвестный тэг ' + tag[0];
	}
}
Строки должны быть такого вида:

<speed=40/>Вы пошли налево.<pause=1500/><speed=20/> Куда теперь?<speed=0/>
1. Пойти налево. 3. Пойти вверх.
2. Пойти направо. 4. Пойти вниз.

Старый 04.01.2019, 22:45
deepNoise вне форума Посмотреть профиль Отправить личное сообщение для deepNoise Найти все сообщения от deepNoise
  № 28  
Ответить с цитированием
deepNoise

Регистрация: May 2018
Сообщений: 27
Цитата:
Тебе нужно написать парсер строк. В кадрах такие вещи не делают.
Я даже не знаю, что это такое) Зачем делать по другому, если всё работает?
Цитата:
Сейчас все построено так, что для каждого вопроса должно быть задано 4 варианта ответов - ни больше ни меньше.
Я просто добавил keysMap[Keyboard.NUMBER_5] = 5; и ещё один кадр в клипе, получилось уже пять вариантов ответов.
Цитата:
Брать текст из клипов - это вообще бред. И это бред вдвойне, учитывая, что сами клипы вообще по сути не используются.
Ну, эти клипы будут ещё содержать картинки и анимации. А по кадрам разбито, чтобы было легче ориентироваться.
Цитата:
Даже для самого простейшего текстового квеста тебе нужно иметь хотя бы начальный багаж знаний в используемом языке и ООП.
Я раньше изучал AS2.0, но после его перехода на версию 3.0 для меня это стал тёмный лес. Изучать заново и перестраиваться под новую версию уже не было ни желания ни времени. А основы я знаю, иначе как бы я понимал переменные и условия с if)

Цитата:
Чисто из спортивного интереса на коленке набросал
Спасибо, всё работает)
Теперь у меня вопрос, можно ли задать имя клипа с помощью значения переменной?
То есть есть такая строка:
Код AS3:
way1.gotoAndStop(keysMap[e.keyCode]);
И нужно, чтобы вместо way1 стояло значение переменной way. По логике это должно выглядеть как то так:
Код AS3:
("way"+way).gotoAndStop(keysMap[e.keyCode]);
но видимо это неправильное выражение.
Вложения
Тип файла: rar textQuestV2.rar (12.9 Кб, 26 просмотров)

Старый 05.01.2019, 00:47
RedHead90 вне форума Посмотреть профиль Отправить личное сообщение для RedHead90 Найти все сообщения от RedHead90
  № 29  
Ответить с цитированием
RedHead90

Регистрация: Apr 2018
Сообщений: 42
Цитата:
Сообщение от deepNoise Посмотреть сообщение
Зачем делать по другому, если всё работает?
А зачем люди придумали канализацию, если и кусты неплохо работают? Зачем ты вообще на AS3 перешел, если всё это и на AS2 можно реализовать?

Цитата:
Сообщение от deepNoise Посмотреть сообщение
Я просто добавил keysMap[Keyboard.NUMBER_5] = 5; и ещё один кадр в клипе, получилось уже пять вариантов ответов.
А с теми клипами, где 4 варианта что теперь будет? Они же тоже станут реагировать на нажатие 5-ки, но 5-го кадра у них нет.

Цитата:
Сообщение от deepNoise Посмотреть сообщение
А основы я знаю, иначе как бы я понимал переменные и условия с if)
Ничего ты не знаешь, Джон Сноу deepNoise. Переменные и условия - это даже не вершина айсберга. Если бы ты знал основы, то этой темы не существовало бы. Без желания учиться и перестраиваться ты далеко не уедешь. Сейчас, пока ты ставишь перед собой простые задачи, ты можешь прийти на форум и дождаться, когда тебе дадут готовое решение, чтобы тупо скопировать его в свой проект, даже не понимая в итоге до конца, как вся эта копи-паста работает. Дальше ты захочешь сделать что-то более сложное и интересное, но на форумах тебе уже никто не поможет, потому-что никто не будет тратить свои силы и время на такие вещи.

Цитата:
Сообщение от deepNoise Посмотреть сообщение
можно ли задать имя клипа с помощью значения переменной?
https://help.adobe.com/ru_RU/FlashPl...tChildByName()

Старый 07.01.2019, 02:07
deepNoise вне форума Посмотреть профиль Отправить личное сообщение для deepNoise Найти все сообщения от deepNoise
  № 30  
Ответить с цитированием
deepNoise

Регистрация: May 2018
Сообщений: 27
Почитал справку и ничего не понял. Кажется там о том, как создавать дочерние и родительские клипы, но не как создать имя клипа с переменной.
Попробовал так:
Код AS3:
var wayClip:MovieClip = new MovieClip();
wayClip.name = 'way'+way;
 
wayClip.gotoAndStop(keysMap[e.keyCode]);
text = wayClip.tf.text.replace(pattern,repl);
Выдаёт такую ошибку:
Цитата:
TypeError: Error #1010: Термин не определен и не имеет свойств.
at textQuestV2_fla::MainTimeline/on_keyDown()
Как сделать правильно?

Создать новую тему Ответ Часовой пояс GMT +4, время: 22:23.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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