编程语言
首页 > 编程语言> > javascript贪吃蛇案例

javascript贪吃蛇案例

作者:互联网

初始化(){
    初始化游戏面板和游戏分数显示区
    造蛇()
    造豆()
    监听键盘()
}

造蛇(){
    循环蛇初始化长度次{
        创造蛇的新关节,每个关节都是一个div
        蛇头变红
        蛇的新关节推入数组
        蛇的新关节的左距离为上一个蛇关节左侧
        蛇的新关节展示在面板上
    }
}

造豆(){
    if(存在旧豆){
        从游戏面板上删除旧豆
    }
    创建新豆,每个豆都是一个span
    调用随机坐标(),为新豆生成出生坐标
    随机坐标(){
        面板宽度1000除以20(豆子宽20px),等分成500份
        乘以一个随机数并取整,得出一个0-500的整数
        乘以20得到一个0-1000范围内的20的整数倍,即横坐标
        纵坐标同理
        遍历蛇关节数组{
            if(和当前豆的坐标冲突){
                随机坐标();
            }
        }
    }
    为新豆赋值横纵坐标
    将新豆追加到面板中
}

监听键盘(){
    按了左键:当方向不为右,方向改为左
    按了上键:当方向不为下,方向改为上
    按了右键:当方向不为左,方向改为右
    按了下键:当方向不为上,方向改为下
    按了空格键:暂停和开始游戏效果切换
}

游戏开始(){
    清除旧定时器
    开启新定时器{
        蛇移动()
        撞自己():判断本次移动蛇是否撞到自己
        吃豆子():判断本次移动蛇是否吃到豆子
    }
}

蛇移动(){   
    获取蛇头左距离和上距离
    判断当前蛇的移动方向{
        if(对应方向上出界){
            游戏结束()
        }
        蛇身移动()
        蛇头移动
    }
    蛇身移动(){ 
        循环所有蛇身{
            后面的关节横向顶替前面的关节
            后面的关节纵向顶替前面的关节
        }    
    }
}

撞自己(){
    遍历所有蛇身{
        if(蛇头坐标与某个蛇身关节坐标冲突){
            结束游戏()
        }     
    }
}

吃豆子(){
    if(蛇头坐标和当前豆的坐标一致){
        分数++
        创建一个新的蛇关节
        新蛇关节的出生坐标就是被吃掉豆子的坐标
        新蛇关节加入到蛇的数组中
        新蛇关节展示在游戏面板中
        造豆()
    }
}

游戏结束(){
    清空定时器
    刷新页面
    展示分数
    提示游戏结束
}

游戏暂停(){
    清空定时器
}

游戏重置(){
    刷新页面
}
复制代码

布局: snake.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>贪食蛇</title>
    <link rel="stylesheet" type="text/css" href="snake.css">
    <script type="text/javascript" src="snake.js"></script>
</head>
<body>
<header>
    <article id="head_left">贪食蛇v1.0</article>
    <article id="head_right">您当前的分数为 <span id="score">0</span> 分</article>
</header>
<section id="board"></section>
<footer>
    <button class="buttons" onclick="start();">开始 [ start ]</button>
    <button class="buttons" onclick="pause();">暂停 [ pause ]</button>
    <button class="buttons" onclick="reset();">重置 [ reset ]</button>
</footer>
</body>
</html>

复制代码

样式: snake.css

/*整体:居中*/
body {width: 1000px; margin: 0 auto;}

/*计分板:调整行高、外边距*/
header { 
    height: 30px; background-color: black; color: white;
    line-height: 30px; margin: 10px auto;
}

/*游戏标题:调整左边距、忽略内边距和边框、左漂浮、文字倾斜、字间距*/
#head_left { 
    width: 700px; padding-left: 20px; box-sizing: border-box; 
    float: left; font-style: italic; letter-spacing: 10px;
}

/*计分提示:调整右内边距、忽略内边距和边框、右浮动、文字居右*/
#head_right { 
    width: 300px; padding-right: 20px; box-sizing: border-box; 
    float: right; text-align: right;
}

/*分数数字:文字加粗,下划线*/
#score { 
    color: yellow; font-weight: bold; text-decoration: underline;
}

