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

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

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 01.12.2011, 19:40
PainKiller вне форума Посмотреть профиль Отправить личное сообщение для PainKiller Найти все сообщения от PainKiller
  № 1  
Ответить с цитированием
PainKiller
 
Аватар для PainKiller

блогер
Регистрация: Sep 2011
Адрес: Москва
Сообщений: 533
Записей в блоге: 4
Attention Задача с перебором двух массивов

Начну с описания задачи. Имеется 18 предметов (класс Value), которые надо расставить по 18 гнездам (класс Target).Соответственно, предметы содержатся в массиве termValueArray, а гнезда в массиве targetsArray. Когда предмет встает в гнездо, справа от него появляется галочка (метод checkShow принимает булево значение и отрисовывает галочку). Когда предмет вынимается из гнезда или переставляется в др. гнездо галочка должна исчезать и появляться только у занятого предметом гнезда. Перетаскивание предметов осуществляется драг-энд-дропом, при отпускании мыши (событие MOUSE_UP) в классе Value диспатчится событие, по которому начинается проверка занятых и свободных гнезд. Проблема как раз и возникла с алгоритмом этой проверки. Поначалу я думал, что задача достаточно тривиальная, и с ходу написал примерно такой код (это только одна из моих многочисленных версий):

Код AS3:
function checkHit(e:Event):void
{
    for (var j:Number = 0; j < termValueArray.length; j++)
			{
				for (var i:Number = 0; i < targetsArray.length; i++)
				{
					if (termValueArray[i].hitTestObject(targetsArray[j]))
					{
						trace("Hitting");
						termValueArray[i].rank = targetsArray[j].targetRank;
						termValueArray[i].x = targetsArray[j].x;
						termValueArray[i].y = targetsArray[j].y;
						targetsArray[j].checkShow = true;
						trace (targetsArray[j].checkShow + " ветвь if" + " i=" + i + " j=" + j);
					}
					else
					{
						trace (targetsArray[j].checkShow + " ветвь else" + " i=" + i + " j=" + j);
						if (targetsArray[j].checkShow)
						{
						       targetsArray[j].checkShow = false;
						}
 
					}
 
				}
Естественно этот код не работает т.к. отрисованная галочка закрывается при последующих прохождениях цикла. Если же вывести код закрытия галочки за цикл с i то она все равно закрывается. Я ломал над этой задачей голову полдня, честно говоря уже ничего не соображаю, начал приходить к выводу, что перебором двух массивов эту задачу решить нельзя вообще. Видимо надо писать какой то внешний контроллер, но он опять же должен проверять занятые и свободные гнезда, и опять же это надо делать перебором! В общем буду рад хоть какому намеку на пути решения этой задачи.

Старый 01.12.2011, 20:08
KBAC вне форума Посмотреть профиль Отправить личное сообщение для KBAC Найти все сообщения от KBAC
  № 2  
Ответить с цитированием
KBAC
 
Аватар для KBAC

Регистрация: Jan 2006
Адрес: Москва (Нижний Новгород)
Сообщений: 229
Записей в блоге: 1
Отправить сообщение для KBAC с помощью Skype™
Можно сделать ссылку на объект Target у объекта Value если они соприкасаются.
И по идее если перемещение делается drag and drop'ом, то e.target будет как раз нужный для проверки объект. Тогда достаточно одного цикла:

Код AS3:
private function onMouseUp(e:MouseEvent):void 
{
	if (!e.traget is Value) return;
	var item:Value = e.target as Value;
 
	if (item.target) {
		item.target.checkShow = false;
		item.target = null;
	}
 
	for (var i:int = 0; i < targetsArray.length; ++) 
	{
		if (item.hitTestObject(targetsArray[i]))
		{
			trace("Hitting");
 
			item.target = targetsArray[i];
			item.target.checkShow = true;
 
			item.rank = targetsArray[i].targetRank;
			item.x = targetsArray[i].x;
			item.y = targetsArray[i].y;
 
                        //чтобы реагировало только на один объект Target 
                        return;
		}			
	}
}
__________________
Будь проще.


Последний раз редактировалось KBAC; 01.12.2011 в 20:14.
Старый 01.12.2011, 20:45
PainKiller вне форума Посмотреть профиль Отправить личное сообщение для PainKiller Найти все сообщения от PainKiller
  № 3  
Ответить с цитированием
PainKiller
 
Аватар для PainKiller

блогер
Регистрация: Sep 2011
Адрес: Москва
Сообщений: 533
Записей в блоге: 4
По моему тут сумбур небольшой - событие onMouseUp наступает в классе Value, но идея понятна, насчет e.target я тоже думал, но ничего хорошего не придумал, попробую ваш код спасибо.

Старый 01.12.2011, 21:00
KBAC вне форума Посмотреть профиль Отправить личное сообщение для KBAC Найти все сообщения от KBAC
  № 4  
Ответить с цитированием
KBAC
 
Аватар для KBAC

Регистрация: Jan 2006
Адрес: Москва (Нижний Новгород)
Сообщений: 229
Записей в блоге: 1
Отправить сообщение для KBAC с помощью Skype™
Основная суть такая:
- делать проверку только для перетаскиваемого объекта
- сбрасывать галочку у гнезда в котором он лежал, если он лежал в каком-то из гнёзд.
- проверять положили ли объект куда-нибудь.

Если проверяете на MOUSE_UP в самом Value, то можете в метод проверки передавать ссылку именно на этот объект.
__________________
Будь проще.

Старый 01.12.2011, 21:04
PainKiller вне форума Посмотреть профиль Отправить личное сообщение для PainKiller Найти все сообщения от PainKiller
  № 5  
Ответить с цитированием
PainKiller
 
Аватар для PainKiller

блогер
Регистрация: Sep 2011
Адрес: Москва
Сообщений: 533
Записей в блоге: 4
только в самом Value массив targetsArray не объявлен. Мне кажется надо просто сохранять в Value ссылку на e.target, и перебирать массив уже в основном классе. Попробую, отпишусь о результатах.

Добавлено через 3 часа 32 минуты
Пока не пробовал кодить, займусь этим завтра, но пока я думал над использованием e.target мне начало казаться что этот метод не сработает. Какой то бред получается, событие диспатчит экземпляр Value и он сам на себя ссылку сохраняет? А потом есть же другие предметы, и они тоже могут занимать на момент проверки гнезда - по любому надо проверять 2 массива. Хотя есть еще идея нечто подобное сделать с dropTarget

Все решил проблему. Всем спасибо за помощь :-). В общем развел выставление галочки и стирание её по двум событиям (одно на MOUSE_UP другое на MOUSE_DOWN)
Вот итоговый код, вроде все работает как надо:
Код AS3:
function checkUP(e:Event):void
		{
			if (! e.target is Value)
			{
				return;
			}
			var item:Value = e.target as Value;
			for (var j:Number = 0; j < targetsArray.length; j++)
			{
				if (item.rank == targetsArray[j].targetRank)
				{
					trace (item.rank +" " + targetsArray[j].targetRank)
					if (targetsArray[j].checkShow)
					{
						targetsArray[j].checkShow = false;
						trace (targetsArray[j].checkShow + " ветка UP" + " j=" + j);
						item.rank = null;
					}
				}
			}
		}
		function checkHit(e:Event):void
		{
			if (! e.target is Value)
			{
				return;
			}
			var item:Value = e.target as Value;
			for (var j:Number = 0; j < targetsArray.length; j++)
			{
				if (item.hitTestObject(targetsArray[j]))
				{
					trace("hitting");
					item.rank = targetsArray[j].targetRank;
					item.x = targetsArray[j].x;
					item.y = targetsArray[j].y;
					targetsArray[j].checkShow = true;
					trace (targetsArray[j].checkShow + " ветка Hit" + " j=" + j);
				}
 
			}
 
 
		}


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

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

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


 


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


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