用原生Canvas写贪吃蛇及问题解决
为了学习Canvas,写了这个小游戏贪吃蛇供自己和大家学习
Github: https://github.com/zhiyishou/Gsnake
Play On: http://zhiyishou.github.io/Gsnake
游戏截图:

前言:
为了方便加载转移,我把整个js都写在了html里,为了方便阅读,将函数结构在html里清晰地分开,
并在代码里有足够注释。
函数结构如下:
|----script
|----Definations
|----Global Snake variables
|----Global Canvas variables
|----Global Panel variables
|----Global Stage variables
|----Global Game status variables
|----Init Functions
|----initPanel
|----initButtons
|----initStage
|----initCanvas
|----initMaps
|----SnakeNode
|----initSnake
|----produceSingle
|----init
|----Draw Funcitons
|----drawScore
|----drawButton
|----drawButtons
|----drawSnake
|----drawSingle
|----drawStage
|----draw
|----Action Functions
|----moveSnake
|----main
|----Event Functions
|----KeyDown
|----getOffsetPosition
|----determineButton
|----MouseMove
|----ClickButton
|----debounce
|----bind
|----Pause
|----Start
|----ReStart
|----Died
|----ROCK and ROLL
|----init()
|----main()
其中碰到的问题与解决:
一、鼠标事件问题
Canvas 中无法实现内部事件的添加和删除,准确的来说,在Canvas就是一张单纯的画布,整个Canvas才能做Dom中的事件操作
如果想在Canvas中实现内部click或mousemove等事件,有两种方案来实现:
1、用四周边界来确定:
- 基于:
- 对Canvas绑定事件后,每当有事件发生,则计算当前鼠标相对于Canvas的坐标值;
- 在每个要绑定事件的对象中设定其四边边距坐标,并将其放在一个数组;
- 触发:事件发生时则遍历整个数组,来根据坐标来判断是否在哪一个对象的边界范围内,来确定鼠标现在所在的对象。
- 缺点:这个做的话要求对象只能是形状规整的直角四边形,对复杂图形的处理没有可实施性。
2、使用CanvasAPI中的isPointInPath方法:
- 基于:
- (同上)对Canvas绑定事件后,每当有事件发生,则计算当前鼠标相对于Canvas的坐标值;
- 将要绑定事件的对象储存在数组里;
- isPonitInPath或isPointInStroke方法针对context上下文来判断一个坐标值是否在其Path中或上;
- 触发:事件发生时则遍历整个数组,并重绘数组里的对象,即改变context,每绘制一个对象则context改变一次,当前的context来使用isPointInPath或isPointInStroke方法,将Offset坐标传入,来判断鼠标是否在其路径上,确定现在focus或click的对象。(canvas中的context会在closePath方法后重新设置)
- 优点:可实现复杂的图形事件。
二、绘制问题
在我原先的版本中我是将整个对象操作和对象绘制设置成一个Interval来实现在,在后来的编写中就发现这样做会很死板,如果想添加或改动一些功能,则要对整个代码进行修改甚至在这种模型下无法实现。
最后还是将绘制和操作分离开来:
- 对绘制设置Interval,如:
setInterval(function(){
draw();
},1000/60) //每秒重绘60次
- 而将绘制对象属性的改变绑定在事件上,如:
该游戏中的Event Functions
原理:对象事件来改变对象的属性,而绘制则是用对象属性来绘制,两个逻辑各司其职,互不干预。
优点:整体程序逻辑会更清晰,更方便后续功能的新增和修改。
The End
用原生Canvas写贪吃蛇及问题解决的更多相关文章
- JavaScript原生实现《贪吃蛇》
概述 JavaScript原生实现<贪吃蛇>,每吃掉一个食物,蛇的身体会变长,食物会重新换位置. 详细 代码下载:http://www.demodashi.com/demo/10728.h ...
- 原生canvas写的飞机游戏
一个原生canvas写的飞机游戏,实用性不大,主要用于熟悉canvas的一些熟悉用法. 项目地址:https://github.com/BothEyes1993/canvas_game
- 用python+pygame写贪吃蛇小游戏
因为python语法简单好上手,前两天在想能不能用python写个小游戏出来,就上网搜了一下发现了pygame这个写2D游戏的库.了解了两天再参考了一些资料就开始写贪吃蛇这个小游戏. 毕竟最开始的练手 ...
- C语言用面向对象的思想写贪吃蛇
大概一年前这时候,接触C语言一个月,那时候知之甚少,对面向对象只觉”可远观而不可亵玩“,而且会看到很多言论说C语言就是面向过程的语言,C++就是面向对象的语言.不过,不记得什么时候在网上看到过一篇博文 ...
- pygame写贪吃蛇
python小白尝试写游戏.. 学了点pygame不知道那什么练手好,先拿贪吃蛇开刀吧. 一个游戏可以粗略的分为两个部分: 数据(变量) 处理数据(函数,方法) 设计变量 首先预想下,画面的那些部分需 ...
- 原生JS制作贪吃蛇小游戏
感情都在代码里,来,干了!... <!doctype html> <html> <head> <meta http-equiv="Content-T ...
- canvas 实现贪吃蛇游戏
var canvas = document.getElementById('canvas'); var cxt = canvas.getContext('2d'); // 定时器 var timer; ...
- 用Js写贪吃蛇
使用Javascript做贪吃蛇小游戏, 1.自定义地图宽高,蛇的初始速度 2.食物随机出现 3.蛇的样式属性 4.贪吃蛇玩法(吃食物,碰到边界,吃食物后加速,计分,) <!DOCTYPE ht ...
- 一步步教你怎么用python写贪吃蛇游戏
目录 0 引言 1 环境 2 需求分析 3 代码实现 4 后记 0 引言 前几天,星球有人提到贪吃蛇,一下子就勾起了我的兴趣,毕竟在那个Nokia称霸的年代,这款游戏可是经典中的经典啊!而用Pytho ...
随机推荐
- Linux ext2/ext3文件系统详解
转载: Linux ext2/ext3文件系统使用索引节点来记录文件信息,作用像windows的文件分配表.索引节点是一个结构,它包含了一个文件的长度.创建及修改时间.权限.所属关系.磁盘中的位置等信 ...
- 【转载】php如何给APP端写接口
如何写好接口 目的:清楚明白所写接口的用途 安全性:做好接口的安全性,防止接口数据泄露,做好必要的参数加密措施 按需分配: 接受值和返回值要实用,不接受和返回不需要的数据,返回值返回什么应与使用者时时 ...
- LaTeX 中文段首空格问题
一般用 “\\”或者回车可以使得下一段段首空两格,但是对于第一段就不行了. 解决办法: 加一个\usepackage{indentfirst}就可以
- mysql优化一
1.show global status 可以列出MySQL服务器运行各种状态值 2.show variables 查询MySQL服务器配置信息 一.慢查询 mysql ...
- 如何让iOS模拟器也能测试蓝牙4.0程序?
买一个CSR蓝牙4.0 USB适配器,插在Mac上 在终端输入sudo nvram bluetoothHostControllerSwitchBehavior="never" 重启 ...
- android 实现代码混淆
对于使用签名的apk,经常使用的反编译之后还是能查看class文件的代码实现.对于反编译可查看个人的博客点击打开链接 使用代码混淆就能是这样的常规反编译失效.很多其它混淆机制见官网http://dev ...
- 采用 EventHandler 模式发布事件(转载)
采用 EventHandler 模式发布事件 (如果不需要与事件一起发送自定义数据,请跳过此步骤,进入步骤 3a.)在发行者类和订阅方类均可看见的范围中声明自定义数据的类. 然后添加保留您的自定义事件 ...
- hibernate 中多对多关系对象集合的保存
多对多关系映射和一对多关系映射开发步骤差不多, 例子如下:员工和项目之间的关系,一个员工可以参与多个项目:一个项目可以有多个开发人员参与.因此是多对多的关系. 1 分析数据表 1.1)员工表 CREA ...
- 让HttpClient不要打印巨多的日志
让HttpClient不要打印巨多的日志 log4j.logger.org.apache.commons.httpclient=DEBUG 參考http://hc.apache.org/httpcli ...
- linux Nginx 日志脚本
这篇文章主要介绍了nginx日志切割脚本.nginx日志分析脚本等,需要的朋友可以参考下. 参考自:http://www.jbxue.com/article/13927.html 任务计划 cront ...