前言
以前用C#写过,某一天找不到文件了,后面闲来无聊纯手敲了一个贪吃蛇小游戏,如果,有想用前端来实现的,可以看看,希望能帮助到你,废话不多,上源码。
1.创建一个html文件,做好准备工作
像这样:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tcs</title>
</head>
<body>
2.直接复制粘贴 html 部分
<audio autoplay loop>
<source src="./Andrew Prahlow - Travelers' encore.ogg" type="audio/mpeg">
</audio>
<div id="main">
<div class="tcs">
<div class="snkers" style="top:225px;left:368px;"></div>
<div class="snkers"></div>
<div class="snkers"></div>
<div class="sw" style="top:225px;left:368px;"></div>
</div>
<div>
<div class="count">您的积分:0</div>
<div class="sm">
<i>
说明:请使用:↑、↓、←、→(不可超出范围)
暂停"q"
</i>
</div>
</div>
</div>
<div class="modal">
<div class="modal-text">
开始("q")
</div>
</div>
3.直接复制css部分
<style>
* {
margin: 0px;
padding: 0px;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-image: url('https://images.unsplash.com/photo-1528320422132-66a5cd87709d?ixlib=rb-1.2.1&auto=format&fit=crop&w=1950&q=80');
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
}
#main {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
/* .back-audio{
display: none;
} */
.tcs {
border-radius: 25px;
background-color: blueviolet;
width: 500px;
height: 500px;
color: antiquewhite;
margin: auto;
position: relative;
}
.sw {
border-radius: 50px;
width: 7px;
height: 7px;
display: block;
position: absolute;
background-color: antiquewhite;
z-index: 0;
}
.snker {
position: relative;
}
.snkers {
position: absolute;
width: 10px;
height: 10px;
background-color: antiquewhite;
border-radius: 3px;
z-index: 999;
animation: snake 1.5s infinite ease-in-out;
}
.snkers:nth-child(1) {
background-color: brown;
}
.count {
color: blueviolet;
font-size: 40px;
font-weight: bold;
margin-right: 200px;
}
.sm {
color: black;
font-size: 20px;
font-weight: bold;
margin-right: 200px;
}
.tcs .snkers {
left: 40px;
animation-delay: .4s;
}
@keyframes snake {
0%,
100% {
opacity: .5;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
}
50% {
opacity: 1;
box-shadow: 0 20px 3px rgba(0, 0, 0, 0.05);
}
}
.modal {
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
/* align-items: center; */
position: fixed;
top: 0px;
left: 0px;
z-index: 999;
display: none;
}
.modal-text {
border-radius: 50%;
border: 2px solid whitesmoke;
color: black;
background-color: whitesmoke;
font-size: 30px;
font-weight: bold;
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
margin: auto;
margin-top: 40vh;
}
</style>
4.不多废话直接粘贴js部分
<script>
var el = document.getElementsByClassName('sw')
var footX, footY
var snkerx = getRandomIntInclusive(1, 40) * 10, snkery = getRandomIntInclusive(1, 40) * 10
var snkerbodyX, snkerbodyY
var publickey = ''
var eattingCount = 0
var isSuspend = 0
var setSpeed=500
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function span(x, y) {
el[0].style.top = x + 'px'
el[0].style.left = y + 'px'
}
function snkerExt(head, x, y) {
head[0].style.top = x + 'px'
head[0].style.left = y + 'px'
snkerx = x
snkery = y
}
function snker(str) {
var head = document.querySelectorAll('.snkers')
var x = snkerx, y = snkery
var judge = judgeKey()
if (str === 'ArrowUp' && judge) {
if (snkery < snkerbodyY) {
x -= 10;
y += 10;
snkerExt(head, x, y)
}
else {
x -= 10;
y -= 10;
snkerExt(head, x, y)
}
}
if (str === 'ArrowDown' && judge) {
if (snkery < snkerbodyY) {
x += 10;
y += 10;
snkerExt(head, x, y)
}
else {
x += 10;
y -= 10;
snkerExt(head, x, y)
}
}
if (str === 'ArrowLeft' && !judge) {
if (snkerx < snkerbodyX) {
x += 10;
y -= 10;
snkerExt(head, x, y)
}
else {
x -= 10;
y -= 10;
snkerExt(head, x, y)
}
}
if (str === 'ArrowRight' && !judge) {
if (snkerx < snkerbodyX) {
x += 10;
y += 10;
snkerExt(head, x, y)
}
else {
x -= 10;
y += 10;
snkerExt(head, x, y)
}
}
if (str === "load") {
head.forEach(el => {
if (el === head[1]) {
snkerbodyX = x
snkerbodyY = y
}
el.style.top = x + 'px'
el.style.left = y + 'px'
y -= 10;
});
}
if (str === "q") {
var a = document.querySelector('.modal')
if (isSuspend % 2 == 0) {
clearInterval(interval)
a.style.display = 'block'
}
else {
a.style.display = 'none'
interval = setInterval(Run, setSpeed)
}
isSuspend++
}
}
function extFunX(el, tag) {
if (tag >= 3) {
if (el.style.left)
el.style.left = y + 'px'
if (el.style.top != snkerbodyX + 'px') {
el.style.top = snkerbodyX + 'px'
}
}
}
function extFunY(el) {
el.style.top = x + 'px'
if (el.style.left != snkerbodyY + 'px') {
el.style.left = snkerbodyY + 'px'
}
}
function extbody(snker) {
var bodyList = []
snker.forEach(el => {
var xbody = Number(el.style.top.replace("px", ""))
var ybody = Number(el.style.left.replace("px", ""))
let els = { x: xbody, y: ybody }
bodyList.push(els)
});
return bodyList
}
function Run() {
judgeScope()//是否犯规
judgeEating()//是否吃到
var judge = judgeKey()
if (judge) {
if (snkery < snkerbodyY) {
var tag = 0
snkery -= 10
snkerbodyY -= 10
y = snkery
var snker = document.querySelectorAll('.snkers')
var elList = extbody(snker)
for (let i = 0; i < snker.length; i++) {
const el = snker[i];
if (i < 2) {
el.style.left = y + 'px'
y += 10
}
else {
var xbody = elList[i - 1].x
var ybody = elList[i - 1].y
el.style.top = xbody + 'px'
el.style.left = ybody + 'px'
}
}
}
else {
snkery += 10
snkerbodyY += 10
y = snkery
var snker = document.querySelectorAll('.snkers')
var elList = extbody(snker)
for (let i = 0; i < snker.length; i++) {
const el = snker[i];
if (i < 2) {
el.style.left = y + 'px'
y -= 10
}
else {
var xbody = elList[i - 1].x
var ybody = elList[i - 1].y
el.style.top = xbody + 'px'
el.style.left = ybody + 'px'
}
}
}
}
else {
if (snkerx < snkerbodyX) {
snkerx -= 10
snkerbodyX -= 10
var x = snkerx
var snker = document.querySelectorAll('.snkers')
var elList = extbody(snker)
for (let i = 0; i < snker.length; i++) {
const el = snker[i];
if (i < 2) {
el.style.top = x + 'px'
x += 10
}
else {
var xbody = elList[i - 1].x
var ybody = elList[i - 1].y
el.style.top = xbody + 'px'
el.style.left = ybody + 'px'
}
}
}
else {
snkerx += 10
snkerbodyX += 10
var x = snkerx
var snker = document.querySelectorAll('.snkers')
var elList = extbody(snker)
for (let i = 0; i < snker.length; i++) {
const el = snker[i];
if (i < 2) {
el.style.top = x + 'px'
x -= 10
}
else {
var xbody = elList[i - 1].x
var ybody = elList[i - 1].y
el.style.top = xbody + 'px'
el.style.left = ybody + 'px'
}
}
}
}
}
var interval = setInterval(Run, setSpeed)
function judgeEating() {
if (footX == snkerx && snkery == footY) {
console.log('吃到了')
resetsw()
eattingCount++;
var count = document.querySelector('.count')
console.log(count)
//提升难度
if(eattingCount%10==0 && setSpeed!=100) setSpeed-=100
count.innerHTML = '您的积分:' + eattingCount
var fnode = document.querySelector('.tcs')
fnode.innerHTML += '<div class="snkers"></div>'
}
}
function judgeScope() {
var snker = document.querySelectorAll('.snkers')
var elList = extbody(snker)
if (snkerx <= 0 || snkery <= 0 || snkerx >= 490 || snkery >= 490) {
clearInterval(interval)
alert("游戏结束,请刷新网页")
}
if (elList.length > 3) {
for (let el = 0; el < elList.length; el++) {
const element = elList[el];
if (el <= 2) continue
if (snkerx == element.x && snkery == element.y) {
clearInterval(interval)
alert("游戏结束,请刷新网页")
}
}
}
}
function judgeKey() {
if (snkerx === snkerbodyX) return true;//x相等横向
if (snkery === snkerbodyY) return false;//y相等竖向
}
function resetsw() {
footX = getRandomIntInclusive(1, 40) * 10//50-450
footY = getRandomIntInclusive(1, 40) * 10//50-450
span(footX, footY)
}
document.addEventListener('keydown', function (event) {
const key = event.key;
publickey = key.toString()
snker(publickey)
});
snker("load")
resetsw()
</script>
5.效果
嘿嘿,我弄了个背景音乐,自己替换掉或者注释掉哦,哈哈哈哈
6.总结
最后,我想说的就是思路吧,我的想法其实很简单,
1.把固定大小的盒子当做游戏活动区间。
2.获取用户键盘控件,用原生js去控制dom的移动和食物的随机性出现,特别是需要注意蛇的成长长度和蛇头(也就是第一个格子)不能触碰到自身,对于蛇的成长很简单,在末尾新增格子,插入dom就行了,但是对于蛇头触碰到蛇身的话我用的办法很简单,就是判断元素位置,这个是可以获取的(有兴趣可以研究一下代码,欢迎指出错误或者不足的地方),
3.游戏暂停和继续,其实就是暂停计时器,嘿嘿,很简单吧。
4.美化一下,写一点样式,(ok啦,没了)
可以用这个练练手啥的,很简单的(具体细节可以复制一下,先看看效果然后再看实现过程)
拜拜!