Перемещение объектов в массиве - PullRequest
0 голосов
/ 14 апреля 2011

У меня есть массив, который заполнен платформами, которые должны двигаться.

    var MovingPlatformArray:Array = new Array();

    for (var c:int = numChildren - 1; c >= 0; c--){
        var child3:DisplayObject = getChildAt(c);
        if (child3.name == "movingplatform"){
            MovingPlatformArray.push(child3);
        }
    }

    this.addEventListener(Event.ENTER_FRAME,ctrl_birdie);

    function ctrl_birdie(e:Event):void{

        for(var c in MovingPlatformArray){

    MovingPlatform[c].y += speed;

   if(MovingPlatformArray[c].hitTestPoint(birdie.x,birdie.y,true)){
        birdtelleryvertrager=0;
        birdtellery = 0;
        birdie.y-=14;
    }

        if(movingplatform.y <= 25){
                speed = 2;  
        }

        if(movingplatform.y >= 350){
             speed = -2;  
        }

   }

Сейчас у меня есть 2 движущиеся платформы в этом массиве. Но только один движется вверх и вниз. Но они оба регистрируют связь с птичкой. Я делаю что-то неправильно? Помощь очень ценится:)

Ответы [ 3 ]

2 голосов
/ 14 апреля 2011

В вашем слушателе вы устанавливаете только положение одной платформы, на которую ссылается одна «движущаяся платформа». Поскольку все ваши сценические экземпляры движущихся платформ называются «movingplatform», одна удачная платформа получает ссылку по имени (остальные игнорируются) вместо того, что вы намеревались, то есть использовать ссылки в вашем массиве и настраивать каждую платформу.

Вы, вероятно, хотели, чтобы movingplatform был локальной переменной в вашем обработчике событий, объявил что-то вроде этого:

var movingplatform:DisplayObject = MovingPlatformArray[c] as DisplayObject;

Я бы рекомендовал использовать для каждого цикла вместо для in , потому что я думаю, что это немного чище, но это незначительная вещь стиля:

for each (var platform:DisplayObject in MovingPlatformArray)
{
    platform.y += speed;
    ... rest of your code ...
}

Для ясности я отредактировал переменную цикла так, чтобы она была платформа вместо подвижной платформы, чтобы избежать путаницы с локальной переменной shadow экземпляра сцены (то есть this.movingplatform). Я хотел, чтобы было ясно, что имя экземпляра рабочей области здесь не используется, потому что непреднамеренная ссылка на имя экземпляра в вашем коде - это, в первую очередь, источник вашей проблемы.

1 голос
/ 14 апреля 2011

Насколько мне известно, у вас есть два варианта.используйте a для каждого, как предложил Адам Смит, или используйте цикл for, как и предполагалось:)

for(var c:uint = 0; c < MovingPlatformArray.length; c++){...

и btw: should "MovingPlatform [c] .y + = speed;"не будьте «MovingPlatformArray [c] .y + = speed;»?

edit: глядя на ваш код, я бы также предложил вам использовать MovingPlatformArray [c] .hitTestObject (birdie) вместо MovingPlatformArray [c].hitTestPoint (birdie.x, birdie.y, правда)

0 голосов
/ 15 апреля 2011

На вашем месте я бы вывел логику для платформы и сохранил ее в классе. (В идеале вы бы сделали это и для объекта птичка) Я создал пример ниже. Видеоклипы на сцене должны расширять Platform, а не MovieClip, чтобы они вызывали методы внизу.

// Use vectors if you know all the items are going to be the same type
var platforms:Vector.<Platform> = new <Platform>[];

for (var c:int = numChildren - 1; c >= 0; c--){
    var child:DisplayObject = getChildAt(c);

    // You shouldn't check against names (as per the original post). Because
    // names should be unique
    if (child is Platform){
        platforms.push(child);

        // This could be random so each platform has a different range
        // This means platform 1 could go from y 30 to y 400, platform 2
        // could go from y 60 to y 200, etc
        child.setRange(25, 400); 
    }
}

this.addEventListener(Event.ENTER_FRAME, gameLoop);

// Have an overall game loop
function gameLoop(e:Event):void {

    // Loop over the platforms
    platforms.forEach(function(item:Platform, i:int, a:Vector.<Platform>):void {
        // Hit test function in the class means you only have to pass in one mc 
        // rather than the points and a boolean
        if(item.hitTest(birdie)) {
            birdtelleryvertrager=0;
            birdtellery = 0;
            birdie.y-=14;
        }

        // Removed the movement logic, this should be kept out of the game loop
        // plus how much better does this read?
        item.move();
    });
}

Тогда где-нибудь в местоположении класса, как в папке game / activeObjects

// A class for the platform stored else where
package game.activeObjects
{
    import flash.display.MovieClip;
    /**
     * 
     */
    public class Platform extends MovieClip {

        private const SPEED:Number = 2;

        private var _direction:int = 1;
        private var _minimumHeight:Number = 25;
        private var _maximumHeight:Number = 350;

        public function Platform() {
        }

        public function setRange(minimumHeight:Number, maximumHeight:Number) {
            _minimumHeight = minimumHeight;
            _maximumHeight = maximumHeight;
        }

        public function move():void {
            this.y += SPEED * _direction;

            if(this.y <= _minimumHeight) {
                _direction = 1;
            } else if(this.y >= _maximumHeight) {
                _direction = -1;
            }
        }

        public function hitTest(mc:MovieClip):Boolean {
            return hitTestPoint(mc.x,mc.y,true);
        }       
    }
}
...