【问题标题】:AS3 return dropped object to initial locationAS3 将放置的对象返回到初始位置
【发布时间】:2013-08-08 20:24:53
【问题描述】:

我正在使用来自http://hub.tutsplus.com/tutorials/create-a-drag-and-drop-puzzle-in-actionscript-30--active-2920 的代码来制作拖放装饰游戏。我试图做到这一点,以便当拖放的对象被拖出目标位置(在我的例子中是形状的轮廓)时,它会回到初始位置......基本上是反转拖放。我一直在搞乱真正的随机代码,到目前为止,这条线最接近我想要的,但我认为代码不正确,而且它也没有返回到初始位置,它只是在舞台的一侧.

所以,我在 stopDragObject 中添加了 else if 行,它使对象从目标位置移除,但它随机移动到舞台的一侧,而不是初始位置:

private function stopDragObject(evt:MouseEvent):void {
        if (evt.target.hitTestObject(getChildByName(evt.target.name + "Target"))) {
            evt.target.x = getChildByName(evt.target.name + "Target").x;
            evt.target.y = getChildByName(evt.target.name + "Target").y;
            
        }  else if (evt.target.x = null) {
            evt.target.x = xPos;
            evt.target.y = yPos;
        }
        
        evt.target.stopDrag();
    }

已解决

在阅读了下面的课程后,我得到了这个结果,并且效果很好! (不完全像课程那样,但至少它有效......)

private function stopDragObject(evt:MouseEvent):void {
        if (evt.target.hitTestObject(getChildByName(evt.target.name + "Target"))) {
            evt.target.x = getChildByName(evt.target.name + "Target").x;
            evt.target.y = getChildByName(evt.target.name + "Target").y;
            
        }  else {
            evt.target.x = getChildByName(evt.target.name + "Int").x;
            evt.target.y = getChildByName(evt.target.name + "Int").y;
        }
        
        evt.target.stopDrag();
    }
    

我添加了一个初始对象,因此该对象只能位于目标或初始位置:)

【问题讨论】:

  • 要将问题标记为已解决,您需要在提供的答案下按“勾号”,使您的问题得到解决(如果有)。我看到有这样一个答案。

标签: actionscript-3 flash drag-and-drop


【解决方案1】:

我会尽量教不提供代码。

让我们画两个矩形:

var s1:Sprite = new Sprite()
var s2:Sprite = new Sprite()
with (s1)
{
    graphics.beginFill(0xfcaaaa, .7)
    graphics.drawRect(0, 0, 400, 400)
    graphics.endFill()
}
with (s2)
{
    graphics.beginFill(0x00aaaa, .7)
    graphics.drawRect(0, 0, 30, 30)
    graphics.endFill()
}
addChild(s1)
addChild(s2)

是不是很简单?您会看到s1s2 大得多(尺寸:400, 400 vs 30, 30)现在将s2 放在我们大s1 的中心:

s2.x = 200;
s2.y = 200;

我们将使用s1 作为s2 移动的边界。

此代码是拖动我们的s2矩形(Sprite)的最简单解决方案:

s2.addEventListener(MouseEvent.MOUSE_DOWN, onDown)
s2.addEventListener(MouseEvent.MOUSE_UP, onUp)

function onDown(e:MouseEvent):void
{
    (e.currentTarget as Sprite).startDrag();
}

function onUp(e:MouseEvent):void
{
    (e.currentTarget as Sprite).stopDrag();
}

现在,如果Sprite s2 仍然位于Sprite s1 的区域内,则将Sprite 返回到起始位置的基本解决方案:hitTestObject 将返回true。更多有用的功能here。让我们检查一下。以这种方式更改onUp函数:

function onUp(e:MouseEvent):void
{
    var s:Sprite = (e.currentTarget as Sprite);
    s.stopDrag();
    if (!s.hitTestObject(s1))
    {
        s.x = 200;
        s.y = 200;
    }
}

您会看到,现在s2 如果从s1 的区域中被拖出,则会返回到起始位置。


现在是主要部分:

如果无法预测物体的起始位置怎么办?现在,当我们知道如何处理已知坐标时,这就是挑战。我假设存在此功能的几种实现。最好的方法之一是设置附加参数,例如startingXstartingY 用于开始拖动时的拖动对象。例如。在我们的示例中,当 onDown 函数被调用时。我猜你在处理Sprites 或MovieClips 并且没有能力这样做。

让我们换一种方式使用Dictionary 对象。 Dictionary 是某种传统的Hash Map,能够使用对象作为键。

哈希映射是一种存储,您可以在其中放置由您提供的键映射的任何值。在 actionscript 3 中,我们将 Object 作为 Hash Map 的有限实现。为什么要使用它?简而言之,因为它简单快捷。但是对于Object,我们不能使用其他Objects作为键,只能使用字符串整数等。

var sites:Object = new Object();
sites['stackoverflow'] = "http://stackoverflow.com/"
trace(sites.stackoverflow) // outputs-> http://stackoverflow.com/

使用Dictionary,我们可以使用对象作为键。 让我们创建它:

var startCoordinates:Dictionary = new Dictionary();

要保存坐标,我们需要xy 属性。


仅供参考:new Object() 相当于 {}

var capitals:Object = new Object();
capitals['Italy'] = 'Rome';

等价于

var capitals:Object = {Italy: 'Rome'};

为了保存当前位置,我们将使用以下代码:

var s:Sprite = (e.currentTarget as Sprite);
startCoordinates[s] = { x: s.x, y: s.y };

我们示例中的整个代码如下所示:

var s1:Sprite = new Sprite()
var s2:Sprite = new Sprite()
addChild(s1)
addChild(s2)
with (s1)
{
    graphics.beginFill(0xfcaaaa, .7)
    graphics.drawRect(0, 0, 400, 400)
    graphics.endFill()
}
with (s2)
{
    graphics.beginFill(0x00aaaa, .7)
    graphics.drawRect(0, 0, 30, 30)
    graphics.endFill()
}
s2.x = 200;
s2.y = 200;
s2.addEventListener(MouseEvent.MOUSE_DOWN, onDown)
s2.addEventListener(MouseEvent.MOUSE_UP, onUp)

var startCoordinates:Dictionary = new Dictionary()

function onDown(e:MouseEvent):void
{
    var s:Sprite = (e.currentTarget as Sprite);
    startCoordinates[s] = { x: s.x, y: s.y };
    s.startDrag();
}

function onUp(e:MouseEvent):void
{
    var s:Sprite = (e.currentTarget as Sprite);
    s.stopDrag();
    if (!s.hitTestObject(s1))
    {
        s.x = startCoordinates[s].x;
        s.y = startCoordinates[s].y;
    }
    delete startCoordinates[s];
}

【讨论】:

  • 非常感谢你,尽管我没有使用你教的方式,但它帮助我思考了它是如何工作的
  • 如果这成功回答了您的问题,请务必将其标记为已接受答案(通过单击问题左上角附近的复选标记)。
猜你喜欢
  • 2011-08-03
  • 1970-01-01
  • 2017-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-09
  • 1970-01-01
相关资源
最近更新 更多