> Faqs > ¿Por qué no colisionan mis sprites e imágenes y hasta desaparecen si es que colisionan?

¿Por qué no colisionan mis sprites e imágenes y hasta desaparecen si es que colisionan?

Mis sprite e imágenes colisionaban antes de modificar la Hitbox y ahora que la modifique no colisionan y no sé el por que pasa esto.

Aclaro que se ve perfectamente la Hitbox y todo con respecto a donde la coloque está bien pero no colisiona y si lo hace el objeto desaparece.

De ante mano quiero disculparme por las molestias y agradezco nuevamente por su ayuda.

Creo tener algún errror de logica pero no sé muy bien. Es la primera vez que programo un videojuego.

  • Uso un servidor creado con la función express.

  • Código de la platilla del juego:

const config = {
    type: Phaser.AUTO,
    width: window.innerWidth,
    height: window.innerHeight,
    scene: [Game],
    physics: {
        default: "arcade",
        arcade: {
            gravity: { y: 400 },
            debug: false
        }
    }
};

var game = new Phaser.Game(config);
  • Aquí les proporciono el código de mi única escena por el momento:
export class Game extends Phaser.Scene {
    constructor() {
        super({key:'game'});
    };

    preload() {
        this.load.image("background","imagenes/Legacy-Fantasy - High Forest 2.3/Background/Background.png");
        this.load.image("mapa","Fondos/mapa.png");
        this.load.spritesheet("caballero_Idle","caballero/Colour2/NoOutline/120x80_PNGSheets/_Idle.png",{ frameWidth: 120, frameHeight: 80 });
        this.load.spritesheet("esqueleto","Skeleton/Sprite Sheets/Skeleton Idle.png",{frameWidth: 24, frameHeight: 30});

    };

    create() {
        //Colisiones del mundo
        this.physics.world.setBoundsCollision(true, true, true, true);

        //Fondo
        this.background = this.physics.add.image(window.innerWidth / 2, window.innerHeight / 2, "background");
        this.background.setScale(window.innerWidth / this.background.width, window.innerHeight / this.background.height);
        this.background.body.allowGravity = false;

        this.mapa = this.physics.add.image(0,800,"mapa").setImmovable();
        this.mapa.setScale(window.innerWidth,0.8);
        this.mapa.body.allowGravity = false;

        //Plataformas

        console.log("Por ahora no tengo plataformas");
        console.log(`Ancho: ${(this.background.scaleX)*32}`);
        console.log(`Alto: ${(this.background.scaleY)*32}`);

        //Personajes

        this.caballero_Idle = this.physics.add.sprite(400,340,"caballero_Idle");
        //this.caballero_Idle.body.allowGravity = false;

        this.esqueleto = this.physics.add.sprite(450,340,"esqueleto");
        this.esqueleto.body.allowGravity = false;

        //Animaciones

        this.anims.create({
            key: 'caballero_Idle',
            frames: this.anims.generateFrameNumbers('caballero_Idle', { start: 0, end: 7 }),
            frameRate: 10,
            repeat: -1,
            yoyo: true,
        });

        this.anims.create({
            key: "esqueleto",
            frames: this.anims.generateFrameNumbers("esqueleto",{start: 0, end: 7}),
            frameRate: 10,
            repeat: -1,
            yoyo: true,
        });

        this.caballero_Idle.anims.play('caballero_Idle');

        this.esqueleto.anims.play("esqueleto");

        //colisiones
        this.background.setCollideWorldBounds(true);
        this.mapa.setCollideWorldBounds(true);
        this.caballero_Idle.setCollideWorldBounds(true);
        this.esqueleto.setCollideWorldBounds(true);

        this.background.setBounce(0);
        this.mapa.setBounce(0);
        this.caballero_Idle.setBounce(0);
        this.esqueleto.setBounce(0);

        this.physics.add.collider(this.esqueleto,this.caballero_Idle);
        this.physics.add.collider(this.esqueleto,this.mapa);
        this.physics.add.collider(this.caballero_Idle,this.mapa);

        //Controles

        this.cursor = this.input.keyboard.createCursorKeys();

        //Camara
        this.cameras.main.setBounds(0, 0, window.innerWidth, window.innerHeight);
        this.cameras.main.startFollow(this.caballero_Idle);

        //Tamaño de las HitBox
        this.caballero_Idle.setSize(30, 40); // Define el tamaño del hitbox
        this.caballero_Idle.setOffset(20, 0); // Posiciona el hitbox dentro del sprite

        this.esqueleto.setSize(30, 32);
        this.esqueleto.setOffset(15, 15);

        this.mapa.setSize(50,200);
        this.mapa.setOffset(0,15);

    };

