0

I'm creating a screen saver which requires a movie clip to be loaded to the stage at a random position based on the size of the screen, then fade out (which I have all of the animation within a movie clip as tweens)

I've hit a road block and can't figure out how to prevent the movie clips from overlapsing on top of each other. If anything, I'd like for them to appear at another random spot that does not cause the overlapse.

here is all of the code for my project:

 stop();

import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.Event;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
var greystoneLogos:Array = new Array  ;
var countTimeArray:Array = new Array  ;
var previousLogos:Array = new Array  ;
var xpoint:int;
var ypoint:int;


function getNewSymbols()
{
    previousLogos = new Array  ;
    greystoneLogos = new Array  ;
    var i:int;
    for (i=0; i < 3; i++)
    {
        greystoneLogos[i] = new GreystoneLogo1();
        greystoneLogos[i].width = 100;
        greystoneLogos[i].height = 60;
        addSymbolToStage(greystoneLogos[i],i*2000);

    }
}

getNewSymbols();



function addSymbolToStage(currentLogo:MovieClip,waitTime:int)
{


    var i3:int;
    var i4:int;
var logoBoundaries:Array = new Array()
var XandY:Array = new Array()
    for (i3=0; i3 < greystoneLogos.length; i3++)
    {
        if (greystoneLogos[i3] !== currentLogo)
        {

            xpoint = randomRange(this.stage.stageWidth - (currentLogo.width * 4.8));
            ypoint = randomRange(this.stage.stageHeight - (currentLogo.height * 6.9));
            logoBoundaries = getOffDimensions(currentLogo)

                for (i4=0; i4 < logoBoundaries.length; i4++)
    {
        XandY = logoBoundaries[i4].split(":")

        while ((xpoint <= (Number(XandY[0]) + Number(currentLogo.width * 4.8)) &&  xpoint >= (Number(XandY[0]) - Number(currentLogo.width * 4.8))) && (ypoint <= (Number(XandY[1]) + Number(currentLogo.height * 6.9)) &&  ypoint >= (Number(XandY[1]) - Number(currentLogo.height * 6.9)))){

        xpoint = randomRange(this.stage.stageWidth - (currentLogo.width * 4.8));
        trace(XandY[0] + " And " + (Number(currentLogo.width * 4.8)))
        trace(xpoint + " And " + (Number(XandY[0]) + Number(currentLogo.width * 4.8)))
        ypoint = randomRange(this.stage.stageHeight - (currentLogo.height * 6.9));
        }
    }




        }
        else
        {
            continue;
        }

    }

    previousLogos.push(currentLogo);
    currentLogo.x = xpoint;
    currentLogo.y = ypoint;
    stage.addChild(currentLogo);
    currentLogo.gotoAndStop(1);
    var countTime:Timer = new Timer(waitTime,1);
    countTime.addEventListener(TimerEvent.TIMER, function(){

       currentLogo.gotoAndPlay(1);
       currentLogo.addFrameScript ( currentLogo.totalFrames - 1 , function(){
        currentLogo.stop()
     stage.removeChild(currentLogo)
     if(stage.numChildren <= 1){

    getNewSymbols(); 

     }

       }) ;

       });
    countTime.start();
}

function getOffDimensions(currentLogo:MovieClip){
    var i3:int;
    var tempArr:Array = new Array()
    for (i3=0; i3 < greystoneLogos.length; i3++)
    {
        if (greystoneLogos[i3] !== currentLogo){
        tempArr[i3]=greystoneLogos[i3].x +":"+ greystoneLogos[i3].y
        }
    }
    return tempArr
}

function randomRange(max:Number, min:Number = 0):Number
{
    return Math.random() * (max - min) + min;
}

There are also may be a handful of unused variables from multiple things I've been trying out.

The code that I posted, will make the movie clip appear at a random spot based on the last movie clip that came up. So let's say we have 3 movie clips (the user will be able to change how many of the clips get displayed) 1 appears at 0,0 the other at 400,400 and the last one appears at 10,10 because I have no way of saving the previous values to compare in the while loop.

