<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <style> *{ margin: 0; padding: 0; } #container{ width: 1000px; height: 550px; border: 1px solid #000; margin: 100px auto; } #ground{ width: 1000px; height: 500px; position: relative; } #button{ float: right; height: 50px; line-height: 50px; } button{ width: 50px; height: 20px; cursor: pointer; } .block{ width: 20px; height: 20px; background: #2abad9; float: left; } .snakeBody{ width: 20px; height: 20px; position: absolute; background: #f57926; } .food{ width: 20px; height: 20px; background: green; position: absolute; } </style> </head> <body> <div id="container"> <div id="ground"></div> <div id="gameControl"> <div id="button"> <button id="start">開始</button> <button id="pause">暫停</button> </div> </div> </div> </body> <script> var timer; window.onload=function(){ createGrass(); createSnake(); createFood(); document.getElementById('start').onclick=function(){ clearInterval(timer); //防止多次點擊開始 timer=setInterval(function(){ snakeMove(diRection); },150); snakeMove(diRection); }; document.getElementById('pause').onclick=function(){ clearInterval(timer); }; }; //創建草坪 function createGrass(){ var oGround=document.getElementById('ground'); var oDiv; for(var i=0;i<50;i++){ for(var j=0;j<25;j++){ oDiv=document.createElement('div'); oDiv.className='block'; oGround.appendChild(oDiv); } } } //創建蛇 var snakeBody=[],oFood,diRection='left'; function createSnake(){ var oGround=document.getElementById('ground'); var oDiv; for(var i=0;i<3;i++){ oDiv=document.createElement('div'); oDiv.className='snakeBody'; oDiv.style.left=(i+40)*20+'px'; oDiv.style.top='60px'; oGround.appendChild(oDiv); snakeBody.push(oDiv); } } //創建食物 function createFood(){ var flag=true; //該標識用于判斷生成的div是否和蛇身div重合 var oGround=document.getElementById('ground'); // var oDiv; var len=snakeBody.length; var iLeft,iTop; oFood=document.createElement('div'); oFood.className='food'; iLeft=parseInt(Math.random()*49)*20; iTop=parseInt(Math.random()*24)*20; for(var i=0;i<len;i++){ if(snakeBody[i].offsetLeft==iLeft && snakeBody[i].offsetTop==iTop){ //可console.log(snakeBody[i]),其中是按照offsetLeft和offsetTop來確定方塊位置的 flag=false; break; } } if(flag==true){ oFood.style.left=iLeft+'px'; oFood.style.top=iTop+'px'; oGround.appendChild(oFood); }else{ createFood(); //若生成的div有重合則再次調用自身 } } //蛇運動 function snakeMove(direction){ //direction用于作為蛇移動的四個方向的判斷 var snakeHead=snakeBody[0]; //獲取蛇頭 diRection=direction; //用于防止比如蛇身本來往左邊走,但是向右按鈕仍然有效的情況 for(var i=snakeBody.length-1;i>0;i--){ //移動說白了就是后面的div使用它前一個div的位置 snakeBody[i].style.left=snakeBody[i-1].offsetLeft+'px'; snakeBody[i].style.top=snakeBody[i-1].offsetTop+'px'; } switch (direction){ //蛇頭的位置 case 'left':snakeHead.style.left=snakeHead.offsetLeft-20+'px';break; case 'right':snakeHead.style.left=snakeHead.offsetLeft+20+'px';break; case 'up':snakeHead.style.top=snakeHead.offsetTop-20+'px';break; case 'down':snakeHead.style.top=snakeHead.offsetTop+20+'px';break; } //蛇頭碰壁 if(snakeHead.offsetLeft==-20 || snakeHead.offsetLeft==1000 || snakeHead.offsetTop==-20 || snakeHead.offsetTop==500){ clearInterval(timer); if(confirm('再來一次?')){ window.location.reload(); } } //蛇碰到自身 for(var j=1;j<snakeBody.length;j++){ if(snakeHead.offsetLeft==snakeBody[j].offsetLeft && snakeHead.offsetTop==snakeBody[j].offsetTop){ clearInterval(timer); if(confirm('再來一次')){ window.location.reload(); } } } //吃掉食物 if(snakeHead.offsetLeft==oFood.offsetLeft && snakeHead.offsetTop==oFood.offsetTop){ oFood.className='snakeBody snake-block'; //食物變成和蛇身一樣的顏色 console.log(snakeBody[snakeBody.length-1].offsetTop); switch (direction){ //把oFood的坐標采用最后一個div的坐標 case 'left':oFood.style.left=snakeBody[snakeBody.length-1].offsetLeft+'px';break; case 'right':oFood.style.left=snakeBody[snakeBody.length-1].offsetLeft+'px';break; case 'up':oFood.style.top=snakeBody[snakeBody.length-1].offsetTop+'px';break; case 'down':oFood.style.top=snakeBody[snakeBody.length-1].offsetTop+'px';break; } snakeBody.push(oFood); //這里最好用push把吃掉的div添加到蛇尾,添加到頭部有一個問題,吐過實物div是靠邊生成,那么吃掉后會超出墻范圍或者直接撞墻 createFood(); } } //上下左右操作 document.onkeydown=function(e){ //document不要換成window,出滾動條的話,window會導致窗口移動 var event=e || window.event; var direction=event.keyCode; switch (direction){ case 37: if(diRection !='right'){ snakeMove('left'); } break; //左 case 39: if(diRection !='left'){ snakeMove('right'); } break; //右 case 38: if(diRection !='down'){ snakeMove('up'); } break; //上 case 40:if(diRection !='up'){ snakeMove('down'); } break; //下 } } </script> </html>
又在別的地方嫖到了這個效果研究了億下下,制作過程如下(超詳細):
<canvas id="canvas"></canvas>
#canvas{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
box-shadow: 0 0 10px rgb(150, 150, 150);
}
position: absolute; 絕對定位。
top: 50%;
left: 50%;
transform: translate(-50%,-50%); 居中。
box-shadow: 0 0 10px rgb(150, 150, 150); 陰影。
var canvas=document.querySelector("#canvas");
var ctx=canvas.getContext('2d');
//畫布寬
var wide=600;
//畫布高
var high=600;
// 變量,判斷一次渲染中只識別按鍵一次
var kd=0;
//當前分數
var fraction=0;
//速度,就是執行定時器的時間參數
var speed=250;
// 蛇的初始顏色 紅色
var yanse=`red`;
// 蛇數組,組成蛇的每一個方塊
var snake=[];
// 食物數組
var food={};
// 蛇的移動方向,x軸:1為向右,-1為向左;y軸:1為向下,-1為向上 。不能斜著走,所以0為某軸無方向。
var diretion={
x:-1,
y:0
}
// 給畫布寬高賦值 打算畫一個長寬都是30個20px的方塊畫布
canvas.width=wide;
canvas.height=high;
function chushi(){
//蛇初始長度為3個方塊,位置如下(這個隨意)
for(let i=0;i<3;i++){
snake.push({
x: i+10,
y: 10
})
}
// 給食物一個隨機位置和隨機顏色
food={
x: parseInt(Math.random()*30),
y: parseInt(Math.random()*30),
color:`rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255})`
}
}
// 繪制圖形
function draw(){
// 繪制顯示當前分數的文字
ctx.fillStyle='rgba(255,255,255,0.5)';
ctx.font="50px 仿宋";
ctx.textAlign='center';
ctx.fillText("你的分數為:"+fraction+" 分",300,300);
// 繪制方格,長寬都是30個,都是19px*19px的方格
for(let i=0;i<30;i++){
for(let j=0;j<30;j++){
ctx.fillStyle='rgba(255, 255, 255,.3)';
ctx.fillRect(i*20,j*20,19,19);
}
}
// 繪制蛇
for(let i=0;i<snake.length;i++){
temp=snake[i];
ctx.fillStyle=yanse;
ctx.fillRect(temp.x*20,temp.y*20,19,19);
// 判斷蛇頭(第一個方塊)是否與身體某個方塊重合 ,就是頭撞到身體
if(temp.x==snake[0].x&&temp.y==snake[0].y&&i!=0){
// 游戲結束,重新給初始化
alert('游戲結束~點擊確認再來一次~');
fraction=0;
snake.length=0;
chushi();
}
}
// 繪制食物,繪制一個圓形
ctx.beginPath();
ctx.fillStyle=food.color;
ctx.arc(food.x*20+9.5,food.y*20+9.5,7,0,Math.PI*2,false);
ctx.stroke();
ctx.fill();
ctx.closePath();
// 給蛇頭繪制一個字符,☆ ,好區分頭尾 ,也可省略
ctx.fillStyle='yellow';
ctx.font="15px 仿宋";
ctx.textAlign="start";
ctx.fillText("☆",snake[0].x*20+2,snake[0].y*20+14.5);
}
//更新
function update(){
// 建一個對象head,這個為蛇的新頭,通過繪制新頭,去掉尾部實現移動效果
var head={};
//判斷蛇頭是否遇到邊界,到邊界則在另一邊重新繪制 x軸
switch (snake[0].x+diretion.x){
case -1: head.x=29;break;
case 30: head.x=0;break;
// 沒到邊界則為當前位置加方向
default: head.x=snake[0].x+diretion.x;
}
//判斷蛇頭是否遇到邊界,到邊界則在另一邊重新繪制 y軸
switch (snake[0].y+diretion.y){
case -1: head.y=29;break;
case 30: head.y=0;break;
// 沒到邊界則為當前位置加方向
default: head.y=snake[0].y+diretion.y;
}
// 判斷新蛇頭是否與食物重合,就是吃到食物
if(head.x==food.x&&head.y==food.y){
//蛇的顏色為吃到食物的顏色
yanse=food.color;
// 重新給食物初始化
food={
x: parseInt(Math.random()*30),
y: parseInt(Math.random()*30),
color:`rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255})`
}
//在蛇尾添加一節
let temp=snake[length-1];
snake.push(temp);
fraction+=1;
// 吃完食物速度加快
if(speed>80){
//定時器間隔減10
speed=speed-10;
// 清除原來定時器,重新繪制
clearInterval(time);
time=setInterval(function () {
kd=0;
ctx.clearRect(0, 0, wide, high);
update();
draw();
}, speed);
}
}
//添加新頭
snake.splice(0,0,head);
//去掉尾部
snake.pop();
}
//判斷點擊事件
document.addEventListener('keydown', event=>{
switch (event.keyCode){
// 按了向上鍵
case 38:
// 判斷當前不是向下移動與還沒按過鍵,否則蛇會重疊
if(diretion.y!=1&&kd==0){
// 重新給移動方向賦值
diretion.x=0;
diretion.y=-1;
kd=1;
}
break;
// 下面以此類推一樣的原理
case 39:
if(diretion.x!=-1&&kd==0){
diretion.x=1;
diretion.y=0;
kd=1;
}
break;
case 40:
if(diretion.y!=-1&&kd==0){
diretion.x=0;
diretion.y=1;
kd=1;
}
break;
case 37:
if(diretion.x!=1&&kd==0){
diretion.x=-1;
diretion.y=0;
kd=1;
}
break;
}
})
chushi();
var time=setInterval(function(){
kd=0;
ctx.clearRect(0,0,wide,high);
update();
draw();
},speed);
avaScript寫一個貪吃蛇的游戲(附源碼)
javascript群內每日課題-今日課題:JavaScript寫一個貪吃蛇的游戲
PS:最近群內很多伙伴想要做游戲學學,練練自己的JavaScript,所以今天做了小游戲,很多人都擔心自己寫的代碼爛,而不敢去寫代碼,總想著等自己等寫出好的代碼再來做游戲,再來練習,其實我的意見是前端新人要多些爛代碼,不管你在學習中還是工作中,你不寫夠足量的爛代碼,是無法進化到寫好代碼的程度,所以練習吧騷年
如果想要更多的企業求職加分項目,案例,游戲源碼,可以來一下我的前端群216634437,每天都會精挑細選一個特效,項目游戲出來詳細講解,分享!
1.body部分
2.style樣式部分
3, JavaScript部分
想要練習這個游戲的進群領取源碼:216634437(代碼已經上傳到群文件,自助下載練習)
頭條號里有許多web前端學習視頻,企業常用特效/案例/項目,敬請關注!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。