首页 > 解决方案 > 如何使用 localStorage 加载变量?

问题描述

这在我之前在另一个项目上工作过,但是当我复制它时它不起作用。我得到了要保存在 JSON 文件中的变量,然后在文件加载时将其加载回来。将变量保存到gameSave变量中确实有效(它显示在控制台日志中),但我不知道变量是否没有保存到 JSON 文件中,或者 JSON 文件是否没有加载。

将其保存为文件会比在这里运行它更好localStorage

// Canvas configuration
const canvas = document.querySelector('canvas')
const context = canvas.getContext('2d')
canvas.width = innerWidth
canvas.height = innerHeight

// Spawn chance
var chance = 900
var score = 0
var highScore = 0
var time = 0
var gameSave = {}

setInterval(() => {
    if (start == 0) {
        chance = 10
    }
    if (start == 1) {
        chance = 1000000
    }

    if (time == 1) {
        chance = 800
    }
    if (time == 3) {
        chance = 700
    }
    if (time == 7) {
        chance = 500
    }
    if (time == 13) {
        chance = 300
    }
    if (time == 21) {
        chance = 250
    }
    if (time == 50) {
        chance = 200
    }
    if (time == 100) {
        chance == 150
    }
    if (time == 150) {
        chance = 100
    }
    if (time == 200) {
        chance = 90
    }
    if (time == 250) {
        chance = 80
    }
    if (time == 300) {
        chance = 70
    }
    if (time == 350) {
        chance = 65
    }
    if (time == 400) {
        chance = 60
    }
    if (time == 450) {
        chance = 55
    }
    if (time == 500) {
        chance = 40
    }

    document.getElementById('scoreSpan').innerHTML = score

}, 0);

setInterval(() => {
    saveGame()
}, 5);

// Classes
class Player {
    constructor(x, y, radius, color) {
        this.x = x
        this.y = y
        this.radius = radius
        this.color = color
    }

    draw() {
        context.beginPath()
        context.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true)
        context.fillStyle = this.color
        context.fill()
    }
}

class Bullet {
    constructor(x, y, radius, color, velocity) {
        this.x = x
        this.y = y
        this.radius = radius
        this.color = color
        this.velocity = velocity
    }
    
    draw() {
        context.beginPath()
        context.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true)
        context.fillStyle = this.color
        context.fill()
    }

    update() {
        this.draw()
        this.x = this.x + this.velocity.x
        this.y = this.y + this.velocity.y
    }
}

class Zumb {
    constructor(x, y, radius, color, velocity) {
        this.x = x
        this.y = y
        this.radius = radius
        this.color = color
        this.velocity = velocity
    }
    
    draw() {
        context.beginPath()
        context.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true)
        context.fillStyle = this.color
        context.fill()
    }

    update() {
        this.draw()
        this.x = this.x + this.velocity.x
        this.y = this.y + this.velocity.y
    }
}

const friction = 0.98
class Particle {
    constructor(x, y, radius, color, velocity) {
        this.x = x
        this.y = y
        this.radius = radius
        this.color = color
        this.velocity = velocity
        this.alpha = 1
    }

    draw() {
        context.save()
        context.globalAlpha = this.alpha
        context.beginPath()
        context.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true)
        context.fillStyle = this.color
        context.fill()
        context.restore()
    }

    update() {
        this.draw()
        this.velocity.x *= friction
        this.velocity.y *= friction
        this.x = this.x + this.velocity.x
        this.y = this.y + this.velocity.y
        this.alpha -= 0.01
    }
}


// Create entities
const x = canvas.width / 2
const y = canvas.height / 2

const player = new Player(x, y, 20, 'white')
const bullets = []
const zumbs = []
const particles = []

let start = 0
// Spawn zumbs
function spawnZumb() {
    setInterval(() => {
        const chanceNum = Math.floor(Math.random() * chance)
        if (chanceNum == 1) {
            const radius = Math.random() * 25 + 15

            let x
            let y
            var velNum = (30 / radius)
            if (velNum < 1) {
                velNum = velNum * 0.9
            }

            if (Math.random() < 0.5) {
                x = Math.random() * canvas.width
                y = Math.random() > 0.5 ? 0 - radius : canvas.height + radius
            } else {
                y = Math.random() * canvas.height
                x = Math.random() > 0.5 ? 0 - radius : canvas.width + radius
            }

            const color = `hsl(${Math.random() *360}, 53%, 68%)`

            const angle = Math.atan2(
                (canvas.height / 2) - y,
                (canvas.width / 2) - x
            )
            const velocity = {
                x: Math.cos(angle) * velNum,
                y: Math.sin(angle) * velNum
            }


            zumbs.push(new Zumb(x, y, radius, color, velocity))

            start += 1
        }
    }, 5)
}


