phaserjs / phaser

Phaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.
https://phaser.io
MIT License
36.94k stars 7.08k forks source link

2d Lights - Not going to add if lights goes added 10+ #6720

Closed Tajammal-Maqbool closed 7 months ago

Tajammal-Maqbool commented 7 months ago

Version

Description

I am adding Lights in my Scene and I faced a very serious issue. I was adding lights on dynamic bullets, When a limit of lights has been added and then removed, It stop adding lights to new bullets. Let me explain more, On the first maybe 10 bullets, lights going to added for each bullet but when this number goes cross then light is not goging to add to bullet.

Check here: image

I am almost sure whenever it cross then number 10 then it leaves adding lights into scene, I am sure because I have test when score goes above the 50 then not added lights because all lighted bullets goes enemeis, On each hit, I give 5 score.

Example Test Code

import Phaser from "phaser";

class GameScene extends Phaser.Scene {
    constructor() {
        super({ key: "GameScene" })

        this.player = null;
        this.gameStarted = true;
        this.bulletObjects = [];
        this.enemyObjects = [];

        this.score = 0;
        this.scoreText = null;

        this.isSoundOn = true;
        this.isMusicOn = true;
        this.soundVol = 100;
        this.musicVol = 100;
    }

    init(data) {
        this.isSoundOn = data.isSoundOn;
        this.isMusicOn = data.isMusicOn;
        this.soundVol = data.soundVol;
        this.musicVol = data.musicVol;
    }

    // single call by the phaser
    preload() {

    }

    // single call by the phaser
    create() {
        const bg = this.physics.add.image(0, 0, "bg").setPipeline("Light2D").setOrigin(0, 0).setDisplaySize(this.game.config.width, this.game.config.height);
        bg.body.allowGravity = false;
        bg.body.immovable = true;
        bg.setBodySize(1520, 80);
        bg.setOffset(0, 442);
        this.scoreText = this.add.text(10, 10, "Score: 0", {
            font: "bold 18px sans-serif"
        });

        // off white color
        this.lights.enable().setAmbientColor(0x404040);
        // var light = this.lights.addLight(400, 300, 300);

        this.player = this.physics.add.sprite(200, this.game.config.height - 140, "player").setPipeline("Light2D").setScale(0.25);
        this.player.setBodySize(200, 500);
        this.player.setOffset(40, 40);
        this.player.setBounce(0.5);
        this.player.setFriction(20);

        this.physics.add.collider(this.player, bg);

        var music = this.sound.add("music");
        music.setVolume(this.musicVol / 100);
        if (this.isMusicOn) {
            music.play({
                loop: true
            });
        }

        let timer = this.time.addEvent({
            delay: 500,
            loop: true,
            callback: () => {
                const enemy = this.physics.add.image(this.game.config.width + 100, this.game.config.height - 120, "enemy").setPipeline("Light2D").setScale(0.35).setOrigin(0.5, 0.5);
                enemy.setBodySize(170, 200);
                enemy.setOffset(50, 65);
                enemy.setVelocityX(-200)

                let colliding = this.physics.add.collider(this.player, enemy, () => {
                    console.log("colliding...");

                    music.stop();

                    colliding.destroy();
                    timer.paused = true;

                    this.scene.start("GameOverScene", {
                        score: this.score,
                        isSoundOn: this.isSoundOn,
                        isMusicOn: this.isMusicOn,
                        soundVol: this.soundVol,
                        musicVol: this.musicVol
                    });
                });

                this.physics.add.collider(enemy, this.enemyObjects, () => {
                    console.log("colliding enemies...");
                });

                this.physics.add.collider(enemy, bg);

                this.enemyObjects.push(enemy);
            },
            callbackScope: this
        });

        this.player.play("idle");

        this.input.keyboard.addListener("keydown-A", (e) => {
            if (this.gameStarted) {
                this.player.setVelocityX(-60);

                if (this.player.anims.currentAnim.key !== "walk") {
                    this.player.play("walk");
                }

                this.player.setOffset(200, 40);
                this.player.flipX = true;
            }
        });
        this.input.keyboard.addListener("keyup-A", (e) => {
            if (this.gameStarted) {
                this.player.setVelocityX(0);
                this.player.play("idle");
            }
        });
        this.input.keyboard.addListener("keydown-W", (e) => {
            if (this.gameStarted && Math.floor(this.player.body.velocity.y) <= 0 && Math.floor(this.player.body.velocity.y) >= -1) {
                this.player.setVelocityY(-140);
            }
        });
        this.input.keyboard.addListener("keydown-D", (e) => {
            if (this.gameStarted) {
                this.player.setVelocityX(60);
                if (this.player.anims.currentAnim.key !== "walk") {
                    this.player.play("walk");
                }
                this.player.setOffset(40, 40);
                this.player.flipX = false;
            }
        });
        this.input.keyboard.addListener("keyup-D", (e) => {
            if (this.gameStarted) {
                this.player.setVelocityX(0);
                this.player.play("idle");
            }
        });
this.input.keyboard.addListener("keydown-F", (e) => {
    if (this.gameStarted) {
        var shot = this.sound.add("shot");
        shot.setVolume(this.soundVol / 100);
        if (this.isSoundOn) {
            shot.play();
        }

        this.player.play("shoot");
        const bulletObject = this.physics.add.image(this.player.x + 50, this.player.y, "bullet").setPipeline("Light2D").setScale(0.35).setAngle(90);
        bulletObject.light = this.lights.addLight(bulletObject.x, bulletObject.y, 100);
        bulletObject.setBodySize(60, 10);
        bulletObject.setVelocityX(400);
        bulletObject.body.allowGravity = false;

        this.physics.add.overlap(bulletObject, this.enemyObjects, (objA, objB) => {
            objA.destroy();
            objB.destroy();

            this.bulletObjects.splice(this.bulletObjects.indexOf(objA), 1);
            this.enemyObjects.splice(this.enemyObjects.indexOf(objB), 1);

            this.tweens.add({
                targets: objA.light,
                intensity: 0,
                radius: 0,
                duration: 100,
                repeat: 0,
                onComplete: () => {
                    // this.lights.removeLight(objA.light);
                },
                callbackScope: this
            })

            this.score += 5;
            this.updateTextScore();
        });

        this.bulletObjects.push(bulletObject);
    }
});
        this.input.keyboard.addListener("keyup-F", (e) => {
            if (this.gameStarted) {
                this.time.addEvent({
                    delay: 100,
                    callback: () => {
                        this.player.play("idle");
                    }
                })
            }
        });
    }

