先看结果截图(界面很丑,但是主要是为了贪吃蛇游戏算法设计和历史记录、排行榜功能的实现,希望以后不被产品经理打,哈哈)
功能描述:
1.开始游戏页面之前输入玩家姓名
2.历史记录:可以查看之前自己玩过的记录(历史记录存储在本机硬盘,所以即使电脑重新开启,下一次也能读取到之前的记录)
3.排行榜:历史玩家的记录
4.清除记录:清除所有存储在本机的记录
实现:
<html>
<head>
<meta charset="utf-8">
<title>mySnacktitle>
<style>
#canvas{border: 1px #000000 solid;
background: #9DE5F4;
display: inline;
margin-top: 80px;
margin-left:50px;
float:left;
}
style>
head>
<body>
<canvas id="canvas" width="450" height="450" >canvas>
<div id="message" style="border:1px solid black;width: 300px;height: 450px;margin-top: 80px;margin-right:100px;float:right">
<button id="pause">暂停button>
<button onclick="javascript:location.reload();" type="button">重新开始button>
<div>div><br/>
<div>当前玩家:<span id="name">span>div><br/>
<div>得分:<span id="score">0span>div><br/>
<div><button id="historyScore_button" onclick="displayHistory()">历史记录button>
<ul id="historyScore">
ul>
div>
<div><button id="ranking_button" onclick="displayRanking()"> 排行榜button>
<ul id="ranking">
ul>
div>
<div>
<button id="clearStorage" onclick="clearStorage()">清除记录button>
div>
div>
body>
<script type="text/javascript">
var canva = document.getElementById("canvas");
var ctx = canva.getContext("2d");//它指定了二维绘图,并且导致这个方法返回一个环境对象,该对象导出一个二维绘图 API
var snakes = [];//定义蛇
var foodX = 0; //食物X轴坐标
var foodY = 0; //食物Y轴坐标
var snakecount = 6;
var size = 15; //格子的长度
var interval = null; //计时器
var toGo = 3; //行进方向
var currentscore=0;//当前得分
var flag=false;//false表示当前用户是新用户,true为老用户
var currentName;//当前用户
var isPause=false;
window.onload = function(){
initMes();
start();
interval = setInterval(move,100);//间隔
document.onkeydown = function(event){
var event = event || window.event;
keydown(event.keyCode);
}
};
function clearStorage() {
localStorage.clear();
alert("记录已清除");
}
function displayRanking() {
var historyMessage=JSON.parse(localStorage.getItem("messageStorage"));//用户历史信息
var ranking=new Array();
for(var i=0;ivar player=historyMessage[i];
var name_highScore={};
var currentScore=player.score;//当前玩家历史得分数组
var currentHighScore=currentScore[0];//当前玩家最高分
for(var j=0;jif(currentHighScore//将玩家以及对应的最高分组成的对象放入数组中
}
//对数组按照分数排序
var k, m, tmp;
for (k = 1; k < ranking.length; k++)
{
tmp = ranking[k];
m = k - 1;
while (m>=0 && tmp.score < ranking[m].score)
{
ranking[m + 1] = ranking[m];
m--;
}
ranking[m + 1] = tmp;
}
// console.log(ranking);
//创建结点
for(var f=ranking.length-1;f>=0;f--){
var ul=document.getElementById('ranking');
var li=document.createElement('li');
li.innerHTML="玩家:"+ranking[f].name+"------最高分:"+ranking[f].score;
ul.appendChild(li);
}
}
function displayHistory() {
var historyMessage=JSON.parse(localStorage.getItem("messageStorage"));//用户历史信息
// console.log("历史记录--》"+historyMessage);
// console.log(historyMessage.length);
var ul=document.getElementById('historyScore');
for(var i=0;iif(historyMessage[i].name==currentName){
var score=historyMessage[i].score;
for(var j=1;jvar li=document.createElement('li');
li.innerHTML='第'+j+'次:'+score[j];
ul.appendChild(li);
}
return;
}
}
}
//游戏开始,初始化用户信息
function initMes(){
var message_child={};
var historyMessage=JSON.parse(localStorage.getItem("messageStorage"));//用户历史信息
// console.log("初始化--》"+historyMessage);
currentName=prompt('请输入你的名字:','');
if(currentName!=null && currentName!=''){
document.getElementById('name').innerHTML=currentName;
}
if(historyMessage != null){
for(var i=0;iif(historyMessage[i].name===currentName){
flag=true; //已经有该用户
// console.log("旧用户");
}
}
}
if(!flag){//新用户
console.log("新用户");
message_child.name=currentName;
message_child.score=[0];
if(historyMessage==null){
historyMessage=new Array();//不仅是新用户,而且该游戏还没有任何历史记录
// console.log("新用户且该游戏还没有任何历史记录");
}
historyMessage.push(message_child);//将新用户的信息对象放入数组中
localStorage.setItem("messageStorage",JSON.stringify(historyMessage));//存入本地
// console.log("新用户加入--》"+JSON.parse(localStorage.getItem("messageStorage")));
}
}
//游戏结束,更新用户信息
function updataMes() {
var historyMessage=JSON.parse(localStorage.getItem("messageStorage"));//用户历史信息
console.log("游戏结束--》"+historyMessage);
// console.log(historyMessage.length);
for(var i=0;iif(historyMessage[i].name==currentName){
historyMessage[i].score.push(currentscore);
localStorage.setItem("messageStorage",JSON.stringify(historyMessage));//存入本地
// console.log(JSON.parse(localStorage.getItem("messageStorage"))[i].score);
return;
}
}
}
//创建画布
function map(){
ctx.clearRect(0,0,450,450);//(x,y,width,height),在给定的矩形中清除一个指定矩形(坐标和像素)
//画出X轴线
for(var x=0;x<=30;x++){
ctx.moveTo(size*x,0); //开始位置
ctx.lineTo(x * size, 450);//结束位置
ctx.strokeStyle = "#000000";//边框颜色
ctx.stroke();
}
//画出y轴线
for(var y=0;y<=30;y++){
ctx.moveTo(0,size*y); //开始位置
ctx.lineTo(450,y * size);//结束位置
ctx.strokeStyle = "#000000";//边框颜色
ctx.stroke();
}
//创建蛇
for (var i = 0; i < snakes.length; i++){
if(snakes[i] == snakes[snakes.length-1]){
ctx.beginPath();
ctx.fillStyle = "red";
ctx.fillRect(snakes[i].x, snakes[i].y, size, size);
ctx.moveTo(snakes[i].x, snakes[i].y);
ctx.lineTo(snakes[i].x + size, snakes[i].y);
ctx.lineTo(snakes[i].x + size, snakes[i].y + size);
ctx.lineTo(snakes[i].x, snakes[i].y + size);
ctx.closePath();
ctx.strokeStyle = "white";
ctx.stroke();
}else{
ctx.beginPath();
ctx.fillStyle = "green";
ctx.fillRect(snakes[i].x, snakes[i].y, size, size);
ctx.moveTo(snakes[i].x, snakes[i].y);
ctx.lineTo(snakes[i].x + size, snakes[i].y);
ctx.lineTo(snakes[i].x + size, snakes[i].y + size);
ctx.lineTo(snakes[i].x, snakes[i].y + size);
ctx.closePath();
ctx.strokeStyle = "white";
ctx.stroke();
}
}
//画出食物
ctx.beginPath();
ctx.fillStyle = "yellow";
ctx.fillRect(foodX, foodY, size, size);
ctx.moveTo(foodX, foodY);
ctx.lineTo(foodX + size, foodY);
ctx.lineTo(foodX + size, foodY + size);
ctx.lineTo(foodX, foodY + size);
ctx.closePath();
ctx.strokeStyle = "red";
ctx.stroke();
}
//初始化
function start(){
//定义蛇
for(var i=0;i0};
}
map();
addFood();
}
//随机生成食物
function addFood(){
foodX = Math.floor(Math.random() * (30 - 1)) * size;
foodY = Math.floor(Math.random() * (30 - 1)) * size;
}
//添加蛇身
function addSnake(){
snakecount++;
snakes.unshift({x:size * 30, y:size * 30});
}
//吃到食物判断
function isEat(){
if (snakes[snakecount - 1].x == foodX && snakes[snakecount - 1].y == foodY) {
currentscore++;
document.getElementById("score").innerHTML=currentscore;
addFood();
addSnake();
}
}
//移动函数
function move(){
switch(toGo){
case 1: //左边
snakes.push({x: snakes[snakecount - 1].x - size, y: snakes[snakecount - 1].y});
break;
case 2: //上边
snakes.push({x: snakes[snakecount - 1].x, y: snakes[snakecount - 1].y - size});
break;
case 3: //右边
snakes.push({x: snakes[snakecount - 1].x + size, y: snakes[snakecount - 1].y});
break;
case 4: //下边
snakes.push({x: snakes[snakecount - 1].x, y: snakes[snakecount - 1].y + size});
// case 5: //下边
// snakes.push({x: snakes[snakecount - 1].x+ size, y: snakes[snakecount - 1].y + size});
//
break;
default:;
}
snakes.shift();
isEat();
isDie();
map();
}
//交互响应函数
function keydown(keyCode){
// console.log(keyCode);
console.log(isPause);
switch(keyCode){
case 37: //左边
if(toGo != 1 && toGo != 3) toGo = 1;break;
case 38: //上边
if(toGo != 2 && toGo != 4) toGo = 2;break;
case 39: //右边
if(toGo != 3 && toGo != 1) toGo = 3;break;
case 40: //下的
if(toGo != 4 && toGo != 2) toGo = 4;break;
// case 65: //右斜
// toGo = 5;break;
case 80: //开始/暂停
if(isPause){
interval = setInterval(move,100);
isPause = false;
document.getElementById('pause').innerHTML = "Pause";
}else{
clearInterval(interval);
isPause = true;
document.getElementById('pause').innerHTML = "Start";
}
break;
}
}
//死亡判断
function isDie(){
if(snakes[snakecount - 1].x == -15 || snakes[snakecount - 1].x == size * 30
|| snakes[snakecount - 1].y == -15 || snakes[snakecount - 1].y == size * 30){
updataMes();
clearInterval(interval);
alert("Game Over!");
}
for(var i = 0; i < snakecount - 1; i++){
if(snakes[snakecount - 1].x == snakes[i].x && snakes[snakecount - 1].y == snakes[i].y){
updataMes();
clearInterval(interval);
alert("Game Over!");
}
}
}
script>
html>
主要技术:
1.html5的新特性—canvas
2.webStroge—localStorage