原生js+canvas实现贪吃蛇效果


Posted in Javascript onAugust 02, 2020

本文实例为大家分享了canvas实现贪吃蛇效果的具体代码,供大家参考,具体内容如下

效果展示:

原生js+canvas实现贪吃蛇效果

源码展示:

页面布局展示:worm.html

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <title>贪吃蛇</title>
 <style type="text/css">
 canvas{
 border: 1px solid black;
 }
 div{
 width: 50px; height: 50px; 
 border: 1px solid black; cursor: pointer;
 text-align: center; line-height: 50px;
 }
 </style>
 <script type="text/javascript" src="Node.js" ></script>
 <script type="text/javascript" src="Worm.js" ></script>
 <script src="Stage.js" type="text/javascript" charset="utf-8"></script>
 <script type="text/javascript">
 function load () {
 //创建一个舞台 调用print方法打印
 stage=new Stage();
 //获取ctx 
 var mCanvas=document.getElementById("mCanvas");
 ctx=mCanvas.getContext('2d');
 stage.print(ctx);
 startPrint();
 }
 
 function changeDir(dir){
 DIR=dir;
 }
 var task;
 var stage;
 var ctx;
 function startPrint () {
 task=window.setInterval(function () {
  stage.worm.step();
  stage.print(ctx);
 }, SPEED);
 }
 function endPrint () {
 window.clearInterval(task);
 }
 
 </script>
 </head>
 <body onload="load()">
 <canvas id="mCanvas" width="500" height="500">
 </canvas>
 
 <table>
 <tr>
 <td></td>
 <td>
  <div onclick="changeDir(UP)">UP</div>
 </td>
 <td></td>
 </tr>
 <tr>
 <td>
  <div onclick="changeDir(LEFT)">LEFT</div>
 </td>
 <td></td>
 <td>
  <div onclick="changeDir(RIGHT)">RIGHT</div>
 </td>
 </tr>
 <tr>
 <td></td>
 <td>
  <div onclick="changeDir(DOWN)">DOWN</div>
 </td>
 <td></td>
 </tr>
 </table>
 
 </body>
</html>

节点类的js  :Node.js

/* 节点类 */
function Node (x, y) {
 this.x=x;
 this.y=y;
 this.equals=function (i, j) {
 return this.x==i && this.y==j;
 };
 
}

舞台类js:Stage.js

/** 舞台类 */
function Stage () {
 this.width=50;
 this.height=50;
 this.worm=new Worm();
 
 /* 在canvas中绘制舞台的内容 */
 this.print=function (ctx) {
 for(i=0; i<this.width; i++){
 for(j=0; j<this.height; j++){
 //如果当前节点是蛇身子的一部分 
 //那么换一种颜色绘制
 if(this.worm.contains(i,j)){
  ctx.fillStyle="#ab55ff";
  ctx.fillRect(i*10, j*10, 10, 10);
 }else if(this.worm.food.equals(i, j)){
  ctx.fillStyle="#000000";
  ctx.fillRect(i*10, j*10, 10, 10);
 }else{
  ctx.fillStyle="#dddddd";
  ctx.fillRect(i*10, j*10, 10, 10);
 }
 }
 }
 //在舞台的左上角绘制分数
 ctx.font="30px Arial";
 ctx.fillStyle="#880000";
 ctx.fillText("score:"+SCORE, 10,40);
 };
}

蛇类js:Worm.js

/** 蛇类 */
var UP=0;
var DOWN=1;
var LEFT=2;
var RIGHT=3;
 
var DIR=UP;
 
