溫習數據演算法—貪吃蛇
- 2021 年 1 月 23 日
- 筆記
前言
很多朋友學習了電腦語言後都做過貪吃蛇的遊戲(VB,C,C++,C#,JAVA,JQuery等),現在估計很多人都忘記怎麼寫了。
我們現在用jquery+css來實現一個貪吃蛇的遊戲效果。
這裡主要溫習一下數據演算法、遊戲中面向對象和由局部到整體的思想。
源碼下載地址+演示地址
百度網盤源碼下載地址: //pan.baidu.com/s/1FGKVQfxgTJaPilKSRH0kDQ 提取碼: sybv
效果圖GIf
設計思路
第一步,構思編寫出靜態頁面。
第二步,讓貪吃蛇動起來。
第三步,通過鍵盤上下左右鍵去控制運動方向,空格鍵暫停。
第四步,判斷貪吃蛇有沒有撞牆,有沒有吃到自己,有的話結束遊戲,生成排名。
第五步,給貪吃蛇隨機生成一個”食物”。
第六步,實現每當貪吃蛇吃了一個”食物”後身體就會變長,移動速度變快。
兩個對象
貪吃蛇有兩個對象,蛇的對象和食物的對象。
食物對象有一個屬性:食物的坐標點,
蛇對象有一個屬性:一個數組(用來存放蛇身體所有的坐標點)。
如何移動
全局需要有一個定時器來周期性的移動蛇的身體。
由於蛇的身體彎彎曲曲有各種不同的形狀,因此我們只處理蛇的頭部和尾部,
每次移動都根據移動的方向的不同來添加新的頭部,再把尾部擦去,看起來就像蛇在向前爬行一樣。
方向控制
由於蛇有移動的方向,因此我們也需要在全局定義一個方向對象,對象中有上下左右所代表的值。
同時,在蛇對象的屬性中我們也需要定義一個方向屬性,用來表示當前蛇所移動的方向。
碰撞檢測
在蛇向前爬行的過程中,會遇到三種不同的情況,需要進行不同的判斷檢測。
第一種情況是吃到了食物,這時候就需要向蛇的數組中添加食物的坐標點;
第二種情況是碰到了自己的身體,
第三種是碰到了邊界,這兩種情況都導致遊戲結束;
如果不是上面的三種情況,蛇就可以正常的移動。
實現過程
搭建遊戲畫面:首先整個遊戲需要一個搭建活動的場景,我們通過Div+css布局來作為整個遊戲的背景。
方向和定位:遊戲背景搭建完後,怎麼來定義我們「蛇」的位置和移動的方向?首先定義一個全局的方向變數,對應的數值就是我們的上下左右方向鍵所代表的keyCode。
我們遊戲幕布的時候通過兩次遍歷畫出了一個坐標系,有X軸和Y軸。
如果每次都用{x:x,y:y}來表示會很麻煩,也顯得很low,我們可以定義一個坐標點對象。
食物對象:既然定義好了坐標點對象,那麼可以先來看一下簡單的對象,就是我們的食物對象,它有一個重要的屬性就是它的坐標點。
既然食物有了坐標點這個屬性,那麼我們什麼時候給他賦值呢?我們知道食物是隨機產生的,因此我們定義了一個Create函數用來產生Food的坐標點。
但是產生的坐標點又不能在蛇的身體上,所以通過一個while循環來產生坐標點,如果坐標點正確了,就終止循環。
//食物 function foodRandom(){ var t = 40; var x = 54; var y = 0; var repeat = false; var top = parseInt(Math.random() * (t - y) + y); var left = parseInt(Math.random() * (x - y) + y); //判斷食物與蛇身坐標是否重合 $('.snake_wrap li').each(function() { if($(this).position().left == left && $(this).position().top == top){ foodRandom(); }else{ repeat = true; } }); //如果食物沒在蛇身上,定位食物 if(repeat){ $('.food').css({'top':top*15 + 1 + 'px','left':left*15 + 1 + 'px'}); } }
蛇對象:首先定義一下蛇基本的屬性,最重要的肯定是蛇的屬性,每次移動時,都需要對這個數組進行一些操作。
其次是蛇的方向,我們給它一個默認方向。然後是食物,在蛇的構造函數中我們傳入食物對象,在後續移動時需要判斷是否吃到食物。
//移動 function run(){ //計時器,每speed時刷新一次 myVar.itimes = setInterval(function(){ //獲取當前食物位置 var food_top = $('.food').position().top; var food_left = $('.food').position().left; //設置新增蛇頭坐標 var header_top = $('.snake_wrap li').eq(0).position().top + myVar.del_y; var header_left = $('.snake_wrap li').eq(0).position().left + myVar.del_x; //當前蛇頭顏色重置 $('.snake_wrap li').eq(0).css({'background': '#779006'}); //新增蛇頭,並賦予樣式 $('.snake_wrap').prepend('<li></li>'); $('.snake_wrap li').eq(0).css({'left':header_left + 'px','top':header_top + 'px','background':'#fff'}) //移除最後一節蛇尾 $('.snake_wrap li:last').remove(); //判斷蛇是否吃到食物 if((header_left == (food_left - 1)) && (header_top == (food_top - 1))){ var last_top = $('.snake_wrap li:last').position().top; var last_left = $('.snake_wrap li:last').position().left; $('.snake_wrap').append('<li></li>'); $('.snake_wrap li:last').eq(0).css({'left':last_left + 'px','top':last_top + 'px'}) //刷新食物 foodRandom(); //蛇身長度 myVar.myscore++; scoreFn(myVar.myscore); //每加長5,速度提升10 if(!(myVar.myscore%5) && myVar.speed > 10){ clearInterval(myVar.itimes); myVar.speed -= 10; run(); } } //邊界判斷 borderDetection(header_top,header_left); //自撞判斷 selfDetection(header_top,header_left); },myVar.speed) }
建議大家下載源碼進行對比查看比較好理解,下面展示的是需要處理的方法;
總結
這裡主要溫習一下數據演算法、遊戲中面向對象和由局部到整體的思想。
邏輯有很多種,不必拘泥於一種,大家可以換一種不同的方法進行實現。
![]() 歡迎關注訂閱我的微信公眾平台【熊澤有話說】,更多好玩易學知識等你來取
作者:熊澤-學習中的苦與樂 公眾號:熊澤有話說 出處: //www.cnblogs.com/xiongze520/p/14308996.html 創作不易,轉載或者部分轉載、摘錄,請在文章明顯位置註明作者和原文鏈接。
|