AS3洗牌动画片段

时间:2015-07-30 08:46:45

标签: actionscript-3 flash

我添加了基本目标,并为我的拼图应用拖放,现在我无法进行改组。在玩家完成或打开fla之后,每次都会在舞台的随机位置开始拼图。我理解使用数组以某种方式进行洗牌,但我不确定如何实现这一点。我已将我的19个拼图的实例存储在数组中,但现在我不知道如何处理这个数组。其他教程在我的联盟中脱颖而出,令我头疼。

刚刚开始为flash专业人士编写代码,所以是的,任何有关改组电影片段的帮助,即拼图片都将不胜感激。

Heres是我的代码,我不发布整个事情,因为从P1到P19基本上是复制粘贴:

import flash.events.Event;

stage.addEventListener(Event.ENTER_FRAME, EntFrame)
function EntFrame(e: Event) : void
{

    P1.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
    function fl_ClickToDrag(event:MouseEvent):void
    {
        P1.startDrag();
    }
    stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
    function fl_ReleaseToDrop(event:MouseEvent):void
    {
        P1.stopDrag();
    }
    if (T1.hitTestObject(P1.Tar1))
    {
        P1.x = 313.15;
        P1.y = 242.75;
    }

    P19.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag_19);
    function fl_ClickToDrag_19(event:MouseEvent):void
    {
        P19.startDrag();
    }
    stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop_19);
    function fl_ReleaseToDrop_19(event:MouseEvent):void
    {
        P19.stopDrag();
    }
    if (T19.hitTestObject(P19.Tar19))
    {
        P19.x = 624.35;
        P19.y = 455.60;
    }
}

2 个答案:

答案 0 :(得分:0)

嗯,一般来说,您可以使用以下代码进行随机播放:

var shuffledVector:Vector.<someClass> = new Vector.<someClass>;
while (originalVector.length > 0) {
    shuffledVector.push(originalVector.splice(Math.random() * originalVector.length, 1)[0]);
}

更长,解释版本:

var shuffledVector:Vector.<someClass> = new Vector.<someClass>; //We will store our shuffled vector in here
var randomIndex:int;                                            //Random index from the originalVector
var resultVector:Vector.<someClass>;                            //result from the originalVector.splice(...) function
var randomElement:someClass;                                    //Random element from the originalVector

while (originalVector.length > 0) {                             //We will reduce the size of the originalVector until the originalVector is empty.
    randomIndex =  Math.random() * originalVector.length;       //Calculate a random index within the range of the originalVector from 0 to originalVector.lenght-1 (note that the range decreases by one on every loop)
    randomVector = originalVector.splice(randomIndex, 1);       //Use splice to remove one element at the randomly choosen index, we will receive a vector with the removed element...
    randomElement = randomVector[0];                            //...so we need to access the element
    shuffledVector.push(randomElement);                         //Add the randomly choosen element to our shuffled vector
}

我已经编写了矢量代码,因为我建议使用矢量而不是数组,但它背后的原理对于数组来说是相同的。

在你的情况下,originalVector是一个用P1-P19 Movieclips填充的向量,someClass是MovieClip。 originalVector最后是空的,可以用shuffled替换,当然如果你把代码放在一个单独的函数中会更有意义:

function Shuffle(originalVector:Vector.<someClass>) : void {
    var shuffledVector:Vector.<someClass> = new Vector.<someClass>;
    while (originalVector.length > 0) {
        shuffledVector.push(originalVector.splice(Math.random() * originalVector.length, 1)[0]);
    }
    originalVector = shuffledVector;
}

Offtopic,但对于进一步编码很重要:其他人已经提到过,在每一帧上添加EventListener并不好,因为它绝对没必要。您只需要添加一次监听器。你的代码是非常重复的,你应该使用一个接受MovieClip,x和y的函数然后调用该函数19次。 例如:

function setUpMovieClip(MC:MovieClip, x:int, y:int) : {
    MC.addEventListener(MouseEvent.MOUSE_DOWN, clickToDrag);
    //more code...
}
在clickToDrag函数中

,您可以访问通过event.target属性单击的MovieClip:

function clickToDrag(e:MouseEvent) : {
    e.target.startDrag();
    //more code...
}

我希望你明白这一点。

答案 1 :(得分:0)

