赞
踩
贪吃蛇是前端人入门且必须的技能。今天闲下来整理介绍一下~~~
首先,先要确定贪吃蛇小游戏的需求:
我们首先通过创建一些div元素来生成网格轨道背景:
然后创建蛇头(我们让蛇头位置是固定的,食物是随机产生的)
接下来是蛇头的自动移动(我们设置一个定时器来实现蛇头的自动移动):
蛇头的变向操作(使用到了键盘事件 我们使用上下左右键来移动 判断keycode值来改变蛇头位置)
接下来创建随机食物:
食物和蛇头的碰撞检测:
注意食物不能成成在身体上,所以我们需要添加条件判断:
吃掉食物后产生身体块
身体块随着头移动
把创建头 食物 身体 封装到一起(共有的地方)
让几个函数需要的参数是一致的,不一样的在内部实现
接下来还要优化以下~判断蛇头是否碰撞了边界和自己的身体,也要不让蛇可以回退移动;随机产生不同分值的食物,获得一定分值后的速度也要变快
以下是具体代码实现:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>贪吃蛇</title>
- <style>
- .out{
- width: 500px;
- height: 500px;
- background: #ccc;
- border: 1px solid blue;
- position: relative;
- overflow: hidden;
- }
- p{
- display: inline-block;
- }
- span{
- display: block;
- }
- </style>
- </head>
- <body>
- <div class="out">
- </div>
- <button onclick="reset()">再玩一局</button>
- 得分:<p></p>
- <span>得分大于等于5,改变速度。得分大于等于10,改变速度。</span>
- <script src="./snake.js"></script>
- <script>
- var col=10;
- var row=10;
- var w=50;
- var h=50;
- var out=$('.out')[0];
- var score=$('p')[0];
- var bodys=[];
- var num=0;
-
-
- var time=1000;//速度
- //背景
- createBg(out,col,row)
- // 蛇头
- var head=createNode(1,out)
- // 食物
- var food=createNode(2,out)//createFood(out,w,h,col,row,1)
- createKeyEvent(head);
- //计时器
- var timer=setInterval(play,time)
- //
- function play() {
- //身体移动
- moveBody(bodys,head)
- //头部移动
- moveHead(head);
- var checkstate=check(head,food);
-
- if(checkstate){
- //计算分数
- num+=Number(food.getAttribute('value'));
- score.innerHTML=num+"分"
- //判断分数 改变速度
- if (num>=5&&num<10) {
- time=600;
- clearInterval(timer);
- timer=setInterval(play,time);
-
- }
- else if(num>=10){
- time=300;
- clearInterval(timer);
- timer=setInterval(play,time);
- }
-
-
- //删除food
- out.removeChild(food);
- //创建food(food不能创建在身体上)
- food=createNode(2,out)
- //创建身体
- if (bodys.length>0) {
- // var body=createBody(out,w,h,bodys[bodys.length-1])
- var body=createNode(3,out,bodys[bodys.length-1])
- console.log(body)
- }else{
- // var body=createBody(out,w,h,head)
- var body=createNode(3,out,head)
- console.log(body)
- }
- bodys.push(body)
- }
-
- var bodycheckstate=checkbody(head,bodys);
- if (bodycheckstate==false) {
- clearInterval(timer);
- alert("咬到自己了!")
- }
-
-
- var borderstate=checkBorder(head,out);
- if (borderstate==false) {
- clearInterval(timer);
- alert("game over!")
- }
- }
-
- </script>
- </body>
- </html>
- <!--
- 1.背景墙 确定行列
- 2.创建蛇头
- 3.蛇头移动
- 4.蛇头变相
- 5.创建实物
- 6.碰撞检测
- 7.增加身体
- 8.食物消失 随机创建新的
- 9身体蛇头一起移动
- -------完成-------
- -->
- //获取元素方法
- function $(string){
- var tag=string.charAt(0);
- var ele=null;
- switch(tag){
- case ".":
- ele=document.getElementsByClassName(string.slice(1))
- break;
- case "#":
- ele=document.getElementById(string.slice(1))
- break;
- default:
- ele=document.getElementsByTagName(string);
- break;
- }
- return ele;
- }
- //创建背景方法
- function createBg(parent,col,row){
- //创建表格
- parent.style.width=row*50+"px";
- parent.style.height=col*50+"px";
- for (var i = 0; i < row; i++) {
- for (var j = 0; j < col; j++) {
- var div =document.createElement('div')
- div.style.width="48px"
- div.style.height="48px"
- div.style.border="1px solid white"
- div.style.float='left'
- parent.appendChild(div);
- }
- }
- }
-
- //事件监听
- function createKeyEvent(head){
- document.onkeyup=function(event){
- console.log(event)
- var event=event||window.event
- var key=event.keyCode;
- if (head.className=='top'&&key==40) {
- return;
- }
- else if (head.className=='right'&&key==37) {
-
- return;
- }
- else if (head.className=='down'&&key==38) {
- return;
- }
- else if (head.className=='left'&&key==39) {
- return;
- }
- switch(key){
- case 40:
- head.className='down'
- break;
- case 37:
- head.className="left"
- break;
- case 38:
- head.className="top"
- break;
- case 39:
- head.className="right"
- break;
- }
- }
- }
-
- //身体碰撞检测
- function checkbody(obj1,arr) {
- for (var i = 1; i < arr.length; i++) {
- if (obj1.offsetTop==arr[i].offsetTop&&obj1.offsetLeft==arr[i].offsetLeft) {
- return false;
- }
- }
- }
-
-
-
-
- //碰撞检测
- function check(obj1,obj2){
- if (obj1.offsetLeft==obj2.offsetLeft&&obj1.offsetTop==obj2.offsetTop) {
- return true;
- }
- return false;
- }
- //头部移动
- function moveHead(head){
- var left=0;
- var top=0;
- switch(head.className){
- case 'left':
- left=head.offsetLeft-50;
- top=head.offsetTop
- break;
- case 'right':
- left=head.offsetLeft+50;
- top=head.offsetTop
- break;
- case 'top':
- left=head.offsetLeft;
- top=head.offsetTop-50
- break;
- case 'down':
- left=head.offsetLeft;
- top=head.offsetTop+50
- break;
- }
- head.style.left=left+'px'
- head.style.top=top+'px'
- }
- //移动body
- function moveBody(array){
- if (array.length>0) {
- for (var i = array.length - 1; i >= 0; i--) {
- switch(array[i].className){
- case 'left':
- x=array[i].offsetLeft-50;
- y=array[i].offsetTop
- break;
- case 'right':
- x=array[i].offsetLeft+50;
- y=array[i].offsetTop
- break;
- case 'top':
- x=array[i].offsetLeft;
- y=array[i].offsetTop-50
- break;
- case 'down':
- x=array[i].offsetLeft;
- y=array[i].offsetTop+50
- break;
- }
- array[i].style.left=x+"px";
- array[i].style.top=y+'px'
- if (i==0) {
- array[i].className=head.className
- }else{
- array[i].className=array[i-1].className
- }
-
- }
- }
- }
- /*
- 检测坐标是否重合
- */
-
- function checkfood(x,y,array){
- console.log(head)
- if (x==head.offsetLeft&&y==head.offsetTop) {
- return false
- }
- for (var i = 0; i < array.length; i++) {
- // 检测到重复
- if (array[i].offsetLeft==x&&array[i].offsetTop==y) {
- return false;
- }
- if (i==array.length-1) {
- return true;
- }
- }
- return true;
- }
- /*
- 创建节点对象
- type 1 蛇头 2 food 3 身体
- */
- function createNode(type,parent,preObj){
- var x=0;
- var y=0;
- var w=50;
- var h=50;
- var bgColor;
- var fen;
- var className="";
- var preObj=preObj?preObj:null
- switch(type){
- case 1:
- bgColor="red"
- className="right"
- break;
- case 2:
- var foodtype=parseInt(Math.random()*10)%3
- var foods=[['yellow',1],['skyblue',2],['pink',3]]
- bgColor=foods[foodtype][0]
- fen=foods[foodtype][1]
- var array=bodys;
- // console.log(array)
- test();
- function test(){
- var a=parseInt(Math.random()*row)*50;
- var b=parseInt(Math.random()*col)*50;
- var state=checkfood(a,b,array)
- if (state) {
- x=a;
- y=b;
- }else{
- test();
- }
- }
- break;
- case 3:
- switch(preObj.className){
- case 'left':
- x=preObj.offsetLeft+50;
- y=preObj.offsetTop
- break;
- case 'right':
- x=preObj.offsetLeft-50;
- y=preObj.offsetTop
- break;
- case 'top':
- x=preObj.offsetLeft;
- y=preObj.offsetTop+50
- break;
- case 'down':
- x=preObj.offsetLeft;
- y=preObj.offsetTop-50
- break;
- }
- className=preObj.className;
- bgColor='black'
- break ;
- default:
- break
-
- }
- var node=document.createElement('div');
- node.style.background=bgColor;
- node.style.position="absolute";
- node.style.left=x+"px";
- node.style.top=y+"px";
- node.style.width=w+"px";
- node.style.height=h+"px";
- node.style.zIndex=999;
- node.className=className;
- node.setAttribute("value",fen)
- parent.appendChild(node)
- return node;
- }
-
-
-
- function reset(){
- window.location.reload();
- }
- //检测碰撞到边界框
- function checkBorder(obj1,obj2) {
- if (obj1.offsetLeft>obj2.offsetWidth||obj1.offsetLeft<0||obj1.offsetTop<0||obj1.offsetTop>obj2.offsetHeight) {
- return false;
- }
- return true;
- }
'运行
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。