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