PDA

Просмотр полной версии : Как сделать функцию для нескольких объектов?


_JOKER_
27.02.2011, 15:04
Есть у меня небольшая функция, с помощью которого можно двигать объект и если передвинуть его в определённую точку и отпустить лкм - он там остановится, а если отпустить лкм в любом другом месте - возвратится назад
так вот, этих точек и объектов у меня несколько. Как сделать чтоб эта функция применялась к сразу нескольким функциям и объектам? Например чтоб разные объекты можно было оставить в разных точках
сам код:
import fl.transitions.Tween;
import fl.transitions.easing.*;

var place = new Array()
place[0] = placeLamp
place[1] = placeAmpermetr
place[2] = placeVoltmetr

place[0].visible = !visible
place[1].visible = !visible
place[2].visible = !visible

var moveBackX: Tween;
var moveBackY: Tween;

var obj = new Array
obj[0] = lamp
obj[1] = ampermetr
obj[2] = voltmetr

var point = new Array()
point[0] = point1
point[1] = point2
point[2] = point3
point[3] = point4

lamp.addEventListener(MouseEvent.MOUSE_DOWN, dragF);
stage.addEventListener(MouseEvent.MOUSE_UP, backF);

function dragF(e:MouseEvent):void
{
lamp.startDrag();
}

function backF (e:MouseEvent):void
{
if (point1.hitTestPoint(lamp.x, lamp.y))
{
lamp.stopDrag();
var lampStopX = new Tween(lamp, "x", Strong.easeOut, lamp.x, point1.x, 0.5, true)
var lampStopY = new Tween(lamp, "y", Strong.easeOut, lamp.y, point1.y, 0.5, true)
}
else
{
lamp.stopDrag();
moveBackX = new Tween(lamp, "x", Strong.easeOut, lamp.x, placeLamp.x, 0.5, true)
moveBackY = new Tween(lamp, "y", Strong.easeOut, lamp.y, placeLamp.y, 0.5, true)
}

}
исходник (http://*********/30576361)

tsarapkabel
27.02.2011, 15:33
Вешай слушатель события на все объекты
lamp.addEventListener(MouseEvent.MOUSE_DOWN, dragF);
ampermetr.addEventListener(MouseEvent.MOUSE_DOWN, dragF);
voltmetr.addEventListener(MouseEvent.MOUSE_DOWN, dragF);
Потом в функции dragF делай event.target.нужноеДействие.

_JOKER_
01.03.2011, 01:35
tsarapkabel, спасибо, получилось =)
теперь я хочу сделать, чтоб не только для lamp действовало возвращение к своему месту, а и для других объектов
function dragF(e:MouseEvent):void
{
e.target.startDrag();
}

function backF (e:MouseEvent):void
{
if (point1.hitTestPoint(e.target.x, e.target.y))
{
e.target.stopDrag();
var lampStopX = new Tween(e.target, "x", Strong.easeOut, e.target.x, point1.x, 0.5, true)
var lampStopY = new Tween(e.target, "y", Strong.easeOut, e.target.y, point1.y, 0.5, true)
}
else
{
e.target.stopDrag();
moveBackX = new Tween(e.target, "x", Strong.easeOut, e.target.x, place.x, 0.5, true)
moveBackY = new Tween(e.target, "y", Strong.easeOut, e.target.y, place.y, 0.5, true)
}

}
то есть чтоб для каждого объекта свой place.x и place.y
и ещё хочу, чтоб эти объекты можно было лепить не только к point1, а и к другим point-ам

nOobCrafter
01.03.2011, 01:48
я думаю говорить про ооп и прочишь штуки бесполезно?
например можно как то так:
function backF (e:MouseEvent):void
{
switch (e.target) // можно так же сравнивать по инстанснеймам, как вам там удобнее
{
case lamp:
useLamp();
break;
case ampermetr:
useAmpermetr();
break;
case voltmetr:
useVoltmetr();
break;
}
}

private function useLamp():void
{
lamp.stopDrag();
// new Tween(lamp, "x", Strong.easeOut, lamp.x, point1.hitTestPoint(lamp.x, lamp.y) ? point1.x : place.x, 0.5, true);
// new Tween(lamp, "y", Strong.easeOut, lamp.y, point1.hitTestPoint(lamp.x, lamp.y) ? point1.y : place.y, 0.5, true);
// можно в одну строчку как выше, но пример ниже нагляднее, хотя смысл тот же

if (point1.hitTestPoint(lamp.x, lamp.y))
{
new Tween(lamp, "x", Strong.easeOut, lamp.x, point1.x, 0.5, true);
new Tween(lamp, "y", Strong.easeOut, lamp.y, point1.y, 0.5, true);
} else {
moveBackX = new Tween(lamp, "x", Strong.easeOut, lamp.x, place.x, 0.5, true)
moveBackY = new Tween(lamp, "y", Strong.easeOut, lamp.y, place.y, 0.5, true)
}
}

то есть для каждого обьекта пишете свою функцию и все.

_JOKER_
08.03.2011, 01:44
nOobCrafter, тогда stopDrag не работает, lamp.addEventListener не подключается к useLamp()
P.S.: у меня проблемы с интернетом, часто на сайт заходить не получается

expl
08.03.2011, 02:00
function backF (e:MouseEvent):void
{
switch (e.target) // можно так же сравнивать по инстанснеймам, как вам там удобнее
{
case lamp:
useLamp();
break;
case ampermetr:
useAmpermetr();
break;
case voltmetr:
useVoltmetr();
break;
}
}


