首页 > 解决方案 > 在 HTML Canvas 中更新分数的函数之外的其他函数中使用更新的分数时遇到问题

问题描述

我正在创建一个基本的射击游戏,您可以在其中杀死怪物以获得积分。在创建新敌人的过程中,我想要一个系统,当你的分数达到一定数量时它们会生成,但由于某种原因,分数不会在我的动画功能之外更新,导致新敌人不会生成。这是我的情况的相关代码。这是我的第一个问题,所以如果我在提问的方式上做错了什么,请告诉我。谢谢!

let score = 0;

//enemy variables
let enemyX;
let enemyY;
let enemyRadius;
let enemyColor;
let enemySpeed;
let enemyHealth;
//big enemy variables
let bigenemyX;
let bigenemyY;
let bigenemyRadius;
let bigenemyColor;
let bigenemySpeed;
let bigenemyHealth;

//spawn enemies function; responsible for spawning the basic enemies
const spawnEnemies = () => {
    setInterval(() => {
        //enemy variables
        enemyY = Math.random() * canvas.height;
        enemyRadius = 50;
        enemyX = canvas.width + enemyRadius;
        enemyColor = 'green';
        enemySpeed = 7;
        enemyHealth = 150;
        //creates a new enemy into the enemies array every second
        enemies.push(new Enemy(enemyX, enemyY, enemyRadius, enemyColor, enemySpeed, enemyHealth))
    }, 1000)
}

//spawn big enemies function; responsible for spawning the big enemies
const spawnBigEnemies = () => {
    setInterval(() => {
        //big enemy variables
        bigenemyY = Math.random() * canvas.height;
        bigenemyRadius = 100;
        bigenemyX = canvas.width + bigenemyRadius;
        bigenemyColor = 'pink';
        bigenemySpeed = 3;
        bigenemyHealth = 500;
        //creates a new big enemy into the enemies array every ten seconds
        enemies.push(new Enemy(bigenemyX, bigenemyY, bigenemyRadius, bigenemyColor, bigenemySpeed, bigenemyHealth))
    }, 10000)
}


const animate = () => {
enemies.forEach((enemy, index) => {
        //enemy dies
        if (enemy.health === 0) {
            //removes enemy from enemies array
            enemies.splice(index, 1)
            //increases score by 1 if regular enemy is killed
            if (enemy.radius === enemyRadius) {
                score ++;
                scoreHTML.innerHTML = score;
            }
            //increases score by 5 if big enemy is killed
            else if (enemy.radius === bigenemyRadius) {
                score += 5;
                scoreHTML.innerHTML = score;
            }
        }
        
        //game ends if rocket and enemy collide or no lives remaining
        if (collides(rocket, enemy) || lives === 0) {
            //pauses animation on canvas
            cancelAnimationFrame(animationId)
            //game over screen displays
            gameOverModal.style.display = 'flex'
            //displays score on game over screen
            pointsHTML.innerHTML = score;
        }
        //if enemy goes off screen
        if (enemy.x - enemy.radius <= 0) {
            //deletes the enemy from enemies array
            enemies.splice(index, 1);
            //lives go down
            lives --;
            //lives counter is updated
            livesHTML.innerHTML = lives;
        }
    })
}
}

//spawns enemies on screen
spawnEnemies()
//TESTING for big enemy spawning
if (score >= 50) {
    spawnBigEnemies()
}

标签: javascripthtmlhtml5-canvasgame-development

解决方案


因此,if当浏览器解析您的代码时,最后一条语句只运行一次。但是,到那时,用户显然不会达到 50 的分数,因此该if语句永远不会运行spawnBigEnemies()

如何解决:您需要一种“观察”分数的方法,以确定何时产生新的敌人。我不能准确地给你一个解决方案,因为我看不到你所有的代码。但是,如果您想在 JS 中“观察”一个变量,这是供您参考的:如何检测变量何时更改 JavaScript 中的值?

P/S: 你也只希望函数spawnBigEnemies()在分数达到 50 后被调用一次,因为你setInterval在这个函数中使用

编辑

let isSpawning = true;
const spawnEnemies = () => {
    setInterval(() => {
        //your codes    
        ...
        if (score >= 50 && isSpawning) {
            spawnBigEnemies();
            isSpawning = false;
        }
    }, 1000)
}

推荐阅读