Javascript 在HTML画布中更新分数的函数之外的其他函数中使用更新的分数时遇到问题
我正在创建一个基本的射击游戏,你可以通过杀死怪物来获得分数。在创建新敌人的过程中,我想要一个系统,当你的分数达到某个数字时,他们会繁殖,但由于某种原因,分数不会在我的动画功能之外更新,导致新敌人不会繁殖。这是与我的情况相关的代码。这是我的第一个问题,所以如果我问问题的方式有任何错误,请告诉我。谢谢大家!Javascript 在HTML画布中更新分数的函数之外的其他函数中使用更新的分数时遇到问题,javascript,html,html5-canvas,game-development,Javascript,Html,Html5 Canvas,Game Development,我正在创建一个基本的射击游戏,你可以通过杀死怪物来获得分数。在创建新敌人的过程中,我想要一个系统,当你的分数达到某个数字时,他们会繁殖,但由于某种原因,分数不会在我的动画功能之外更新,导致新敌人不会繁殖。这是与我的情况相关的代码。这是我的第一个问题,所以如果我问问题的方式有任何错误,请告诉我。谢谢大家! let score = 0; //enemy variables let enemyX; let enemyY; let enemyRadius; let enemyColor; let en
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()
}
let得分=0;
//敌人变数
让灌肠;
让灌肠;
让灌肠半径;
让艾尼霉素;
让敌人加速;
让我们保持健康;
//大敌变数
让bigenemyX;
让仇视;
让Bigenemy半径;
让双生色;
让死敌加快速度;
让我们保持健康;
//繁殖敌人功能;负责繁殖基本敌人
const spawners=()=>{
设置间隔(()=>{
//敌人变数
enemyY=Math.random()*canvas.height;
灌肠半径=50;
enemyX=canvas.width+enemyRadius;
enemyColor=‘绿色’;
敌人速度=7;
enemyHealth=150;
//每秒在敌人阵列中创建一个新敌人
敌人。推(新敌人(灌肠,灌肠,灌肠半径,灌肠颜色,灌肠速度,灌肠健康))
}, 1000)
}
//产卵大敌功能;负责繁殖大型敌人
const spawnbigfriends=()=>{
设置间隔(()=>{
//大敌变数
bigenemyY=Math.random()*canvas.height;
双基因半径=100;
bigenemyX=canvas.width+bigenemyRadius;
bigenemyColor='粉红色';
bigeneyspeed=3;
bigenemyHealth=500;
//每10秒在敌人阵列中创建一个新的大敌人
敌人。推(新敌人(bigenemyX,bigenemyY,bigenemyRadius,bigenemyColor,bigenemySpeed,bigenemyHealth))
}, 10000)
}
常量动画=()=>{
敌人。forEach((敌人,索引)=>{
//敌人死了
如果(敌方健康===0){
//从敌人阵列中移除敌人
3.拼接(索引,1)
//如果杀死普通敌人,则增加1分
如果(敌方半径===敌方半径){
分数++;
scoreHTML.innerHTML=分数;
}
//如果杀死大敌人,则增加5分
else if(敌方半径===敌我半径){
分数+=5分;
scoreHTML.innerHTML=分数;
}
}
//若火箭和敌人相撞或者并没有剩余生命,游戏结束
如果(碰撞(火箭,敌人)| |生命===0){
//暂停画布上的动画
取消动画帧(动画ID)
//屏幕显示游戏
gameOverModal.style.display='flex'
//在游戏屏幕上显示分数
pointsHTML.innerHTML=分数;
}
//如果敌人离开屏幕
如果(敌方x-敌方半径=50){
()
}
我不是专家,但我猜分数不会更新,因为您使用的是let
术语。您可能希望使用var
将范围变为全局范围。按照您现在的代码方式,分数只会在函数内部发生变化
//在这里声明let。
设i=0;
for(让i=0;i这样,当浏览器解析代码时,最后一个if
语句只运行一次。然而,到那时,用户显然不会达到50分,因此if
语句永远不会运行spawnbighouses()
如何修复:你需要一种方法来“观察”分数,以确定何时产生新的敌人。我不能给你一个解决方案,因为我看不到你的所有代码。但如果你想“观察”JS中的变量,这是供你参考的:
p/S:
您还只希望在分数达到50分后调用函数spawnbighouses()
,因为您在此函数中使用了setInterval
编辑
let isSpawning = true;
const spawnEnemies = () => {
setInterval(() => {
//your codes
...
if (score >= 50 && isSpawning) {
spawnBigEnemies();
isSpawning = false;
}
}, 1000)
}
我可以看到,在javascript执行后,您会立即检查分数>50。由于分数最初为零,这将永远不会起作用。在您更改分数时,请执行此检查。在您的情况下,只有当普通敌人被杀死时,您的分数才会更改(在大敌人之前),因此只需在此处添加此检查
在这里加了支票-
if (enemy.radius === enemyRadius) {
score ++;
//TESTING for big enemy spawning
if (score >= 5) { // do additional check with a flag so that this condition only evaluates to true only once
spawnBigEnemies()
}
scoreHTML.innerHTML = score;
}
最终代码-
//画布设置
const canvas=document.querySelector('canvas');
const ctx=canvas.getContext('2d',{alpha:false});
//设置画布尺寸
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
//全局变量
分数=0;
让生命=10;
放松=错误;
失望=错误;
让spawn=false;
//dom变量
让scoreHTML=document.getElementById('score');
让livesHTML=document.getElementById('lives');
const startGameButton=document.getElementById('startgamebtn');
const gameOverModal=document.getElementById('gameOverModal');
设pointsHTML=document.getElementById('points');
//玩家变量
让playerX=100;
让playerY=100;
让playerWidth=100;
让playerHeight=100;
让playerColor='红色';
让玩家速度=12;
//项目符号变量
半径取5;
让bulletColor='白色';
速度=20;
//敌人变数
让灌肠;
让灌肠;
让灌肠半径;
让艾尼霉素;
让敌人加速;
让我们保持健康;
//大敌变数
让bigenemyX;
让仇视;
让Bigenemy半径;
让双生色;
让死敌加快速度;
让我们保持健康;
//火箭级
级火箭{
构造器(x、y、宽度、高度、颜色、dy){
这个.x=x;
这个。y=y;
这个。宽度=宽度;
高度=高度;
这个颜色=颜色;
this.dy=dy;
}
//火箭牵引功能
画(){
ctx.fillStyle=this.color;
ctx.fillRect(this.x,this.y,this.width,this.heig