Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   некоторые объекты вылетают из массива самовольно (http://www.flasher.ru/forum/showthread.php?t=206604)

Vansimar 14.02.2014 14:35

некоторые объекты вылетают из массива самовольно
 
В чем проблема собственно.. у меня есть массив для пулек
Код AS3:

var bullets:Array = new Array();

в классе пульки есть метод update();

я гоняю в цикле массив пулек в ENTER_FRAME
Код AS3:

private function updateBullets():void{
                        for(var i:int =0;i<bullets.length;i++){
                                bullets[i].update();
                        }
                }

так .

В классе пульки есть проверки на вылет за границу и проверка на попадание по врагу.. То есть пулька удаляется из массива только в двух случаях. Удаляю с помощью
Код AS3:

InGame.bullets.splice(InGame.bullets.indexOf(this), 1);

Вроде как все хорошо работает, но в игре иногда пару пуль останавливаются и висят на сцене, то есть удаляются из массива и update() у них не срабатывает.. я этого не писал, если бы сработала моя функция удаления то они бы исчезли,так как я перед удалением делаю пульке visible = false; Может кто сталкивался с такой проблемой?

Akopalipsis 14.02.2014 15:03

Вы подумайте, как работает цикл, если каждую итерацию заново расчитываеть его длину, что и делает строчка bullets.length.

Vansimar 14.02.2014 15:05

Ну а разве так не должно быть?

votar1408 14.02.2014 15:06

Вы изменяете размер массива, по которому проходитесь, а цикл у вас забит на определенное количество итераций.

Vansimar 14.02.2014 15:07

То есть лучше каждый раз размер пересчитывать?

Akopalipsis 14.02.2014 15:10

Попробуйте в момент удаления пульки i убавлять на один.
На словах не могу объяснить, у меня не получается.

Vansimar 14.02.2014 15:18

не совсем понял

Akopalipsis 14.02.2014 15:23

У Вас десять элементов, в цикле Вы остановились на i==5 и поняли, что произошло столкновение.
Вы удалили элемент из массива и его длина теперь 9, но i так и остается равной 5. А под номером пять, теперь пуля, которая мгновение назад была шестой и ждала своей очереди, чтобы ей дернули update.
Но так-как i не убавили, то и пуля обновления не получила.

Wolsh 14.02.2014 15:24

У Вас итератор цикла постоянно растет, а из массива удаляется элемент с текущим индексом и массив схлопывается на один элемент.
Короче, у Вас допустим i = 6. И Вы решили удалить элемент bullets[6].
Теперь bullets[7] стал bullets[6]. Итерация 6 закончилась, и i стал равен 7. Теперь цикл проверяет элемент bullets[7], который до удаления был bullets[8]. А тот, который до удаления был [7] а после удаления стал [6] — остается непроверенным.

И еще я бы советовал почитать что-нибудь на тему ООП. Пуля, которая знает весь окружающий мир, создает физические законы и сама решает свою судьбу — это не пуля. Пуля это кусок металла, подчиняющийся законам физики и летящий по миру, который о ней знает. Как Вы голову не сломали, выворачивая все наизнанку?

FlasherEgor 14.02.2014 15:25

Можно же еще метод filter применять к исходному массиву, а возвращаемый фильтрованием присваивать переменной, изначально ссылавшейся на исходный массив. По-моему - очень удобная штука, хотя, может я и не прав.

Vansimar 14.02.2014 15:26

ну на следующей итерации ENTER_FRAME bullets.length заново рассчитается, и та,обделенная апдейтом пулька все же получит свое внимание и свой апдейт и полетит дальше, а у меня они намертво останавливаются

Akopalipsis 14.02.2014 16:42

Цитата:

ну на следующей итерации ENTER_FRAME bullets.length заново рассчитается, и та,обделенная апдейтом пулька все же получит свое внимание
Так, да... Тогда код показывайте.

Добавлено через 46 секунд
Но это все равно не правильно, не должен цикл хоть и на кадр, но неправильно работать.

Vansimar 14.02.2014 16:44

Ну вот код пульки
Код AS3:

package objects.weapons
{
        import animation.AntActor;
 
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.geom.Point;
        import flash.geom.Rectangle;
        import flash.globalization.NumberParseResult;
        import flash.text.TextField;
 
        import gameClass.Game;
 
        import objects.Entity;
        import objects.Hero;
        import objects.enemies.Enemy;
        import objects.enemies.Tnt;
        import objects.shop.Box;
        import objects.shop.Coinsbox;
 
        import screens.InGame;
 
        import utils.ageVector;
 
        public class Bullet extends Entity
        {
                private var vectorEnd: ageVector;
                private var vectorStart: ageVector;
                private var angle:Number;
                private var angle2:Number;
 
 
                private var bulletBang:AntActor;
                private var bullet:AntActor;
                private var speed: int = 10;
                private var power:int = 5;
                private var text:TextField;
                private var i:int = 0;
 
                public function Bullet(vec: ageVector,point:Point,_speed:int,_power:int)
                {
                        super();
                        vectorEnd = new ageVector();
                        vectorEnd.x = vec.x;
                        var k:int;
 
                        if(InGame.entities[0] as Hero){
                                var percent:int = (InGame.entities[0] as Hero).getStamina();
                                var value: int =20- 20* (percent/100);
                                k = randRange(vec.y-value,vec.y+value);
                                vectorEnd.y = k;
                        }else{
                                k = randRange(vec.y,vec.y);
                                vectorEnd.y = k;
                        }
                        speed = _speed;
                        power = _power;
                        angle = Math.atan2(vectorEnd.x-point.x,vectorEnd.y-point.y);
 
                        angle2 = Math.atan2(vectorEnd.y-point.y,vectorEnd.x-point.x);
 
                        vectorStart = new ageVector(this.x, this.y);
                        this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
                }
 
                private function onAddedToStage(event:Event):void
                {
                        this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
                        //this.addEventListener(Event.ENTER_FRAME, update);
                        createAnimation();
                        createHitBox(2, 2, 5,5);
                        isBullet = true;
 
 
                        bullet.rotation = angle2;
 
                }               
 
                public override function update():void
                {
                        //text.text = String(i++);
 
                        if(x>720 || x<0 || y>550 ||y<0){
                                this.kill();
                                setIndex();
 
                        }       
                        this.x += Math.sin(angle) * speed;
                        this.y += Math.cos(angle) * speed;
                        checkCollision();
                        checkCollisionWithBox();
 
                }
                private function checkCollisionWithBox():void{
                        for(var i:int= 1;i< InGame.entities.length;i++){
                                if(InGame.entities[i] && InGame.entities[i].isBox){
                                        if(InGame.entities[i].isDead ==false ){
                                                var paddleRect:Rectangle = this.returnHitBox().getBounds( this );
                                                var enemy:Entity;
                                                if((InGame.entities[i] as Coinsbox))
                                                        enemy = (InGame.entities[i] as Coinsbox);
                                                if((InGame.entities[i] as Box))
                                                        enemy = (InGame.entities[i] as Box);
                                                var tempSprite:Sprite = enemy.returnHitBox();
                                                var ballRect:Rectangle = tempSprite.getBounds( this );
                                                var isColliding:Boolean = paddleRect.intersects( ballRect );
                                                if(isColliding && !isDead){
                                                        bulletBang.visible = true;
                                                        bulletBang.play();
                                                        isDead = true;
                                                        bullet.visible = false;
 
                                                        speed = 0;
                                                        InGame.entities[i].getDamage(power);
                                                        break;
                                                }
                                        }
                                }
                        }
                }
 
                private function checkCollision():void
                {
                        for(var i:int= 1;i< InGame.entities.length;i++){
                                if(InGame.entities[i] && InGame.entities[i].isEnemy){
                                        if(InGame.entities[i].isDead ==false ){
                                                var paddleRect:Rectangle = this.returnHitBox().getBounds( this );
                                                var enemy:Entity;
                                                if((InGame.entities[i] as Enemy) != null)
                                                        enemy = (InGame.entities[i] as Enemy);
                                                else {
                                                        enemy = (InGame.entities[i] as Tnt);
                                                }
                                                var tempSprite:Sprite = enemy.returnHitBox();
                                                var ballRect:Rectangle = tempSprite.getBounds( this );
                                                var isColliding:Boolean = paddleRect.intersects( ballRect );
 
                                                if(isColliding && !isDead){
 
                                                            bulletBang.visible = true;
                                                                bulletBang.play();
                                                                isDead = true;
                                                                bullet.visible = false;
 
                                                                speed = 0;
                                                                InGame.entities[i].getDamage(power);
                                                                break;
                                                }
                                        }
                                }
                        }
                }
 
                private function createAnimation():void
                {
 
                        bullet = new AntActor();
                        bullet.addAnimFromCache("bullet"); // Добавляем анимацию
                        bullet.stop();
                        bullet.animSpeed =0.5 // Скорость анимаци
                        addChild(bullet);
 
 
                        bulletBang = new AntActor();
                        bulletBang.addAnimFromCache("bullet_bang"); // Добавляем анимацию
                        bulletBang.repeat = false;
                        bulletBang.addEventListener(Event.COMPLETE, endShootCallback);
                        bulletBang.stop();
                        bulletBang.visible= false;
                        this.addChild(bulletBang);
 
                        text = new TextField();
                        addChild(text);
 
                }
 
                private function setIndex():void{
                        InGame.bullets.splice(InGame.bullets.indexOf(this), 1);
                }
 
                public function endShootCallback(e:Event):void
                {
                        this.visible = false;
                        bulletBang.stop();
 
                        this.kill();
                        setIndex();       
                }
        }
}


Akopalipsis 14.02.2014 16:57

А Вы повторно пули используете? А то может просто анимация заканчивается?

Vansimar 14.02.2014 16:59

нет, постоянно новые

Добавлено через 30 секунд
Да и все равно, они должны дальше лететь

Wolsh 14.02.2014 17:19

Цитата:

this.kill()
В this нет никакого kill(). Имелось ввиду super.kill()? Код покажите.

Vansimar 14.02.2014 17:20

Код AS3:

public function kill():void{
 
                        this.visible = false;
                        if(parent){
                                parent.removeChild(this);
                        }
                }

Добавлено через 1 минуту
Этот метод в родительском классе

Vansimar 14.02.2014 17:44

Вложений: 1
Вот к примеру эти пульки дальше не летят

Bletraut 14.02.2014 22:00

если дело в переборке массива, то я использую такую конструкцию
Код AS3:

 var i:int = bullets.length;
while(i--)
{
}


Vansimar 15.02.2014 16:22

не помогло(


Часовой пояс GMT +4, время: 11:55.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.