首页 > 作文

JS+Canvas实现贪吃蛇小游戏

更新时间:2023-04-04 16:39:59 阅读: 评论:0

今天呢,主要和小伙伴们分享一下一个贪吃蛇游戏从构思到实现的过程~因为我不是很喜欢直接po代码,所以只copy代码的童鞋们请出门左转不谢。

按理说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.clopath();

现在我们有地图了

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

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

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

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

//随机数function lectfrom() {   return math.floor(math.random() * 14 + 1);}

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

var x = lectfrom() * (600/16);var y = lectfrom() * (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.fil乔丹的身高有多少米lrect(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.clopath();}

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

context.beginpath();  var x = lectfrom(xsum - 2) * xsplit;  var y = lectfrom(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.clopath();

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

//移动方法//[c]移动方向 上右下左 0123function 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) {        ca 0:            newx = oldx;            newy = oldy - ysplit;            break;        ca 1:            newx = (oldx - 0) + xsplit;            newy = oldy;            break;        ca 2:            newx = ol高中化学必修一笔记dx;            newy = (oldy - 0) + ysplit;            break;        ca 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);                } el {                    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.clopath();}

控制蛇的方向:

//键盘事件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);    } el if (e && e.keycode == 38) { //上        move = (moveto == 2 ? 2 : 0);    } el if (e && e.keycode == 39) { //右        move = (moveto == 3 ? 3 : 1);    } el if (e && e.keycode == 40) { //下        move = (moveto == 0 ? 0 : 2);    } el if (e && e.keycode == 32) {//暂停游戏        clearinterval(timer);    }    moveto = move; //修改当前移动方向};

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

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

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

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

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

我写过关于websocket的实现,有兴趣的也可以去看看,下面是链接:

基于supersocket实现的websocket(后端)

基于supersocket实现的websocket(前端)

到此这篇关于js+canvas实现贪吃蛇小游戏的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。

本文发布于:2023-04-04 16:39:57,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/24fe13c791622bd286b8e7cba4092dc2.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:JS+Canvas实现贪吃蛇小游戏.doc

本文 PDF 下载地址:JS+Canvas实现贪吃蛇小游戏.pdf

下一篇:返回列表
标签:礼物   坐标   吃到   掉了
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图