    update(){
        if(this.cursor.left.isDown){
            this.caballero_Idle.setVelocityX(-500);
        }else if(this.cursor.right.isDown){
            this.caballero_Idle.setVelocityX(500);
        }else if(this.cursor.up.isDown){
            this.caballero_Idle.setVelocityY(-200);
        }else{
            this.caballero_Idle.setVelocityX(0);
        };

        //this.physics.moveToObject(this.esqueleto, this.caballero_Idle, 100);

         //this.cameras.main.startFollow(this.caballero_Idle);

         // Dibujar un rectángulo de depuración alrededor del hitbox del sprite
        var graphics = this.add.graphics();
        graphics.clear(); // Limpia el gráfico si ya se dibujó en el último frame
        graphics.lineStyle(2, 0xff0000, 1); // Establece el color y el grosor de la línea

        // Dibuja un rectángulo basado en el tamaño y posición del hitbox del sprite
        //graphics.strokeRect(
        //this.esqueleto.x - this.esqueleto.body.offset.x,
        //this.esqueleto.y - this.esqueleto.body.offset.y,
        //this.esqueleto.body.width,
        //this.esqueleto.body.height,
        //graphics.clear()
        //);

        //graphics.strokeRect(
        //this.caballero_Idle.x - this.caballero_Idle.body.offset.x,
        //this.caballero_Idle.y - this.caballero_Idle.body.offset.y,
        //this.caballero_Idle.body.width,
        //this.caballero_Idle.body.height,
        //graphics.clear()
        //);

        graphics.strokeRect(
        this.mapa.x - this.mapa.body.offset.x,
        this.mapa.y - this.mapa.body.offset.y,
        this.mapa.body.width,
        this.mapa.body.height,
        );

    };

};

Nuevamente una disculpa por todas las molestias y les agradezco por todo el tiempo que le dedican a esto.

Respuestas

A ver si alguna de estas cosas te puede ayusdar a resolver tus problemas.

a hitbox se está configurando después de los colliders

En tu código, primero añades las colisiones:

this.physics.add.collider(this.esqueleto, this.caballero_Idle);
this.physics.add.collider(this.esqueleto, this.mapa);
this.physics.add.collider(this.caballero_Idle, this.mapa);

Luego, más abajo, cambias el tamaño de las hitboxes con:

this.caballero_Idle.setSize(30, 40);
this.caballero_Idle.setOffset(20, 0);

this.esqueleto.setSize(30, 32);
this.esqueleto.setOffset(15, 15);

Esto puede ser un problema, porque Phaser usa los valores actuales de la hitbox cuando se crean los colliders. Si cambias el tamaño de la hitbox después, puede que las colisiones no se comporten como esperas.

Prueba a mover la configuración de la hitbox antes de crear las colisiones:

// Tamaño de las HitBox
this.caballero_Idle.setSize(30, 40);
this.caballero_Idle.setOffset(20, 0);

this.esqueleto.setSize(30, 32);
this.esqueleto.setOffset(15, 15);

// Ahora sí, agregamos colisiones
this.physics.add.collider(this.esqueleto, this.caballero_Idle);
this.physics.add.collider(this.esqueleto, this.mapa);
this.physics.add.collider(this.caballero_Idle, this.mapa);

Verifica setImmovable() y setSize() en mapa**

En tu código, configuras mapa como inamovible:

this.mapa = this.physics.add.image(0, 800, "mapa").setImmovable();

Pero luego le aplicas setSize():

this.mapa.setSize(50, 200);
this.mapa.setOffset(0, 15);

El problema es que las imágenes en Phaser no tienen cuerpos físicos por defecto. Es posible que necesites cambiar this.physics.add.image(...) por this.physics.add.sprite(...) para que mapa tenga físicas correctamente.

Como sugerencia prueba a hacer setImmovable() después de configurar el tamaño:

this.mapa.setSize(50, 200);
this.mapa.setOffset(0, 15);
this.mapa.setImmovable(true);

allowGravity en el esqueleto

Parece que estás configurando allowGravity en false para el esqueleto, lo que puede estar evitando colisiones correctas con el suelo (mapa):

this.esqueleto.body.allowGravity = false;

Igual deberías permitir la gravedad y ajustar velocity.y si es necesario

Si quieres que el esqueleto no caiga, prueba usar setImmovable() en lugar de allowGravity = false:

this.esqueleto.setImmovable(true);

O bien, si quieres que caiga pero se quede en el suelo, agrégale una velocidad inicial:

this.esqueleto.body.velocity.y = 0;

Si aún sigues teniendo problemas, habilita el modo debug en las físicas para ver si las hitboxes están bien configuradas:

const config = {
    type: Phaser.AUTO,
    width: window.innerWidth,
    height: window.innerHeight,
    scene: [Game],
    physics: {
        default: "arcade",
        arcade: {
            gravity: { y: 400 },
            debug: true // Esto activa el debug
        }
    }
};

Si las colisiones siguen sin funcionar, revisa la consola cuando activas el debug.a ver si te da alguna info que aclare más el problema.

Miguel Angel
3370 147 216 17