贪吃蛇小游戏基本简单布局

news2024/11/24 15:26:39

代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Layui贪吃蛇小游戏</title>
  <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/layui/2.5.7/css/layui.css">
</head>
<body>
  <div class="layui-container">
    <h1 class="layui-header">Layui贪吃蛇小游戏</h1>
    <div class="layui-row">
      <div class="layui-col-md8">
        <canvas id="gameCanvas" width="400" height="400"></canvas>
      </div>
      <div class="layui-col-md4">
        <div class="layui-card">
          <div class="layui-card-header">游戏控制</div>
          <div class="layui-card-body">
            <button id="startBtn" class="layui-btn">开始游戏</button>
            <button id="pauseBtn" class="layui-btn">暂停游戏</button>
            <button id="resetBtn" class="layui-btn">重置游戏</button>
          </div>
        </div>
      </div>
    </div>
  </div>

  <script src="https://cdn.bootcdn.net/ajax/libs/layui/2.5.7/layui.js"></script>
  <script>
    layui.use(['layer', 'form'], function(){
      var layer = layui.layer;
      var form = layui.form;

      // 游戏逻辑
      var canvas = document.getElementById('gameCanvas');
      var ctx = canvas.getContext('2d');
      var snakeSize = 10;
      var snake = [
        {x: 200, y: 200},
        {x: 190, y: 200},
        {x: 180, y: 200},
        {x: 170, y: 200},
        {x: 160, y: 200}
      ];
      var food = {x: 0, y: 0};
      var dx = 10;
      var dy = 0;

      function drawSnakePart(snakePart) {
        ctx.fillStyle = 'lightgreen';
        ctx.strokeStyle = 'darkgreen';
        ctx.fillRect(snakePart.x, snakePart.y, snakeSize, snakeSize);
        ctx.strokeRect(snakePart.x, snakePart.y, snakeSize, snakeSize);
      }

      function drawSnake() {
        snake.forEach(drawSnakePart);
      }

      function advanceSnake() {
        const head = {x: snake[0].x + dx, y: snake[0].y + dy};
        snake.unshift(head);
        const didEatFood = snake[0].x === food.x && snake[0].y === food.y;
        if (didEatFood) {
          createFood();
        } else {
          snake.pop();
        }
      }

      function clearCanvas() {
        ctx.fillStyle = 'white';
        ctx.strokeStyle = 'black';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.strokeRect(0, 0, canvas.width, canvas.height);
      }

      function createFood() {
        food.x = Math.floor(Math.random() * canvas.width / 10) * 10;
        food.y = Math.floor(Math.random() * canvas.height / 10) * 10;
        snake.forEach(function isFoodOnSnake(part) {
          const foodIsOnSnake = part.x === food.x && part.y === food.y;
          if (foodIsOnSnake) {
            createFood();
          }
        });
      }

      function drawFood() {
        ctx.fillStyle = 'red';
        ctx.strokeStyle = 'darkred';
        ctx.fillRect(food.x, food.y, snakeSize, snakeSize);
        ctx.strokeRect(food.x, food.y, snakeSize, snakeSize);
      }

      function main() {
        if (didGameEnd()) return;
        setTimeout(function onTick() {
          changingDirection = false;
          clearCanvas();
          drawFood();
          advanceSnake();
          drawSnake();
          main();
        }, 100)
      }

      function didGameEnd() {
        for (let i = 4; i < snake.length; i++) {
          if (snake[i].x === snake[0].x && snake[i].y === snake[0].y) return true;
        }
        const hitLeftWall = snake[0].x < 0;
        const hitRightWall = snake[0].x > canvas.width - 10;
        const hitTopWall = snake[0].y < 0;
        const hitBottomWall = snake[0].y > canvas.height - 10;
        return hitLeftWall || hitRightWall || hitTopWall || hitBottomWall;
      }

      function resetGame() {
        snake = [
          {x: 200, y: 200},
          {x: 190, y: 200},
          {x: 180, y: 200},
          {x: 170, y: 200},
          {x: 160, y: 200}
        ];
        dx = 10;
        dy = 0;
        createFood();
      }

      createFood();
      main();

      document.addEventListener('keydown', changeDirection);

      function changeDirection(event) {
        const LEFT_KEY = 37;
        const RIGHT_KEY = 39;
        const UP_KEY = 38;
        const DOWN_KEY = 40;

        if (changingDirection) return;
        changingDirection = true;

        const keyPressed = event.keyCode;
        const goingUp = dy === -10;
        const goingDown = dy === 10;
        const goingRight = dx === 10;
        const goingLeft = dx === -10;

        if (keyPressed === LEFT_KEY && !goingRight) {
          dx = -10;
          dy = 0;
        }

        if (keyPressed === UP_KEY && !goingDown) {
          dx = 0;
          dy = -10;
        }

        if (keyPressed === RIGHT_KEY && !goingLeft) {
          dx = 10;
          dy = 0;
        }

        if (keyPressed === DOWN_KEY && !goingUp) {
          dx = 0;
          dy = 10;
        }
      }

      // 游戏控制
      var startBtn = document.getElementById('startBtn');
      var pauseBtn = document.getElementById('pauseBtn');
      var resetBtn = document.getElementById('resetBtn');

      startBtn.onclick = function() {
        main();
      }

      pauseBtn.onclick = function() {
        clearTimeout(main);
      }

      resetBtn.onclick = function() {
        resetGame();
      }
    });
  </script>
