近重要在研究OAuth2,等demo完成了,会给大家来一个专题分享。

看到我身边的一个同事在玩 蛇蛇争霸 感觉蛮有意思的,这里找了一个 贪吃蛇的游戏 分享给大家。

按理说canvas与其应用是老生常谈了,可我在准备阶段却搜索不到有用的资料(不是代码!),所以说呢,只能自力更生.

首先是大致要考虑的东西:

1.要有蛇(没蛇怎么叫贪吃蛇)。

2.然后要有地图(蛇是不能上天的)。

3.不能水平\垂直掉头(如果想掉头,需要至少变换方位并且至少移动一格才可)。

4.食物(不然怎么贪吃)。

5.吃了食物要变长(这才是精髓)。

PS:~现在我回想起来,当时的确只想到这么多(⊙﹏⊙)

怎么做呢?从大到小,先画个矩形作地图,可我觉得太丑,于是花了一张图出来:

context.beginPath();

var bgImg = new Image();

bgImg.src = "img/background.png";

context.drawImage(bgImg, 0, 0, 600, 600);

context.closePath();

现在我们有地图了

地图上好像缺点什么……没错就是礼物,所以我们现在生成礼物,那么问题来了:礼物最多有几个、生成位置、何时生成。

我这里暂时定义为:最多2个、随机位置生成、当礼物个数小于2时生成至2个。

接下来就很简单了,上图中,允许蛇活动的范围是14颗树(周围两颗树是墙),然后16颗树=600px,很容易我们得到每格多宽~

所以呢,我们只需要定义一个随机生成1-14整数的方法就可以很轻松找到应该生成的位置:

//随机数

function selectfrom() {

return Math.floor(Math.random() * 14 + 1);

}

然后再用求出的数乘以每一格子的宽度,即可求出生成的具体X坐标,因为是正方形,所以Y也一样:

var x = selectfrom() * (600/16);

var y = selectfrom() * (600/16);

并且每得到一组礼物坐标后,都需要存储在一个数组内(一会儿有大用处),至于画矩形太基础我就不说了。

And Now,我们有了礼物,有了地图,就差蛇了,那么问题又来了:出生的蛇多长、出生地、死亡方式、移动方式、转弯方式、如何判断吃掉了礼物、吃掉了礼物变长到哪里。

出生蛇长度:实际编写过程中,我发现默认长度1和2都不能够很好的体现“蛇的转弯”,所以定义为3,并且需将蛇身所有坐标记录在数组内。

出生地:地图中央或者自己定一个位置(按照格子来分),XY坐标求取方式上面已经说过不再赘述。

死亡方式:碰到障碍,或者(吃到自己)蛇头碰到蛇身。

移动方式:通过定义一个全局变量记录当前方向(0、1、2、3,默认1),并且使用计时器驱动蛇运动。

转弯方式:加入键盘按键检测事件,当方向键按下的时候修改-记录方向的全部变量即可。

如何判断吃掉了礼物:每次蛇头移动时,都要遍历下礼物集合(上面有说过),如果蛇头将要移动到的下个坐标与之重合了,则视为吃掉了礼物。

吃掉了礼物变长到哪里:直接加在头部可能会导致意外的死亡,所以我决定吃到礼物后的下一次移动不消除蛇尾(最后一个元素)。

有了上面的构思,我们可以着手定义一些可能会用到的公共变量:

var canvas = document.getElementById("mycanvas");//画布主体

var context = canvas.getContext("2d");

var timer;//计时器

const WIDTH = canvas.width;//画布宽

const HEIGHT = canvas.height;//画布高

const XSUM = 16; //画布宽分为几格

const YSUM = 15; //画布高分为几格

const MAXFFOD = 2; //最大食物数量

var score = 0;//定义记录游戏得分

var xsplit = WIDTH / XSUM; //x每一格子的宽度

var ysplit = HEIGHT / YSUM; //y每一格子的高度

var foodcount = 0; //当前食物数量

var sinak = []; //贪吃蛇坐标集

var get = []; //礼物坐标集

var MoveTo = 1; //移动方向 默认1(右)

有了这些变量,是不是发现很多东西都通了呢?

我们先来画蛇:

//画贪吃蛇

function drawsinak(sl) { //sl默认长度

context.beginPath();

context.fillStyle = "#000";

var ling = 0; //贪吃蛇被打印长度

for (var r = 0; r < sinak.length; r++) {

context.fillRect(sinak[r].split(',')[0], sinak[r].split(',')[1], xsplit, ysplit);

ling++;

}

if (ling == 0) {

for (var i = 0; i < sl; i++) {

context.fillRect(xsplit * (7 - i), ysplit * 6, xsplit, ysplit); //默认出生点:7,6默认中心点

sinak.push(xsplit * (7 - i) + ',' + ysplit * 6);

}

}

context.fill();

context.closePath();

}

