JavaScript游戏运行随着时间慢慢

JavaScript Game run slowly over time

我正在用 JS 编写游戏代码, 运行 很好,但是随着时间的推移,FPS 会变慢。 搜索到这里后,我认为问题可能来自图像加载,但我不知道如何使用该函数来 运行 图像加载后的代码。 此外,我的代码在 DOMContentLoaded addevenlistener 中。 问题真的可以从图像负载中提供吗? 谢谢!

这是我的一段代码

function animate() {    
    ctx.resetTransform();
    ctx.translate(-(player.x - canvas.width / 2), -(player.y - canvas.height / 2)); //for center the character on the map
    ctx.drawImage(Images_array[1], 0, 0, canvasSize.width / 1.1, canvasSize.height / 1.1, 0, 0, canvasSize.width, canvasSize.height); //drawing the background
    // enterInHouse();
    drawSprite(Images_array[0], player.width * player.frameX, player.height * player.frameY, player.width, player.height, player.x, player.y, player.width * scale, player.height * scale) // drawing the sprite
    movePlayer() 
    handlePlayerFrame()
    // collisionRedbox()
    // displaGameboy()
    // if (inHouse === false) {
    //     createBluebox.enterInCollision(blackBoxs, player)    
    // }  
    window.requestAnimationFrame(animate); 
    }
    animate()
    window.addEventListener('resize', displayCanvas)

我是这样加载图片的。

const playerSprite = new Image();
    playerSprite.src = "img/main_chara.png ";
    const background = new Image();
    background.src = "img/background.png";
    const office = new Image();
    office.src = "img/interieur_git.png";
    const retraining = new Image();
    retraining.src = 'img/reconversion.png';
    const contact = new Image();
    contact.src = 'img/contact_me.png';
    const grangeOne= new Image();
    grangeOne.src = 'img/grange.png'
    const house= new Image();
    house.src = 'img/maison.png'
    const bigHouse= new Image();
    bigHouse.src='img/maison_principale.png'

如果您愿意,我可以向您展示更多代码。 非常感谢你帮助我

您可以使用 onload 函数了解图像何时加载,然后开始游戏。

const playerSprite = new Image();
playerSprite.src = "img/main_chara.png ";
playerSprite.onload = function(){}

更多信息: https://www.techrepublic.com/article/preloading-and-the-javascript-image-object/

您在动画的每个绘图上都绑定了一个事件监听器。

window.addEventListener('resize', displayCanvas)

所以在 60 fps 的 1 秒后你有 60 个事件监听器,2 秒后有 120 个,一分钟后有 3600 个事件监听器,十分钟后有 36000 个

绑定事件处理程序一次,将其绑定在 animate() 函数之外。

此外,在 https://maxlassort.github.io/MyWorld/index.js

查看您的代码

您拥有在每一帧调用的函数 moveplayer()。

function movePlayer() {
        action_btnt.addEventListener('touchstart', function (e) {
            (actionBtn=true)
            e.stopPropagation();
        },{ passive: true })
       
        up.addEventListener('touchstart', function (e) {
            (movingUp=true)
            player.moving = true
            e.stopPropagation();
        },{ passive: true })
        up.addEventListener('touchend', function () {
            movingUp=false
            player.moving = false
        },{ passive: true })
        right.addEventListener('touchstart', function (e) {
            (movingRight=true)
            player.moving = true
            e.stopPropagation();
        },{ passive: true })
        right.addEventListener('touchend', function () {
            movingRight=false
            player.moving = false
        },{ passive: true })
        down.addEventListener('touchstart', function (e) {
            (movingDown=true)
            player.moving = true
            e.stopPropagation();
        },{ passive: true })
        down.addEventListener('touchend', function () {
            movingDown=false
            player.moving = false
        },{ passive: true })
        left.addEventListener('touchstart', function (e) {
            (movingLeft=true)
            player.moving = true
            e.stopPropagation();
        },{ passive: true })
        left.addEventListener('touchend', function () {
            movingLeft=false
            player.moving = false
        },{ passive: true })


        if(openPannels===false) {
          if(movingRight===false && movingLeft===false){
            if (movingDown===true && player.y < 2000) {
                player.y += player.speed
                player.frameY = 0;
                player.moving = true
            }
            if (movingUp===true && player.y > 360) {
                player.y -= player.speed
                player.frameY = 3;
                player.moving = true
            }
          }
            if (movingRight===true && player.x < 3000) {
                player.x += player.speed
                player.frameY = 2;
                player.moving = true
            }
            if (movingLeft===true && player.x > 360) {
                player.x -= player.speed
                player.frameY = 1;
                player.moving = true
            }
        }
    }

此函数有 9 个事件侦听器,每个 framedraw 都绑定。所以每秒 9 * 60,导致每个绘制帧有 32400 个绑定事件。

还将这些事件处理程序放在 moveplayer 函数之外。这样他们只绑定一次,可以访问您的 javascript 上下文变量。

        action_btnt.addEventListener('touchstart', function (e) {
            (actionBtn=true)
            e.stopPropagation();
        },{ passive: true })

        up.addEventListener('touchstart', function (e) {
            (movingUp=true)
            player.moving = true
            e.stopPropagation();
        },{ passive: true })
        up.addEventListener('touchend', function () {
            movingUp=false
            player.moving = false
        },{ passive: true })
        right.addEventListener('touchstart', function (e) {
            (movingRight=true)
            player.moving = true
            e.stopPropagation();
        },{ passive: true })
        right.addEventListener('touchend', function () {
            movingRight=false
            player.moving = false
        },{ passive: true })
        down.addEventListener('touchstart', function (e) {
            (movingDown=true)
            player.moving = true
            e.stopPropagation();
        },{ passive: true })
        down.addEventListener('touchend', function () {
            movingDown=false
            player.moving = false
        },{ passive: true })
        left.addEventListener('touchstart', function (e) {
            (movingLeft=true)
            player.moving = true
            e.stopPropagation();
        },{ passive: true })
        left.addEventListener('touchend', function () {
            movingLeft=false
            player.moving = false
         },{ passive: true })

function movePlayer() {

        if(openPannels===false) {
          if(movingRight===false && movingLeft===false){
            if (movingDown===true && player.y < 2000) {
                player.y += player.speed
                player.frameY = 0;
                player.moving = true
            }
            if (movingUp===true && player.y > 360) {
                player.y -= player.speed
                player.frameY = 3;
                player.moving = true
            }
          }
            if (movingRight===true && player.x < 3000) {
                player.x += player.speed
                player.frameY = 2;
                player.moving = true
            }
            if (movingLeft===true && player.x > 360) {
                player.x -= player.speed
                player.frameY = 1;
                player.moving = true
            }
        }
    }