</body>
</html>

结果图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1258645.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据库】执行计划中的两趟算法机制原理,基于排序算法来分析,算法的限制,执行代价以及优化

基于排序的两趟算法 ​专栏内容&#xff1a; 手写数据库toadb 本专栏主要介绍如何从零开发&#xff0c;开发的步骤&#xff0c;以及开发过程中的涉及的原理&#xff0c;遇到的问题等&#xff0c;让大家能跟上并且可以一起开发&#xff0c;让每个需要的人成为参与者。 本专栏会定…

跨越速运在货运高峰的同时,受邀参加国际医疗器械博览会

作为国内领先的物流企业&#xff0c;跨越速运在一年一度的年终大促&#xff0c;货运高峰的同时&#xff0c;受第88届中国国际医疗器械博览会&#xff08;以下简称CMEF&#xff09;活动主办方邀请&#xff0c;&#xff09;于2023年10月31日&#xff0c;在深圳国际会展中心重磅亮…

Linux驱动开发——网络设备驱动(理论篇)

目录 一、前言 二、网络层次结构 三、网络设备驱动核心数据结构和函数 一、前言 网络设备驱动是 Linux 的第三大类驱动&#xff0c;也是我们学习的最后一类 Linux 驱动。这里我们首先简单学习一下网络协议层次结构&#xff0c;然后简单讨论 Linux 内核中网络实现的层次结构。…

我发现了这个神器‼在线制作电子画册so easy~

你是不是也厌倦了传统纸质画册的繁琐&#xff1f;想要一个更便捷、更时尚的方式来展示你的作品&#xff1f;那么&#xff0c;今天向你介绍的这款神器&#xff0c;绝对能让你眼前一亮&#xff01; 没错&#xff0c;它就是在线制作电子画册的利器&#xff01;FLBOOK在线制作电子杂…

测绘资质海洋测绘乙级申请条件

海洋测绘专业新申请要求是什么&#xff1f;准备哪些材料呢&#xff1f;要符合什么条件&#xff1f;参考本文 一、所需申请材料 &#xff08;一&#xff09;申请书&#xff1b; &#xff08;二&#xff09;企业营业执照或事业单位法人证书&#xff1b; &#xff08;三&#…

使用westssl工具实现自动更新SSL证书的流程

SSL证书默认有效期默认为1年&#xff0c;部分免费证书的默认有效期为3个月。您必须在证书到期前的30个自然日内续费并更新证书&#xff0c;才能延长证书的服务时长。证书续费时&#xff0c; 会颁发一个新的证书&#xff0c;您收到新证书后需要手工更新到服务器上。部分证书支持…

Make sure bypassing Vue built-in sanitization is safe here.

一、问题描述 二、问题分析 XSS(跨站脚本攻击) XSS攻击通常指的是通过利用网页开发时留下的漏洞&#xff0c;通过巧妙的方法注入恶意指令代码到网页&#xff0c;使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript&#xff0c;但实际上也可以包括J…

运行新vue3项目

一&#xff0c;下载node并安装 官网&#xff1a;https://nodejs.org/en/ 查看版本&#xff1a; node -v二&#xff0c;cd进入到vue3项目目录 cd D:\Program-space\HBuilderXProject\Vue3project三&#xff0c;npm install npm install四&#xff0c;查看安装 npm list五&a…

