日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

我也来写一个贪吃蛇

發布時間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 我也来写一个贪吃蛇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  最近工作量好大,好忙,趁周末練練手,花了近3小時寫了一個貪吃蛇。(后續會把自己的一些想法繼續更新,目前是1.3版本~更新過4次,文末有更新說明)。

  這是實踐操作的地址:http://iforj.com:8000/tool/snake/

  

  實現貪吃蛇的功能很簡單。

  我就分享一下我實現貪吃蛇看起來在界面上移動并且吃食物長大的原理。

  我建了一個數組list_arr[]來保存貪吃蛇所在的每個格子的id,并建了2個全局變量x和y,監聽貪吃蛇頭的位置,當然x和y也是貪吃蛇的起始位置。

  那么貪吃蛇移動實際上就是每次從list_arr[]里取出第一個元素(list_arr.shift()方法),取出的第一個元素也可以認為是貪吃蛇的尾巴,然后把這個元素(也就是格子的id)代表的格子的css中的貪吃蛇的樣式去掉。然后,把[x, y]這組坐標所代表的格子的id扔進list_arr[]里(list_arr.push()),并給這個格子添加上貪吃蛇的樣式。所以實際上每次就操作了2個格子的樣式。

  如果貪吃蛇吃食物([x, y]與食物所在坐標相同),那么把食物那個格子的css去掉代表食物的樣式并加上貪吃蛇的樣式,并且不去掉尾巴,也就是不去掉list_arr[]里的第一個元素所在格子的樣式。

?

