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

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

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

Регистрация: Apr 2010
Сообщений: 170
По умолчанию События мышки для Sprite. Есть проблема.

Всем доброго вечера!

У меня имеется базовый класс для всех выводимых объектов:

Код AS3:
package d.game.render
{
	import d.game.map.MapObject;
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Sprite;
 
	// Объект для вывода
	public class RenderObject extends Sprite
	{
		public static const STATIC_OBJECT		:uint	= 0;
		public static const DYNAMIC_OBJECT		:uint	= 1;
 
		public var type:uint=0;										// Тип объекта
		public var desc:MapObject=null;								// Описание объекта на карте
 
		// Конструктор
		public function RenderObject(_displayObject:DisplayObject)
		{
			if(_displayObject is Bitmap)
			{
				var bitmapSource:Bitmap=_displayObject as Bitmap;
				var bitmapDuplicate:Bitmap=new Bitmap(bitmapSource.bitmapData);
 
				addChild(bitmapDuplicate);
			}
			else if(_displayObject is MovieClip)
			{
				var movieClipSource:Class=Object(_displayObject).constructor as Class;
				var movieClipDuplicate:MovieClip=new movieClipSource();
 
				addChild(movieClipDuplicate);
			}
		}
 
	}
 
}
Собственно из кода видно что туда я засовываю либо рисунок (Bitmap), либо клип (MovieClip). Каждый такой класс я подписываю на события мышки:

Код AS3:
renderDynamicObject.addEventListener(MouseEvent.MOUSE_OUT,OnMouseOutDynamicObject);
renderDynamicObject.addEventListener(MouseEvent.MOUSE_OVER,OnMouseOverDynamicObject);
И вот обработка:

Код AS3:
private function OnMouseOutDynamicObject(_event:MouseEvent):void
{
	var renderDynamicObject:RenderDynamicObject=_event.currentTarget as RenderDynamicObject;
 
	renderDynamicObject.filters=null;
}
 
private function OnMouseOverDynamicObject(_event:MouseEvent):void
{
	var renderDynamicObject:RenderDynamicObject=_event.currentTarget as RenderDynamicObject;
 
	renderDynamicObject.filters=Game.mapFilter.objectFilter;
}
Если кому интересно, то RenderDynamicObject унаследован от RenderObject:

Код AS3:
package d.game.render
{
	import d.game.map.MapDynamicObject;
	import flash.display.DisplayObject;
 
	// Вывод динамического объекта
	public class RenderDynamicObject extends RenderObject
	{
		// Конструктор
		public function RenderDynamicObject(_desc:MapDynamicObject,_displayObject:DisplayObject)
		{
			type=DYNAMIC_OBJECT;
 
			desc=_desc;
			super(_displayObject);
		}
 
	}
 
}
Думаю все уже поняли что я хочу реализовать эффект подсвечивания тех объектов, на которые навели мышкой. У меня это получилось, но получилось не так как хотелось бы.

[IMG]http://i021.***********/1202/80/f917e1f7c8c8.png[/IMG]

На рисунке пугало - это Bitmap. Я мышкой ещё не навёл на объект, а он уже подсветился. Такое ощущение что он активирует наводку даже на прозрачном месте.

Как это исправить? Чтобы он тютельку в тютельку наводил.

Старый 09.02.2012, 00:03
Inet_PC вне форума Посмотреть профиль Отправить личное сообщение для Inet_PC Посетить домашнюю страницу Inet_PC Найти все сообщения от Inet_PC
  № 2  
Ответить с цитированием
Inet_PC
 
Аватар для Inet_PC

Регистрация: Feb 2009
Адрес: Гы...поди, найди!
Сообщений: 853
Записей в блоге: 1
Думаю Вам вот это должно помочь.
__________________
http://www.chessmax.ru

Старый 09.02.2012, 13:34
s3dworld вне форума Посмотреть профиль Отправить личное сообщение для s3dworld Найти все сообщения от s3dworld
  № 3  
Ответить с цитированием
s3dworld

Регистрация: Apr 2010
Сообщений: 170
Inet_PC
Спасибо, вроде то что нужно!

Я правда не понял как его использовать. Получается что он сам наследуется от MovieClip. Вот я от Loader'а через свойство content получаю либо Bitmap, либо MovieClip. Предположим я получил Bitmap (узнать так ли это очень легко). И что дальше мне делать? Как мне из этой информации создать InteractivePNG с этой картинкой?