Это называется "что-то код слишком простой - давайте свичей налепим - свичи же это красиво!"

nOobCrafter
08.03.2011, 03:36
expl по вашему if|else лучше?

expl
08.03.2011, 13:38
между if и switch нет принципиальной разницы


switch (e.target) // можно так же сравнивать по инстанснеймам, как вам там удобнее
{
case lamp:
useLamp();
break;
case ampermetr:
useAmpermetr();
break;
case voltmetr:
useVoltmetr();
break;
}


Что тут происходит? Мы вместо того, чтобы подписать на каждую кнопку свое УНИКАЛЬНОЕ действие, подписываем один слушатель с определением какая кнопка сработала. Зачем? У нас не было лишней логики, теперь мы ее добавили - можно себя поздравить

nOobCrafter
08.03.2011, 14:39
я развил код из второго поста, мне именно такой подход не очень нравится, но имхо это лучше чем 100500 левых хендлеров. С учетом того что действия вообщем то однотипные можно определить динамические данные и дальше метода backF ходить не придется. Пример ниже:
import fl.transitions.Tween;
import fl.transitions.easing.*;

var moveBackX : Tween;
var moveBackY : Tween;
var pointsArr :Array = [point1, point2, point3, point4];
var placeArr :Array = [placeLamp, placeAmpermetr, placeVoltmetr];
var len :int = placeArr.length;
for (var i:int = 0; i < len; i++)
placeArr[i].visible = !visible; // я правда не понял зачем

var objectsArr :Array = [lamp, ampermetr, voltmetr];
len = objectsArr.length;
for (i = 0; i < len; i++)
objectsArr[i].addEventListener(MouseEvent.MOUSE_DOWN, onObjectMouseDownHandler);

stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUpHandler);

function onObjectMouseDownHandler(e:MouseEvent):void
{
e.currentTarget.startDrag();
}

function onStageMouseUpHandler(e:MouseEvent):void
{
var obj:Sprite = e.currentTarget as Sprite;
var index:int = objectsArr.indexOf(obj); // т.к. кодите в иде, то индекс можно было сохранить как св-во мувика, он всеравно динамический, но можно и так.
if (index == -1) return;
var point:Sprite = pointsArr[index]; // спрайты или что там?
var place:Sprite = placeArr[index]; // спрайты или что там?

new Tween(obj, "x", Strong.easeOut, obj.x, point.hitTestPoint(obj.x, obj.y) ? point.x : place.x, 0.5, true);
new Tween(obj, "y", Strong.easeOut, obj.y, point.hitTestPoint(obj.x, obj.y) ? point.y : place.y, 0.5, true);

obj.stopDrag();
}
из всего этого видно что данный подход имеет очевидные плюсы, а вам мало того что пришлось бы руками подписываться на каждый хендлер, так еще и описывать его.

expl
08.03.2011, 14:51
Если для 100500 объектов нужны РАЗНЫЕ действия - нужно задуматься, а то ли вообще мы делаем?

nOobCrafter
08.03.2011, 15:04
Мы вместо того, чтобы подписать на каждую кнопку свое УНИКАЛЬНОЕ ( == РАЗНЫЕ?) действие, подписываем один слушатель с определением какая кнопка сработала. Зачем? У нас не было лишней логики, теперь мы ее добавили - можно себя поздравить
Задумайтесь. Пользы от ваших постов не вижу, аргументируйте пожалуйста свои претензии.

willis83
08.03.2011, 15:12
можно просто создать базовый класс который будет содержать в себе основные функции и слушатели по перетаскиванию, и от него расширять лампу, амперметр и др.

expl
08.03.2011, 15:29
Задумайтесь. Пользы от ваших постов не вижу, аргументируйте пожалуйста свои претензии.
Не, претензии были бы если бы этот код достался мне в поддержу, а так это просто мнение.

Исходник, который является предметом топика, к сожалению, открыть не могу, поэтому на примитивных примерах:
Способ 1

button0.addEventListener(MouseEvent.CLICK, onSomeButtonClick)
button1.addEventListener(MouseEvent.CLICK, onSomeButtonClick)
function onSomeButtonClick(event:Event):void {
делаемОбщее;
switch (event.target)
{
case button0:
делаем одно; break;
case button1:
делаем другое; break;
}
}


Достоинтва:
- одна функция вместо 2-х
Недостатки:
- появилась услованая логика - источник багов (например очень просто вместо button1 написать button3, на которую вообще этот слушатель не навешан)
- допустим мы хотим расширить класс и добавить еще одну кнопку, по нажатии на которую должно "делаться общее" - придется лезть в свитч базового класса (или, еще веселее - копипастить его весь в клас-потомок и дописывать недостающее);
- допустим мы хотим поменять слушатель button1 на другой, если продолжать следовать этому подходу - мы что флаг будем делать? и в свиче еще ифом разбирать?
(утрирую конечно, можно так же отписать и подписать другой слушатель с другими свичами)
- нельзя перегрузить действие одной кнопки
(на самом деле можно, если кусок свича в функцию вынести)

Способ 2:
Недостатки:
- 2 функции вместо одной
- ?

button0.addEventListener(MouseEvent.CLICK, onButton0Click)
button1.addEventListener(MouseEvent.CLICK, onButton1Click)
function onButton0Click(event:Event):void {
doCommon();
делаем одно
}
function onButton2Click(event:Event):void {
doCommon();
делаем другое
}
function doCommon():void { делаем общее; }