AS3 - обнаружение, если вы нажали на объект, не нажимая кнопку мыши - PullRequest
4 голосов
/ 29 апреля 2011

Хорошо, в as3, когда вы щелкнете, будет щелкнуть объект на верхнем слое. Я хочу, чтобы кто-то нажал клавишу пробела и чтобы объекты на экране проверяли, касается ли она точки.

Итак, я впервые попробовал hittest ...

if (this.hitTest (myPoint)) { играть(); }

Теперь проблема заключалась в том, что объекты, стоящие за другими, думали, что на них "нажимали".

Потом, разочаровавшись, я воспользовался Google, ничего не смог найти, поэтому, пожалуйста, что-нибудь поможет.

Ответы [ 4 ]

5 голосов
/ 29 апреля 2011

Я думаю, что это код, который вы ищете:

stage.addEventListener(KeyboardEvent.KEY_DOWN, function(e : KeyboardEvent) : void {
    if(e.keyCode == Keyboard.SPACE) {
        var objects : Array = stage.getObjectsUnderPoint(new Point(stage.mouseX, stage.mouseY));
        if (objects.length > 0) {
            var topmost : DisplayObject = objects[objects.length-1];
            trace(topmost.name);
        }
    }
});

Ключ - это метод getObjectsUnderPoint flash.

2 голосов
/ 14 декабря 2011
DisplayObjectContainer.getObjectsUnderPoint()

Будьте внимательны getObjectsUnderPoint не возвращает DisplayObjectContainers, как показано здесь:

var mc:MovieClip = new MovieClip();
var shape:Shape = new Shape();
    shape.graphics.beginFill(0);
    shape.graphics.drawRect(0,0,5,5);
mc.addChild(shape);
var shape2:Shape = new Shape();
    shape2.graphics.beginFill(0);
    shape2.graphics.drawRect(0,0,5,5);
mc.addChild(shape2);
addChild(mc);
getObjectsUnderPoint(new Point(1,1)); // returns [object Shape],[object Shape]

Вы можете использовать свойство parent возвращенных объектов DisplayObject, чтобы найти объект DisplayObjectContainer ...

var containerBeingLocated:Sprite;

for each (var obj:DisplayObject in objectsUnderPoint) {
    if (isWithin(obj, containerBeingLocated)) {
        trace('container located');
    }
}

function isWithin ($obj:DisplayObject, $container:DisplayObjectContainer):Boolean {
    while ($obj) {
        if ($obj === $container) {
            return true;
        } else {
            $obj = $obj.parent;
        }
    }
    return false;
}
1 голос
/ 29 апреля 2011

Это отличный вопрос, для которого у меня нет готового решения. То, на какую вещь нажимают на переднем плане, является одной из тех вещей, которые вы воспринимаете как должное, когда получаете бесплатно в качестве цели MouseEvent. Самая простая часть - настроить все ваши экранные объекты для прослушивания KeyboardEvent, соответствующего нажатию клавиши пробела, и для проверки нажатия с указанием позиции мыши в это время.

Мне кажется, что остальная ваша проблема, настоящая проблема, сводится к одному определению, которое вам нужно сделать: A и B занимают одно и то же пространство экрана, которое находится впереди. Другими словами, когда у вас есть список всех объектов DisplayObject, для которых hitTest является хитом, вам нужна эта функция сравнения, чтобы отсортировать их спереди назад. Вот как я вижу, что работает:

Чтобы определить, находится ли DisplayObject A перед или позади DisplayObject B, вам необходимо проследить происхождение их списка отображения до их общего предка, а затем посмотреть на следующее поколение вниз от этого, чтобы увидеть, если - в точке где их происхождение расходится - предок объекта A находится перед или позади объекта B (т.е. их относительная глубина в контейнере общего предка). Рассмотрим дерево отображения следующим образом:

       E
      / \
     C   D
    /     \
   A       B

Е - общий предок. Чтобы определить, находится ли A позади B, вам нужно проверить, находится ли C позади D, что означает, что вам нужно проверить глубины C и D в контейнере E (с помощью DisplayObjectContainer.getChildIndex (child)). Очевидно, что в сложном пользовательском интерфейсе общим предком может быть много поколений назад, но он всегда будет, даже если это сцена.

EDIT:

Как я упустил очевидное ?! Вы не хотите нажимать кнопку мыши, но не сказали, что не можете использовать MouseEvents вообще, верно? Используйте событие ROLL_OVER или MOUSE_OVER, чтобы отследить, что вы перевернули, и HitTest с этим объектом [шлепает по лбу в стыде].

0 голосов
/ 29 апреля 2011

Хороший вопрос .. Я посмотрю вокруг, но сейчас все, о чем я могу думать, - это иметь массив, содержащий все ваши объекты (добавленные в том же порядке, как они были в DisplayList), а затем перебирать в обратном направлениичтобы найти первое столкновение.

Например (и простите за очень ленивый пример):

    var objs:Array = [];

/**
 * Returns an object at a point with the highest depth
 * @param at A Point to check at
 */
function checkForHighest(at:Point):DisplayObject
{
    var i:uint = objs.length-1;
    for(i; i>0; i--)
    {
        var j:DisplayObject = DisplayObject(objs[i]);

        if(objs.hitTest(at)) return objs[i];
    }

    return null;
}

Первый найденный объект DisplayObject будет самым высоким в DisplayList.

...