iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JS+Canvas实现贪吃蛇小游戏
  • 951
分享到

JS+Canvas实现贪吃蛇小游戏

2024-04-02 19:04:59 951人浏览 薄情痞子
摘要

今天呢,主要和小伙伴们分享一下一个贪吃蛇游戏从构思到实现的过程~因为我不是很喜欢直接PO代码,所以只copy代码的童鞋们请出门左转不谢。 按理说canvas与其应用是老生常谈了,可我

今天呢,主要和小伙伴们分享一下一个贪吃蛇游戏从构思到实现的过程~因为我不是很喜欢直接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.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,实现网络版贪吃蛇。

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

基于SuperSocket实现的WebSocket(后端

基于SuperSocket实现的WebSocket(前端

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

--结束END--

本文标题: JS+Canvas实现贪吃蛇小游戏

本文链接: https://www.lsjlt.com/news/163054.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JS+Canvas实现贪吃蛇小游戏
    今天呢,主要和小伙伴们分享一下一个贪吃蛇游戏从构思到实现的过程~因为我不是很喜欢直接PO代码,所以只copy代码的童鞋们请出门左转不谢。 按理说canvas与其应用是老生常谈了,可我...
    99+
    2024-04-02
  • JS实现贪吃蛇小游戏
    目录一、初始化结构二、渲染蛇的颜色 三、蛇的运动四、蛇死亡的判定方式 蛇有两种判定死亡的方式五、食物的创建六、蛇吃食物边长七、开始游戏功能八、暂停/继续游戏功能页面效果: 贪吃蛇游...
    99+
    2024-04-02
  • 用JS实现贪吃蛇小游戏
    本文实例为大家分享了JS实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 效果图: 完整代码如下: HTML <!DOCTYPE html> <html la...
    99+
    2024-04-02
  • js怎么实现贪吃蛇小游戏
    这篇文章将为大家详细讲解有关js怎么实现贪吃蛇小游戏,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。示例代码<!DOCTYPE html> <h...
    99+
    2024-04-02
  • 用JS实现贪吃蛇游戏
    本文实例为大家分享了JS实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 效果图: 完整代码如下: html: <!DOCTYPE html> <html la...
    99+
    2024-04-02
  • H5如何使用canvas实现贪吃蛇小游戏
    小编给大家分享一下H5如何使用canvas实现贪吃蛇小游戏,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体如下:实现效果如下实现思路:ps:这个只是思路,详细可...
    99+
    2023-06-09
  • pygame实现贪吃蛇小游戏
    本文实例为大家分享了pygame实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 由于这段时间实在是太聊了,没什么事做,游戏也玩腻了,所以玩起来pygame。pygame是真的容...
    99+
    2024-04-02
  • C#实现贪吃蛇小游戏
    本文实例为大家分享了C#实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 之前一直想写一个贪吃蛇小游戏,上个周末终于有时间做了一个,现在和大家分享。 界面 界面比较简单,一个按钮...
    99+
    2024-04-02
  • js如何实现贪吃蛇游戏
    本篇内容介绍了“js如何实现贪吃蛇游戏”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!两个小时完成的,有点简陋。直接看效果。打开调试面板,在r...
    99+
    2023-06-14
  • Java+JFrame实现贪吃蛇小游戏
    分享一个Java贪吃蛇小游戏,主要用到的是Java的JFrame,适合初学者。 首先创建一个合适大小的窗口,我这里是900*720 package com.lzijin;     ...
    99+
    2024-04-02
  • 原生js实现简单贪吃蛇小游戏
    本文实例为大家分享了js实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 先上图 话不多说,代码奉上,喜欢的请留下你的小星星♥(ˆ◡ˆ...
    99+
    2024-04-02
  • Android Studio实现贪吃蛇小游戏
    项目目录 一、项目概述二、开发环境三、详细设计四、运行演示五、项目总结六、源码获取 一、项目概述 贪吃蛇是一款经典的街机游戏,不仅在电子游戏史上占有一席之地,也在很多人的童年回忆中留下了深...
    99+
    2023-10-01
    android studio android 安卓 安卓app android程序
  • js实现贪吃蛇游戏含注释
    本文实例为大家分享了js实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 两个小时完成的,有点简陋。 直接看效果。打开调试面板,在resource面板,新建snippet 粘贴...
    99+
    2024-04-02
  • Vue3+Canvas实现简易的贪吃蛇游戏
    目录前言规则思路流程图代码实现技术栈基本变量定义初始化食物绘制蛇头/蛇身绘制碰撞算法、边界条件积分计算、暂停,继续等功能后记前言 贪吃蛇作为一个经典的小游戏,是很多人儿时的记忆,当时...
    99+
    2024-04-02
  • 原生js编写贪吃蛇小游戏
    本文实例为大家分享了js编写贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 刚学完js模仿着教程,把自己写的js原生小程序。 HTML部分 <!DOCTYPE html&...
    99+
    2024-04-02
  • 怎么用JS实现贪吃蛇游戏
    本文小编为大家详细介绍“怎么用JS实现贪吃蛇游戏”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么用JS实现贪吃蛇游戏”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。效果图:完整代码如下:html:<!DO...
    99+
    2023-07-02
  • JavaScript实现贪吃蛇游戏
    本文实例为大家分享了JavaScript实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下 通过JavaScript,我们可以实现贪吃蛇游戏,具体功能如下: (1)通过按上下左右键来...
    99+
    2024-04-02
  • Java实现贪吃蛇游戏
    下面是一个简单的Java实现贪吃蛇游戏的示例代码:```javaimport javax.swing.*;import java.a...
    99+
    2023-08-09
    Java
  • QT实现贪吃蛇游戏
    为了熟悉QT的相关知识,我用了大约8个小时的时间用QT再次写了一遍贪吃蛇。 因为QT的机制和平时写的程序流程不同,所以程序中可能没有遵守代码规范。 运行效果: 程序内除了实现贪吃蛇...
    99+
    2024-04-02
  • python实现简单贪吃蛇小游戏
    本文实例为大家分享了python实现简单贪吃蛇的具体代码,供大家参考,具体内容如下 1. 导入游戏库 import pgzrun import random 2.游戏初始化 # 窗口...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作