1. 程式人生 > >原生JS之貪吃蛇

原生JS之貪吃蛇

注:本文章程式碼根據網上教程所編寫(略有改動)

 

html

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>貪吃蛇</title>
    <link rel="stylesheet" href="snake.css">
</head>

<body>
    <div class="startPage" id="startPage">
        <div class="startBtn" id="startBtn"></div>
    </div>
    <div class="wrapper">
        <div class="left-side">
            <img src="img/start.png" alt="" id="start">
            <img src="img/pause.png" alt="" id="pause">
        </div>
        <div class="main">
            <div class="header">
                <div class="score">
                    分數:
                    <span id="score"></span>
                </div>
            </div>
            <div class="content" id="content">

            </div>
        </div>
    </div>
    <!-- 遊戲失敗的彈窗 -->
    <div class="loser" id="loser">
        <div class="con">
            <div class="close" id="close"></div>
            <span class="loserScore" id="loserScore"></span>
        </div>
    </div>



    <script src="snake.js"></script>
</body>

</html>

 

css

* {
    margin: 0;
    padding: 0;
}

.startPage {
    width: 100%;
    height: 100%;
    z-index: 999;
    position: absolute;
    top: 0;
    left: 0;
    /* display: none; */
}

.startBtn {
    background-image: url("img/startGame.png");
    height: 170px;
    width: 200px;
    background-size: 100% 100%;
    cursor: pointer;
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    margin: auto;
}

.wrapper {
    width: 100%;
    height: 100%;
    background-image: url('img/bg.jpg');
    background-size: 100% 100%;
    position: relative;
}

.left-side {
    width: 24%;
    position: absolute;
    height: 20%;
    /* border: 1px solid black; */
    top: 65%;
    left: 38%;
}

.left-side img {
    display: none;
    float: left;
    margin-left: 50px;
    margin-top: 50px;
    cursor: pointer;
}

.main {
    position: absolute;
    left: 25%;
    width: 50%;
    height: 70%;
    /* border: 1px solid black; */
}

.header {
    width: 100%;
    height: 80px;
    text-align: center;
}

.score {
    line-height: 80px;
    color: #dddddd;
    font-size: 20px;
    font-weight: bold;
}

.content {
    position: absolute;
    width: 79.5%;
    height: 48%;
    left: 10%;
    top: 43%;
    /* border: 1px solid black; */
}

.loser {
    display: none;
    width: 100%;
    height: 1000px;
    top: 0;
    left: 0;
}

.con {
    background-image: url('img/startP.jpg');
    background-size: 100% 100%;
    width: 400px;
    height: 300px;
    position: absolute;
    margin: auto;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: 20px;
}

.close {
    background-image: url('img/closeBtn.png');
    background-size: 100% 100%;
    position: absolute;
    top: 0;
    right: 0;
    height: 40px;
    width: 40px;
    cursor: pointer;
}

.loserScore {
   
    height: 30px;
    height: 40px;
    position: absolute;
    top: 42%;
    left: 40%;
    color: #222222;
    font-size: 30px;
    font-weight: bold;
}

.food {
    background-image: url('img/apple.png');
    background-size: 100% 100%;
}

/* 蛇頭 */

.head {
    background-image: url('img/head.png');
    background-size: 100% 100%;
}

/* 蛇身 */

.body {
    background-image: url('img/body.png');
    background-size: 100% 100%;
}

 

Js

程式碼設計思路

//點選開始遊戲--startPage消失--遊戲開始

//隨機出現食物、出現三節蛇開始運動

//上下左右---改變運動方向

//判斷是否吃到食物---食物消失,蛇身+1

//判斷遊戲結束--彈框

程式碼

