【代码】Javascript贪吃蛇源代码

RWYQ阿伟 | 2023-04-12 | 笔记 | 0条留言 | 2456 | 2023-04-12更新

【代码】Javascript贪吃蛇源代码

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Game by Dinaki -->
    <meta charset="UTF-8">
    <title>Snake</title>
</head>
<body>
    <canvas id='game'></canvas>
    
    <script>
        const game = document.getElementById('game'),
              ctx = game.getContext('2d');

        const width = 800,
              height = 600,
              bgColor = '#000',
              snakeColor = '#fff',
              foodColor = 'red',
              fontColor = "#eee",
              snakeSize = 20;

        let snake = new Snake(),
            fruit = new Fruit(),
            highScore = localStorage['highScore'] || 1;

        setInterval(update, 1000/10)

        game.width = width;
        game.height = height;

        function update() {
            // Collision
            if (snake.tail.length > 2) {
                for (let i = 0; i < snake.tail.length - 1; i++) {
                    if (snake.tail[i].x === snake.pos.x && snake.tail[i].y === snake.pos.y) {
                        snake.restart();
                    }
                }
            }
            if (snake.pos.x == fruit.pos.x && snake.pos.y == fruit.pos.y) {
                snake.grow();
                fruit.randomPos();
            }
            
            ctx.fillStyle = bgColor;
            ctx.fillRect(0,0,width,height)
            
            ctx.fillStyle = fontColor;
            ctx.font = "20px Arial";
            ctx.fillText("Score: " + snake.tail.length, 20, 40);
            ctx.fillText("High Score: " + highScore, width - 160, 40);
            
            if (snake.tail.length > highScore) {
                highScore = snake.tail.length;
                localStorage['highScore'] = highScore;
            }
            
            ctx.fillStyle = snakeColor;
            //ctx.fillRect(snake.pos.x, snake.pos.y, snakeSize, snakeSize);
            snake.tail.forEach(tPos => ctx.fillRect(tPos.x + 1, tPos.y + 1, snakeSize - 2, snakeSize - 2));
            
            ctx.fillStyle = foodColor;
            ctx.fillRect(fruit.pos.x, fruit.pos.y, snakeSize, snakeSize);
            
            if (snake.pos.x < 0) {
                snake.pos = { x: width - snakeSize, y: snake.pos.y };
            }

            if (snake.pos.x >= width) {
                snake.pos = { x: 0, y: snake.pos.y };
            }

            if (snake.pos.y < 0) {
                snake.pos = { x: snake.pos.x, y: height - snakeSize };
            }

            if (snake.pos.y >= height) {
                snake.pos = { x: snake.pos.x, y: 0 };
            }
            

            snake.move();
        }

        // Events
        document.onkeyup = function(event) {
            switch (event.keyCode) {
                case 37:
                    if (snake.currSpeed.x !== 1) {
                        snake.speed.x = -1;
                        snake.speed.y = 0;
                    }
                    break;
                case 38:
                    if (snake.currSpeed.y !== 1) {
                        snake.speed.y = -1;
                        snake.speed.x = 0;
                    }
                    break;
                case 39:
                    if (snake.currSpeed.x !== -1) {
                        snake.speed.x = 1;
                        snake.speed.y = 0;
                    }
                    break;
                case 40:
                    if (snake.currSpeed.y !== -1) {
                        snake.speed.x = 0;
                        snake.speed.y = 1;
                    }
                    break;
            }
        }

        // Snake class
        function Snake() {
            this.tail = [{x: 0, y: 0}];
            this.speed = {
                x: 1,
                y: 0
            }
            this.currSpeed = { x: 1, y: 0 };
            
            this.restart = function() {
                this.tail = [{ x: 0, y: 0 }];
                this.speed.x = 1;
                this.speed.y = 0;
            }
            this.move = function() {
                let newPos = { x: this.pos.x, y: this.pos.y };
                if (snake.speed.x > 0) {
                    newPos.x += snakeSize;
                } else if (snake.speed.x < 0) {
                    newPos.x -= snakeSize;
                }
                if (snake.speed.y > 0) {
                    newPos.y += snakeSize;
                } else if (snake.speed.y < 0) {
                    newPos.y -= snakeSize;
                }
                
                this.tail.splice(0, 1);
                this.tail.push(newPos);
                
                this.currSpeed = { x: this.speed.x, y: this.speed.y };
            }
            this.grow = function() {
                let newTail = { x: this.pos.x, y: this.pos.y };
                if (snake.speed.x > 0) {
                    newTail.x += snakeSize;
                } else if (snake.speed.x < 0) {
                    newTail.x -= snakeSize;
                }
                if (snake.speed.y > 0) {
                    newTail.y += snakeSize;
                } else if (snake.speed.y < 0) {
                    newTail.y -= snakeSize;
                }
                
                this.tail.push(newTail);
            }
            
            Object.defineProperty(this, 'pos', {
                get: function() {
                    return this.tail[this.tail.length - 1]
                },
                set: function(val) {
                    this.tail[this.tail.length -1] = val;
                }
            })
            return this;
        }

        // Fruit class
        function Fruit() {
            this.pos = {
                x: 400,
                y: 200
            };
            this.randomPos = function() {
                let col = Math.floor(width / snakeSize),
                    row = Math.floor(height / snakeSize);
                
                let rndX = Math.floor(Math.random() * (col)) * snakeSize,
                    rndY = Math.floor(Math.random() * (row)) * snakeSize;
                
                this.pos = { x: rndX, y: rndY };
            }
            
            return this;
        }
    </script>
</body>
</html>

效果如下,可以使用键盘控制


博客内容遵循 署名-非商业性使用-相同方式共享4.0国际(CC BY-NC-SA 4.0)协议。

本文链接:https://rwyqboy.top/post/743.html

版权声明:本文由阿伟的笔记本发布,如需转载请注明出处。

...

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。