I hope this clarifies it a tad more

EDIT:

Based on a function shown below, I've added this:

for (i3=0; i3 < greystoneLogos.length; i3++)
    {
        if (greystoneLogos[i3] !== currentLogo && greystoneLogos[i3] != null)
        {

            while(currentLogo.hitTestObject(greystoneLogos[i3]) == true){  

            xpoint = randomRange(this.stage.stageWidth - (currentLogo.width));
            ypoint = randomRange(this.stage.stageHeight - (currentLogo.height));
            i3 = 0
             }
        }else{
            continue;
        }

    }

Which results in a rather bad loop as well as the logo's still overlap above each other

4

2 回答 2

0

我能想到解决这个问题的最快方法在new MovieClip,如果返回 true,则再次运行放置代码

于 2013-09-05T12:08:27.743 回答
0

好的,这是这种最快方式的实现。您可以通过 .numChildren 属性跟踪您当前的 displayObject。您甚至不需要一系列徽标或东西。假设您有一个向屏幕添加新电影剪辑的函数。它知道您可以拥有多少个剪辑(MovieClipDummy 只是我的测试类 - 它绘制一个具有指定半径的圆。它应该被您的对象替换)。

private function addAnotherMovieClip(): void {
    if (_currentDummmiesCount < _dummmiesCount) {
        var newDummy: MovieClipDummy = new MovieClipDummy(90);
        addChild(newDummy);
        //If we get a stackoverflow error (see below)
        //we just remove our object from the screen as it will most likely just won't fit
        if (checkForEmptySpace(newDummy) != "") {
            removeChild(newDummy);
            return;
        }
    } else {
        //Do nothing or do something
    }
}

它调用另一个函数 checkForEmptySpace,它会尝试放置您的影片剪辑,使其不会与其他对象重叠。这里是:

private function checkForEmptySpace(newClip: Sprite): String {
    //you should store your screen width somewhere.
    //you can also call stage.stageWidth instead, but first make sure that you
    //always have a link to the stage or it will throw an error
    newClip.x = Math.random() * _screenWidth;
    newClip.y = Math.random() * _screenHeight;
    //===========================
    //Important part - we try to check all the present children of our container
    //numChildren is a property of the DisplayObjectContainer
    for (var i: int; i < numChildren; i++) {
        //We need a try here because we will get a StackOverflow error if there's no empty space left
        try {
            //We need to check if our current display object, received with getChildAt()
            //is not the same as the one we've just added to the screen
            //And if our new object intersects with ANY other object on the stage - we
            //call THIS function once again.
            //We do recursion because we can easily catch an error and remove this object from
            //the screen
            if (newClip != getChildAt(i) && newClip.hitTestObject(getChildAt(i))) {
                //If our recursive function returns an error - we should pass it further
                if (checkForEmptySpace(newClip) != "") {
                    return "error";
                }
            }
            //The only error that can go here is stackoverflow error. So when we get one
            //we return this error string
        } catch (error: Error) {
            trace(error);
            return "error";
        }
    }
    //We only return this empty string if we don't have stackoverflow error
    //so there's possibly no space left for another movieclip
    return "";
}

您可以在没有递归的情况下执行此操作,但您必须使用另一种逻辑检查空白空间。

而且,您可以通过使用Minkowski 加法来更“专业”地做到这一点。您应该考虑存储电影剪辑的“边界”点数组(假设每个电影剪辑都是一个矩形),当您向屏幕添加新对象时,您计算这个 Minkowsky 加法。它会在您的屏幕上出现一些“空闲”点,这些点代表您的新影片剪辑的任何可能坐标。实现这样的东西非常有趣,因为准确性将是惊人的。但如果你没有时间 - 只需使用递归放置功能

于 2013-09-06T06:08:46.077 回答