Добавлено через 1 час 53 минуты
Проблему решил с помощью getPixel32() для Bitmap. Теперь есть проблема с MovieClip. Опишу всё глобально...

Карта в игре изометрическая (2.5D).



При обращении к ячейке карты первым параметром я указываю номер столбца, а затем номер строки. Вывод полей идёт по простому алгоритму - перебор от столбцов к полям (конечно у меня все поля рисуются на один общий Bitmap и затем он выводится на экран). Что касается объектов (статические, динамические, монстры и NPC), то для них предусмотрен другой слой, который лежит поверх Bitmap с ячейками карты. Для вывода объектов (то есть кто поверх кого стоит) написана функция сортировки (ведь не все объекты имеют размер в 1x1 ячейки). К статическим же объектам я не применяют никаких операций, они просто выводятся и сортируются при изменении состояния мира, а так же для них я отключаю свойство mouseEnabled, чтобы они не мешали другим объектам обрабатывать события мышки. Что касается динамических объектов, то они могут быть либо подгружаемым Bitmap, либо подгружаемым SWF (то есть MovieClip). Собственно для вывода всего есть общий корень RenderObject:

Код AS3:
package d.game.render
{
  import d.game.map.MapObject;
  import flash.display.Bitmap;
  import flash.display.DisplayObject;
  import flash.display.MovieClip;
  import flash.display.Sprite;
 
  // Объект для вывода
  public class RenderObject extends Sprite
  {
    public static const STATIC_OBJECT    :uint  = 0;
    public static const DYNAMIC_OBJECT    :uint  = 1;
 
    public static const BITMAP        :uint  = 0;
    public static const MOVIE_CLIP      :uint  = 1;
 
    public var type:uint=0;                    // Тип объекта
    public var desc:MapObject=null;                // Описание объекта на карте
 
    public var graphType:uint=0;                // Тип графики
 
    public var bitmap:Bitmap=null;                // Рисунок
    public var movieClip:MovieClip=null;            // Клип
 
    // Конструктор
    public function RenderObject(_displayObject:DisplayObject)
    {
      if(_displayObject is Bitmap)
      {
        graphType=BITMAP;
 
        bitmap=new Bitmap((_displayObject as Bitmap).bitmapData);
        addChild(bitmap);
      }
      else if(_displayObject is MovieClip)
      {
        graphType=MOVIE_CLIP;
 
        var movieClipSource:Class=Object(_displayObject).constructor as Class;
        movieClip=new movieClipSource();
 
        addChild(movieClip);
      }
    }
 
  }
 
}
Каждый выводимый динамический объект является классом RenderDynamicObject:

Код AS3:
package d.game.render
{
  import d.game.Game;
  import d.game.map.MapDynamicObject;
  import flash.display.DisplayObject;
  import flash.events.MouseEvent;
 
  // Вывод динамического объекта
  public class RenderDynamicObject extends RenderObject
  {
    // Конструктор
    public function RenderDynamicObject(_desc:MapDynamicObject,_displayObject:DisplayObject)
    {
      type=DYNAMIC_OBJECT;
 
      desc=_desc;
      super(_displayObject);
    }
 
    // Увели с динамического объекта
    public function OnMouseOut(_event:MouseEvent):void
    {
      filters=null;
    }
 
    // Навели на динамический объект
    public function OnMouseOver(_event:MouseEvent):void
    {
      if(graphType==MOVIE_CLIP) filters=Game.mapFilter.objectFilter;
    }
 
    // Водим по динамическому объекту
    public function OnMouseMove(_event:MouseEvent):void
    {
      if(graphType==BITMAP)
      {
        var color:uint=bitmap.bitmapData.getPixel32(_event.localX,_event.localY);
 
        var colorAlpha:uint  = color  >>>  24      ;
        var colorRed:uint  = color  >>>  16  & 0xFF  ;
        var colorGreen:uint  = color  >>>  8  & 0xFF  ;
        var colorBlue:uint  = color      & 0xFF  ;
 
        if(colorAlpha>0)
          filters=Game.mapFilter.objectFilter;
        else
          filters=null;
      }
    }
 
  }
 
}
А теперь посмотрите на рисунок:



Обратите внимание на дерево и сундук. Это два динамических объекта с которыми можно взаимодействовать. Дерево подгружается через Loader как Bitmap, сундук - SWF (MovieClip). Что касается подсвечивания Bitmap, я с Вашей помощью разобрался. Теперь всю внимание на MovieClip...

