web前端项目-贪吃蛇小游戏【附源码】

web前端项目-贪吃蛇小游戏

【贪吃蛇】是一款经典的小游戏,采用HTMLCSSJavaScript技术进行开发,玩家通过控制一条蛇在地图上移动,蛇的目的是吃掉地图上的食物,并且让自己变得更长。游戏的核心玩法是控制蛇的移动方向和长度,同时避免蛇头碰到自己的身体或者游戏边界

运行效果:上下左右键控制蛇的移动;空格为游戏开始/暂停;可以在游戏界面设置蛇的移动速度
在这里插入图片描述
在这里插入图片描述

HTML源码–index.html

<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>贪吃蛇小游戏</title>
<link rel="stylesheet" href="css/snake.css">
<script type="text/javascript" src="js/snake.js"></script>
</head>

<body>
<div class="box">
    <span>分数:<span id="foodNum"></span></span>
    <span>选择速度:<select id="setSpeed">
		<option value="200">慢速</option>
		<option value="100">中速</option>
		<option value="50">快速</option>
	</select></span>
    <span>开始/暂停(空格键)</span>
</div>
<table id="map"></table>
</body>
</html>

js源码–snake.js

function Snake(){
    this.rows = 21;//21行
    this.cols = 21;//21列
    this.speed = 200;//前进速度
    this.curKey = 0;//当前方向按键键码值
    this.timer = 0;
    this.pos = [];//蛇身位置
    this.foodPos = {"x":-1,"y":-1};
    this.foodNum = 0;//吃掉食物数量
    this.dom = document.getElementById("map");//地图元素
    this.pause = 1;//1表示暂停,-1表示开始
}
Snake.prototype.map = function(){//创建地图
	if(this.dom.firstChild){
		this.dom.removeChild(this.dom.firstChild);//重新开始 删除之前创建的tbody
	}
    for( j = 0; j < this.rows; j++ ){
        var tr = this.dom.insertRow(-1);//插入一行
        for( i = 0; i < this.cols; i++ ){
            tr.insertCell(-1);//插入一列
        }
    }
}
Snake.prototype.food = function(){//生成食物
    do{
        this.foodPos.y = Math.floor( Math.random()*this.rows );
        this.foodPos.x = Math.floor( Math.random()*this.cols );
    }while( this.dom.rows[this.foodPos.y].cells[this.foodPos.x].className != "" )//防止食物生成在蛇身上
    this.dom.rows[this.foodPos.y].cells[this.foodPos.x].className="snakefood";//设置食物样式
    document.getElementById("foodNum").innerHTML=this.foodNum++;//设置分数
}
Snake.prototype.init = function(){
    this.map();//创建地图
    arguments[0] ? this.speed=arguments[0] : false;//选择速度
    this.pos = [{"x":2,"y":0},{"x":1,"y":0},{"x":0,"y":0}];//定义蛇身位置
    for(var j=0; j<this.pos.length; j++ ){//显示蛇身
        this.dom.rows[this.pos[j].y].cells[this.pos[j].x].className="snakebody";
    }
    this.dom.rows[this.pos[0].y].cells[this.pos[0].x].className="snakehead";//为蛇头设置样式
    this.curKey = 0;//当前方向按键键码值
    this.foodNum = 0;//吃掉食物数量
    this.food();//生成食物
    this.pause = 1;//1表示暂停,-1表示开始
}
Snake.prototype.trigger = function(e){
	var _t=this;
    var e = e || event;
    var eKey = e.keyCode;//获取按键键码值
    if( eKey>=37 && eKey<=40 && eKey!=this.curKey && !( (this.curKey == 37 && eKey == 39) || (this.curKey == 38 && eKey == 40) || (this.curKey == 39 && eKey == 37) || (this.curKey == 40 && eKey == 38) ) && this.pause==-1 ){//如果按下的是方向键,并且不是当前方向,也不是反方向和暂停状态
        this.curKey = eKey;        //设置当前方向按键键码值        
    }else if( eKey==32 ){
        this.curKey = (this.curKey==0) ? 39 : this.curKey;
		this.pause*=-1;
		if(this.pause==-1){
			this.timer=window.setInterval(function(){_t.move()},this.speed);//蛇身移动
		}else{
			window.clearInterval(this.timer);//停止
		}
    }
}
Snake.prototype.move = function(){//移动
    switch(this.curKey){
        case 37: //左方向
            if( this.pos[0].x <= 0 ){ //蛇头撞到边界
				this.over(); 
				return; 
			}else{ 
				this.pos.unshift( {"x":this.pos[0].x-1,"y":this.pos[0].y}); //添加元素
			}
            break;
        case 38: //上方向
            if( this.pos[0].y <= 0 ){ 
				this.over(); 
				return; 
			}else{ 
				this.pos.unshift( {"x":this.pos[0].x,"y":this.pos[0].y-1}); 
			}
            break;
        case 39://右方向
            if( this.pos[0].x >= this.cols-1 ){ 
				this.over(); 
				return; 
			}else{ 
				this.pos.unshift( {"x":this.pos[0].x+1,"y":this.pos[0].y}); 
			}
            break;
        case 40: //下方向
            if( this.pos[0].y >= this.rows-1 ){ 
				this.over(); 
				return; 
			}else{ 
				this.pos.unshift( {"x":this.pos[0].x,"y":this.pos[0].y+1}); 
			}
            break;
    }
    if( this.pos[0].x == this.foodPos.x && this.pos[0].y == this.foodPos.y ){//蛇头位置与食物重叠
        this.food();//生成食物
    }else if( this.curKey != 0 ){
        this.dom.rows[this.pos[this.pos.length-1].y].cells[this.pos[this.pos.length-1].x].className="";
        this.pos.pop();//删除蛇尾
    }
    for(i=3;i<this.pos.length;i++){//从蛇身的第四节开始判断是否撞到自己
        if( this.pos[i].x == this.pos[0].x && this.pos[i].y == this.pos[0].y ){ 
            this.over();//游戏结束
            return;
        }
    }
    this.dom.rows[this.pos[0].y].cells[this.pos[0].x].className="snakehead";//画新蛇头
    this.dom.rows[this.pos[1].y].cells[this.pos[1].x].className="snakebody";//原蛇头变为蛇身
}
Snake.prototype.over = function(){
    alert("游戏结束");
    window.clearInterval(this.timer);//停止
    this.init();//重置游戏
}
window.onload = function(){
    var snake = new Snake();//创建对象实例
    snake.init();//调用初始化方法
    document.onkeydown = function(e){ 
		snake.trigger(e); //按下按键时调用方法
	}
    document.getElementById("setSpeed").onchange = function(){ 
		this.blur(); 
		snake.init(this.value); 
	}
}

