• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed błąd/bug wykrywania kolizji/overlapu(nakrycia) w Phaser.io

Object Storage Arubacloud
0 głosów
165 wizyt
pytanie zadane 13 sierpnia 2015 w JavaScript przez jegor377 Stary wyjadacz (13,230 p.)
zamknięte 13 sierpnia 2015 przez jegor377

Witam! Mam mały problem i nwm jak mam go rozwiązać, bo ze strony kodu wszystko wydaje się być ok. Otóż, napisałem sobie klasę Player (gracz) do mojej gry, która miała za zadanie stworzyć mi gracza, sprite sparku (takie coś co wyskakuje z karabinu gdy się strzeli) oraz klasa ta miała przechowywać mi grupę pocisków, które podczas utworzenia mają nadawaną siłę w stronę kursora oraz zwiększany jest ich licznik (maksymalnie można utworzyć 15 pocisków), a następnie mają sobie lecieć aż nie będzie kolizji z wallem (ścianą), no i gdy taka kolizja nastąpi to obiekt jest usuwany metodą kill() oraz licznik jest zmniejszany. No i niestety to nie działa tak do końca, bo gdy wystrzele pocisk, to niby sobie leci, trafia w ścianę i znika, ale tylko gdy wystrzele 1-4, jednak gdy wystrzele je wszystkie to pociski po prostu mają w dupie kolizje ze ścianami i lecą sobie nie wiadomo gdzie... Nie wiem jak to naprawić, bo w sumie to nie jest problem zbyt dużej prędkości, ponieważ lecą z prędkością 150, a to dosyć wolno... (player chodzi szybciej i nie przechodzi przez ściany) Jak to naprawić? Czegoś im nie nadałem? Daje kod do tej klasy (tylko ona kontroluje bullety i je przechowuje.

 

function _Player()
{
    this.player = game.add.sprite(GameData.levelData.player_data.spawn_point.x*GameData.levelData.tile_size.w,
                                      GameData.levelData.player_data.spawn_point.y*GameData.levelData.tile_size.h,
                                      'dude');
    
    game.physics.enable( this.player, Phaser.Physics.ARCADE);
    this.player.width = GameData.levelData.tile_size.w;
    this.player.height = GameData.levelData.tile_size.h;
    
    this.spark = game.add.sprite(this.player.x-2, this.player.y-(this.player.height+30)/2, 'fire_spark'); ///2+47
    this.spark.width = 25;
    this.spark.height = 32;
    
    this.bullets = game.add.group();
    this.bullets_count = 0;
    
    this.bullets.enableBody = true;
    this.bullets.physicsBodyType = Phaser.Physics.ARCADE;
    
    this.isShoting = false;
    this.canShoot = false;
    this.fireTimer = new _MyTimer(1000);
    
    this.player.body.drag = {x: 700, y: 700};
    
    this.player.body.collideWorldBounds = true;
    
    this.player.anchor.setTo(0.5, 0.5);
    this.player.animations.add('walk', [1,2,3,4,5,6,7,8], 20, true);
    game.camera.follow(this.player);
    
    this.player.angle = 0;
    
    this.spark.anchor.setTo(0.5, 0.5);
    this.spark.animations.add('fire', [1,2,3,4], 25, true);
    this.spark.animations.add('do_nothing', [0], 1, true);
    this.spark.animations.play('do_nothing');
    
    this.destroyBullet = function(bullet, wall) {
        bullet.kill();
        this.bullets_count--;
    }
    
    this.update = function() {
        
        GameData.Player.player.angle = game.physics.arcade.angleToPointer(GameData.Player.player)*180/Math.PI+90; //+1.5707963267948966192313216916398 [rad]
        
        this.getSparkAngle();
        
        game.physics.arcade.collide(this.player, GameData.tilemap);
        
        if(!this.isShoting) this.spark.animations.play('do_nothing');
        
        game.physics.arcade.collide(this.bullets.getFirstAlive(), GameData.walls, this.destroyBullet, null, this);
        //collision = this.checkIfBulletsIsOnTheWorld();
        //if(collision.collide==false && collision.objIndex!=null) this.destroyBullet(collision, null);
        
        
        this.fireTimer.update();
        if(this.fireTimer.isTimedUp())
        {
            this.canShoot = !this.canShoot;
        }
        
    }
    
    this.checkIfBulletsIsOnTheWorld = function() {
        for(a = 0; a < this.bullets; a++)
        {
            hBullet = this.bullets.getIndex(a);
            if(game.world.x+game.world.width>=hBullet.x && game.world.x+game.world.width<=hBullet.x+hBullet.width &&
               game.world.y>=hBullet.y-game.world.height &&
               game.world.y+game.world.height<=hBullet.y+hBullet.height+game.world.height) return {collide: true, objIndex: hBullet};
            
            if(game.world.y+game.world.height>=hBullet.y && game.world.y+game.world.height<=hBullet.y+hBullet.height &&
               game.world.x>=hBullet.x-game.world.width &&
               game.world.x+game.world.width<=hBullet.x+hBullet.width+game.world.width) return {collide: true, objIndex: hBullet};
            
            if(game.world.x>=hBullet.x && game.world.x<=hBullet.x+hBullet.width &&
               game.world.y>=hBullet.y-game.world.height &&
               game.world.y+game.world.height<=hBullet.y+hBullet.height+game.world.height) return {collide: true, objIndex: hBullet};
            
            if(game.world.y>=hBullet.y && game.world.y<=hBullet.y+hBullet.height &&
               game.world.x>=hBullet.x-game.world.width &&
               game.world.x+game.world.width<=hBullet.x+hBullet.width+game.world.width) return {collide: true, objIndex: hBullet};
            
            return {collide: false, objIndex: hBullet};
        }
        return {collide: false, objIndex: null};
    }
    
    this.getSparkAngle = function() {
        if(this.spark.frame!=0)
        {
            xs = this.player.x;
            ys = this.player.y;
            r = (this.player.height+30)/2;
            n = 360.0;

            for(i=0; i<(this.player.angle-91.0 > 0.0 ? this.player.angle-91.0 : 360.0+this.player.angle-91.0); i++)
            {

                alpha = 6.283185 * i / (n - 1);

                x = xs + r * Math.cos(alpha);
                y = ys + r * Math.sin(alpha);
            }

            this.spark.x=x;
            this.spark.y=y;

            delete xs;
            delete ys;
            delete r;
            delete n;
            delete alpha;

            this.spark.angle=this.player.angle;
        }
    }
    
    this.getBulletAnglePos = function() {
        xs = this.player.x;
        ys = this.player.y;
        r = (this.player.height+60)/2;
        n = 360.0;

        for(i=0; i<(this.player.angle-90.0 > 0.0 ? this.player.angle-90.0 : 360.0+this.player.angle-90.0); i++)
        {
            alpha = 6.283185 * i / (n - 1);

            x = xs + r * Math.cos(alpha);
            y = ys + r * Math.sin(alpha);
        }

        return {rx: x, ry: y};
    }
    
    this.shoot = function() {
        if(this.canShoot)
        {
            this.spark.animations.play('fire');
            if(this.bullets_count<15)
            {
                this.bullets_count++;
                
                bullet_pos = this.getBulletAnglePos();
                last_bullet = undefined;
                last_bullet = this.bullets.create(bullet_pos.xr, bullet_pos.yr, 'bullet');
                
                game.physics.enable( last_bullet, Phaser.Physics.ARCADE);
                last_bullet.width = 8;
                last_bullet.height = 11;
                last_bullet.reset(bullet_pos.rx, bullet_pos.ry);
                last_bullet.anchor.setTo(0.5, 0.5);
                last_bullet.angle = this.player.angle;
                last_bullet.colldeWorldBounds = true;
                game.physics.arcade.moveToPointer(last_bullet, 150);
            }
            this.isShoting=true;
        }
    }
}

PS Trochę zrobione na odwal, ale potem to poukładam. (to moja pierwsza gra w js.)

komentarz zamknięcia: Problem został rozwiązany :)