可以看到我将生成的蛇的坐标都计入了数组内,生成的礼物自然也要计入:

context.beginPath();

var x = selectfrom(XSUM - 2) * xsplit;

var y = selectfrom(YSUM - 2) * ysplit;

context.fillStyle = "red";

for (var i = 0; i < get.length; i++) {

context.fillRect(get[i].split(',')[0], get[i].split(',')[1], xsplit, ysplit);

context.fill();

foodcount++;

}

if (MAXFFOD > foodcount) {

context.fillRect(x, y, xsplit, ysplit);

context.fill();

foodcount++;

get.push(x + ',' + y);

}

context.closePath();

接下来比较重要了,蛇的移动,以及吃到礼物和触发死亡判断:

//移动方法

//[c]移动方向 上右下左 0123

function sinakMove(c) {

context.beginPath();

//默认右侧为头

var tou = sinak[0]; //头

var weiba = sinak[sinak.length - 1]; //尾巴

var oldX = tou.split(',')[0]; //头部旧X坐标

var oldY = tou.split(',')[1]; //头部旧Y坐标

var newX = 0; //头部最新X坐标

var newY = 0; //头部最新Y坐标

//计算头部最新XY坐标

switch (c) {

case 0:

newX = oldX;

newY = oldY - ysplit;

break;

case 1:

newX = (oldX - 0) + xsplit;

newY = oldY;

break;

case 2:

newX = oldX;

newY = (oldY - 0) + ysplit;

break;

case 3:

newX = oldX - xsplit;

newY = oldY;

break;

}

var flag = 0; //有沒有吃到礼物 0沒有1有

//如果吃到了礼物,则不消减尾部最后元素

for (var i = 0; i < get.length; i++) {

if (newX == get[i].split(',')[0] && newY == get[i].split(',')[1]) {

sinak.unshift(newX + ',' + newY);

foodcount--; //礼物计数减少1个

get.splice(i, 1); //清空礼物

flag = 1;

}

}

//如果沒有吃到礼物,则判断是否碰到障碍或吃到自己

if (flag == 0) {

for (var i = 0; i < sinak.length; i++) {

if (newX == sinak[i].split(',')[0] && newY == sinak[i].split(',')[1]) {

if (confirm('吃掉了自己,游戏失败!是否重新开始?')) {

location.reload(true);

} else {

context.clearRect(0, 0, WIDTH, HEIGHT);

}

}

}

if (xsplit * (XSUM - 2) < newX || ysplit * (YSUM - 2) < newY || newX == 0 || newY == 0) {

if (confirm('撞墙了,游戏失败!是否重新开始?')) {

location.reload(true);

}

}

}

//如果没有吃到礼物,那么进行普通移动

if (flag == 0) {

sinak.unshift(newX + ',' + newY);

sinak.splice(sinak.length - 1, 1);

}

//画蛇

for (var r = 0; r < sinak.length; r++) {

context.fillRect(sinak[r].split(',')[0], sinak[r].split(',')[1], xsplit, ysplit);

}

context.closePath();

}

控制蛇的方向:

//键盘事件

document.onkeydown = function (event) {

var e = event || window.event || arguments.callee.caller.arguments[0];

var move = 0; //移动方向

if (e && e.keyCode == 37) { //左

move = (MoveTo == 1 ? 1 : 3);

} else if (e && e.keyCode == 38) { //上

move = (MoveTo == 2 ? 2 : 0);

} else if (e && e.keyCode == 39) { //右

move = (MoveTo == 3 ? 3 : 1);

} else if (e && e.keyCode == 40) { //下

move = (MoveTo == 0 ? 0 : 2);

} else if (e && e.keyCode == 32) {//暂停游戏

clearInterval(timer);

}

MoveTo = move; //修改当前移动方向

};

这里做了防误操作,当蛇正在朝向某方向移动时,直接输入反方向是无效的。如:蛇正向右走,这时直接按←键是无效的,仍然往右走。

一路跟着做到这里,相信大家的贪吃蛇已经可以正常游戏了,不过我这个做的很糙,大家可以加入一些自己的想法,比如:

计分通关,通关之后通过加快蛇的移动速度来增加难度。

随机生成多种果实,比如加速果实,双倍成长果实等。

加入WebSocket,实现网络版贪吃蛇。