CSS源码–snake.css

  *                         { margin:0; padding:0; font-family:Verdana,宋体; font-size:12px;}
  table#map { width:auto; height:auto; margin:0 auto; border-collapse:collapse; border-spacing:0; background-color:#EAEAEA; clear:both; background:#74AFE0}
  td                 { width:10px; height:10px; border:1px solid black;}
  .snakehead         { background-color: orangered;}
  .snakebody         { background-color:#FFCC00;}
  .snakefood         { background-color: orangered;}
  .box        { width:310px; margin:0 auto; padding:3em 0; list-style:none;}
  .box>span{ float:left; height:30px; margin-right:1.5em; line-height:30px;}

注: 以上为本项目的所有源码,无图片素材

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习记录--梯度检验

数值逼近 为了对梯度进行检验&#xff0c;需要计算近似误差值来接近梯度 对于单边误差和双边误差公式&#xff0c;其中双边误差与真实梯度相差更小&#xff0c;故一般采用双边误差公式 双边误差 公式&#xff1a; 梯度检验(gradient checking) 对于成本函数&#xff0c;求出…

微信小程序之组件和API

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

S/MIME电子邮件证书申请指南

近年来&#xff0c;邮件安全问题日益突出&#xff0c;电子邮件成为诈骗、勒索软件攻击的重灾区。恶意邮件的占比屡创新高&#xff0c;邮件泄密事件更是比比皆是。在如此严峻的网络安全形势下&#xff0c;使用S/MIME电子邮件证书进行邮件收发是当今最佳的邮件安全解决方案之一。…

RT-Thread 15. list_timer与软定时器

1. 代码 void rt_thread_usr1_entry(void *parameter) {/* set LED2 pin mode to output */rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT);while (1){rt_pin_write(LED2_PIN, PIN_HIGH);rt_thread_mdelay(2000);rt_pin_write(LED2_PIN, PIN_LOW);rt_thread_mdelay(3000);} }int ma…

Demo: 实现PDF加水印以及自定义水印样式

实现PDF加水印以及自定义水印样式 <template><div><button click"previewHandle">预览</button><button click"downFileHandle">下载</button><el-input v-model"watermarkText" /><el-input v-mo…

class_7: C++引用

//1、引用是给变量取别名&#xff0c;定义的时候必须初始化&#xff0c;且指向一个确定的内存空间&#xff1b; //2、引用实质是指针常量&#xff0c;值可以改变&#xff0c;地址不可改变&#xff0c;即不可重复赋值#include <iostream> using namespace std;//1、引用是…

阿赵UE学习笔记——10、Blender材质和绘制网格体

