溫習資料演算法—貪吃蛇

學習中的苦與樂發表於2021-01-23

前言

很多朋友學習了計算機語言後都做過貪吃蛇的遊戲(VB,C,C++,C#,JAVA,JQuery等),現在估計很多人都忘記怎麼寫了。

我們現在用jquery+css來實現一個貪吃蛇的遊戲效果。

這裡主要溫習一下資料演算法、遊戲中物件導向和由區域性到整體的思想。

 


 

原始碼下載地址+演示地址

百度網盤原始碼下載地址: https://pan.baidu.com/s/1FGKVQfxgTJaPilKSRH0kDQ    提取碼: sybv

 

線上演示地址:http://www.xiongze.net/snake/index.html

 

 


 

效果圖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)
        }

 

建議大家下載原始碼進行對比檢視比較好理解,下面展示的是需要處理的方法;

 

 

 

 

總結

這裡主要溫習一下資料演算法、遊戲中物件導向和由區域性到整體的思想。

邏輯有很多種,不必拘泥於一種,大家可以換一種不同的方法進行實現。

 

 

 

歡迎關注訂閱我的微信公眾平臺【熊澤有話說】,更多好玩易學知識等你來取
作者:熊澤-學習中的苦與樂
公眾號:熊澤有話說
出處: https://www.cnblogs.com/xiongze520/p/14308996.html
創作不易,轉載或者部分轉載、摘錄,請在文章明顯位置註明作者和原文連結。  

 

相關文章