HTML5 + js 贪吃蛇游戏设计与实现

游戏截图:



游戏架构:

此游戏架构大概分为三层:


Game.html:

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

 

完整代码:



html5 snake game


 

 
你的浏览器不支持这个游戏!
  




    
////游戏画板
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").οnclick=function(){
GameStart(context,contxtScore);
}
 
////暂停/继续
$("btnPauseGame").onclick =function(){
          if($("btnPauseGame").value == "继续"){
          RunGame(context,contxtScore);
          $("btnPauseGame").value = "暂停";
          gameStatus = 1;
          }
          else{
          PauseGame();
          $("btnPauseGame").value = "继续";
          gameStatus = 2;
          }
}
 
////加载
          window.οnlοad=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").οnchange=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);
}


 
 

 
Game.js:
说明:包含了游戏的主干逻辑,业务逻辑层的实现。
完整代码:
document.write("");
document.write("");
document.write("");
document.write("");
////////////////////////
////游戏入口////////////
////////////////////////
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";
}
}
 
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"////食物颜色
 
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:(暂时没有用到,用于扩展),系统全局控制,例如场景绘制



你可能感兴趣的:(HTML5,Javascript)