var content = document.getElementById('content');
var startPage = document.getElementById('startPage');
var scoreBox = document.getElementById('score');
var loser = document.getElementById('loser');
var loseScore = document.getElementById('loserScore');
var closeBtn = document.getElementById('close');
var startBtn = document.getElementById('startBtn');
var start = document.getElementById('start');
var pause = document.getElementById('pause');
var startGameBool = true;
var startPaushBool = true;
var code;
var snakeMove;
var speed = 300;
init();
//初始化函式
function init() {
    //地圖
    this.mapW = parseInt(getComputedStyle(content).width); //取得地圖寬
    this.mapH = parseInt(getComputedStyle(content).height); //取得地圖高

    this.mapDiv = content;

    //食物
    this.foodW = 20; //食物寬度
    this.foodH = 20; //食物高度
    this.foodX = 0;
    this.foodY = 0;
    //蛇
    this.snakeW = 20;
    this.snakeH = 20;
    this.SnakeBody = [
        [3, 1, 'head'],
        [2, 1, 'body'],
        [1, 1, 'body']
    ];
    //遊戲屬性
    this.direct = 'right';
    //當方向為右時  只能上/下操作 不能左/右操作
    this.left = false;
    this.right = false;
    this.up = true;
    this.down = true;

    this.score = 0;

}
bindEvent();

function StartGame() {

    food();
    snake();
    bindEvent();
}
//生成食物
function food() {
    var food = document.createElement('div');
    food.style.width = this.foodW + 'px';
    food.style.height = this.foodH + 'px';
    food.style.position = 'absolute';
    this.foodX = Math.floor(Math.random() * (this.mapW / 20));
    this.foodY = Math.floor(Math.random() * (this.mapH / 20));
    food.style.left = this.foodX * 20 + 'px';
    food.style.top = this.foodY * 20 + 'px';
    this.mapDiv.appendChild(food).setAttribute('class', 'food');

    for(var i=0;i<this.SnakeBody.length;i++){
        if(this.foodX==SnakeBody[i][0]&&this.foodY== SnakeBody[i][1]){
            food();
        }
    }
}
//生成蛇
function snake() {

    for (var i = 0; i < this.SnakeBody.length; i++) {

        var snake = document.createElement('div');
        snake.style.width = this.snakeW + 'px';
        snake.style.height = this.snakeH + 'px';
        snake.style.position = 'absolute';
        snake.style.left = this.SnakeBody[i][0] * 20 + 'px';
        snake.style.top = this.SnakeBody[i][1] * 20 + 'px';
        snake.classList.add(this.SnakeBody[i][2]);
        this.mapDiv.appendChild(snake).classList.add('snake');
        switch (this.direct) {
            case 'right':

                break;
            case 'up':
                snake.style.transform = 'rotate(270deg)';
                break;
            case 'left':
                snake.style.transform = 'rotate(180deg)';

                break;
            case 'down':
                snake.style.transform = 'rotate(90deg)';

                break;
            default:
                break;
        }
    }
}
//運動
function move() {

    for (var i = this.SnakeBody.length - 1; i > 0; i--) {
        this.SnakeBody[i][0] = this.SnakeBody[i - 1][0];
        this.SnakeBody[i][1] = this.SnakeBody[i - 1][1];

    }
    switch (this.direct) {
        case 'right':
            this.SnakeBody[0][0] += 1;
            break;
        case 'up':
            this.SnakeBody[0][1] -= 1;
            break;
        case 'left':
            this.SnakeBody[0][0] -= 1;
            break;
        case 'down':
            this.SnakeBody[0][1] += 1;
            break;
        default:
            break;
    }

    removeClass('snake');
    snake();
    //蛇吃到食物
    if (this.SnakeBody[0][0] == this.foodX && this.SnakeBody[0][1] == this.foodY) {

        //獲取最後一個蛇身的位置
        var snakeEndX = this.SnakeBody[this.SnakeBody.length - 1][0];
        var snakeEndY = this.SnakeBody[this.SnakeBody.length - 1][1];
        switch (this.direct) {
            case 'right':
                this.SnakeBody.push([snakeEndX + 1, snakeEndY, 'body']);
                break;
            case 'up':
                this.SnakeBody.push([snakeEndX, snakeEndY - 1, 'body']);
                break;
            case 'left':
                this.SnakeBody.push([snakeEndX - 1, snakeEndY, 'body']);
                break;
            case 'down':
                this.SnakeBody.push([snakeEndX, snakeEndY + 1, 'body']);
                break;
            default:
                break;
        }

        this.score += 1;
        scoreBox.innerHTML = this.score;
        removeClass('food');
        food();
    }

    //判斷邊界
    //碰到左/右邊界
    if (this.SnakeBody[0][0] < 0 || this.SnakeBody[0][0] >= this.mapW / 20) {

        // console.log("gg");
        relodGame();
    }
    //碰到上/下邊界
    if (this.SnakeBody[0][1] < 0 || this.SnakeBody[0][1] >= this.mapH / 20) {
        // console.log("gg");
        relodGame();

    }
    //蛇頭的座標
    var snakeHX = this.SnakeBody[0][0];
    var snakeHY = this.SnakeBody[0][1];
    for (var i = 1; i < this.SnakeBody.length; i++) {
        if (snakeHX == SnakeBody[i][0] && snakeHY == SnakeBody[i][1]) {
            // console.log("gg");
            relodGame();

        }
    }

    
}
//遊戲結束後 重置遊戲
function relodGame() {
    removeClass('snake');
    removeClass('food');
    clearInterval(snakeMove);
    this.SnakeBody = [
        [3, 1, 'head'],
        [2, 1, 'body'],
        [1, 1, 'body']
    ];
    this.left = false;
    this.right = false;
    this.up = true;
    this.down = true;

    loser.style.display = 'block';
    loseScore.innerHTML = this.score;
    this.score = 0;
    scoreBox.innerHTML = this.score;
    startGameBool = true;
    startPaushBool = true;
   
}

