1

編集:これをもっと早くキャッ​​チしなかったなんて信じられない. 私の問題は、最初の変数を何度も何度も再宣言し、本質的にプログラムを続行するのではなく、最初からやり直すことでした。それを修正するために、最初の 2 行を次のように置き換えました。

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

今では魅力のように機能します。私はこれに初心者のように感じます。時間を無駄にしてしまった人には申し訳ありません。私は自分の質問への回答としてこれを投稿しますが、私はまだ新しいのでできません。


元の投稿は次のとおりです。

広告をランダムに選択して再生し、別の広告をランダムに再生するフラッシュを作成しようとしています。そのために、配列をシャッフルし、配列gotoAndPlayの最初の要素のラベルを -ing してから、その要素を削除することで成功しました。各広告の最後にはgotoAndPlay(1);、すべてのメイン コードが最初のフレームにあります。配列が空の場合、再構築して再シャッフルします。

問題は、すべての広告が実行されるまで広告を繰り返してほしくないということです。私はそれを理解したと思いますが、私は前向きではありません. さらに、配列の最後の要素を新しい要素の最初の要素と同じにしたくないので、同じ広告が連続して 2 回表示されることはありません。使用したばかりの要素が使用しようとしている要素と一致するかどうかを検出し、一致した場合は再シャッフルしようとしていますが、私のテストでは、同じ広告が 2 回続けて表示されることがあります。

私は明らかに何か間違ったことをしていますが、ActionScript3 にまったく慣れていない (そして実際にフラッシュする) ので、それが何であるかを特定するのに非常に苦労しています。これが私が今持っているものです:

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 の理由から、私には制御できないため、1 つのファイルまたは 1 つのコード ブロックに制限されています。私は外部で何かをホストすることはできません。私が知る限り、これには Flash が最良の選択肢です。

どんな助けでも大歓迎です、ありがとう!私がひどく、ひどく間違ったことをして、これがまったく実行されるのが不思議な場合は、遠慮なく教えてください!

編集: 2 回目の実行が最初の実行と同じ順序であれば、まったく問題ありません。主なことは、ランダムである必要があることです。これはおそらく実装がはるかに簡単です。

編集 2: 大規模な DERP HERE. 実行するたびに再初期化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])
        }
    }
}

unused配列に項目が 1 つ残っている場合、配列が補充されることに注意してくださいunused。これにより、最後の結果が連続して 2 回繰り返されなくなります。これにより、ループする前に各項目が 1 回返され、同じ項目が 2 回繰り返されることはありません。

次のように言って使用します。

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 に答える