let animationID
function animate() {
    // Frame configuration
    animationID = requestAnimationFrame(animate)

    context.fillStyle = 'rgba(0, 0, 0, 0.1)'
    context.fillRect(0, 0, canvas.width, canvas.height)

    // Remove bullets on hit
    bullets.forEach((bullet, bulletIndex) => {
        bullet.update()

        if (
            bullet.x + bullet.radius < 0
            || bullet.x - bullet.radius > canvas.width
            || bullet.y + bullet.radius < 0
            || bullet.y - bullet.radius > canvas.height
        ) {
            setTimeout(() => {
                bullets.splice(bulletIndex, 1)
            }, 0);
        }
    })

    // Draw player
    player.draw()

    particles.forEach((particle, particleIndex) => {
        if (particle.alpha <= 0) {
            particles.splice(particleIndex, 1)
        } else {
            particle.update()
        }
    })

    // Zumb configuration
    zumbs.forEach((zumb, index) => {
        zumb.update()

        // End game conditions
        const distance = Math.hypot(player.x - zumb.x, player.y - zumb.y)
        if (distance - zumb.radius - player.radius < 1) {
            endGame()
        }

        // Detect collision between Zumb and bullet
        bullets.forEach((bullet, bulletIndex) => {
            const distance = Math.hypot(bullet.x - zumb.x, bullet.y - zumb.y)

            if (distance - zumb.radius < 1) {

                // Create particles
                for (let i = 0; i < zumb.radius * 2; i++) {
                    particles.push(new Particle(
                        zumb.x,
                        zumb.y,
                        Math.random() * 2,
                        zumb.color,
                        {
                            x: (Math.random() - 0.5) * ((Math.random() * 5) + 1),
                            y: (Math.random() - 0.5) * ((Math.random() * 5) + 1)
                        }
                    ))
                }

                if (zumb.radius - 10 > 10) {
                    gsap.to(zumb, 0.2, {
                        radius: zumb.radius - 10
                    })
                    score += 1
                } else {
                    setTimeout(() => {
                        zumbs.splice(index, 1)
                        score += 1
                        time += 1
                    }, 0)
                }

                bullets.splice(bulletIndex, 1)

            }   
        })
    })
}



canvas.addEventListener('click', (event) => {
    const angle = Math.atan2(
        event.clientY - canvas.height / 2,
        event.clientX - canvas.width / 2
    )
    const velocity = {
        x: Math.cos(angle) * 5,
        y: Math.sin(angle) * 5
    }

    bullets.push(
        new Bullet(
            canvas.width / 2,
            canvas.height / 2,
            6,
            '#e9eb8d',
            velocity
        )
    )
})

function endGame() {
    cancelAnimationFrame(animationID)
    document.getElementById('overScore').innerHTML = score
    if (score > highScore) {
        highScore = score
    }
    document.getElementById('highScore').innerHTML = highScore
    document.getElementById('container').style.display = 'flex'
}

function loadGame() {
    var savedGame = JSON.parse(localStorage.getItem('gameSave'))
    if (typeof savedGame.highScore !== 'undefined') {
        highScore = savedGame.highScore
    }
}

function saveGame() {
    gameSave = {
        highScore: highScore
    }
    localStorage.setItem('gameSave', JSON.stringify(gameSave))

    console.log(gameSave)
    console.log(highScore)
}

window.onload = function() {
    loadGame()
}

function restart() {
    location.reload()
}

animate()
spawnZumb()
body {
    margin: 0;
    padding: 0;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    font-family: 'Montserrat';
}

canvas {
    display: block;
}

#score {
    position: absolute;
    top: 20px;
    left: 20px;
    color: white;

    font-size: 25px;
    font-weight: 700;

    user-select: none;
}

#container {
    position: fixed;
    width: 100vw;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    display: none;
}
.start-game {
    background-color: white;
    padding: 40px 70px;
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.scores {
    display: flex;
    flex-direction: row;
    justify-content: center;
    margin-bottom: 30px;
}
.current-score, .high-score {
    margin: 0 20px;
    text-align: center;
}
h1 {
    padding: 0;
    margin: 0;
    font-size: 50px;
    font-weight: 900;
}
p {
    padding: 0;
    margin: 0;
}
button {
    width: 100%;
    background-color: rgb(39, 78, 111);
    font-size: 16px;
    font-family: 'Montserrat';
    border: none;
    padding: 10px;
    border-radius: 50px;
    color: white;
    cursor: pointer;
}
button:hover, button:focus {
    outline-style: none;
    background-color: rgb(61, 122, 175);
}

embed {
    position: absolute;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Against Zumbs</title>
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;300;400&display=swap" rel="stylesheet">
</head>
<body>
    <canvas></canvas>

    <div id="score"><span>Score: <span id="scoreSpan">0</span></span></div>

    <div id="container">
        <div class="start-game">
            <div class="scores">
                <div class="current-score">
                    <h1 id="overScore">0</h1>
                    <p>Current score</p>
                </div>
                <div class="high-score">
                    <h1 id="highScore">0</h1>
                    <p>High score</p>
                </div>
            </div>
            <button onclick="restart()">Start Game</button>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.1/gsap.min.js"
        integrity="sha512-cdV6j5t5o24hkSciVrb8Ki6FveC2SgwGfLE31+ZQRHAeSRxYhAQskLkq3dLm8ZcWe1N3vBOEYmmbhzf7NTtFFQ=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</body>
</html>

标签: javascripthtml

解决方案


推荐阅读