HTML5 + js 貪吃蛇游戲設計與實現

m47c 9年前發布 | 54K 次閱讀 HTML5 游戲開發

游戲截圖:

HTML5 + js 貪吃蛇游戲設計與實現


游戲架構:

此游戲架構大概分為三層:

HTML5 + js 貪吃蛇游戲設計與實現

Game.html:

說明:包含了界面的展示,以及一些事件的入口。

 

完整代碼:

    <html>  
    <head>  
    <title>html5 snake game</title>  
    <script src ="game.js"></script>  
    </head>  

    <body>  

    <table>  
    <tr>  
    <td>  
    <!-- 
    游戲面板 
    -->  
    <canvas id="cvsPnl"style="top:0px;border:5px solid;color:#FF9900" width="10"height="10" >你的瀏覽器不支持這個游戲!</canvas>  
    </td>  
    <td valign="top">  
    <!-- 
    配置面板 
    -->  
    <div id="divSpeed">  
    <canvas id="cvsSpeed"width="120px" height="55px" ></canvas>  
    <select id="selSpeed">  
    <optionvalueoptionvalue="1000">1000</option>  
    <optionvalueoptionvalue="800">800</option>  
    <optionvalueoptionvalue="500">500</option>  
    <optionvalueoptionvalue="300">300</option>  
    <optionvalueoptionvalue="200">200</option>  
    </select>  
    </div>  

    <div id="divGameCtl">  
    <input id="btnStartGame"type="button" value="開始"></input>    
    <input id="btnPauseGame"type="button" value="暫停"></input>  
    <br />  
    </div>  
    <br />  
    <div id="divPlayerName">  

    <canvas id="cvsName"width="50px" height="52px"></canvas><inputtypeinputtype="text" id="txtName"style="width:120px;"></input>  
    <input id="btnRememberMe"value="記住我" type="button"></input>  
    </div>  

    <div>  
    <canvas id="cvsScore"></canvas>  
    </div>  


    </td>  
    </tr>  
    <table>  


    <dividdivid="debug"></div>  
       

    <scripttype="text/javascript">  

    ////游戲畫板  
    var canvasGamePnl =document.getElementById("cvsPnl");  
    var context =canvasGamePnl.getContext("2d");  

    ////分數  
    var canvasScore =document.getElementById("cvsScore");  
    var contxtScore =canvasScore.getContext("2d");  

    ////速度  
    var canvasSpeed =document.getElementById("cvsSpeed");  
    var contxtSpeed =canvasSpeed.getContext("2d");  

    ////姓名  
    var canvasName =document.getElementById("cvsName");  
    var contxtName =canvasName.getContext("2d");  

    ////開始  
    $("btnStartGame").onclick=function(){  
    GameStart(context,contxtScore);  
    }  

    ////暫停/繼續  
    $("btnPauseGame").onclick =function(){  
              if($("btnPauseGame").value == "繼續"){  
              RunGame(context,contxtScore);  
              $("btnPauseGame").value = "暫停";  
              gameStatus = 1;  
              }  
              else{  
              PauseGame();  
              $("btnPauseGame").value = "繼續";  
              gameStatus = 2;  
              }  
    }  

    ////加載  
              window.onload=function(){  
              $("cvsPnl").width =screenWidth;  
              $("cvsPnl").height=screenHeight;  
        $("selSpeed").selectedIndex = 0;  

              DrawFont(contxtSpeed,"選擇游戲速度",120);  
              DrawFont(contxtName,"姓名",50);  

              $("txtName").value =GetPlayerName();  
              }  



    ////鍵盤事件handler  
        document.onkeydown = function (){  
         var key = document.all ? event.keyCode : arguments[0].keyCode;  
               ////left  
               if(key == 37){  
               if(direction != "right"){  
               direction = "left";  
               }  
               }  
               ////up  
               else if(key == 38){  
               if(direction != "down"){  
               direction ="up";  
               }  
               }  
               ////right  
               else if(key == 39){  
               if(direction != "left"){  
               direction = "right";  
               }  
               }  
               ////down  
               else if(key == 40){  
               if(direction != "up"){  
               direction = "down";  
               }  
               }  
        }  

              ////設置速度  
              $("selSpeed").onchange=function(){  
              if(gameStatus != 3){  
              sleepTime =parseInt(GetSelectObj("selSpeed").value);  
              }  

              }  

              /////記住我  
              $("btnRememberMe").onclick =function(){  
              ScorePlayerName($("txtName").value);  
              alert("已保存");  
              }  




    ////繪出文字  
    function DrawFont(context,txt,size){  
     context.font='30px impact';  
     context.fillStyle=fontColor;  
     context.textAlign='left';  
    // context.shadowColor="#00ff00";  
    // context.shadowOffsetX = 15;  
    // context.shadowOffsetY=-10;  
     context.fillText(txt,0,50,size);  
    }  
    </script>  
    </body>  


    </html>  

    Game.js:  
    說明:包含了游戲的主干邏輯,業務邏輯層的實現。  
    完整代碼:  
    document.write("<scriptlanguage='javascript' src='config.js'></script>");  
    document.write("<scriptlanguage='javascript' src='utility.js'></script>");  
    document.write("<scriptlanguage='javascript' src='player.js'></script>");  
    document.write("<scriptlanguage='javascript' src='global.js'></script>");  
    ////////////////////////  
    ////游戲入口////////////  
    ////////////////////////  
    function GameStart(context,contxtScore){  

    InitGame(context,contxtScore);  
    RunGame(context,contxtScore);  
    }  


    ////////////////////////  
    ////初始化游戲////////////  
    ////////////////////////  
    function InitGame(context,contxtScore){  

    ////貪吃蛇  
    for(var i = initSize ;i > 0;i --){  
    snakeArr[i - 1] = new Object();  
    snakeArr[i - 1].x = (initSize - i + 1) *unitSize;  
    snakeArr[i - 1].y = 0;  
    }  
    ////方向  
    direction = "right";  
    ////食物  
    food = new Object();  

    ////繪制屏幕方格  
    DrawScreen(context);  
    ////隨即食物  
    RandomFood(context);  
    ////分數  
    DrawScore(contxtScore,score);  


    }  

    ////////////////////////  
    ////運行游戲////////////  
    ////////////////////////  
    function RunGame(context,contxtScore){  
    if(timer){  
    clearInterval(timer);  
    }  

    timer = setInterval(function(){  
    if(IsGameOver()){  
             alert("gameover!");  
    clearInterval(timer);  
    return;  
    }  
    EatFoodHandler(context,contxtScore);  
    Refresh(context);  
    SetPosition();  
    DrawSnake(context);  

    },sleepTime);  
    }  


    ////////////////////////  
    ////刷新////////////////  
    ////////////////////////  
    function Refresh(context){  
    FillRect(context,snakeArr[snakeArr.length -1].x,snakeArr[snakeArr.length - 1].y,unitSize,unitSize,screenColor);  
    DrawRect(context,snakeArr[snakeArr.length -1].x,snakeArr[snakeArr.length - 1].y,unitSize,unitSize,lineColor);  
    }  


    ////////////////////////  
    ////畫蛇身//////////////  
    ////////////////////////  
    function DrawSnake(context){  

    for(var i = 0;i < snakeArr.length;i ++){  
    FillRect(context,snakeArr[i].x,snakeArr[i].y,unitSize,unitSize,snakeColor);  
    DrawRect(context,snakeArr[i].x,snakeArr[i].y,unitSize,unitSize,lineColor);  
    }  
    }  

    ////////////////////////  
    ////畫屏幕//////////////  
    ////////////////////////  
    function DrawScreen(context){  
    for(var i = screenLeft;i < screenLeft +screenWidth / unitSize;i ++){  
    for(var j = screenTop;j < screenTop +screenHeight / unitSize;j ++){  
    FillRect(context,i * unitSize,j *unitSize,unitSize,unitSize,screenColor);  
    DrawRect(context,i * unitSize,j *unitSize,unitSize,unitSize,lineColor);  
    }  
    }  
    }  

    ////////////////////////  
    ////設置坐標////////////  
    ////////////////////////  
    function SetPosition(){  

    for(var i = snakeArr.length - 2;i >= 0;i --){  
    snakeArr[i + 1].x = snakeArr[i].x;  
    snakeArr[i + 1].y = snakeArr[i].y;  

    }  
    if(direction == "left"){  
    snakeArr[0].x -= unitSize;  
    }  
    else if(direction == "right"){  
    snakeArr[0].x += unitSize;  
    }  
    else if(direction == "up"){  
    snakeArr[0].y -= unitSize;  
    }  
    else if(direction == "down"){  
    snakeArr[0].y += unitSize;  
    }  
    }  

    ////////////////////////  
    ////判斷是否結束游戲///  
    ////////////////////////  
    function IsGameOver(){  
    if(snakeArr[0].x < 0 ||snakeArr[0].x> screenWidth){  
    return true;  
    }  
    if(snakeArr[0].y < 0 ||snakeArr[0].y> screenHeight){  
    return true;  
    }  

    for(var i = 1;i < snakeArr.length;i ++){  
    if(snakeArr[0].x == snakeArr[i].x&& snakeArr[0].y == snakeArr[i].y){  
             gameStatus= 3;  
    return true;  
    }  
    }  
    return false;  
    }  


    ////////////////////////  
    ////隨即食物////////////  
    ////////////////////////  
    function RandomFood(context){  

    food.x = GetRandom((screenWidth / unitSize)- 1) * unitSize;  
    food.y = GetRandom((screenHeight /unitSize) - 1) * unitSize;  
    for(var i = 0;i < snakeArr.length;i ++){  
    if(food.x == snakeArr[i].x &&food.y == snakeArr[i].y){  
    RandomFood(context);  
    }  
    }  

    FillRect(context,food.x ,food.y,unitSize,unitSize,foodColor);////utility.js  
    DrawRect(context,food.x ,food.y,unitSize,unitSize,lineColor);////utility.js  

    }  

    ////////////////////////  
    ///食物處理/////////////  
    ////////////////////////  
    functionEatFoodHandler(context,contxtScore){  

    if(direction == "left"){  
    if((snakeArr[0].x - unitSize == food.x)&& snakeArr[0].y == food.y){  

             IncreaseLen(contxtScore);  
             ClearFood(context);  
             RandomFood(context);  
    }  
    }  
    else if(direction == "right"){  
    if(snakeArr[0].x + unitSize == food.x&& snakeArr[0].y == food.y){  

             IncreaseLen(contxtScore);  
             ClearFood(context);  
             RandomFood(context);  
    }  
    }  
    else if(direction == "up"){  
    if(snakeArr[0].x == food.x &&(snakeArr[0].y - unitSize == food.y)){  

             IncreaseLen(contxtScore);  
             ClearFood(context);  
             RandomFood(context);  
    }  
    }  
    else if(direction == "down"){  
    if(snakeArr[0].x == food.x &&snakeArr[0].y + unitSize == food.y){  

             IncreaseLen(contxtScore);  
             ClearFood(context);  
             RandomFood(context);  
    }  
    }  

    }  

    ////////////////////////  
    ////清除食物////////////  
    ////////////////////////  
    function ClearFood(context){  
    FillRect(context,food.x,food.y,unitSize,unitSize,screenColor);  
    DrawRect(context,food.x,food.y,unitSize,unitSize,lineColor);  

    }  

    ////////////////////////  
    ////增加長度////////////  
    ////////////////////////  
    function IncreaseLen(contxtScore){  

    var newObj = new Object();  
    newObj.x = food.x;  
    newObj.y = food.y;  
    snakeArr.unshift(newObj);  

    ////分數增加  
    IncreaseScore(contxtScore);////player.js  

    }  

    ////暫停  
    function PauseGame(){  
             clearInterval(timer);  
    }  

    Utility.js:  
    說明:提供了一些工具方法,工具層。  
    完整代碼:  

    ////返回客戶端對象  
    function $(clientId){  
    return document.getElementById(clientId);  
    }  

    ////獲得SELECT選中項  
    function GetSelectObj(clientId){  
    var obj = $(clientId);  

    var index = obj.selectedIndex; // 選中索引  
    return obj.options[index];  
    }  

    ////調試使用  
    function DebugVar(param){  
    $("debug").innerHTML=param;  
    }  

    function DebugTxt(text){  
    $("debug").innerHTML = text;  
    }  

    ////畫方塊  
    functionDrawRect(context,left,right,width,height,color){  
                       //設置填充樣式  
                       context.strokeStyle= color;  
                       context.strokeRect(left,right,width, height);  
    }  

    ////填充方塊  
    functionFillRect(context,left,right,width,height,color){  
                       //設置填充樣式  
                       context.fillStyle= color;  
                       context.fillRect(left,right,width,height);  
    }  

    ////繪畫文字  
    function DrawScore(context,txt){  

     context.moveTo(0,0);  
     context.clearRect(0,0,500,500);  

     context.font='60px impact';  
     context.fillStyle=fontColor;  
     context.textAlign='center';  
    // context.shadowColor="#00ff00";  
    // context.shadowOffsetX = 15;  
    // context.shadowOffsetY=-10;  
    txt = "分數:" + txt;  
     context.fillText(txt,100,100,fontSize);   

    }  

    ////繪制漸變  
    function ScreenGradient(context){  

    var grd =context.createLinearGradient(0,0,screenWidth,screenHeight);  
    grd.addColorStop(0,"#FFCC00");  
    grd.addColorStop(1,"#99FFFF");  
    context.fillStyle = grd;  
    context.fillRect(0,0,screenWidth,screenHeight);  
    }  

    ////生產隨機數  
    function GetRandom(n){returnMath.floor(Math.random()*n+1)}  

    ////存儲鍵值對  
    function addKV(k,v){  
    localStorage.setItem(k,v);  

    }  

    ////取得鍵值對的值  
    function getV(k){  
    return localStorage.getItem(k);  
    }  

    ////獲得本地存儲的所有值并轉化為字符串  
    function getAllValueToStr(){  
    var content = "";  
     for(var i=0;i<localStorage.length;i++){  
     //key(i)獲得相應的鍵,再用getItem()方法獲得對應的值  
      content += localStorage.key(i)+ " : " +localStorage.getItem(localStorage.key(i)) + "<br />";  
    }  
    }  

    Player.js:  
    說明:包含了玩家的一些操作,game.js下面一層,屬于業務邏輯輔助層。  
    完整實現:  

    function GetPlayerName(){  
             varname = getV("userName");  
    return name != null ? name : "newplayer" ;  
    }  

    function IncreaseScore(context){  
    score += 10;  
    DrawScore(context,score);////utility.js  
    }  

    function ScorePlayerName(name){  
    addKV("userName",name);  
    }  

    Config.js:  
    說明:游戲相關配置以及變量,系統配置層。  
    完整代碼:  
    ////////////////////////  
    ////變量、配置參數//////  
    ////////////////////////  


    var screenWidth = 800;////屏幕寬度  
    var screenHeight = 500;////屏幕高度  
    var unitSize = 20;////單元格大小  
    var initSize = 3;////初始長度  
    var screenLeft = 0;////屏幕橫起始坐標  
    var screenTop = 0;////屏幕縱起始坐標  
    var snakeArr = new Array();////貪吃蛇數組  
    var food;////食物  
    var snakeColor = "#009999";////蛇身顏色  
    var direction;////蛇的方向  


    var screenColor = "#99CCFF";////屏幕顏色  
    var lineColor = "#ffffff";////線條顏色(方格)  
    var lineWidth = 3;////線條寬度  
    var foodColor = "#FFCC00"http:////食物顏色  

    var fontColor = "#996600";////分數顏色  
    var fontSize = 300;////分數字體大小  


    var timer;////定時器  
    var sleepTime = 200;////休眠時間  
    var level=0;////級別  
    var score=0;////分數  
    var currentPlayer;////當前玩家  

    var gameStatus = 0;////0:未開始 1:運行 2:暫停 3:已結束  

    global.js:(暫時沒有用到,用于擴展),系統全局控制,例如場景繪制  

來自:http://blog.csdn.net/lan_liang/article/details/6657697

 本文由用戶 m47c 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!