HTML 5 + CSS 3 + JavaSript 實現貪喫蛇

HTML 5 + CSS 3 + JavaSript 實現貪喫蛇

在這裏插入圖片描述

參考代碼:經典貪喫蛇源碼(含註釋)

源代碼

<!DOCTYPE html>
<html>
<head>
<title>Retro Snake</title>
<link rel="icon" href="https://raw.githubusercontent.com/CourserLi/JavaScirpt-snake/master/head.ico" type="image/x-icon"/>
<style type="text/css">
    body {background-image:url(https://raw.githubusercontent.com/CourserLi/JavaScirpt-snake/master/pic.jpg);background-size:100%;}
    body {background-repeat:no-repeat;}
    body {margin:100px;text-align:center;}  
    h1 {font-size:210%;}
    h1 {font-family:Georgia,Serif;}
</style>
</head>
<body>
<!--設置id,寬400像素,高400像素,背景顏色設置爲灰色-->
<canvas id="canv" width="400" height="400" style="background-color:gray"></canvas>
</canvas>
<h1>Courser Li</h1>

<script>
    //聲明變量
    //設置canvas畫布的繪圖的環境,當前唯一支持的參數是2d
    var box=document.getElementById('canv').getContext('2d');  //用於繪製矩形的變量
    //聲明一個變量表示蛇
    var snake;
    //聲明鍵盤事件的變量,1表示向右,-1向左,20向下,-20向上
    var direction;
    //聲明蛇頭
    var n;
    //聲明食物變量
    var food;
    //聲明速度初始變量
    speed=100;

    //繪製地圖
    function draw(point,color)
    {
        //fillStyle()方法爲設置用於填充繪畫的顏色
        box.fillStyle=color;
        //fillRect()方法用於繪製“被填充”的矩形
        box.fillRect(point%20*20+1,~~(point/20)*20+1,18,18);  //行 列 長 寬(長寬不能大於20,因爲要在矩形直接留間隙)
    }
    
    //各種變量初始化,背景初始化
    function ready()
    {
        //循環繪製地圖塊
        for(var i=0;i<400;i++)
            draw(i,"#313131");
        //對蛇和食物進行靜態賦值並繪製到地圖上
        snake=[66,65,64];
        direction=1;  //起始方向向右
        food=344;
        draw(food,"yellow");
        draw(66,"#00b7ee");
        draw(65,"#00b7ee");
        draw(64,"#00b7ee");
    }
    //自動運行函數
    (function(){ready();}());

    //核心算法
    function run()
    {
        //在遊戲開始以後“開始遊戲”按鈕變爲不可點擊狀態
        document.getElementById("butn").setAttribute("disabled",true);
        //用unshift()方法向數組的開頭添加一個新元素,新元素爲蛇下一步所移動的座標
        snake.unshift(n=snake[0]+direction);
        //邊界判斷,如果蛇頭碰到上下左右四個邊或者碰到自己的身子
        //遊戲結束,初始化遊戲,將“開始遊戲”按鈕設置爲可以點擊,點擊開始按鈕可以重新進行遊戲
        if(snake.indexOf(n,1)>0||n<0||n>399||(direction==-1&&n%20==19)||(direction==1&&n%20==0))
        {
            ready();
            document.getElementById("butn").removeAttribute("disabled");
            return alert("遊戲結束");
        }
        //如果蛇頭沒有碰到邊界或蛇身,在地圖上繪製蛇頭
        draw(n,"#00b7ee");
        //如果蛇頭喫到了食物(座標相同)
        if(n==food)
        {
            //隨機在地圖上產生一個新食物,新事物不能於蛇身子重合
            //Math.random()是令系統隨機選取大於等於 0.0 且小於 1.0 的僞隨機 double 值
            while(snake.indexOf(food=~~(Math.random()*400))>=0);
            //繪製食物
            draw(food,"yellow");
        }
        //如果蛇頭沒有喫到食物
        else
        {
            //將蛇尾元素刪除並且根據刪除的座標繪製爲地圖塊的顏色
            draw(snake.pop(),"#313131");
        }
        //每100毫秒重複執行一次該函數
        setTimeout(arguments.callee,speed);
    }

    //添加鍵盤事件
    document.onkeydown=function(e)
    {
        //如果蛇當前橫着走,當鍵盤輸入up時,將蛇頭方向改爲向上,輸入down時將蛇頭方向改爲向下
        if((direction==1||direction==-1)&&(snake[0]-snake[1]==1||snake[0]-snake[1]==-1))
        {
            if(e.keyCode==38)  //上
                direction=-20;
            if(e.keyCode==40)  //下
                direction=20;
        }
        //如果蛇當前豎着走,當鍵盤輸入left時向左,right時向右
        if((direction==20||direction==-20)&&(snake[0]-snake[1]==20||snake[0]-snake[1]==-20))
        {
            if(e.keyCode==39)  //右
                direction=1;
            if(e.keyCode==37)  //左
                direction=-1;
        }
    }
</script>
<div>
    <button id="butn" type="button" onclick="run()">開始遊戲</button>
</div>
</body>
</html>

相關屬性與方法

<canvas id="canvas" width="300" height="300" style="background-color:write"> 
var box=document.getElementById('canv').getContext('2d'); //兩種方法寫在一起

box.fillStyle = 'green';  //繪製矩形的顏色
box.fillRect(10, 10, 150, 100);  //描繪矩形的位置及大小

canvas 元素
直接在 html 標籤中設置 width 和 height 屬性並使用 JavaScript 來指定畫布背景爲白色

.getElementById() 方法
獲取 < canvas > 標籤的引用

.getContext() 方法
渲染圖像(目前只有 2d)

fillStyle 屬性
讓長方形變成綠色

.fillRect() 方法
將它的左上角放在(10, 10),把它的大小設置成寬150高100
在這裏插入圖片描述

補充

JavaScript中 ~~ 的使用方法

~~ 代表雙非按位取反運算符
對於正數,它向下取整;對於負數,向上取整;對於非數字,取值爲 0

~~0;         // => 0
~~null;      // => 0
~~{};        // => 0
~~false;     // => 0
~~true;      // => 1
~~1.9;       // => 1
~~-1.9;      // => -1

JavaScript中 .indexOf 方法
返回 某個指定的字符串值在字符串中首次出現的位置 或 元素在列表中首次出現的位置,若找不到則返回 -1

var str="Hello world!"
document.write(str.indexOf("Hello") + "<br/>")
document.write(str.indexOf("World") + "<br/>")
document.write(str.indexOf("world"))

output:
0
-1
6

解決bug

問題: 若 run 函數一輪循環接收多個鍵位會導致遊戲強制結束
解決方法: 調整鍵盤事件僅當 snake 數組前兩個元素相鄰時(矩形緊挨時)才能執行,而只有 run 函數結束上一輪循環時,snake 數組纔開始接收鍵位,也就是一輪循環,只能接收一個鍵位

:
if(direction==1||direction==-1)
if(direction==20||direction==-20):
if((direction==1||direction==-1)&&(snake[0]-snake[1]==1||snake[0]-snake[1]==-1))
if((direction==20||direction==-20)&&(snake[0]-snake[1]==20||snake[0]-snake[1]==-20))

原本我還想加入一些有趣的玩法,奈何實力不足,我想等我有能力了再重新加入這些玩法,想加入的玩法如下:

  • 隨着時間貪喫蛇的速度會減少,但吃了一個食物速度會增加 一點,相當於競速模式,獲勝的條件即速度到達某個值 或 長度大於某個值(這個我本可以實現,但無法具體在網頁上顯示具體數值就,所以還是不加了)
  • 添加暫停按鈕(最好加個快捷鍵)
  • 失敗與勝利的彈出窗口改變樣式
  • 貪喫蛇初始位置隨機(本代碼是靜態生成,但食物是動態生成的)
  • 顏色隨着位置的改變而改變(七彩蛇)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章