基于html5贪吃蛇小游戏,使用HTML5 Canvas制作贪吃蛇小游戏相关推荐

  1. emfps游戏教程_【新教学上架】全面讲解FPS游戏第一人称动画制作 | Max动画——FPS游戏动作绑定实战案例教学...

    原标题:[新教学上架]全面讲解FPS游戏第一人称动画制作 | Max动画--FPS游戏动作绑定实战案例教学 Max动画--FPS游戏动作绑定实战案例教学 本教程由Emperor-Honoka老师制作, ...

  2. 大学生的小乐趣:html画布制作贪吃蛇小游戏

    源代码已存放在github上:https://github.com/WYKXLDZ/CollegeJoy/tree/master/snake 最终效果: 做贪吃蛇游戏需要Html5,部分Css美化,重 ...

  3. php开发h5游戏,H5的canvas实现贪吃蛇小游戏

    这次给大家带来H5的canvas实现贪吃蛇小游戏,H5的canvas实现贪吃蛇小游戏注意事项有哪些,下面就是实战案例,一起来看一下. 本文介绍了H5 canvas实现贪吃蛇小游戏,分享给大家,具体如下 ...

  4. HTML5用canvas制作飞机大战小游戏

    css样式: <!DOCTYPE html> <html lang="en"><head><meta charset="UTF- ...

  5. 用html5 Canvas制作一个简单的游戏 英雄抓小怪物(上)

    1.创建一个Canvas对象 先在HTML页面上创建画布,然后再通过document.getElementById()来获取. //创建画布canvas,并获取画布上下文环境 var  canvas ...

  6. 怎样用HTML5 Canvas制作一个简单的游戏

    为了让大家清楚HTML5制作游戏的简单流程,所以先了制作一个非常简单的游戏,来看一看这个过程.   游戏非常简单,无非就是英雄抓住怪物就得分,然后游戏重新开始,怪物出现在地图的随机位置,英雄初始化在地 ...

  7. [译]怎样用HTML5 Canvas制作一个简单的游戏

    这是我翻译自LostDecadeGames主页的一篇文章,原文地址:How To Make A Simple HTML5 Canvas Game. 下面是正文: 自从我制作了一些HTML5游戏(例如C ...

  8. html5上色游戏制作,怎样用HTML5 Canvas制作一个简单的游戏

    原文连接: How To Make A Simple HTML5 Canvas Game 自从我制作了一些HTML5游戏(例如Crypt Run)后,我收到了很多建议,要求我写一篇关于怎样利用HTML ...

  9. [Mugeda HTML5技术教程之16]案例分析:制作跨屏互动游戏

    本节我们将要做一个跨屏互动应用的案例分析,该应用时给一家商场做活动使用的,是一个跨屏爱消除游戏.PC端页面显示在连接在PC的大屏幕上,参与活动的玩家可以用自己的手机扫描PC端页面上的二维码,连接成功后 ...

  10. python连连看小游戏_利用Python制作一个连连看小游戏,边学边玩!

    导语 今天我们将制作一个连连看小游戏,让我们愉快地开始吧~ 开发工具 Python版本:3.6.4 相关模块: pygame模块: 以及一些Python自带的模块 环境搭建 安装Python并添加到环 ...

最新文章

  1. 学习redhat linux 6.1中文版笔记
  2. 如何杀死进程及子进程
  3. Faster-RCNN算法精读
  4. java oracle 图片_JAVA读取Oracle中的blob图片字段并显示
  5. java 飞行记录器_Java 11功能– Java飞行记录器
  6. 深度学习-服务端训练+android客户端物体识别实战(caffe入门教程+mobilenet+ncnn+android)
  7. 用递归与分治策略求解网球循环赛日程表_算法设计:分治法(比赛日程安排)...
  8. python如何可视化编辑gui_python gui,python可视化窗口编程
  9. VSS 获取全部子文件
  10. TrustedInstaller权限的问题
  11. PowerVR SDK
  12. 希腊字母读音及科学方面应用
  13. 测试人的后半生:跑滴滴还是送外卖?
  14. Python-hrvanalysis库 挖掘心电信号特征 方法总结
  15. 设置WinSCP实时更新目录
  16. DOM 对象的方法和属性
  17. 华为云CDN加速,真正的六边形战士
  18. 实习培训记录1-HTML
  19. Qt信号槽机制详解及案例
  20. 学习python爬虫经验分享--爬取洛克王国宠物图片

热门文章

  1. 谷歌优化指南,谷歌SEO优化超详细新手教程
  2. 常州SEO姜东:搜索引擎的工作原理抓取、索引和排名-搜索引擎如何工作
  3. 微信美食菜谱小程序系统毕业设计毕设(8)毕业设计论文模板
  4. 用python 将PDF中的表格转化为Excel
  5. Oracle教学辅助.书写历史的甲骨文--ORACLE公司传奇
  6. 用LUSK方式对硬盘进行加密和解密
  7. C语言入门之变量、常量、字符串、转义字符
  8. 我司将成立政产学研用科创中心 文丹枫博士受聘签约
  9. python下载电影_打造一款Python实现自动下载电影的“脚本”!那种电影也可以哦!...
  10. Java Date类型数据 时间加一天,加一小时,加一分,加一秒