Action Script 3. Как запомнить координаты последнего объекта x

Я создаю флеш игру, в которой объекты падают с неба, и игрок должен уничтожить их, нажав на них. Но у меня есть проблема, иногда они порождают друг друга. Вот пример того, что я имею в виду:

неправильный спавн

Объекты должны появляться рядом друг с другом, но не друг с другом.

Вот мои постоянные переменные:

public static const GRAVITY:Number = 3;
public static const HIT_TOLERANCE:Number = 50;  

//Powerup
public static const APPLE_END_Y:Number = 640;
public static const APPLE_SPAWN_CHANCE:Number = 0.02; //per frame per second
public static const APPLE_START_Y:Number = 110;
public static const APPLE_SPAWN_START_X:Number = 50;
public static const APPLE_SPAWN_END_X:Number = 500;

//Scoring
public static const PLAYER_START_SCORE:Number = 0;
public static const SCORE_PER_APPLE:Number = 10;

Вот часть кода, где создаются объекты:

private function update(evt:Event)
{

    //Spawn new apples
    if (Math.random() < randomChance)
    {
        //spawn x  coordinates
        var newPirmas = new Pirmas();
        newPirmas.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
        var newAntras = new Antras();
        newAntras.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
        var newTrecias = new Trecias();
        newTrecias.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
        var newApple = new Apple();
        newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
        //spawn y coordinates
        newPirmas.y = C.APPLE_START_Y;
        newAntras.y = C.APPLE_START_Y;
        newTrecias.y = C.APPLE_START_Y;
        newApple.y = C.APPLE_START_Y;

        newPirmas.addEventListener(MouseEvent.CLICK, onClick);
        newAntras.addEventListener(MouseEvent.CLICK, onClick);
        newTrecias.addEventListener(MouseEvent.CLICK, onClick);
        newApple.addEventListener(MouseEvent.CLICK, onClick);

        itemsToSpawn.push(newPirmas, newAntras, newTrecias, newApple);
    }   
}        

Как кто-то сказал: As for making sure they don't overlap, you can keep a history of their spawn points, and change how you get their random X value. Just iterate through the array of previous X values, and make sure the new one isn't within (oldX + (width/2)).

Но я не могу сделать это успешно, не могли бы вы помочь мне сохранить историю их точек появления? Большое спасибо.

1 ответ

var t:Array = [];
t[0] = [APPLE_SPAWN_START_X, APPLE_SPAWN_END_X + APPLE_WIDTH/2];

t сохранит доступные интервалы, по которым вы можете создать новое яблоко. Во время начала нет яблока, и у t есть только один интервал, звезда X интервала - APPLE_SPAWN_START_X, конец X интервала - APPLE_SPAWN_END_X + APP_WIDTH/2.

где вы хотите сгенерировать новое яблоко, вы найдете свободный интервал в t, если мы найдем интервал как mInterval(интервал может быть помещен в яблоко, значит endX - starX >= APPLE_WIDTH), тогда мы могли бы сгенерировать ваше новое яблоко,

Нам просто нужно изменить строки в вашей функции обновления, как

newPirmas.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;

Вместо

newPirmas.x = mInterval[0] + Math.random()*APPLE_WIDTH;

Когда мы устанавливаем newPirmas.x, мы ломаем mInterval и генерируем два новых интервала, значениями являются [mInterval[0],newPirmas.x] и []newPirmas.x + APPLE_WIDTH, mInterval[0]], поэтому нам нужно удалите mInterval в t и поместите два новых интервала в t.

    /**
     * 
     * @return index of available interval in target array
     */
    public static function findAvailInterval(target:Array, appleWidth:int):int {

        if (target == null || target.length == 0) {
            return -1;
        }

        var endX:int = 0;
        var startX:int = 0;

        var length:int = target.length;

        for (var i:int = 0; i < length; i++) {

            var temp:Array = target[i] as Array;

            if (temp == null || temp.length < 2) {
                return -1;
            }

            startX = temp[0];
            endX = temp[1];

            var intervalWidth:int = endX - startX;//the interval width

            if (intervalWidth >= appleWidth) {//find an available one
                return i;
            }
        }

        return -1;
    }

    public static function breakInterval(target:Array, appleWidth:int, index:int):int {
        var temp:Array = target[index];

        var startX:int = temp[0];
        var endX:int = temp[1];

        var width:int = endX - startX;

        var availableNewXRange:int = width - appleWidth;//the apple‘s max x, and the min x is startX

        //random a position
        var appleX:int = startX + availableNewXRange*Math.random();

        var leftInterval:Array = [startX, appleX];//the left interval of apple

        var rightInterval:Array = [appleX+appleWidth, endX];//the right interval of apple

        //delete temp
        target.splice(index, 1);

        if (isAvailableInterval(leftInterval, appleWidth)) {
            target.push(leftInterval);
        }

        if (isAvailableInterval(rightInterval, appleWidth)) {
            target.push(rightInterval);
        } else {
            trace("vvv");
        }

        return appleX;
    }

    private static function isAvailableInterval(interval:Array, appleWidth:int):Boolean {

        if (interval == null || interval.length < 2) {
            return false;
        }

        return (interval[1] - interval[0]) >= appleWidth;
    }

Поместите три функции в класс A

        var target:Array = [[0, 1000]];
        var appWidth:int = 80;
        for (var i:int = 0; i < 4; i++) {
            var index:int = A.findAvailInterval(target, appWidth);

            if (index != -1) {
                var interval:Array = target[index];

                RR.breakInterval(target, appWidth, index);

                trace(interval);
            }
        }
Другие вопросы по тегам