文档章节

如何用js实现贪吃蛇

smile_微笑
 smile_微笑
发布于 2017/09/07 12:26
字数 1441
阅读 34
收藏 0
点赞 0
评论 0

如何用js实现贪吃蛇

用自己学过的js知识来实现贪吃蛇游戏

首先就是贪吃蛇的游戏规则(不用说了,大家都玩过)

如何实现呢?

1.可以用html+css的方式来实现(样式需要多些一点) 2.用canvas画布的方式(这个看起来高大上,好就用这个)

编程方式可以使用面向对象、面向过程的方式(我这里选择的面向过程的方式,后面可以改成面向对象的方式)

首先全局定义几个方法中需用到的变量

  • width = 15; //这个是代表每个格子的宽度

  • snakeCount = 6; //这个是表示蛇身体的长度(初始值是6可以修改)

  • snake = [] //存储蛇当前的位置坐标

  • foodX foodY //用来表示食物的坐标

  • toGo //保存当前移动的方向

需要实现以下几个方法:

1.绘制的方法(包含绘制背景地图,绘制蛇当前的位置,食物的位置)

  function drawRect(){
       //选用450*450正方形格子进行绘制(因为定义每个格子是大小是15*15 所以需要绘制30个格子)
        for(var i=0;i<30;i++){
            ctx.strokeStyle="#000000";
            ctx.beginPath();//开始路径
  
            //起点
            ctx.moveTo(i*15,0);
            //终点
            ctx.lineTo(i*15,450);
  
            //起点
            ctx.moveTo(0,i*15);//移动到指定点
            //终点
            ctx.lineTo(450,i*15);//从当前的点到指定点画直线
  
            ctx.closePath();//结束路径
            //绘制线
            ctx.stroke();//对当前路径进行描边
        }
        //绘制蛇(循环遍历蛇当前自身的长度数值,然后取出坐标数组snake存储的每个格子的坐标值进行绘制)
        for(var i=0;i<snakeCount;i++){
            //设置矩形的填充颜色
            ctx.fillStyle = "#000";
            if(i==snakeCount-1)ctx.fillStyle = "red";			
            //绘制矩形 x,y,width,height
            ctx.fillRect(snake[i].x,snake[i].y,15,15);
        }
  
       //绘制食物(这个比较简单就一个格子 直接填充喜欢的颜色就行了)
        
        ctx.fillStyle="#66ff99";
        //绘制矩形 x,y,width,height
        ctx.fillRect(foodX,foodY,15,15);//填充一个矩形
        ctx.fill();
  
    }

2.蛇移动的方法move

function move(){
        //传入当前移动的方向值toGo 从全局变量获取
        //每次往数组里面压进去对应的坐标值(此时此刻脑子里必须有一个坐标系 哈哈 )
		switch(toGO){
			//向左(每移动一个格子x坐标需要-一个格子的长度15,y坐标不变)
			case 1: snake.push({x:snake[snakeCount-1].x-15,y:snake[snakeCount-1].y});
			break;
			//向上(每移动一个格子x坐标不变,y坐标-一个格子的长度15)
			case 2: snake.push({x:snake[snakeCount-1].x,y:snake[snakeCount-1].y-15});
			break;
			//向右(每移动一个格子x坐标需要+一个格子的长度15,y坐标不变)
			case 3: snake.push({x:snake[snakeCount-1].x+15,y:snake[snakeCount-1].y});
			break;
			//向下(最后一个留给你自己思考了)
			case 4: snake.push({x:snake[snakeCount-1].x,y:snake[snakeCount-1].y+15});
			break;
		}

		//删除第一个元素(往前移动一个格子之后,尾巴的格子需要删除掉(这样才能保证蛇的长度不变))
		snake.shift();
		
		
		//重新绘制(既然上面都已经计算好坐标了,剩下的事就是我们需要将上面的数据绘制出来,不然就是天方夜谭 ,绘制之前别忘了清除之前的画布,千万不要留下任何作案痕迹)
		ctx.clearRect(0,0,450,450);
		
		//每次移动之后必须检测当前位置是否合法(不合法就不让你继续游戏了)
		isDead();
		//我每次移动之后必须检测当前位置有木有星星给我吃(因为我饿了)
		isEat();
		(好了,完事具备 ,啥也别说了,最后一步开始画了,调用前面声明的方法drawRect)
		drawRect();
	}