На рисунке выше сундук будет поверх дерева (это всё верно). При наведении на сундук, он будет выделяться даже тогда, когда я навёл на его прозрачные пиксели. А вот это мне не понятно, я считал что MovieClip весь из себя интерактивный и всё умеет понимать. Как мне для него сделать так, чтобы он понимал что не нужна мне обводка при наведении на прозрачные пиксели?

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

Какие есть идеи?

Добавлено через 2 часа 29 минут
Первую проблему решил:

Код AS3:
package d.game.render
{
  import adobe.utils.CustomActions;
  import d.game.map.MapObject;
  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.display.DisplayObject;
  import flash.display.MovieClip;
  import flash.display.Sprite;
 
  // Объект для вывода
  public class RenderObject extends Sprite
  {
    public static const STATIC_OBJECT    :uint  = 0;
    public static const DYNAMIC_OBJECT    :uint  = 1;
 
    public static const BITMAP        :uint  = 0;
    public static const MOVIE_CLIP      :uint  = 1;
 
    public var type:uint=0;                    // Тип объекта
    public var desc:MapObject=null;                // Описание объекта на карте
 
    public var graphType:uint=0;                // Тип графики
 
    public var bitmap:Bitmap=null;                // Рисунок
    public var movieClip:MovieClip=null;            // Клип
 
    public var bitmapsData:Vector.<BitmapData>=null;      // Список изображений в клипе
 
    // Конструктор
    public function RenderObject(_displayObject:DisplayObject)
    {
      if(_displayObject is Bitmap)
      {
        graphType=BITMAP;
 
        bitmap=new Bitmap((_displayObject as Bitmap).bitmapData);
        addChild(bitmap);
      }
      else if(_displayObject is MovieClip)
      {
        graphType=MOVIE_CLIP;
 
        var movieClipSource:Class=Object(_displayObject).constructor as Class;
        movieClip=new movieClipSource();
 
        bitmapsData=new Vector.<BitmapData>();
 
        for(var i:uint=0;i<movieClip.totalFrames;i++)
        {
          movieClip.gotoAndStop(i);
 
          var bitmapData:BitmapData=new BitmapData(movieClip.width,movieClip.height,true,0x000000);
 
          bitmapData.draw(movieClip);
          bitmapsData.push(bitmapData);
        }
 
        movieClip.gotoAndStop(0);
 
        addChild(movieClip);
      }
    }
 
  }
 
}
Ну и обработка:

Код AS3:
// Водим по динамическому объекту
public function OnMouseMove(_event:MouseEvent):void
{
  var color:uint=0;
  var colorAlpha:uint=0;
  var colorRed:uint=0;
  var colorGreen:uint=0;
  var colorBlue:uint=0;
 
  if(graphType==BITMAP)
  {
    color=bitmap.bitmapData.getPixel32(_event.localX,_event.localY);
 
    colorAlpha  = color  >>>  24      ;
    colorRed  = color  >>>  16  & 0xFF  ;
    colorGreen  = color  >>>  8  & 0xFF  ;
    colorBlue  = color      & 0xFF  ;
 
    if(colorAlpha>0)
      filters=Game.mapFilter.objectFilter;
    else
      filters=null;
  }
  else
  {
    color=bitmapsData[movieClip.currentFrame].getPixel32(_event.localX,_event.localY);
 
    colorAlpha  = color  >>>  24      ;
    colorRed  = color  >>>  16  & 0xFF  ;
    colorGreen  = color  >>>  8  & 0xFF  ;
    colorBlue  = color      & 0xFF  ;
 
    if(colorAlpha>0)
      filters=Game.mapFilter.objectFilter;
    else
      filters=null;
  }
}
Теперь наводится как и положено. А вот вторая проблема актуальна:



Курсор на дереве, но дерево но подсвечивается, так как Flash считает что мы бродим по клипу сундука. Что делать?

Добавлено через 2 часа 54 минуты
Можно ли как-то сделать так, чтобы когда я определил что навели на прозрачный пиксель, то я как-то отменяю что ли событие и оно ищет куда я дальше попал?


Последний раз редактировалось s3dworld; 09.02.2012 в 14:02.
Создать новую тему Ответ Часовой пояс GMT +4, время: 16:27.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

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

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


 


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


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