利用js制作简单的贪吃蛇游戏
首先,我们先来分析一下整个页面的构成。一看可知,游戏框内是一个盒子里面有许多的小方块,我们可以利用 ul和li标签来制作蛇和食物。右侧就是简单的 2个p标签·一个select标签· 2个input标签而已。代码如下
<div class="box" id="box">
<ul class="oul" id="oul">
</ul>
</div>
<div class="box1" id="box1">
<p>最佳历史纪录:<span id="ls">0</span></p>
<p >当前长度:<span id="dqcd">0</span></p>
<select id="level">
<option value="300">初级</option>
<option value="200">中级</option>
<option value="100">较难</option>
</select>
<input type="button" id="btn1" value="开始">
<input type="button" id="btn2" value="暂停">
</div>
<audio src="mp3/bg.mp3" loop id="bgaudio"></audio>
<audio src="mp3/go.wav" id="go"></audio>
<audio src="mp3/chi.mp3" id="chi"></audio>
<script type="text/javascript" src="zepto.min.js"></script>
<script type="text/javascript" src="touch.js"></script>
<script type="text/javascript" src="sss.js"></script>
<!-- 引入支持库 -->
因为我们需要很多的小格子,所以 li标签 我们将用利用js里的for循环来创建,这样会使我们的代码量减少,减轻我们的工作量,我们在介绍js代码会详细介绍,现在先不多说。我们接下来要为html文档加上样式,因为代码比较简单,所以我们可以将样式随意写在什么地方。css代码如下:
*{
margin: 0;
padding: 0;
}
input{
outline: none;
margin: auto;
}
.box{
width: 3.2rem;
margin: auto;
float: left;
}
.oul{
width: 3.14rem;
height: 3.14rem;
border:0.03rem solid peru;
}
.oul li{
list-style: none;
width: 5%;
height: 5%;
float: left;
}
.box1{
width: 2rem;
height: 1rem;
padding-top: 0.3rem;
font-size: 0.2rem;
margin: auto;
float: left;
}
#level{
width: 100%;
height: 0.4rem;
}
#ls{
color:paleturquoise;
margin-left: 0.1rem;
}
#dqcd{
color:paleturquoise;
margin-left: 0.01rem;
}
#btn1{
width: 50%;
height:0.3rem;
margin-left: 0.4rem;
margin-top: 0.2rem;
background: palegreen;
color: #fff;
}
#btn2{
width: 50%;
height: 0.3rem;
margin-left: 0.4rem;
margin-top: 0.2rem;
background: palegreen;
color: #fff;
}
因为我们需要兼容移动端设备和pc端设备,所以我们需要在css前加上媒体查询样式,并且在使用单位时,需要用到rem而不是px。
媒体查询代码如下:
@media screen and (min-width: 320px) {
html {
font-size: 100px; } }
@media screen and (min-width: 360px) {
html {
font-size: 113px; } }
@media screen and (min-width: 375px) {
html {
font-size: 117px; } }
@media screen and (min-width: 384px) {
html {
font-size: 120px; } }
@media screen and (min-width: 412px) {
html {
font-size: 128px; } }
@media screen and (min-width: 414px) {
html {
font-size: 129px; } }
@media screen and (min-width: 440px) {
html {
font-size: 138px; } }
@media screen and (min-width: 480px) {
html {
font-size: 150px; } }
上面我们已经将基本样式都写好,下面我们就要编辑js代码
因为我们需要兼容移动端设备,而现在的移动设备大多数没有键盘,所以我们需要引入一些库来支持手指划动,比如 bammer.js或者touch.js等等。我们这里使用的是touch.js。
在上面,我们并没有在html文档中建立 li标签,所以我们需要在js里建立,利用for循环:
var oul = document.getElementById("oul");
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var bgaudio = document.getElementById("bgaudio");
var si = document.getElementById("go");
var chi = document.getElementById("chi");
var dqcd = document.getElementById("dqcd");
var ls = document.getElementById("ls");
var level = document.getElementById("level");
// 首先我们先获取各个标签的id,在后面会用到
var ox = document.createDocumentFragment();
function ab (){
for(var i = 0 ; i<400 ; i++){
var oli = document.createElement("li")
ox.appendChild(oli)
}
}
ab();
oul.appendChild(ox);
如果你建立后看的不直观,你可以给 li标签 一个边框,以便于观看,由于我们需要看到每一个小格子的索引,所以我们在循环内添加(oli.innerHTML = i),我们就可以清楚的看到每一个格子的索引值。
建立了游戏外边框后,我们开始建立蛇的身体和蛇的食物。在每一次的刷新后,我们会发现蛇身体和食物的颜色都会随机变化,所以我们需要建立一个随机颜色的函数,在每一次使用时直接调用就可以了。
function co (){
return "rgb("+Math.floor(Math.random()*256)+","+Math.floor(Math.random()*256)+","+Math.floor(Math.random()*256)+")"
}
建立蛇身,蛇身长五,所以我们初始化一个变量,然后利用for循环建立
var snk = [];
snk = oul.children;
var snkbody = [];
var ox = document.createDocumentFragment();
for(var i=0;i<5;i++){
snkbody.push({pos:i,color:co()})
}
// 创建蛇身
function cd (){
for(var j=0,l=snkbody.length;j<l;j++){
snk[snkbody[j].pos].style.background=snkbody[j].color;
}
}
cd();
// 为蛇添加随机颜色
然后我们为你为蛇建立食物,但是我们需要注意食物不能与蛇身在初始化到一起,所以我们需要如下代码:
var food = [{pos:0,color:"red"}];
function isin (index){
for(var j=0,l=snkbody.length;j<l;j++){
if(snkbody[j].pos==index){
return true;
break;
}
}
return false;
};
function snkfood (){
var index = Math.floor(Math.random()*400);
while(isin(index)){
index = Math.floor(Math.random()*400);
}
food = {pos:index,color:co()}
snk[index].style.background=food.color;
}
// 如果食物被蛇身覆盖,随机再次产生产生一个食物
snkfood();
下面我们就需要让蛇动起来
var snkh = snkbody.slice(-1)[0].pos;
var snkw = snkbody.slice(0,1)[0].pos;
// 获取蛇头蛇尾位置
for(var k=0,l=snkbody.length;k<l-1;k++){
snkbody[k].pos=snkbody[k+1].pos;
}
snkh = snkbody[l-1].pos;
// 蛇向前一步走
然而我们像现在发现蛇虽然会走了,但是蛇尾的颜色并不会改变,所以我们还需要将蛇尾的颜色改变。
snk[snkw].style.background=0;
如果我们需要改变蛇的前进方向,我们需要清楚我们的设备,如果是移动设备,我们需要使用手指滑动方法,如果是pc设备,我们需要识别按键,所以我就使用了获取body.width的方法,如果大于1024,即识别为pc端,否则为移动端。
var bodywid = document.body.offsetWidth;
if(bodywid>1024){
document.addEventListener("keydown",function(e){
e=e||window.event;
switch(e.keyCode){
case 37:{
// left
if(fxg==39)return false;
fxg=e.keyCode;
break;
}
case 38:{
if(fxg==40)return false;
fxg=e.keyCode;
break;
// up
}
case 39:{
if(fxg==37)return false;
fxg=e.keyCode;
break;
// right
}
case 40:{
if(fxg==38)return false;
fxg=e.keyCode;
break;
// down
}
}
},false);
// 识别按键
}else{
oul.touch({
swipeLeft:function(){
kkk(37)
},
swipeRight:function(){
kkk(39)
},
swipeUp:function(){
kkk(38)
},
swipeDown:function(){
kkk(40)
},
});
// 划动改变函数kkk的值,使蛇改变方向
function kkk (e){
switch(e){
case 37:{
// left
if(fxg==39)return false;
fxg=e;
break;
}
case 38:{
if(fxg==40)return false;
fxg=e;
break;
// up
}
case 39:{
if(fxg==37)return false;
fxg=e;
break;
// right
}
case 40:{
if(fxg==38)return false;
fxg=e;
break;
// down
}
}
}
// 39:右 1:40 2:37 3:38
}
if(fxg==40){
snkbody[l-1].pos=snkbody[l-1].pos+20;
}else if(fxg==37){
snkbody[l-1].pos=snkbody[l-1].pos-1;
}
else if(fxg==38){
snkbody[l-1].pos=snkbody[l-1].pos-20;
}
else if(fxg==39){
snkbody[l-1].pos=snkbody[l-1].pos+1;
}
// 根据我们的索引可以看出,向下就是依次+20,向上就是-20,向左就是-1,向右就是+1,所以我们在按键之后改变蛇头的方向即可
我们的蛇现在就可以走了,我们还想让他能够吃到食物
if(snkh==food.pos){
snkbody.unshift({pos:snkw,color:food.color});
// 将食物放到蛇尾
snkfood();
// 再次刷新食物
chi.play();
// 播放吃食物音效
var snkbodycd = snkbody.length-5;
// 获取分数
dqcd.innerText=snkbodycd;
// 刷新当前分数
}
我们在平时玩贪吃蛇的时候,碰壁也会死亡,所以我们还需要做一下碰壁处理
// 我们的小格子边框是20个,所以我们要在全局建立个数变量
var geshu = 20;
// 之后根据索引找出各个边框处小格子的规律,并且识别蛇头方向,进行碰壁处理
var fxg = 39;
// 初始化方向为向右
if((snkh+1)%geshu==0&&fxg==39){
sile();
}
else if(snkh>=400-geshu&&fxg==40){
sile();
}
else if(snkh%geshu==0&&fxg==37){
sile();
}
else if(snkh<geshu&&fxg==38){
sile();
}
我们在识别完墙壁后,我们还需要识别自己,让蛇撞上自己之后,也会死亡。
for(var i =0,l=snkbody.length;i<l-1;i++){
if(snkbody[i].pos==snkh){
sile();
}
}
cd();
这样我们的贪吃蛇游戏已经完成了大半
下面就是我们将制作点击按钮和暂停按钮
btn1.onclick=function(){
sudu = level.value
// 设置速度
clearInterval(ddd)
// 首先清除定时器,防止多次点击定时器冲突
ddd=setInterval(function(){
fzhs ();
},sudu)
// 将以上蛇开始运动的代码放入一个名为fzhs的代码中循环
bgaudio.play();
// 播放背景音乐
}
// 点击开始
btn2.onclick=function(){
clearInterval(ddd);
// 清除定时器
bgaudio.pause();
// 声音暂停
}
在蛇死亡后,还需要死亡音效,弹出框,页面刷新
function sile(){
var l = snkbody.length-5;
// 计算蛇吃了几个食物
var score = localStorage.getItem("score")
if(l>score){
localStorage.setItem("score",l)
}
// 如果当前分数大于历史最高分数,我们要将历史最高分数设置为当前分数
si.play();
// 播放死亡音乐
alert("GameOver");
// 弹出GameOver
location.reload();
页面刷新
return false;
}
我们还需要设置历史最高分数
var score = localStorage.getItem("score")||0;
ls.innerHTML = score;
这样一个贪吃蛇小游戏就做完了,你还可以对样式和js进行改进,并告诉我,让我们共同进步!!!
最后,我的github游戏奉上,希望你喜欢。
https://Smallmotor.github.io/...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。