3.随机出现食物的方法

  function addFood(){
  		//随机坐标 向下取整
  		foodX = Math.floor(Math.random()*30)*15;
  		foodY = Math.floor(Math.random()*30)*15;
  		
  		//这里有一个坑(食物不能增加到蛇的身上,所以要判断一下,如果随机生成坐标是蛇当前自身占据的位置,必须要重新生成,不然还怎么玩...)
  		for(var i=0;i<snakeCount-1;i++){
  			if(foodX == snake[i].x && foodY == snake[i].y){
  				addFood();
  			}
  		}
  	}

4.检测当前位置是否有食物的方法:

  function isEat(){
    //如果蛇头部的坐标等于食物位置的坐标,那就不好意思,表示吃掉
  		if(snake[snakeCount-1].x==foodX&&snake[snakeCount-1].y==foodY){
  			//重新生成食物
  			addFood();
  			//蛇长度加1
  			snakeCount++;
  			//往数组添加一个元素
  			snake.unshift({x:-15,y:-15});
  		}
  	}

5.既然是游戏就必须有游戏规则(违反了就中断游戏)

  //定义游戏规则
	function isDead(){
		//判断边界
		if(snake[snakeCount-1].x>435||snake[snakeCount-1].y>435
		||snake[snakeCount-1].x<0||snake[snakeCount-1].y<0){
			alert("wendy想不开自杀了!");
			window.location.reload();
		}
		//判断自身 遍历蛇身上所有坐标 判断是否与蛇头重叠	
		for(var i=0;i<snakeCount-1;i++){
			if(snake[snakeCount-1].x==snake[i].x&&snake[snakeCount-1].y==snake[i].y){
				alert("wendy咬啥不好,咬自己屁股!");
				window.location.reload();
			}
		}
	}

6.好了 最后一步了 游戏启动的方法

function btnstart(){
         //设置蛇移动速度
       (哎 有点懒,就让它自己动吧,当然也可以用手动按键实现)
        setInterval(move,150);
        //监听键盘事件
        document.onkeydown = function(e){
            //浏览器的兼容性
            var e = e||window.event;		
            keyDown(e);(为了代码风格好看点 我就把这个方法定义到下面)
        }
 }
 function keyDown(e){
 		//keyCode键码  
 		switch(e.keyCode){
 			case 37: toGO=1;(按键后,保存方向值到全局变量)
 			break;
 			case 38: toGO=2;
 			break;
 			case 39: toGO=3;
 			break;
 			case 40: toGO=4;
 			break;
 		}
 }   
 

7.这里才是真的最后一步了,因为要放到浏览器执行所以页面加载时调用

//当前页面加载完成执行这个方法,要进如这个画布
	window.onload = function(){
		start();//这个start是蛇和食物最初始出现的位置
		btnstart();
	} 

© 著作权归作者所有

共有 人打赏支持
smile_微笑
粉丝 2
博文 55
码字总数 69100
作品 0
深圳
程序员
100行JS实现HTML5的3D贪吃蛇游戏

js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型,多次想尝试提交...

xhload3d
2014/03/06
0
7
iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge

iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge 转载:原地址 https://www.jianshu.com/p/e951af9e5e74 上一篇文章介绍了UIWebView 如何通过WebViewJavascriptBridge 来实现......

法斗斗
05/11
0
0
javascript学习资料分享

有志于web前端工作的话,javascript的知识是必不可少的。越学,我越觉得自己所欠缺的越多。路漫漫其修远兮,吾将上下而求索。下面将一些好的资料分享给大家。 JavaScript学习资料: (1)遇见...

小微
2012/04/06
0
5
CC框架实践(3): 让jsBridge更优雅