阿赵UE学习笔记目录   大家好&#xff0c;我是阿赵。   之前介绍了虚幻引擎的材质和材质实例。这次来介绍一个比较有趣的内置的Blender材质。   在用Unity的时候&#xff0c;我做过一个多通道混合地表贴图的效果&#xff0c;而要做过一个刷顶点颜色混合地表和水面的效果。…

数学建模--论文

内容来自数学建模BOOM&#xff1a;【快速入门】北海&#xff1a;数模建模基础MATLAB入门论文写作数学模型与算法(推荐数模美赛国赛小白零基础必看教程)_哔哩哔哩_bilibili 目录 一、论文整体模版 1.整体框架 2.示例 二、标题 1.标题主题事项 三、摘要 1.摘要三要素&am…

Linux系统:yum仓库

目录 一、yum 1、yum概述 2、yum仓库 3、yum实现过程原理 二、yum配置文件详解 1、主配置文件 2、yum仓库设置文件 3、yum日志文件 三、yum命令详解 1、查询 1.1 yum list [软件名] 1.2 yum info [软件名] 1.3 yum search <关键词> 1.4 yum provides <关…

无重复字符的最长子串[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个字符串s&#xff0c;请你找出其中不含有重复字符的最长子串的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是"abc"&#xff0c;所以其长度为3。 示例 2: 输入: s &…

Verilog刷题笔记17

题目&#xff1a; For hardware synthesis, there are two types of always blocks that are relevant: Combinational: always (*) Clocked: always (posedge clk) Clocked always blocks create a blob of combinational logic just like combinational always blocks, but …

el-table中设置第一列为多选框,且多选框动态禁用

给el-table第一列写成以下代码: <el-table-columntype"selection"width"55"></el-table-column> 效果: 多选框动态禁用 el-table中设置了 type"selection"&#xff0c;但是由于部分数据是已经处理过的&#xff0c;不允许选中&…

css-盒子等样式学习

盒子居中&#xff0c;继承外层盒子的宽高 兼容性&#xff08;border-box&#xff09;将边框收到盒子内部 初始化div 不用管box-setting content-box 还原 创建为一个类 &#xff0c;让所有需要还原的类 进行继承 padding 用法表示margin上下左右边距 body 外边距&…

高性价比低功耗高性能蓝牙5.2系统级芯片PHY6230

PHY6230 是一款高性价比低功耗高性能Bluetooth LE 5.2系统级芯片&#xff0c;集成32-bit高性能低功耗MCU&#xff0c;16KB OTP&#xff0c;8KB Retention SRAM和64KB ROM&#xff0c;可选EEPROM。内置高性能多模射频收发机最大发射功率10dBm&#xff0c;BLE 1Mbps速率下接收灵敏…

最新 生成pdf文字和表格

生成pdf文字和表格 先看效果 介绍 java项目&#xff0c;使用apache的pdfbox工具&#xff0c;可分页&#xff0c;自定义列 依赖 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.22<…

5-微信小程序语法参考

1. 数据绑定 官网传送门 WXML 中的动态数据均来自对应 Page 的 data。 数据绑定使用 Mustache 语法&#xff08;双大括号&#xff09;将变量包起来 ts Page({data: {info: hello wechart!,msgList: [{ msg: hello }, { msg: wechart }]}, })WXML <view class"vie…

Nodejs 第三十二章(数据库)

MySQL是一种开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它是最受欢迎的数据库系统之一。MySQL广泛用于Web应用程序和其他需要可靠数据存储的应用程序中。 以下是MySQL数据库的一些重要特点和概念&#xff1a; 数据库&#xff1a;MySQL是一个数据库…

Oracle21C + PLSQL Developer 15 + Oracle客户端21安装配置完整图文版

一、Oracle21C PLSQL Developer 15 Oracle客户端文件下载 1、Oracl21C下载地址&#xff1a;Database Software Downloads | Oracle 中国 2、 PLSQL Developer 15下载地址&#xff1a;Registered download PL/SQL Developer - Allround Automations 3、 Oracle 客户端下载地址…

【linux驱动】用户空间程序与内核模块交互-- IOCTL和Netlink

创建自定义的IOCTL&#xff08;输入/输出控制&#xff09;或Netlink命令以便用户空间程序与内核模块交互涉及几个步骤。这里将分别介绍这两种方法。 一、IOCTL 方法 1. 定义IOCTL命令 在内核模块中&#xff0c;需要使用宏定义你的IOCTL命令。通常情况下&#xff0c;IOCTL命令…

RHCE9学习指南 第21章 用bash写脚本

grep的用法是&#xff1a; grep 关键字 file 意思是从file中过滤出含有关键字的行。 例如&#xff0c;grep root /var/log/messages&#xff0c;意思是从/var/log/messages中过滤出含有root的行。这里很明确的是过滤含有“root”的行。 如果我要是想在/var/log/messages中过滤…