1

编辑:我不敢相信我没有早点发现这个。原来我的问题是一遍又一遍地重新声明我的第一个变量,基本上是重新启动程序而不是继续它。为了解决这个问题,我将前两行替换为:

if (initialized === undefined) {
    trace("INITIALIZING");
    var MCs = [];
    var lastPos = "intializer";
    var initialized = 1;
}

现在它就像一个魅力。对于这个,我觉得自己像个菜鸟;对不起任何我浪费时间的人。我会将其发布为我自己问题的答案,但由于我还是新手,它不会让我这样做。


原帖如下:

我正在尝试制作一个随机选择一个广告,播放它,然后随机播放另一个的 Flash。为此,我成功地改组了一个数组,然后gotoAndPlay在数组的第一个元素中添加标签,然后删除该元素。在每个广告的末尾,gotoAndPlay(1);所有主要代码都在第一帧上。如果数组是空的,它会重建它并重新洗牌。

问题是,我不希望它重复任何广告,直到它贯穿所有广告;我我已经明白了,但我并不积极。此外,我不希望数组中的最后一个元素与新元素中的第一个元素相同,因此同一广告不会连续显示两次。我试图让它检测它刚刚使用的元素是否与它即将使用的元素匹配,如果发生这种情况则重新洗牌,但在我的测试中,它偶尔会连续两次显示相同的广告。

我显然做错了什么,但是对于 ActionScript3 (实际上是 flash)是全新的,我在识别它是什么时遇到了很多麻烦。这是我现在拥有的:

var MCs = [];
var lastPos = "intializer";

if (MCs.length == 0) {
    MCs = reset();
    if (lastPos == MCs[0]) {
        while (lastPos == MCs[0]) {
            MCs = reset();
        }
    }
}
if (MCs.length > 0) {
    lastPos = MCs[0];
    MCs.splice(0,1);
    gotoAndPlay(lastPos+"MC");
}

function reset(){
    var PrepMCs = new Array("Image1", "Image2", "Image3");
    var WorkMCs = new Array(PrepMCs.length);

    var randomPos:Number = 0;
    for (var i:int = 0; i < WorkMCs.length; i++)
    {
        randomPos = int(Math.random() * PrepMCs.length);
        WorkMCs[i] = PrepMCs.splice(randomPos, 1)[0];
    }
    return WorkMCs;
}

就个人而言,我宁愿只用 JavaScript、HTML 和图像来做这件事;这真的很简单。但出于托管/CMS 的原因,我无法控制,我仅限于单个文件或单个代码块;我不能在外部托管任何东西,据我所知,Flash 是我最好的选择。

任何帮助将不胜感激,谢谢!如果我做了什么可怕的、可怕的错误的事情,这甚至是一个奇迹,请不要犹豫告诉我!

编辑:我刚刚想到,如果第二次运行的顺序与第一次运行的顺序相同,则完全没问题,等等。主要的是,它需要是随机的。这可能更容易实现。

编辑 2:这里有大量的 DERP。每次它运行时,它都会重新初始化MCs并且lastPos......换句话说,它每次都在洗牌并重新开始。我应该研究的是如何在变量尚未初始化的情况下只运行一行代码。

4

3 回答 3

1

公然从@32bitKid 窃取,这是我的版本。

我对他的解决方案的主要问题是推送/拼接的想法。尽可能地,我喜欢创建一次,然后重复使用。即使有效,缩小和增长的阵列也很庞大。

此外,此方法不会重新排序数组,这可能有价值,也可能没有价值。

顺便说一句,我喜欢他防止重复上一项(“几乎是空的”)的方式。

所以这里有另一种方法:

package
{

    public class RandomizedList
    {
        private var _items:Array;
        private var idxs:Array;
        private var rnd:int;
        private var priorItemIdx:int;
        private var curIdx:int;

        public function RandomizedList(inarr:Array)
        {
            items = inarr;
        }

        private function initRandomize():void
        {
            idxs = new Array();

            //Fisher-Yates initialization (http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle):
            idxs[i] = 0;
            for (var i:int = 1; i < items.length; i++)
            {
                rnd = int(Math.random() * (i + 1));
                idxs[i] = idxs[rnd];
                idxs[rnd] = rnd;
            }

            curIdx = 0;
            priorItemIdx = -1;
        }

        private function randomize():void
        {
            var tempint:int;
            //Fisher-Yates (http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle):
            for (var i:int = items.length; i >= 1; i--)
            {
                rnd = int(Math.random() * (i + 1));
                tempint = idxs[i];
                idxs[i] = idxs[rnd];
                idxs[rnd] = tempint;
            }

            curIdx = 0;
        }

        public function next():void
        {
            if (curIdx >= idxs.length)
            {
                randomize();
            }

            if (items.length > 1 && priorItemIdx == idxs[curIdx])
            {
                curIdx++;
            }

            priorItemIdx = idxs[curIdx++];
            return items[priorItemIdx];
        }

        public function get items():Array
        {
            return _items;
        }

        public function set items(value:Array):void
        {
            _items = value;
            initRandomize();
        }
    }
}
于 2012-04-26T22:17:18.453 回答
0

我会使用这样的实用程序类来抽象出我想要的行为:

import flash.text.TextField;

class Randomizer {

    private var unused:Array = [];
    private var used:Array;

    public function Randomizer(playList:Array) {
        used = playList;
    }

    public function next():* {
        // If almost empty, refill the unused array
        if(unused.length <= 1) refill();

        // Get the first item off the playList
        var item:* = unused.shift();

        // Shove it into the bucket
        used.push(item); 

        // return it back
        return item;
    }

    public function refill():void {
        var i:int;
        // Fisher-Yates shuffle to refill the unused array
        while(used.length > 0) {
            i = Math.floor(Math.random() * used.length)
            unused.push(used.splice(i,1)[0])
        }
    }
}

请注意,unusedunused数组中仍有一项时,它会重新填充数组,这使得最后一个结果不可能连续重复两次。这将在循环之前返回每个项目一次,并且永远不会重复相同的项目两次。

您可以通过以下方式使用它:

var ads:Randomizer = new Randomizer(["Image1", "Image2", "Image3"]);
ads.next(); // will return something
ads.next(); // will return something
ads.next(); // will return something
ads.next(); // will return something
// Keep going into infinity...

此代码有一个小测试示例在这里工作。

于 2012-04-26T20:34:51.947 回答
-1

看看这是否有意义

//create your array of all your ad names/frame labels
var PrepMCs:Array = new Array("Image1", "Image2", "Image3");

var shuffledMCs:Array = [];

//store the name of the last played ad in this var
var lastAdPlayed:String;

//shuffle the array
shuffleArray(PrepMCs);


function shuffleArray(arrayToShuffle:Array):void {  
//clear the array
shuffledMCs = [];

var len:int = arrayToShuffle.length;

for(var i:int = 0; i<len; i++) {
shuffledMCs[i] = arrayToShuffle.splice(int(Math.random() * (len - i)), 1)[0];
}

//test to see if the new first ad is the same as the last played ad
if (lastAdPlayed == shuffledMCs[0]) {
//reshuffle
    shuffleArray(PrepMCs);
} else {

lastAdPlayed = [0];

trace(shuffledMCs);

playAds();
}    

}



//after each ad has played, call this function
function playAds():void {

if (shuffledMCs.length > 0) {

    gotoAndPlay(shuffledMCs[0]);
    shuffledMCs.splice(0,1);

} else {
    //array is empty so we have played all the ads
    shuffleArray(PrepMCs);
}

}
于 2012-04-26T19:23:34.017 回答