前言 CC框架下如何让我们的jsBridge更加优雅? jsBridge是作为js和java之间通信的桥梁,本身它的职责只是完成通信。 本文不是介绍js与java通信过程的实现,你可以使用第三方库(如:JsBridg...

lucky_billy
06/20
0
0
好的javascript程序员

这段时间一直在使用JS进行开发,其实我挺喜欢JS的,一个主要的原因就是自由。JS限制较少可以容易的实现自己的一些思想。或者换种说法,就是可以写出极其精简的代码,虽然精简不到LISP的水平,...

崔钢
2014/10/25
0
0
JavaScript引擎的工作原理

什么是JavaScript解析引擎? 简单地说,JavaScript解析引擎就是能够“读懂”JavaScript代码,并准确地给出代码运行结果的一段程序。比方说,当你写了 var a = 1 + 1; 这样一段代码,JavaScr...

武文海
2014/09/25
0
0
JavaScript面试大全(二)

eval()是做什么的? [eval()是“魔鬼”][1] null,undefined 的区别? [来看看大神阮一峰的解释吧][2] 写一个通用的事件侦听器函数。 [JS事件监听器][3] Node.js的适用场景? [NodeJS优缺点及...

百变茄
2014/06/05
0
0
JS与Object-C交互补充

有一个场景,用户点击Web页面,产生JS交互时,如何根据JS事件,App做出响应。 我们可以自己做一个简单的js交互,实现基于的原理是: 1. object-c利用stringByEvaluatingJavaScriptFromStrin...

treebug
2015/06/06
0
0
四月前端知识集锦(每月不可错过的文章集锦)

目前自己组建的一个团队正在写一份面试图谱,将会在七月中旬开源。内容十分丰富,第一版会开源前端方面知识和程序员必备知识,后期会逐步写入后端方面知识。因为工程所涉及内容太多(目前已经...

夕阳
05/02
0
0
React Native Android 源码分析之启动过程

前言 这篇开始将分析 React Native 是在 Android 端的启动过程是怎么样。 用过 React Native 的小伙伴都知道,React Native 是可以使用 JS 来编写一份代码,并可以同时跑在 Android 和 iOS ...

骑摩托马斯
07/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

CentoOS6.6安装netcat

CentOS下安装netcat 使用zookeeper过程中,需要监控集群状态。在使用四字命令时(echo conf | nc localhost 2181),报出如下错误:-bash: netcat: command not found。 我的系统是CentOS 6....

ghou-靠墙哭
11分钟前
0
0
es6之解构赋值巧用

ES6 允许按照一定模式,从数组、对象等中提取值,对变量进行赋值,这被称为解构赋值。 如何进行解构赋值我这里就不赘述,本篇文章主要是将解构赋值的巧妙使用之处。 1、交互变量的值 常用交互...

秋季长青
16分钟前
0
0
Elasitcsearch High Level Rest Client学习笔记(三)批量api

Bulk Request BulkRequest可以在一起从请求执行批量添加、更新和删除,至少需要添加一个操作 BulkRequest request = new BulkRequest(); //创建BulkRequestrequest.add(new IndexRequest("...

木子SMZ
19分钟前
0
0
mybatis-dynamic sql

OGNL expressions if 判断是否存在值 <select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test="title != null"> AND title like #{tit......

writeademo
27分钟前
0
0
社交系统ThinkSNS+ V1.8.3更新播报

     研发发布版本号:1.8.3   本次版本于2018年7月16日发布   本次发布类型:新增功能、细节调整与优化   社交系统ThinkSNSPlus更新体验:请于官网下载/安装最新版或联系QQ35159...

ThinkSNS账号
30分钟前
0
0
教育思考:选择编程是一场父母和孩子的和解[图]

教育思考:选择编程是一场父母和孩子的和解[图]: 之前有个很热的段子是这样讲的:深夜十点的时候,某小区一女子大声喊叫“什么关系?啊?!到底什么关系?你说!”最后发现原来是一位妈妈陪...

原创小博客
31分钟前
0
0
X64汇编之指令格式解析

最近由于项目组内要做特征码搜索的东西,便于去Hook一些未导出函数,你懂得...于是就闲着学习了一下x86/x64的汇编指令格式。x86的汇编指令格式请参照http://bbs.pediy.com/showthread.php?t...

simpower
33分钟前
0
0
rust 语法概要(只适合不熟悉时快速查阅使用,不适合理解其精髓。未完待续)

注意:本内容只适合快查,不适合理解精髓。精髓请研读 https://kaisery.github.io/trpl-zh-cn/foreword.html 基本数据类型 i8,i16,i32,i64,i128 u8,u16,u32,u64,u128 f32,f64 char bool:true...

捍卫机密
36分钟前
0
0
JS中严格模式和非严格模式

1,使用 严格模式的使用很简单,只有在代码首部加入字符串 "use strict"。必须在首部即首部指其前面没有任何有效js代码除注释,否则无效 2.注意事项 (1)不使用var声明变量严格模式中将不通...

AndyZhouX
37分钟前
0
0
Nginx配置error_page 404 500等自定义的错误页面

Nginx 做web server时, 开发中发现有时候的网站代码有错误,我们需要跳转到一个指定内容的错误页面: 1. 在nginx.conf配置文件上加上一句: fastcgi_intercept_errors on; 2. 服务中加上: er...

MichaelShu
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部