2 odpowiedzi

0 głosów
odpowiedź 13 sierpnia 2015 przez Rogal Obywatel (1,070 p.)
bezposrednio nie widac na tacy co jest nie tak ( nawet nie ma tej funkcji kill tutaj -> tylko ja wywolujesz )

poza tym => probuj debugowac. Wrzucaj w console.log'a wartosci ktore otrzymuje kazda funkcja, przekazuj wartosci w parametrach i sprawdzaj. Od nitki do klebka. Na tym polega debugowanie.

Druga sprawa, dlaczego caly czas odwolujesz sie this ? poczytaj sobie o metodach call i apply. Z drugiej strony aby nie powielac kodu stworz sobie zmienna, ktora bedzie zawierala jakis ciag powtarzajacego sie kodu, dla wiekszej czytelnosci.
komentarz 13 sierpnia 2015 przez jegor377 Stary wyjadacz (13,230 p.)
przyjacielu, przecież to jest phaser i ja tu nie pisałęm tej metody kill(), tylko ją wywoływałem. This używam, bo muszę się odwołać do obiektów tej klasy, a nie chcę udziwniać kodu jeszcze bardziej. xd Debugowałem i to nic nie daje... Spróbuje jeszcze dodać do tych bulletów, że są jakimiś specjalnymi ciałami, ale nie wiem czy to coś da... :/ W każdym bądź razie thx za call i apply (nie wiedziałem nawet, że takie coś jest xd)! :D
0 głosów
odpowiedź 13 sierpnia 2015 przez jegor377 Stary wyjadacz (13,230 p.)
Dobra rozwiązałem! To nie był bug, tylko moja głupota! xd chodzi o to, że zamiast sprawdzić czy wszystkie bullety miały kolizję, to wziąłem pierwszy "żyjący" i dlatego to nie działało xd Wystarczy zmienić zapis game.physics.arcade.collide(this.bullets.getFirstAlive(), GameData.walls, this.destroyBullet, null, this); na game.physics.arcade.overlap(this.bullets, GameData.walls, this.destroyBullet, null, this); i jest wszystko ok. :)

Podobne pytania

0 głosów
1 odpowiedź 170 wizyt
pytanie zadane 13 marca 2018 w JavaScript przez Storm Obywatel (1,570 p.)
0 głosów
0 odpowiedzi 126 wizyt
pytanie zadane 5 stycznia 2023 w JavaScript przez xTMx3 Obywatel (1,560 p.)
0 głosów
1 odpowiedź 118 wizyt
pytanie zadane 30 grudnia 2022 w JavaScript przez xTMx3 Obywatel (1,560 p.)

92,568 zapytań

141,420 odpowiedzi

319,617 komentarzy

61,953 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...