<!doctype html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>body {position: relative;margin: 0;width: 100vw;height: 100vh;}.wrapper {padding: 40px 0;}.snake-box {margin: 0 auto;border-collapse: collapse; border:solid #ddd; border-width:1px 0px 0px 1px;}.snake-box td {padding: 10px;border: solid #ddd; border-width: 0px 1px 1px 0px; }.snake-body {background-color: #8078f3;}.snake-initial-right, .snake-right {position: relative;border-top-right-radius: 12px;border-bottom-right-radius: 12px;background-color: #8078f3; }.snake-right {/*-webkit-animation: moveright .2s linear;-moz-animation: moveright .2s linear;*/animation: moveright .2s linear;}@keyframes moveright {0% {transform: translate(-10px, 0);}100% {transform: translate(0, 0);}}.snake-initial-right:before,.snake-right:before {content: '';position: absolute;top: 4px;right: 6px;width: 3px;height: 3px;-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;background-color: #000;}.snake-initial-right:after,.snake-right:after {content: '';position: absolute;bottom: 4px;right: 6px;width: 3px;height: 3px;-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;background-color: #000;}.snake-left {position: relative;border-top-left-radius: 12px;border-bottom-left-radius: 12px;background-color: #8078f3;animation: moveleft .2s linear;}@keyframes moveleft {0% {transform: translate(10px, 0);}100% {transform: translate(0, 0);}}.snake-left:before {content: '';position: absolute;top: 4px;left: 6px;width: 3px;height: 3px;-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;background-color: #000;}.snake-left:after {content: '';position: absolute;bottom: 4px;left: 6px;width: 3px;height: 3px;-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;background-color: #000;}.snake-top {position: relative;border-top-left-radius: 12px;border-top-right-radius: 12px;background-color: #8078f3;animation: movetop .2s linear;}@keyframes movetop {0% {transform: translate(0, 10px);}100% {transform: translate(0, 0);}}.snake-top:before {content: '';position: absolute;top: 6px;left: 4px;width: 3px;height: 3px;-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;background-color: #000;}.snake-top:after {content: '';position: absolute;top: 6px;right: 4px;width: 3px;height: 3px;-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;background-color: #000;}.snake-bottom {position: relative;border-bottom-left-radius: 12px;border-bottom-right-radius: 12px;background-color: #8078f3;animation: movebottom .2s linear;}@keyframes movebottom {0% {transform: translate(0, -10px);}100% {transform: translate(0, 0);}}.snake-bottom:before {content: '';position: absolute;bottom: 6px;left: 4px;width: 3px;height: 3px;-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;background-color: #000;}.snake-bottom:after {content: '';position: absolute;bottom: 6px;right: 4px;width: 3px;height: 3px;-webkit-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;background-color: #000;}.food {position: relative;background-color: #008000;}.food:after {content: 'f';position: absolute;top: 0;left: 0;width: 100%;height: 100%;text-align: center;line-height: 20px;color: #fff;font-weight: 700;}.food-fast {background-color: #e81616;}.food-convert {background-color: #00f;}.btn-box {text-align: center;margin-bottom: 30px;}
</style>
</head>
<body>
<div class="wrapper"><div class="btn-box"><p>可以用空格鍵控制開始、暫停、繼續</p><button id="btn_control">開始</button></div><table id="snake_box" class="snake-box"></table>
</div>
<script>
//Array擴展indexOf
Array.prototype.indexOf = function(val) {for (var i = 0; i < this.length; i++) {if (this[i] == val) return i;}return -1;
};(function() {function option() {var option = {};option.width = 20;  //x軸數量option.height = 20;  //y軸數量option.speed = 600;  //setInterval的執行周期option.fastSpeed = 150;  //加速周期option.fastStep = 20;  //加速步長return option;}var o = new option();var snakeBox = document.getElementById('snake_box');snakeBox.innerHTML = null;var fragment = document.createDocumentFragment();var snakeBoxArray = new Array();for (var i = 0; i < o.height; i++) {var sTr = document.createElement('tr');sTr.setAttribute('class', 'row');var cellFragment = document.createDocumentFragment();snakeBoxArray[i]=  new Array(); for (var j = 0; j < o.width; j++) {var sTd = document.createElement('td');var sId = j + '_' + i;sTd.setAttribute('id', sId);sTd.setAttribute('class', 'cell');cellFragment.appendChild(sTd);snakeBoxArray[i][j] = j + '_' + i;}fragment.appendChild(sTr).appendChild(cellFragment);}snakeBox.appendChild(fragment);var x = Math.floor(o.width / 2),y = Math.floor(o.height / 2),list_arr = [],  //記錄蛇的cellfast_arr = [],  //記錄蛇加速的格子數dir_arr = [];  //記錄蛇身的方向document.getElementById(snakeBoxArray[x][y]).classList.add('snake-initial-right');list_arr.push(x + '_' + y);/*實現鍵盤方向事件,在非同軸方向移動時,會提前移動一格,以解決快速按下非同軸方向鍵時,setInterval延遲觸發問題,能實現空格事件控制按鈕*/var lastDir = 39; //記錄上一次方向document.onkeydown = control;function control(e) {var dir,btn = document.getElementById('btn_control');if (e.keyCode == 32) {if (btn.innerHTML == '開始') {moveEvent = setInterval(move.bind(this, 39), o.speed);btn.innerHTML = '暫停';} else if (btn.innerHTML == '暫停') {btn.innerHTML = '繼續';clearInterval(moveEvent);} else if (btn.innerHTML == '繼續') {btn.innerHTML = '暫停';moveEvent = setInterval(move.bind(this, lastDir), o.speed);  //移動}return false;  //一定要false,否則會觸發btn的click監聽事件}if (btn.innerHTML == '開始' || btn.innerHTML == '繼續') {return true;  //設置為false,會關閉所有鍵盤觸發事件}switch(e.keyCode) {case 37:  //左 if (lastDir == 37 || (list_arr.length > 1 && lastDir == 39)) {return true;} else {document.getElementById(snakeBoxArray[y][x]).setAttribute('class', 'cell snake-body');x--;snakeHeadStyle = 'snake-left';lastDir = dir = 37;					}break;case 38:  //上if (lastDir == 38 || (list_arr.length > 1 && lastDir == 40)) {return true;} else {document.getElementById(snakeBoxArray[y][x]).setAttribute('class', 'cell snake-body');y--;snakeHeadStyle = 'snake-top';lastDir = dir = 38;}break;case 39:  //右 	if (lastDir == 39 || (list_arr.length > 1 && lastDir == 37)) {return true;} else {document.getElementById(snakeBoxArray[y][x]).setAttribute('class', 'cell snake-body');x++;snakeHeadStyle = 'snake-right';lastDir = dir = 39;}break;case 40:  //下 if (lastDir == 40 || (list_arr.length > 1 && lastDir == 38)) {return true;} else {document.getElementById(snakeBoxArray[y][x]).setAttribute('class', 'cell snake-body');y++;snakeHeadStyle = 'snake-bottom';lastDir = dir = 40;}break;				}death();list_arr.push(x + '_' + y);fast_arr.push('');dir_arr.push(dir)if (document.getElementById(snakeBoxArray[y][x]).classList.contains('food')) {if (document.getElementById(snakeBoxArray[y][x]).classList.contains('food-fast')) {o.speed = option().fastSpeed;fast_arr.length = 0;  //重置加速步長}document.getElementById(snakeBoxArray[y][x]).setAttribute('class', 'cell');document.getElementById(snakeBoxArray[y][x]).classList.add(snakeHeadStyle);food();	} else {if (fast_arr.length >= o.fastStep) {o.speed = option().speed;}var tail = list_arr.shift();dir_arr.shift();document.getElementById(tail).setAttribute('class', 'cell')document.getElementById(snakeBoxArray[y][x]).classList.add(snakeHeadStyle);}clearInterval(moveEvent);moveEvent = setInterval(move.bind(this, dir), o.speed);  //移動}/*移動函數*/var moveEvent;function move(direction) {document.getElementById(snakeBoxArray[y][x]).setAttribute('class', 'cell snake-body');switch(direction) {case 37:  //左x--;snakeHeadStyle = 'snake-left';convertHeadStyle = 'snake-right';break;case 38:  //上y--;snakeHeadStyle = 'snake-top';convertHeadStyle = 'snake-bottom';break;case 39:  //右x++;snakeHeadStyle = 'snake-right';convertHeadStyle = 'snake-left';break;case 40:  //下 y++;snakeHeadStyle = 'snake-bottom';convertHeadStyle = 'snake-top';break;}death();list_arr.push(x + '_' + y);dir_arr.push(direction)fast_arr.push('');if (document.getElementById(snakeBoxArray[y][x]).classList.contains('food')) {	if (document.getElementById(snakeBoxArray[y][x]).classList.contains('food-fast')) {o.speed = option().fastSpeed;fast_arr.length = 0;  //重置加速步長clearInterval(moveEvent);moveEvent = setInterval(move.bind(this, direction), o.speed);  //移動}document.getElementById(snakeBoxArray[y][x]).setAttribute('class', 'cell');document.getElementById(snakeBoxArray[y][x]).classList.add(snakeHeadStyle);food();} else {if(fast_arr.length >= o.fastStep) {o.speed = option().speed;clearInterval(moveEvent);moveEvent = setInterval(move.bind(this, direction), o.speed);  //移動	}var tail = list_arr.shift();dir_arr.shift();document.getElementById(tail).setAttribute('class', 'cell')document.getElementById(snakeBoxArray[y][x]).classList.add(snakeHeadStyle);}	}/*死亡判定*/function death() {var flag = list_arr.indexOf(x + '_' + y)if (x < 0 || x >= o.width || y < 0 || y >= o.height || flag != -1) {location.reload();}}/*食物*/var foodCell; //食物位置function food() {var foodX = Math.ceil(Math.random() * o.width) - 1,foodY = Math.ceil(Math.random() * o.height) - 1;foodCell = foodX + '_' + foodY;if (list_arr.indexOf(foodCell) == -1) {n = Math.round(Math.random() * 100);document.getElementById(foodCell).classList.add('food');if (n >=0 && n < 60) {return true;  //普通食物} else if (n >=60 && n < 85) {document.getElementById(foodCell).classList.add('food-fast');} else if (n >= 85 && n <= 100) {document.getElementById(foodCell).classList.add('food-convert');}// document.getElementById(foodCell).classList.add('food-fast');} else {return food();}}food();/*按鈕控制*/document.getElementById('btn_control').addEventListener('click', function(e) {if (e.target.innerHTML == '開始') {moveEvent = setInterval(move.bind(this, 39), o.speed);e.target.innerHTML = '暫停';} else if (e.target.innerHTML == '暫停') {e.target.innerHTML = '繼續';clearInterval(moveEvent);} else if (e.target.innerHTML == '繼續') {e.target.innerHTML = '暫停';moveEvent = setInterval(move.bind(this, lastDir), o.speed);  //移動}})
})();	</script>
</body>
</html>

  

  

  

  

?

更新說明:

  1.0版本:實現最基本的功能,貪吃蛇移動,吃食物和死亡判定;

  1.1版本:加入了控制按鈕,支持空格控制按鈕;解決快速按下非同軸方向鍵時,setInterval延遲觸發問題;在貪吃蛇長度為1時,可以往4個方向移動,當大于2時,不能往移動方向反方向移動;

  1.2版本:美化UI(小蛇有蛇頭和眼睛了,有興趣的可以加個蛇尾,原理和蛇頭類似);食物加入了顏色和對應效果(目前只有紅色的加速效果有效,加速周期和加速步長都在option里配置);o現在是繼承option;

  其實還寫了一個藍色食物的換向效果:

if (document.getElementById(snakeBoxArray[y][x]).classList.contains('food-convert')) {document.getElementById(snakeBoxArray[y][x]).setAttribute('class', 'cell snake-body');list_arr.reverse();dir_arr.reverse();document.getElementById(list_arr[list_arr.length - 1]).setAttribute('class', 'cell');document.getElementById(list_arr[list_arr.length - 1]).classList.add(convertHeadStyle);x = list_arr[list_arr.length - 1].split('_')[0];y = list_arr[list_arr.length - 1].split('_')[1];clearInterval(moveEvent);var newDir;if (dir_arr[dir_arr.length - 1] == 37) {lastDir = newDir = 39;} else if (dir_arr[dir_arr.length - 1] == 38) {lastDir = newDir = 40;} else if (dir_arr[dir_arr.length - 1] == 39) {lastDir = newDir = 37;} else if (dir_arr[dir_arr.length - 1] == 40) {lastDir = newDir = 38;} moveEvent = setInterval(move.bind(this, newDir, o.speed));  //移動	
}

  建了一個數組dir_arr來監聽蛇身體每個格子的方向(就是蛇頭每次進入一個新格子的方向),然后轉向也就是把監聽小蛇身體位置的list_arr和監聽方向的dir_arr均顛倒(reverse()),然后重置蛇頭坐標(x,y),list_arr和dir_arr里的最后一個元素就是轉向后的小蛇新的頭部位置和方向,最后重置setInterval就可以了。原理就是如上。該特殊食物由于效果觸發后,轉向是往之前蛇頭第一次進入當前的蛇尾所在的格子的方向的反方向進行的,所以在小蛇較長或者貼邊緣移動時,很容易觸發死亡判定,所以最后把這個特殊事務移除了。

  1.3版本:美化UI,新增了蛇頭進入新格子的動畫(如果蛇身也要,原理一樣;animation沒有對瀏覽器作適配,需要的自己適配);

  

  2016年11月23日發現一個bug:

    在小蛇長度為4時,繞一個2*2的正方形格子轉圈為直接觸發死亡條件,發現是代碼334行先觸發死亡判定,而后在350行才將尾巴從小蛇身體內去掉,最簡單的改法應該就是下面這樣了:

    

?

轉載于:https://www.cnblogs.com/youyouluo/p/6057132.html

總結

以上是生活随笔為你收集整理的我也来写一个贪吃蛇的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产高清小视频 | wwwav在线| 黄网站在线观看视频 | 天天躁日日躁狠狠躁av | 国产小视频自拍 | 亚洲图片激情小说 | 中文字幕大全 | 久久久噜噜噜久久 | 亚洲天天操 | 国产ts人妖系列高潮 | 91亚洲精华国产精华精华液 | 丰满少妇在线观看bd | 亚洲婷婷在线 | 亚洲乱码视频在线观看 | 日本三级大全 | 97人妻天天摸天天爽天天 | 三级视频黄色 | 国产激情一区二区三区 | 日韩视频一区二区 | 亚洲精品中文字幕在线观看 | 李丽珍毛片| 久草婷婷| 人妻丰满熟妇av无码区免 | 成人午夜视频在线 | 免费久久精品视频 | 国产成人精品自拍 | 最新av | 国产十八熟妇av成人一区 | 国产一区二区三区四区五区在线 | 日批免费网站 | 麻豆视频网 | 91国模| 手机在线视频一区 | 精品国产av一区二区三区 | 国产一区二区久久久 | 男男毛片 | 九九视频免费 | 91av视频在线免费观看 | 国产情侣酒店自拍 | av福利在线 | 国产精品2 | 日韩乱码一区二区 | 亚洲精品在线视频观看 | 五月六月婷婷 | 欧美a在线观看 | 日韩亚洲一区二区 | 亚洲aaaaaa| 免费看成人aa片无码视频羞羞网 | 亚洲中文字幕一区二区在线观看 | 贝利弗山的秘密在线观看 | 337p亚洲精品色噜噜狠狠 | 不卡视频在线 | 青青草成人免费视频 | 91在线中文字幕 | 国产精品久久久久久久久岛 | 青青草视频播放 | 三级免费黄 | 久草视频在线免费播放 | 久久久久久亚洲中文字幕无码 | 久久久久无码国产精品不卡 | 亚洲人成色777777精品音频 | 麻豆精品影院 | 又欲又污又肉又黄短文 | 国产午夜精品理论片 | 水密桃av| 日韩狠狠操 | 国产黄色免费网站 | 国产真人做爰毛片视频直播 | 黄色网页大全 | 自拍偷拍欧美亚洲 | 久久影音先锋 | 免费成人深夜夜行网站视频 | 久久久男女 | 亚洲国产视频一区 | 99热在线国产 | 国产一二三在线观看 | 韩国美女啪啪 | av资源在线免费观看 | 黄色的视频网站 | 日本精品一二区 | 亚洲无码久久久久 | 欧美精品亚洲精品 | 中文字幕在线免费播放 | 久久精品免费一区二区 | 黄视频在线播放 | 午夜av在线播放 | 国产精品传媒麻豆hd | 久热精品在线视频 | 波多野结衣免费在线视频 | 在线你懂的 | 神马久久av | www.日韩高清 | 久久久久久久久久一级 | 男女激情大尺度做爰视频 | 催眠调教后宫乱淫校园 | 色丁香av | 欧美人与性动交a欧美精品 日韩免费高清视频 | 97国产在线播放 | 蜜臀av性久久久久蜜臀aⅴ四虎 |