这是我希望更全面的答案。

首先,抛弃那些内联函数。现在你创建一个ENTER_FRAME监听器,并在该函数内部定义了内联函数。这意味着每个帧标记(与帧速率相关,而不是主时间轴),这些函数将再次创建,并且由于您将它们添加为侦听器的处理程序,它们将永远保留在内存中。

这是一种对此进行编码的方法,展示了减少冗余并消除这些内存泄漏的方法。假设如下:

  1. 您在舞台上有19个名为T1 - T19的对象,它们代表了这些作品的可能位置。

  2. 您在舞台上有19件名为P1 - P19,并且这些数字与T位置相关,因为该片段的正确位置。< / p>

    //let's create a function to randomize the piece location
    function seedPieces() {
        //create an array consisting of the integers 1 - 19
        var unusedSpaces:Vector.<int> = new Vector.<int>;
        var i:int;
        for (i = 1; i <= 19; i++) {
            //populate that array
            unusedSpaces.push(i);
        }
    
        var curLocation:DisplayObject; //helper var for the loop below
        var curPiece:Sprite; //helper var for the loop below
    
        //loop 19 times (from 1 - 19) - one iteration for each piece
        for (i = 1; i <= 19; i++) {
            curPiece = this["P" + i] as Sprite; //you can get the piece this way, or use an array if you've made one, like `pieces[i];`
            trace(curPiece.name);
            //splice removes and returns the item at the specified index (in this case a random number between 0 and arrays length less 1) - the second parameter is amount of items to remove (just 1 for this case)
            curLocation = this["T" + unusedSpaces.splice(int(Math.random() * unusedSpaces.length), 1)] as DisplayObject; 
            trace("  ",curLocation.name);
            //move the piece to the random location:
            curPiece.x = curLocation.x;
            curPiece.y = curLocation.y;
        }
    }
    
    //NOW, as an aside, you should use a loop to add all your listeners for the sake of sanity - if you have them in an array, loop through that, or use the sloppy way like this:
    for (var i:int = 1; i <= 19; i++) {
        Sprite(this["P" + i]).addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
    }
    
    //create a var to hold any piece that is currently being dragged, so you know which piece to stop drag on later
    var currentDraggingItem:Sprite;
    seedPieces();
    
    
    
    function fl_ClickToDrag(event:MouseEvent):void
    {
    
        //assign this clicked item to the currentDraggingItem var
        currentDraggingItem = event.currentTarget as Sprite;
    
        //bring this one to the front
        currentDraggingItem.parent.addChild(currentDraggingItem);
    
        //you can use this one click handler for all pieces
        //the piece that was actually clicked, is referenced by event.currentTarget
        currentDraggingItem.startDrag();
    
    
        //add the mouse up listener now that the mouse is currently DOWN
        stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
    
        //listen every frame while dragging
        stage.addEventListener(Event.ENTER_FRAME, EntFrame);
    }
    
    function fl_ReleaseToDrop(event:MouseEvent):void
    {
        //if currentDraggingItem has a value, stop drag it
        if (currentDraggingItem) {
            currentDraggingItem.stopDrag();
            //send to the back
            currentDraggingItem.parent.addChildAt(currentDraggingItem,0);
        }
        //remove the mouse up and enter frame listener now that the mouse is UP
        stage.removeEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
        stage.removeEventListener(Event.ENTER_FRAME, EntFrame);
    
        if(checkComplete()){
            //game over, do something
        }
    }
    
    function EntFrame(e: Event) : void
    {
        //this will snap the peice to the correct spot when the mouse is touching the correct spot
        if(currentDraggingItem){
            if (this[currentDraggingItem.name.replace("P","T")].hitTestPoint(mouseX,mouseY))
            {
                currentDraggingItem.x = this[currentDraggingItem.name.replace("P","T")].x;
                currentDraggingItem.y = this[currentDraggingItem.name.replace("P","T")].y;
            }
        }
    }
    
    function checkComplete():Boolean {
        //use a loop to go through all your pieces and check if they are in the right spot. Again, you could have them in an array, or do it the lazy way
        for (var i:int = 1; i <= 19; i++) {
            if (!this["T"+i].hitTestObject(this["P"+i]))
            {
                return false;
            }
        }
        return true;
    }