/*游戏面板:居中、父元素设置成相对点*/
#board { 
    height: 500px; background-color: black;
    margin: 0 auto; position: relative;
}

/*豆子:显示为区块、圆角、z轴、绝对定位*/
#board span { 
    width: 20px; height: 20px; background-color: yellow;
    display: block; border-radius: 50%; 
    z-index: 0; position: absolute; 
}

/*蛇:圆角、绝对定位、z轴*/
#board div { 
    width: 20px; height: 20px; background-color: skyblue; 
    border-radius: 50%; position: absolute; z-index: 1; 
}

/*功能按钮区:内容居中*/
footer { text-align: center; }

/*功能按钮:文字颜色、外边距*/
footer .buttons{ 
    width: 150px; height: 30px;background-color: black;
    color: yellow; margin: 10px; 
}
复制代码

脚本: snake.js

let snakeArray = []; /*初始化蛇关节的数组*/
let isPause = false; /*游戏是否暂停:未暂停*/
let snakeSize = 5; /*蛇的初始长度*/
let direct = "right"; /*蛇初始方向:向右*/
let speed = 80; /*蛇移动初始速度:80*/
let score, timer, board, bean; /*游戏初始分数显示区,定时器,面板,豆*/

// 初始化(){
onload = () => {
    //     初始化游戏面板和游戏分数显示区
    board = document.querySelector("#board");
    score = document.querySelector("#score");
    //     造蛇()
    createSnake();
    //     造豆()
    createBean();
    //     监听键盘()
    keyListener();
};

// 造蛇(){
function createSnake() {
    //     循环蛇初始化长度次{
    for (let i = 0; i < snakeSize; i++) {
        //         创造蛇的新关节,每个关节都是一个div
        let snake = document.createElement("div");
        //         蛇头变红
        if (i === 0) {
            snake["style"]["backgroundColor"] = "red";
        }
        //         蛇的新关节推入数组
        snakeArray.push(snake);
        //         蛇的新关节的左距离为上一个蛇关节左侧
        snake["style"]["left"] = (snakeSize - i - 1) * 20 + "px";
        //         蛇的新关节展示在面板上
        board.appendChild(snake);
    }
}

// 造豆(){
function createBean() {
    //     if(存在旧豆){
    if (bean) {
        //     从游戏面板上删除旧豆
        board.removeChild(bean);
    }
    //     创建新豆,每个豆都是一个span
    bean = document.createElement("span");
    let x = null, y = null;
    //     调用随机坐标(),为新豆生成出生坐标
    randomXY();

    //     随机坐标(){
    function randomXY() {
//         面板宽度1000除以20(豆子宽20px),等分成500份
//         乘以一个随机数并取整,得出一个0-500的整数
//         乘以20得到一个0-1000范围内的20的整数倍,即横坐标
//         纵坐标同理
        x = parseInt("" + (Math.random() * (1000 / 20))) * 20;
        y = parseInt("" + (Math.random() * (500 / 20))) * 20;

//         遍历蛇关节数组{
        for (let i = 0; i < snakeArray.length; i++) {
            //             if(和当前豆的坐标冲突){
            if (snakeArray[i]["offsetLeft"] === x) {
                if (snakeArray[i]["offsetTop"] === y) {
//                 随机坐标();
                    randomXY();
                    break;
                }
            }
        }
    }

//     为新豆赋值横纵坐标
    bean["style"]["left"] = x + "px";
    bean["style"]["top"] = y + "px";
//     将新豆追加到面板中
    board.appendChild(bean);
}

//监听键盘
function keyListener() {
    document.onkeydown = event => {
        let oEvent = event || window.event;
        switch (oEvent.keyCode) {
            case 37 :
                //     按了左键:当方向不为右,方向改为左
                if (direct !== "right") {
                    direct = "left";
                }
                break;
            case 38 :
                //     按了上键:当方向不为下,方向改为上
                if (direct !== "down") {
                    direct = "up";
                }
                break;
            case 39 :
                //     按了右键:当方向不为左,方向改为右
                if (direct !== "left") {
                    direct = "right";
                }
                break;
            case 40 :
                //     按了下键:当方向不为上,方向改为下
                if (direct !== "up") {
                    direct = "down";
                }
                break;
            case 32 :
                //     按了空格键:暂停和开始游戏效果切换
                if (!isPause) {
                    pause();
                } else {
                    start();
                }
                isPause = !isPause;
                break;
        }
    }
}