var SCORE=0;
var SPEED=300;
//蛇类初始化的形状
function Worm () {
 this.nodes=[];
 this.nodes[this.nodes.length]=new Node(20,10);
 this.nodes[this.nodes.length]=new Node(20,11);
 this.nodes[this.nodes.length]=new Node(20,12);
 this.nodes[this.nodes.length]=new Node(20,13);
 this.nodes[this.nodes.length]=new Node(20,14);
 this.nodes[this.nodes.length]=new Node(20,15);
 this.nodes[this.nodes.length]=new Node(21,15);
 this.nodes[this.nodes.length]=new Node(22,15);
 this.nodes[this.nodes.length]=new Node(23,15);
 this.nodes[this.nodes.length]=new Node(24,15);
 this.nodes[this.nodes.length]=new Node(24,16);
 this.nodes[this.nodes.length]=new Node(24,17);
 this.nodes[this.nodes.length]=new Node(24,18);
 this.nodes[this.nodes.length]=new Node(24,19);
 
 /* 蛇会走一步 */
 this.step=function () {
 //计算出头结点 把头节点添加到nodes数组中
 var oldHead=this.nodes[0];
 var newHead;
 switch (DIR){
 case UP:
 if(oldHead.y-1<0){
  newHead=new Node(oldHead.x, 49);
 }else{
  newHead=new Node(oldHead.x, oldHead.y-1);
 }
 break;
 case DOWN:
 if(oldHead.y+1>49){
  newHead=new Node(oldHead.x, 0);
 }else{
  newHead=new Node(oldHead.x, oldHead.y+1);
 }
 break;
 case LEFT:
 if(oldHead.x-1<0){
  newHead=new Node(49, oldHead.y);
 }else{
  newHead=new Node(oldHead.x-1, oldHead.y);
 }
 break;
 case RIGHT:
 if(oldHead.x+1>49){
  newHead=new Node(0, oldHead.y);
 }else{
  newHead=new Node(oldHead.x+1, oldHead.y);
 }
 break;
 }
 this.nodes.unshift(newHead);
 
 if(!this.food.equals(newHead.x, newHead.y)){
 //把尾节点删掉 (在没有吃到食物的时候)
 this.nodes.pop();
 }else{
 //吃到了食物 重新生成食物
 this.food=this.randomFood();
 SCORE+=10;
 SPEED-=50;
 endPrint();
 startPrint();
 }
 };
 
 /* 判断i,j节点是否是当前蛇身子的一部分 */
 this.contains=function (i, j) {
 for(k=0; k<this.nodes.length; k++){
 var node=this.nodes[k];
 if(node.x==i && node.y==j){
 return true;
 }
 }
 return false;
 };
 
 //声明生成食物的方法
 this.randomFood=function () {
 var x;
 var y;
 do{
 x=Math.floor(Math.random()*50);
 y=Math.floor(Math.random()*50);
 }while(this.contains(x, y));
 return new Node(x, y);
 };
 
 //声明食物
 this.food=this.randomFood();
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
CSS和JS标签style属性对照表(方便js开发的朋友)
Nov 11 Javascript
JQuery触发事件例如click
Sep 11 Javascript
js图片轮播效果实现代码
Apr 18 Javascript
深入浅析react native es6语法
Dec 09 Javascript
js实现字符串和数组之间相互转换操作
Jan 12 Javascript
js鼠标单击和双击事件冲突问题的快速解决方法
Jul 11 Javascript
ECMAScript6轮播图实践知识总结
Aug 17 Javascript
jquery实现输入框实时输入触发事件代码
Dec 21 Javascript
详解vue2.0脚手架的webpack 配置文件分析
May 27 Javascript
vue-cli初始化项目中使用less的方法
Aug 09 Javascript
uniapp实现横向滚动选择日期
Oct 21 Javascript
浅谈nuxtjs校验登录中间件和混入(mixin)
Nov 06 Javascript
js+canvas实现五子棋小游戏
Aug 02 #Javascript
js实现3D旋转相册
Aug 02 #Javascript
js实现双色球效果
Aug 02 #Javascript
js实现tab栏切换效果
Aug 02 #Javascript
原生js canvas实现鼠标跟随效果
Aug 02 #Javascript
原生js+canvas实现下雪效果
Aug 02 #Javascript
jQuery实现滑动开关效果
Aug 02 #jQuery
You might like
可以在线执行PHP代码包装修正版
2008/03/15 PHP
php异常:Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE  eval()'d code error
2011/05/19 PHP
PHP设计模式之结构模式的深入解析
2013/06/13 PHP
php实现连接access数据库并转txt写入的方法
2017/02/08 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
2020/05/02 PHP
判断脚本加载是否完成的方法
2009/05/26 Javascript
javascript定义函数的方法
2010/12/06 Javascript
在服务端(Page.Write)调用自定义的JS方法详解
2013/08/09 Javascript
ExtJS 刷新后如何默认选中刷新前最后一次选中的节点
2014/04/03 Javascript
JavaScript实现基于Cookie的存储类实例
2015/04/10 Javascript
JS实时弹出新消息提示框并有提示音响起的实现代码
2016/04/20 Javascript
jQuery ajaxSubmit 实现ajax提交表单局部刷新
2016/07/04 Javascript
从零开始学习Node.js系列教程三:图片上传和显示方法示例
2017/04/13 Javascript
JS实现烟花爆炸效果
2020/03/10 Javascript
JQuery事件冒泡和默认行为代码实例
2020/05/13 jQuery
解决echarts vue数据更新,视图不更新问题(echarts嵌在vue弹框中)
2020/07/20 Javascript
微信小程序实现锚点跳转
2020/11/23 Javascript
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:EE凭借法力虚空拿下4杀
2017/03/30 DOTA
[01:19:46]EG vs Secret 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.21.mp4
2020/07/19 DOTA
python实现sublime3的less编译插件示例
2014/04/27 Python
python的keyword模块用法实例分析
2015/06/30 Python
Python中使用platform模块获取系统信息的用法教程
2016/07/08 Python
python使用两种发邮件的方式smtp和outlook示例
2017/06/02 Python
python在html中插入简单的代码并加上时间戳的方法
2018/10/16 Python
Python爬取微信小程序通用方法代码实例详解
2020/09/29 Python
CSS3中的content属性使用示例
2015/07/20 HTML / CSS
固特异美国在线轮胎店:Goodyear Tire
2019/02/23 全球购物
致长跑运动员广播稿
2014/01/31 职场文书
竞选班干部的演讲稿
2014/04/24 职场文书
2014年质量工作总结
2014/11/22 职场文书
2014年职称评定工作总结
2014/11/26 职场文书
餐厅收银员岗位职责
2015/04/07 职场文书
海底两万里读书笔记
2015/06/26 职场文书
八年级数学教学反思
2016/02/17 职场文书
Nginx内网单机反向代理的实现
2021/11/07 Servers
DE1103使用报告
2022/04/05 无线电