为了学习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、用四周边界来确定:

  • 基于:
    1. 对Canvas绑定事件后,每当有事件发生,则计算当前鼠标相对于Canvas的坐标值;
    2. 在每个要绑定事件的对象中设定其四边边距坐标,并将其放在一个数组;
  • 触发:事件发生时则遍历整个数组,来根据坐标来判断是否在哪一个对象的边界范围内,来确定鼠标现在所在的对象。
  • 缺点:这个做的话要求对象只能是形状规整的直角四边形,对复杂图形的处理没有可实施性。

2、使用CanvasAPI中的isPointInPath方法:

  • 基于:
    1. (同上)对Canvas绑定事件后,每当有事件发生,则计算当前鼠标相对于Canvas的坐标值;
    2. 将要绑定事件的对象储存在数组里;
    3. 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写贪吃蛇及问题解决的更多相关文章

  1. JavaScript原生实现《贪吃蛇》

    概述 JavaScript原生实现<贪吃蛇>,每吃掉一个食物,蛇的身体会变长,食物会重新换位置. 详细 代码下载:http://www.demodashi.com/demo/10728.h ...

  2. 原生canvas写的飞机游戏

    一个原生canvas写的飞机游戏,实用性不大,主要用于熟悉canvas的一些熟悉用法. 项目地址:https://github.com/BothEyes1993/canvas_game

  3. 用python+pygame写贪吃蛇小游戏

    因为python语法简单好上手,前两天在想能不能用python写个小游戏出来,就上网搜了一下发现了pygame这个写2D游戏的库.了解了两天再参考了一些资料就开始写贪吃蛇这个小游戏. 毕竟最开始的练手 ...

  4. C语言用面向对象的思想写贪吃蛇

    大概一年前这时候,接触C语言一个月,那时候知之甚少,对面向对象只觉”可远观而不可亵玩“,而且会看到很多言论说C语言就是面向过程的语言,C++就是面向对象的语言.不过,不记得什么时候在网上看到过一篇博文 ...

  5. pygame写贪吃蛇

    python小白尝试写游戏.. 学了点pygame不知道那什么练手好,先拿贪吃蛇开刀吧. 一个游戏可以粗略的分为两个部分: 数据(变量) 处理数据(函数,方法) 设计变量 首先预想下,画面的那些部分需 ...

  6. 原生JS制作贪吃蛇小游戏

    感情都在代码里,来,干了!... <!doctype html> <html> <head> <meta http-equiv="Content-T ...

  7. canvas 实现贪吃蛇游戏

    var canvas = document.getElementById('canvas'); var cxt = canvas.getContext('2d'); // 定时器 var timer; ...

  8. 用Js写贪吃蛇

    使用Javascript做贪吃蛇小游戏, 1.自定义地图宽高,蛇的初始速度 2.食物随机出现 3.蛇的样式属性 4.贪吃蛇玩法(吃食物,碰到边界,吃食物后加速,计分,) <!DOCTYPE ht ...

  9. 一步步教你怎么用python写贪吃蛇游戏

    目录 0 引言 1 环境 2 需求分析 3 代码实现 4 后记 0 引言 前几天,星球有人提到贪吃蛇,一下子就勾起了我的兴趣,毕竟在那个Nokia称霸的年代,这款游戏可是经典中的经典啊!而用Pytho ...

随机推荐

  1. hibernate 在做更新和删除的时候一定要把事务开启

    在做更新和删除的时候一定要把事务开启 在做更新和删除的时候一定要把事务开启 在做更新和删除的时候一定要把事务开启 重要的事情说三遍!!! curd之前配置文件 <property name=&q ...

  2. android多线程进度条

    多线程实现更新android进度条. 实例教程,详细信息我已经注释   android多线程进度条   01package com.shougao.hello; 02 03import android ...

  3. windows 2003 如何实现远程桌面与本地桌面统一

    最近在使用XP对2003服务器进行远程管理的时候,发现远程桌面与本地桌面不一致,本身在本地桌面开启的程序例如杀毒软件防火墙之类的,在远程桌面居然看不到,同时在远程桌面开启的程序,跑到服务器本地桌面也看 ...

  4. linux 源码安装 Nginx

    1.安装前环境准备安装make:# yum -y install gcc automake autoconf libtool make安装g++:# yum install gcc gcc-c++ 2 ...

  5. 基于socket.io的实时消息推送

    用户访问Web站点的过程是基于HTTP协议的,而HTTP协议的工作模式是:请求-响应,客户端发出访问请求,服务器端以资源数据响应请求. 也就是说,服务器端始终是被动的,即使服务器端的资源数据发生变化, ...

  6. Android系统应用信息中存储和缓存的计算方法

    进行例如以下操作: 设置->应用->选择一个应用->应用信息 会到达例如以下界面: 能够看到这个应用占用的磁盘空间. 先说结果,这几项会计算哪些文件(夹). 1.应用,由三项相加组成 ...

  7. 获取http内容的php函数

    实现获取http内容的php函数. 代码如下: <?php function http_open($url, $data, $cookie = null, $method = "GET ...

  8. jae的mongo数据库管理工具(原创)

    园里前段时间有人介绍了京东的jae,申请了试用了一下,各种坑,勉强可以测试用用. jae一直没有Mongo数据库的管理工具,没办法,自己写了一个凑合着先用着. 使用方法: 1.修改配置:下载后面的程序 ...

  9. ny33 蛇形填数

    蛇形填数 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 在n*n方陈里填入1,2,...,n*n,要求填成蛇形.例如n=4时方陈为: 10 11 12 1 9 16 1 ...

  10. (2)FluidMoveBehavior 之单击 Grid 中 Tile 进行排序

    在上一篇文章中,使用 FluidMoveBehavior 结合 FluidMoveSetTagBehavior 可以使数据从 ListBox 中的 数据显示时,产生缓慢的动画,从而更加生动.其实 Fl ...