// 游戏开始(){
function start() {
    //     清除旧定时器
    clearInterval(timer);
    //     开启新定时器{
    timer = setInterval(() => {
//     蛇移动()
        move();
//     撞自己():判断本次移动蛇是否撞到自己
        isHit();
//      吃豆子():判断本次移动蛇是否吃到豆子
        isEat();
    }, speed);
}

// 蛇移动(){
function move() {
    //     获取蛇头左距离和上距离
    let hLeft = snakeArray[0].offsetLeft;
    let hTop = snakeArray[0].offsetTop;
//     判断当前蛇的移动方向{
    switch (direct) {
        case "left":
//         if(对应方向上出界){
            if (hLeft <= 0) {
//             游戏结束()
                gameover();
                return;
            }
//         蛇身移动()
            snakeBodyMove();
//         蛇头移动
            snakeArray[0]["style"]["left"] = hLeft - 20 + "px";
            break;
        case "up":
            if (hTop <= 0) {
                gameover();
                return;
            }
            snakeBodyMove();
            snakeArray[0]["style"]["top"] = hTop - 20 + "px";
            break;
        case "right":
            if (hLeft >= 1000 - 20) {
                gameover();
                return;
            }
            snakeBodyMove();
            snakeArray[0]["style"]["left"] = hLeft + 20 + "px";
            break;
        case "down":
            if (hTop >= 500 - 20) {
                gameover();
                return;
            }
            snakeBodyMove();
            snakeArray[0]["style"]["top"] = hTop + 20 + "px";
            break;
    }

//     蛇身移动(){
    function snakeBodyMove() {
        //         循环所有蛇身{
        for (let i = snakeArray.length - 1; i > 0; i--) {
            //             后面的关节横向顶替前面的关节
            snakeArray[i]["style"]["left"] = snakeArray[i - 1]["style"]["left"];
            //             后面的关节纵向顶替前面的关节
            snakeArray[i]["style"]["top"] = snakeArray[i - 1]["style"]["top"];
        }
    }
}

/*判断本次移动是否撞到自己*/
function isHit() {
    //     遍历所有蛇身{
    for (let i = 1, j = snakeArray.length; i < j; i++) {
        //         if(蛇头坐标与某个蛇身关节坐标冲突){
        if (snakeArray[0].offsetLeft === snakeArray[i].offsetLeft) {
            if (snakeArray[0].offsetTop === snakeArray[i].offsetTop) {
                //             结束游戏()
                gameover();
                break;
            }
        }
    }
}


// 吃豆子(){
function isEat() {
    //     if(蛇头坐标和当前豆的坐标一致){
    if (snakeArray[0].offsetLeft === bean.offsetLeft) {
        if (snakeArray[0].offsetTop === bean.offsetTop) {
            //         分数++
            score.innerText = parseInt(score.innerText) + 1;
            //         创建一个新的蛇关节
            let snake = document.createElement("div");
            //         新蛇关节的出生坐标就是被吃掉豆子的坐标
            snake["style"]["left"] = bean["style"]["left"];
            snake["style"]["top"] = bean["style"]["top"];
            //         新蛇关节加入到蛇的数组中
            snakeArray.push(snake);
            //         新蛇关节展示在游戏面板中
            board.appendChild(snake);
            //         造豆()
            createBean();
        }
    }
}

// 游戏结束(){
function gameover() {
    //     清空定时器
    clearInterval(timer);
    //     刷新页面
    location.reload();
    //     提示游戏结束
    alert("game over!");
}


// 游戏暂停(){
function pause() {
    //     清空定时器
    clearInterval(timer)
}


// 游戏重置(){
function reset() {
    //     刷新页面
    location.reload();
}



标签:style,游戏,javascript,案例,贪吃蛇,let,坐标,关节,snakeArray
来源: https://www.cnblogs.com/wjlynew/p/13929816.html