function removeClass(className) {
    var ele = document.getElementsByClassName(className);
    while (ele.length > 0) {
        ele[0].parentNode.removeChild(ele[0]);
    }
}

function setDirect(code) {
    switch (code) {
        case 37:
            if (this.left) {
                this.direct = 'left';
                this.left = false;
                this.right = false;
                this.up = true;
                this.down = true;
            }
            break;
        case 38:
            if (this.up) {
                this.direct = 'up';
                this.left = true;
                this.right = true;
                this.up = false;
                this.down = false;
            }
            break;
        case 39:
            if (this.right) {
                this.direct = 'right';
                this.left = false;
                this.right = false;
                this.up = true;
                this.down = true;
            }
            break;
        case 40:
            if (this.down) {
                this.direct = 'down';
                this.left = true;
                this.right = true;
                this.up = false;
                this.down = false;
            }
            break;
        default:
            break;
    }
}

function bindEvent() {
    closeBtn.onclick = function () {
        loser.style.display = 'none';
        startPage.style.display = 'block';
        start.style.display = 'none';
        pause.style.display = 'none';
      
    }
    startBtn.onclick = function () {
        startPage.style.display = 'none';
        start.style.display = 'block';
        pause.style.display = 'block';
        //此處初始化 為了防止當再次開始遊戲時的方向傳送改變
        init();

        StartGame();
        document.onkeydown = function (e) {

            code = e.keyCode;
            setDirect(code);
        }


        snakeMove = setInterval(function () {
            move();
        }, speed);
    }
    start.onclick = function () {

        startAgain();
    }
    pause.onclick = function () {
        stop();
    }
}

function startAgain() {
    document.onkeydown = function (e) {
        var code = e.keyCode;
        setDirect(code);
    }
    snakeMove = setInterval(function () {
        move();
    }, speed);
}

function stop() {
    clearInterval(snakeMove);
    document.onkeydown = function (e) {
        e.returnValue = false;
        return false;
    };
}