Code.org Game Lab项目运行卡顿,求JavaScript代码优化方案
Code.org Game Lab游戏卡顿优化求助
我正在完成期末项目,这是一个使用JavaScript在Code.org Game Lab中开发的游戏。代码最初运行流畅毫无卡顿,但随着开发推进,运行速度大幅下降!角色开始出现延迟,最终完全无法移动。
我曾尝试将多个函数的任务合并到一个处理角色运动的函数中,起初有一定效果,但好景不长。createPlatform()函数最初运行正常,但现在也导致代码运行变慢。该函数的作用是根据传入的参数生成对应屏幕数量的平台,它原本可以正常工作,但现在已让游戏变得无法游玩。
原代码
var max_X = 200; var min_X = 50; var min_Y = 330; var platforms = []; var centered = false; var sprite = createSprite(200, 250); sprite.setAnimation("alienBlue_2"); //sprite.scale = 0.15; function draw() { startGame(2, "gray", "groundBrickPlain.png_1", 4); drawSprites(); } function startGame(levelGravity, backG, platformType, platSize) { //var Currentlevel = level; // Set the initial velocity and gravity sprite.velocityY = 0; var gravity = levelGravity; // Clear the screen background(backG); createPlatform(platSize, platformType); // Apply gravity sprite.velocityY = sprite.velocityY + gravity; move(); if ((keyDown("tab") && keyDown("right")) && centered){ chageWorldSpeed(7); } if (sprite.y >= min_Y) { console.log("You died."); } // Prevent the sprite from falling through the platform //dontFall(312, 0); // Make the sprite jump //jump(-12, "alienBlue_jump_1"); var brickN1 = createSprite(200, 200); brickN1.setAnimation("brickNormal"); } function chageWorldSpeed(speed) { for (var p = 0; p < platforms.length; p++) { platforms[p].x -= speed; } } function createPlatform(numScreens, platType) { var startX = 0; var startY = 380; var spacing = 40; var numBricks = numScreens* 400; for (var i = 0; i < numBricks; i += spacing) { var platform = createSprite(startX + i, startY); platform.setAnimation(platType); platform.scale = 0.0333333333333333333333333333; platforms.push(platform); } } function move() { // Make the sprite move if (keyDown("left")) { sprite.velocityX = -5; sprite.setAnimation("alienBlue_walk_1_copy_1"); for (var i = 0; i < platforms.length; i++) { platforms[i].x += 5; } } else if (keyDown("right")) { sprite.velocityX = 5; sprite.setAnimation("alienBlue_walk_1"); for (var t = 0; t < platforms.length; t++) { platforms[t].x -= 5; } }else if(keyDown("down")) { squat("alienBlue_duck_1"); }else { sprite.velocityX = 0; sprite.setAnimation("alienBlue_2"); } if(sprite.x == max_X && keyDown("right")) { sprite.velocityX = 0; centered = true; } if (sprite.x == min_X && keyDown("left")) { var spriteX = 5; sprite.velocityX = 0; for (var h = 0; h < platforms.length; h++) { platforms[h].x -= spriteX; } } var jumped = false; for (var m = 0; m < platforms.length; m++) { if (keyDown("space")|| (keyDown("up")) && sprite.isTouching(platforms[m])) { sprite.setAnimation("alienBlue_jump_1"); sprite.velocityY = -12; jumped = true; break; } } if (!jumped) { sprite.setAnimation("alienBlue_2"); // Reset animation if no jump occurs } for (var v = 0; v < platforms.length; v++) { if (sprite.velocityY > 0 && sprite.isTouching(platforms[v])){ sprite.velocityY = 0; sprite.y = 312; } } } function squat(anim) { sprite.setAnimation(anim); } function dontFall(yVal, yVelocity) { for (var v = 0; v < platforms.length; v++) { if (sprite.velocityY > 0 && sprite.isTouching(platforms[v])){ sprite.velocityY = yVelocity; sprite.y = yVal; } } } function blockLeft(xVal) { var spriteX = xVal; sprite.velocityX = 0; for (var h = 0; h < platforms.length; h++) { platforms[h].x -= spriteX; } }
卡顿核心原因
- 每帧重复生成平台:
draw()函数每帧执行,内部调用的startGame()又会调用createPlatform(),导致每帧生成大量平台精灵,platforms数组无限膨胀,内存占用和遍历成本急剧上升。 - 每帧创建重复精灵:
startGame()中每帧都创建brickN1精灵,持续生成新对象加重性能负担。 - 多次重复遍历数组:
move()函数中多次遍历platforms数组,数组越大,每帧的计算量就越高。
优化方案
平台只初始化一次
将createPlatform()从startGame()中移出,放到全局初始化区域,只执行一次,避免重复生成平台。移除重复创建的静态精灵
如果brickN1是静态元素,直接在全局初始化时创建一次即可,无需每帧重复生成。动态清理超出屏幕的平台
当平台移出屏幕范围时,调用removeSprite()销毁精灵,并从platforms数组中删除,防止数组无限增大;同时可以在屏幕另一侧生成新平台,实现无限地形效果。合并重复遍历逻辑
将move()中多次遍历platforms的操作合并为一次,减少循环次数,降低每帧计算量。
优化后的代码示例
var max_X = 200; var min_X = 50; var min_Y = 330; var platforms = []; var centered = false; var sprite = createSprite(200, 250); sprite.setAnimation("alienBlue_2"); // 全局初始化平台和静态砖块,只执行一次 createPlatform(4, "groundBrickPlain.png_1"); var brickN1 = createSprite(200, 200); brickN1.setAnimation("brickNormal"); function draw() { startGame(2, "gray"); drawSprites(); } function startGame(levelGravity, backG) { sprite.velocityY = 0; var gravity = levelGravity; background(backG); // 应用重力 sprite.velocityY += gravity; move(); if ((keyDown("tab") && keyDown("right")) && centered){ chageWorldSpeed(7); } if (sprite.y >= min_Y) { console.log("You died."); } } function chageWorldSpeed(speed) { for (var p = platforms.length - 1; p >= 0; p--) { var platform = platforms[p]; platform.x -= speed; // 清理左侧超出屏幕的平台,并在右侧生成新平台 if (platform.x < -20) { removeSprite(platform); platforms.splice(p, 1); var newPlatform = createSprite(420, 380); newPlatform.setAnimation("groundBrickPlain.png_1"); newPlatform.scale = 0.03333333333333333; platforms.push(newPlatform); } } } function createPlatform(numScreens, platType) { var startX = 0; var startY = 380; var spacing = 40; // 修正平台数量计算,避免生成过多无效平台 var numBricks = numScreens * 400 / spacing; for (var i = 0; i < numBricks; i++) { var platform = createSprite(startX + i * spacing, startY); platform.setAnimation(platType); platform.scale = 0.03333333333333333; platforms.push(platform); } } function move() { var moveLeft = keyDown("left"); var moveRight = keyDown("right"); var isOnPlatform = false; var jumped = false; // 处理左右移动与平台清理/生成 if (moveLeft) { sprite.velocityX = -5; sprite.setAnimation("alienBlue_walk_1_copy_1"); for (var i = platforms.length - 1; i >= 0; i--) { platforms[i].x += 5; // 清理右侧超出屏幕的平台,左侧生成新平台 if (platforms[i].x > 420) { removeSprite(platforms[i]); platforms.splice(i, 1); var newPlatform = createSprite(-20, 380); newPlatform.setAnimation("groundBrickPlain.png_1"); newPlatform.scale = 0.03333333333333333; platforms.push(newPlatform); } } } else if (moveRight) { sprite.velocityX = 5; sprite.setAnimation("alienBlue_walk_1"); for (var t = platforms.length - 1; t >= 0; t--) { platforms[t].x -= 5; // 清理左侧超出屏幕的平台,右侧生成新平台 if (platforms[t].x < -20) { removeSprite(platforms[t]); platforms.splice(t, 1); var newPlatform = createSprite(420, 380); newPlatform.setAnimation("groundBrickPlain.png_1"); newPlatform.scale = 0.03333333333333333; platforms.push(newPlatform); } } } else if(keyDown("down")) { squat("alienBlue_duck_1"); sprite.velocityX = 0; } else { sprite.velocityX = 0; sprite.setAnimation("alienBlue_2"); } // 角色边界处理 if(sprite.x >= max_X && moveRight) { sprite.velocityX = 0; centered = true; } if (sprite.x <= min_X && moveLeft) { sprite.velocityX = 0; for (var h = 0; h < platforms.length; h++) { platforms[h].x -= 5; } } // 合并碰撞检测与跳跃逻辑,一次遍历完成 for (var m = 0; m < platforms.length; m++) { var platform = platforms[m]; // 检测是否站在平台上 if (sprite.velocityY > 0 && sprite.isTouching(platform)){ sprite.velocityY = 0; sprite.y = 312; isOnPlatform = true; } // 只有站在平台上才能触发跳跃 if (isOnPlatform && (keyDown("space") || keyDown("up"))) { sprite.setAnimation("alienBlue_jump_1"); sprite.velocityY = -12; jumped = true; break; } } // 重置动画(排除移动、下蹲、跳跃状态) if (!jumped && !moveLeft && !moveRight && !keyDown("down")) { sprite.setAnimation("alienBlue_2"); } } function squat(anim) { sprite.setAnimation(anim); }
内容的提问来源于stack exchange,提问作者Renier Jr.
相关产品推荐
相关产品推荐