    updateTextScore() {
        this.scoreText.setText("Score: " + this.score);
    }

    // multiple calls by the phaser
    update() {
        for (let i = 0; i < this.bulletObjects.length; i++) {
            if (this.bulletObjects[i].x > this.game.config.width) {
                this.tweens.add({
                    targets: this.bulletObjects[i].light,
                    intensity: 0,
                    radius: 0,
                    duration: 100,
                    repeat: 0,
                    onComplete: () => {
                        // this.lights.removeLight(this.bulletObjects[i].light);
                    },
                    callbackScope: this
                })

                this.bulletObjects[i].destroy();
                this.bulletObjects.splice(i, 1);
            }
            this.bulletObjects[i].light.x = this.bulletObjects[i].x;
            this.bulletObjects[i].light.y = this.bulletObjects[i].y;
        }

        for (let i = 0; i < this.enemyObjects.length; i++) {
            if (this.enemyObjects[i].x < 0) {
                this.enemyObjects[i].destroy();
                this.enemyObjects.splice(i, 1);
            }
        }
    }
}

export default GameScene;

Additional Information

This issue looking like maybe any condition before adding the lights or maybe due to adding too much lighting algorithm start working slow. Hopefully You will find the issue. Thanks for making the Phaser.io

Tajammal-Maqbool commented 7 months ago

Oohh sorry, My bad, I found the solution from chatgpt, need to increase the maxLights. Sorry for creating the issue.

import Phaser from "phaser";
import GameOverScene from "./gameOverScene";
import GameScene from "./gameScene";
import LoadingScene from "./loadingScene";
import MainMenuScene from "./mainMenuScene";
import SettingsScene from "./settingsScene";

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: "#2d2d2d",
    physics: {
        default: "arcade",
        arcade: {
            debug: false,
            gravity: {
                y: 100
            }
        }
    },
    maxLights: 100,
    parent: "body",
    dom: {
        createContainer: true
    },
    scene: [
        LoadingScene,
        MainMenuScene,
        SettingsScene,
        GameScene,
        GameOverScene
    ]
}

export default config;
photonstorm commented 7 months ago

You can increase maxLights as you've found - but I would strongly recommend you re-use the lights as well (or at least swap to using Point Lights). If the light has left the screen, or the bullet it was attached to is now destroyed, then always remove the light to free-up some resources.