Просмотр полной версии : Перемещение пользовательского курсора поверх всех объектов на сцене
Vansimar
23.09.2011, 15:27
у меня есть класс package src{
import flash.display.MovieClip;
import flash.display.*;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.ui.Mouse;
public class Cursor extends MovieClip {
private var cursor:MovieClip;
public function Cursor( _stage:DisplayObjectContainer, _cursor:MovieClip )
{
cursor = _cursor;
addChild( cursor );
_stage.addEventListener( Event.MOUSE_LEAVE, cursorHide );
_stage.addEventListener( MouseEvent.MOUSE_MOVE, cursorFollow );
Mouse.hide();
}
private function cursorHide( evt:Event ):void
{
//Mouse.hide();
cursor.visible = false;
}
private function cursorFollow( evt:MouseEvent ):void
{
if ( !cursor.visible ) cursor.visible = true;
cursor.x = stage.mouseX;
cursor.y = stage.mouseY;
evt.updateAfterEvent();
}
}
} как мне сделать чтоб мой курсор был выше всех объектов в списке отображения ,а то он находится за другими объектами
Для справки в 10.2 встроенный курсор можно внедрять непосредственно через механизм курсора операционной системы
MouseCursorData (http://help.adobe.com/ru_RU/FlashPlatform/reference/actionscript/3/flash/ui/MouseCursorData.html)
Поиск на сайте этом есть... http://www.flasher.ru/forum/showthread.php?t=158990&highlight=%EA%F3%F0%F1%EE%F0
Добавлено через 5 минут
Для справки в 10.2 встроенный курсор можно внедрять непосредственно через механизм курсора операционной системы
MouseCursorData
Имхо - Как то не очень, только 32х32, FP версия больше 10.2, еще и устройством может не поддерживаться (Mouse.supportsNativeCursor)
допишите обработчик Event.ENTER_FRAME и в нём addChild( cursor );, тогда курсор всё время будет подниматься наверх в дисплей листе.
Добавлено через 1 минуту
в принципе можно это написать и в вашем cursorFollow(evt:MouseEvent), но если курсор двигаться не будет
а на сцену будут добавляться символы то, вполне возможно, что он опять скроется в нижележащих слоях.
допишите обработчик Event.ENTER_FRAME и в нём addChild( cursor );, тогда курсор всё время будет подниматься наверх в дисплей листе.
Прощай производительность((. Так делать не стоит. Я же привел ссылку, там черным побелому, либо 2 контейнера, либо переписать addChild, либо Event.ADDED
gloomyBrain
23.09.2011, 16:44
допишите обработчик Event.ENTER_FRAME и в нём addChild( cursor );, тогда курсор всё время будет подниматься наверх в дисплей листе.
Ну что за бред, а?
@Автор темы
Создайте отдельный Sprite для курсора и отдельный спрайт для всего остального. Положите контейнер для курсора выше контейнера для всего остального. Добавьте курсор в его собственный верхний контейнер. Ну а все остальное - в нижний.
Согласен, нужно просто добавить курсор в stage.
Прощай производительность((...
Ну что за бред, а?.
Ну всё, блин! Флешка посадит проц, однозначно, тут же!!! Да? Так что ли?
Может не будем драматизировать?
Хотя, господа, правы. Предложенный мной вариант самый некрасивый из этих трех.
Не подумал...
Еще как посадит(. А потом люди удивляются почему у одних 3D во флеше не тормозит, а других баннеры проц подвешивают, и не стоит забывать про мобильные устройства...
Еще как посадит(. А потом люди удивляются почему у одних 3D во флеше не тормозит, а других баннеры проц подвешивают, и не стоит забывать про мобильные устройства...
Что делает флешка когда получает команду добавить уже добавленный объект в контейнер? - Ничего о_О (если не требуется перемещения в дисплей листе - что нам и нужно, в случае когда объект не
на самом верху).
И, что вы тогда тут раззадорились по этом поводу?
Да все норм, просто я чуток по другому думаю:
Каждый кадр будет создаваться лишний Event;
В массиве подписчиков на ENTER_FRAME будет лишний никому не нужный элемент;
Лишний вызов обработчика onFrame;
Лишний вызов addChild;
А так же лишняя проверка внутри addChild.
А может и еще хуже, но это уже все уже похоже на флейм и к теме не особо относится...
Всё это так. Вы правы. И тем не менее это совершенно не критично для производительности, если только
вы не пишете приложение требующее жесткого контроля за ресурсами. Но, если бы топикстартер писал подобное то "новичковых" вопросов уже не задавал бы.
Vansimar
23.09.2011, 17:58
что то ничего не получается,то курсор перестает работать как курсор(не кликает) то просто пропадает
Не кликает? Может для курсора выставить mouseChildren и mouseEnabled в false? Или даже для слоя на котором курсор лежит, если конечно там кроме него ничего...
Добавлено через 2 минуты
Всё это так. Вы правы. И тем не менее это совершенно не критично для производительности, если только
вы не пишете приложение требующее жесткого контроля за ресурсами. Но, если бы топикстартер писал подобное то "новичковых" вопросов уже не задавал бы.
Согласен:)
Vansimar
23.09.2011, 18:23
а насчет положить курсор в контейнер,и все остальное в другой контейнер, у меня на сцене просто графика лежит вся в мувике,потом я создаю программно объекты курсора и других персонажей по которым мне нужно кликать, я вот тут не понял куда в какие контейнеры засовывать
графику (или что там? символ) изображающую курсор держите в мувике отдельно, над слоем (DisplayObjectContainer, это Sprite() или MovieClip()) содержащим все остальное. На контейнер с содержимым вешаете слушатель клика, его свойство target будет указывать на интеракт. объект по которому кликнули.
У вас так получается?
Vansimar
23.09.2011, 19:11
я не понял как это сделать( "На контейнер с содержимым" содержимым графику фона? и где нужно вешать событие клика,а интеракт это что?
я делаю проще
setChildAt(cursor,numOfChildren-1);
Добавлено через 1 минуту
допишите обработчик Event.ENTER_FRAME и в нём addChild( cursor );, тогда курсор всё время будет подниматься наверх в дисплей листе.
Добавлено через 1 минуту
в принципе можно это написать и в вашем cursorFollow(evt:MouseEvent), но если курсор двигаться не будет
а на сцену будут добавляться символы то, вполне возможно, что он опять скроется в нижележащих слоях.
а ето вопше бред!!!
я не понял как это сделать( "На контейнер с содержимым" содержимым графику фона? и где нужно вешать событие клика,а интеракт это что?
Посмотрите этот класс (на словах трудновато понятно объяснить),
примерно нужно как здесь (основное, там в методе init()):
package
{
import flash.display.MovieClip;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.ui.Mouse;
[SWF(width="600", height="500", frameRate="30")]
public class SeparateCustomMouseExample extends Sprite
{
/**-------------------------------------------------------------------------------
*
* V A R I A B L E ' S
*
* --------------------------------------------------------------------------------
*/
//{
private var _containSimbols:Sprite;
private var _mouseSimbol:Sprite;
private var _dragableObject:MovieClip;
//}
/**-------------------------------------------------------------------------------
*
* P U B L I C
*
* --------------------------------------------------------------------------------
*/
//{
public function SeparateCustomMouseExample()
{
if(stage)init()
else this.addEventListener(Event.ADDED_TO_STAGE, init)
}
//}
/**-------------------------------------------------------------------------------
*
* P R I V A T E
*
* --------------------------------------------------------------------------------
*/
//{
private function init(e:Event = null):void
{
this.removeEventListener(Event.ADDED_TO_STAGE, init);
/**
* Сейчас опеределяем структуру дисплей листа
*/
///создаем контейнер для отображаемых объектов
///(но не укзателя)
_containSimbols = new Sprite();
///добавляем его на сцену первым
this.addChild( _containSimbols );
///добавляем в него символы
var simbolA:MovieClip = createMovieClip();
var simbolB:MovieClip = createMovieClip();
var simbolC:MovieClip = createMovieClip();
_containSimbols.addChild( simbolA );
_containSimbols.addChild( simbolB );
_containSimbols.addChild( simbolC );
///это контейнер в который помещаем
///графику заменяющую системный указатель( курсор )
_mouseSimbol = new Sprite();
///ВАЖНО! Отключаем интерактивность
///символа который заменяет мышку!
_mouseSimbol.mouseEnabled = false;
_mouseSimbol.mouseChildren = false;
var simbolMouse:Shape = createMouseGraphics();
///заполняем контейнер предназначеный
///для замены указателя какой-то графикой
_mouseSimbol.addChild( simbolMouse );
///прячем системный
Mouse.hide();
///добавляем свой курсор (обратите внимание - вторым,
///после контейнера с прочим содержимым
this.addChild( _mouseSimbol);
///слушаем движение указателя и перемещаем за ним
///наш созданный указатель
stage.addEventListener(MouseEvent.MOUSE_MOVE, moveMouseHandler);
///слушаем клики по контейнеру с интерактивным содержимым (это могут быть другие мувики
///или спрайты)
_containSimbols.addEventListener(MouseEvent.MOUSE_DOWN, downMouseHandler);
}
/**
* Тут слушаем перемещение указателя
* и перемещаем наш символ, который его
* зменяет.
* @param e
*/
private function moveMouseHandler(e:MouseEvent):void
{
_mouseSimbol.x = e.stageX;
_mouseSimbol.y = e.stageY;
}
/**
* Тут слушаем нажатие мышью (указателем)
* и делаем выводы :)
* @param e
*/
private function downMouseHandler(e:MouseEvent):void
{
_containSimbols.removeEventListener(MouseEvent.MOUSE_DOWN, downMouseHandler);
_dragableObject = MovieClip(e.target);
var rect:Rectangle = new Rectangle( 0, 0, stage.stageWidth - _dragableObject.width, stage.stageHeight -_dragableObject.height );
_dragableObject.startDrag( false, rect);
stage.addEventListener(MouseEvent.MOUSE_UP, upMouseHandler);
stage.addEventListener(Event.MOUSE_LEAVE, upMouseHandler );
}
/**
* Если пользователь отпустил указатель, или указатель
* вышел за пределы сцены прекращаем таскать объект
* вновь устанавливем слушателя на захват объекта.
* @param e
*/
private function upMouseHandler(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, upMouseHandler);
stage.removeEventListener(Event.MOUSE_LEAVE, upMouseHandler );
_containSimbols.addEventListener(MouseEvent.MOUSE_DOWN, downMouseHandler);
_dragableObject.stopDrag();
}
/**-------------------------------------------------------------------------------
*
* Здесь делаем графику, это не важно.
*
* --------------------------------------------------------------------------------
*/
private function createMouseGraphics():Shape
{
var mouseSimbol:Shape = new Shape();
with ( mouseSimbol.graphics )
{
beginFill( 0x000000 );
drawCircle( 0, 0, 10 );
endFill();
}
return mouseSimbol;
}
private function createMovieClip():MovieClip
{
var movie:MovieClip = new MovieClip();
var color:uint = Math.random() * 0xFFFFFF;
var size:int = Math.random() * 100 + 30;
with ( movie.graphics )
{
beginFill( color );
drawRect( 0, 0, size, size);
endFill();
}
return movie;
}
//}
}
}
Добавлено через 2 минуты
Пример рабочий. Можете привязать его к новому fla и запустить.
Добавлено через 5 минут
а ето вопше бред!!!
Да. Это была неудачная мысль :).
А вы в самом деле так лепите как написали?
gloomyBrain
24.09.2011, 03:09
@wolhw
я делаю проще
Это ровно то же самое, что написать addChild();
Vansimar
24.09.2011, 11:28
ребят,я чуть позже скину мой исходничок,посмотрите пожалуйста его
Vansimar
24.09.2011, 12:02
Посмотрите пожалуйста,что тут нужно исправить
Что делает флешка когда получает команду добавить уже добавленный объект в контейнер? - Ничего о_О (если не требуется перемещения в дисплей листе - что нам и нужно, в случае когда объект не
на самом верху).
Странно, но эксперименты показали, что данный код заставляет перерисовывать участок экрана с объектом
(даже если индекс ребенка не меняется, и не смотря на то, что событие ADDED _не_ посылается):
addChild(child);
А данный, только если меняется индекс:
if (getChildIndex(child) != numChildren - 1)
{
addChild(child);
}
Vansimar
24.09.2011, 12:23
так как мне исправить ситуацию?
Ну вот так уже получше будет
Vansimar
24.09.2011, 12:44
Спасибо большое!вы лучшие!
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.