数字图像处理(实践篇)八 Harris角点检测

目录 1 涉及的OpenCV函数 2 实践 在图像中每个方向变化都很大的区域就是角点&#xff0c;一个早期的尝试是由 Chris Harris & Mike Stephens 在1998年的论文 A Combined Corner and Edge Detector 完成的。所以现在称之为 Harris角点检测。 1 涉及的OpenCV函数 cornerHa…

物理层之奈氏准则和香农定理

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

【总结】重极限的计算

这个做法比较严谨&#xff0c;我之前是想着分母趋于0&#xff0c;分子也得趋于0&#xff0c;这个有界量乘无穷小还是无穷小的手法还是很漂亮的。 图一源链接https://www.zhihu.com/question/269472244 图二选自李艳芳真题解析

不可错过的设计工具!7款亲测好用的网页设计工具推荐!

网页设计并不容易&#xff0c;易于使用的网页设计工具更难找到。随着网络的快速发展&#xff0c;网站迅速崛起&#xff0c;网页设计也很流行。本文收集了 7 种良心和易于使用的网页设计工具&#xff0c;每一种近年来都受到网页设计师的广泛欢迎&#xff0c;以确保实用和易于使用…

3D点云目标检测:CT3D解读(未完)

CT3D 一、RPN for 3D Proposal Generation二、Proposal-to-point Encoding Module2.1、Proposal-to-point Embedding2.2、Self-attention Encoding 三、Channel-wise Decoding Module3.1、Standard Decoding3.2、Channel-wise Re-weighting3.3、Channel-wise Decoding Module 四…

山西临汾建筑坍塌悲剧,建设健全建筑结构健康监测系统

11月24日山西临汾的建筑坍塌事故&#xff0c;让人们再次关注到了建筑结构的安全问题。在这场悲剧中&#xff0c;7人不幸遇难&#xff0c;让人痛心。然而&#xff0c;我们不能只是沉浸在悲痛之中&#xff0c;更应该思考如何避免类似的悲剧再次发生。 WITBEE万宾建筑结构健康监测…

自定义右键菜单栏

自定义菜单栏&#xff0c;关键要用到一个类为QWidgetAction&#xff0c;它继承于QAction&#xff0c; 1.使用setDefaultWidget接口将 自定义窗口放到QWidgetAction中&#xff0c; 2.然后再像添加QAction一样&#xff0c;将QWidgetAction添加到QMenu中就可以了。 比如&…

2023年亚太杯APMCM数学建模大赛A题水果采摘机器人的图像识别

2023年亚太杯APMCM数学建模大赛 A题 水果采摘机器人的图像识别 原题再现 中国是世界上最大的苹果生产国&#xff0c;年产量约3500万吨。同时&#xff0c;中国也是世界上最大的苹果出口国&#xff0c;世界上每两个苹果中就有一个是中国出口的&#xff0c;世界上超过六分之一的…

【高效开发工具系列】PlantUML入门使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

[个人笔记] Zabbix实现Webhook推送markdown文本

系统工程 - 运维篇 第四章 Zabbix实现Webhook推送markdown文本 系统工程 - 运维篇系列文章回顾Zabbix实现Webhook推送markdown文本前言实施步骤 Zabbix新增报警媒介类型Zabbix给用户新增报警媒介Zabbix修改动作的执行操作和恢复操作验证&测试 参考来源 系列文章回顾 第一章…

nuxt、vue实现PDF和视频文件的上传、下载、预览

上传 上传页面 <el-form-item :label"(form.ququ3 1 ? 参培 : form.ququ3 2 ? 授课 : ) 证明材料" prop"ququ6"><PdfUpload v-model"form.ququ6" :fileType"[pdf, mp4, avi, ts]"></PdfUpload> </el-form-i…

虚幻学习笔记—文本内容处理

一、前言 本文使用的虚幻引擎5.3.2&#xff0c;在虚幻中已经集成了很多可以直接处理多样化文本的蓝图&#xff0c;比如格式化动态显示、浮点数多样化等。 二、实现 2.1、格式化文本显示动态内容&#xff1a;在设置某个文本时可以使用“Format Text”蓝图设置自定义可以的显示…