婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 使用數據結構給女朋友寫個Html5走迷宮游戲

使用數據結構給女朋友寫個Html5走迷宮游戲

熱門標簽:如何查看地圖標注 電話機器人技術 黃石ai電銷機器人呼叫中心 地圖標注軟件打印出來 智能電銷機器人被禁用了么 高德地圖標注商戶怎么標 欣鼎電銷機器人 效果 惡搞電話機器人 ok電銷機器人

先看效果圖(在線電腦嘗試地址http://biggsai.com/maze.html):


起因


 

又到深夜了,我按照以往在公眾號寫著數據結構!這占用了我大量的時間!我的超越妹妹嚴重缺乏陪伴而 怨氣滿滿!



 

超越妹妹時常埋怨,認為數據結構這么抽象難懂的東西沒啥作用,常會問道:天天寫這玩意,有啥作用。而我答道:能干事情多了,比如寫個小游戲啥的!



 

當我碼完字準備睡覺時:寫不好別睡覺!


分析

如果用數據結構與算法造出東西來呢?

什么東西簡單容易呢?我百度一下,我靠,這個鳥游戲原來不好搞啊,得接觸一堆不熟悉的東西,搞不來搞不來。

有了(靈光一閃),寫個猜數字游戲,問他加減乘除等于幾。

超越妹妹又不是小孩子,糊弄不過去。

經過一番折騰,終于在半夜12點確定寫迷宮小游戲了。大概弄清楚其中的幾個步驟。

大概是:

畫線—>畫迷宮(擦線)—>方塊移動、移動約束(不出界不穿墻)—>完成游戲。畫線(棋盤)

對于html+js(canvas)畫的東西,之前學過javaswing應該有點映像。在html中有個canvas 的畫布,可以在上面畫一些東西和聲明一些監聽(鍵盤監聽)。

對于迷宮來說,那些線條是沒有屬性的,只有位置x,y,你操作這個畫布時候,可能和我們習慣的面相對象思維不一樣。所以,在你設計的線或者點的時候,記得那個點、線在什么位置,在后續劃線還是擦線還是移動的時候根據這個位置進行操作。

 

<!DOCTYPE html>
<html>
  <head>
    <title>MyHtml.html</title>	
  </head> 
  <body>
  <canvas id="mycanvas" width="600px" height="600px"></canvas>
    
  </body>
  <script type="text/javascript">

var aa=14;
    var chess = document.getElementById("mycanvas");
    var context = chess.getContext('2d');

    //  var context2 = chess.getContext('2d');
    //      context.strokeStyle = 'yellow';
    var tree = [];//存放是否聯通
    var isling=[];//判斷是否相連
    for(var i=0;i<aa;i++){
        tree[i]=[];
        for(var j=0;j<aa;j++){
            tree[i][j]=-1;//初始值為0
        }
    }  for(var i=0;i<aa*aa;i++){
        isling[i]=[];
        for(var j=0;j<aa*aa;j++){
            isling[i][j]=-1;//初始值為0
        }
    }
    
    function drawChessBoard(){//繪畫
        for(var i=0;i<aa+1;i++){
            context.strokeStyle='gray';//可選區域
            context.moveTo(15+i*30,15);//垂直方向畫15根線,相距30px;
            context.lineTo(15+i*30,15+30*aa);
            context.stroke();
            context.moveTo(15,15+i*30);//水平方向畫15根線,相距30px;棋盤為14*14;
            context.lineTo(15+30*aa,15+i*30);
            context.stroke();
        }
    }
    drawChessBoard();//繪制棋盤
   
    //      var mymap=new Array(36);
    //      for(var i=0;i<36;i++)
    //     {mymap[i]=-1;}


  </script>
</html>

實現效果


畫迷宮

隨機迷宮怎么生成?怎么搞?一臉懵逼。

因為我們想要迷宮,那么就需要這個迷宮出口和入口有連通路徑,你可能壓根不知道迷宮改怎么生成,用的什么算法。小聲BB:用并查集(不相交集合)

迷宮和不相交集合有什么聯系呢?(規則)

之前筆者在前面數據結構與算法系列中曾經介紹過并查集(不相交集合),它的主要功能是森林的合并,不聯通的通過并查集能夠快速將兩個森林合并,并且能夠快速查詢兩個節點是否在同一個森林中!

我們的隨機迷宮:在每個方格都不聯通的情況下,是一個棋盤方格,這也是它的初始狀態。而這個節點可以跟鄰居可能相連,也可能不相連。我們可以通過并查集實現。

具體思路為:(主要理解并查集)

1:定義好不想交集合的基本類和方法(search,union等)
2:數組初始化,每一個數組元素都是一個集合,值為-1
3:隨機查找一個格子(一維數據要轉換成二維,有點麻煩),在隨機找一面墻(也就是找這個格子的上下左右),還要判斷找的格子出沒出界。
具體在格子中找個隨機數m——>隨機數m在二維中的位置[m/長,m%長]——>這個二維的上下左右隨機找一個位置p[m/長+1,m%長][m/長-1,m%長][m/長,m%長+1][m/長,m%長-1]——>判斷是否越界
4:判斷兩個格子(一維數組編號)是否在一個集合(并查集查找)。如果在,則重新找,如果不在,那么把墻挖去
5:把墻挖去有點繁瑣,需要考慮奇偶判斷它那種墻(上下還是左右,還要考慮位置),然后擦掉。(根據數組轉換成真實距離)。具體為找一個節點,根據位置關系找到一維數組的號位用并查集判斷是否在一個集合中。
6:最終得到一個完整的迷宮。直到第一個(1,1)和(n,n)聯通停止。雖然采用隨機數找墻,但是效果并不是特別差。其中要搞清一維二維數組的關系。一維是真實數據,并查集操作。二維是位置。要搞懂轉化!

注意:避免混淆,搞清數組的地址和邏輯矩陣位置。數組從0開始的,邏輯上你自己判斷。別搞混淆!



主要邏輯為:

 

while(search(0)!=search(aa*aa-1))//主要思路
    {
        var num = parseInt(Math.random() * aa*aa );//產生一個小于196的隨機數
        var neihbour=getnei(num);
        if(search(num)==search(neihbour)){continue;}
        else//不在一個上
        {
           isling[num][neihbour]=1;isling[neihbour][num]=1;
            drawline(num,neihbour);//劃線
            union(num,neihbour);
         
        }
    }

那么在前面的代碼為

<!DOCTYPE html>
<html>
  <head>
    <title>MyHtml.html</title>	
  </head> 
  <body>
  <canvas id="mycanvas" width="600px" height="600px"></canvas>
    
  </body>
  <script type="text/javascript">
//自行添加上面代碼
    //      var mymap=new Array(36);
    //      for(var i=0;i<36;i++)
    //     {mymap[i]=-1;}
    function getnei(a)//獲得鄰居號  random
    {
        var x=parseInt(a/aa);//要精確成整數
        var y=a%aa;
        var mynei=new Array();//儲存鄰居
        if(x-1>=0){mynei.push((x-1)*aa+y);}//上節點
        if(x+1<14){mynei.push((x+1)*aa+y);}//下節點
        if(y+1<14){mynei.push(x*aa+y+1);}//有節點
        if(y-1>=0){mynei.push(x*aa+y-1);}//下節點
        var ran=parseInt(Math.random() * mynei.length );
        return mynei[ran];

    }
    function search(a)//找到根節點
    {
        if(tree[parseInt(a/aa)][a%aa]>0)//說明是子節點
        {
            return search(tree[parseInt(a/aa)][a%aa]);//不能壓縮路徑路徑壓縮
        }
        else
            return a;
    }
    function value(a)//找到樹的大小
    {
        if(tree[parseInt(a/aa)][a%aa]>0)//說明是子節點
        {
            return tree[parseInt(a/aa)][a%aa]=value(tree[parseInt(a/aa)][a%aa]);//不能路徑壓縮
        }
        else
            return -tree[parseInt(a/aa)][a%aa];
    }
    function union(a,b)//合并
    {
        var a1=search(a);//a根
        var b1=search(b);//b根
        if(a1==b1){}
        else
        {
            if(tree[parseInt(a1/aa)][a1%aa]<tree[parseInt(b1/aa)][b1%aa])//這個是負數(),為了簡單減少計算,不在調用value函數
            {
                tree[parseInt(a1/aa)][a1%aa]+=tree[parseInt(b1/aa)][b1%aa];//個數相加  注意是負數相加
                tree[parseInt(b1/aa)][b1%aa]=a1;       //b樹成為a樹的子樹,b的根b1直接指向a;
            }
            else
            {
                tree[parseInt(b1/aa)][b1%aa]+=tree[parseInt(a1/aa)][a1%aa];
                tree[parseInt(a1/aa)][a1%aa]=b1;//a所在樹成為b所在樹的子樹
            }
        }
    }

    function drawline(a,b)//劃線,要判斷是上下還是左右
    {

        var x1=parseInt(a/aa);
        var y1=a%aa;
        var x2=parseInt(b/aa);
        var y2=b%aa;        
        var x3=(x1+x2)/2;
        var y3=(y1+y2)/2;
        if(x1-x2==1||x1-x2==-1)//左右方向的點  需要上下劃線
        {
            //alert(x1);
            //  context.beginPath();
            context.strokeStyle = 'white';
            //    context.moveTo(30+x3*30,y3*30+15);//
            //   context.lineTo(30+x3*30,y3*30+45);
            context.clearRect(29+x3*30, y3*30+16,2,28);
            //    context.stroke();
        }
        else
        {
            //   context.beginPath();
            context.strokeStyle = 'white';
            //  context.moveTo(x3*30+15,30+y3*30);//
            //    context.lineTo(45+x3*30,30+y3*30);
            context.clearRect(x3*30+16, 29+y3*30,28,2);
            //      context.stroke();
        }
    }
     
    while(search(0)!=search(aa*aa-1))//主要思路
    {
        var num = parseInt(Math.random() * aa*aa );//產生一個小于196的隨機數
        var neihbour=getnei(num);
        if(search(num)==search(neihbour)){continue;}
        else//不在一個上
        {
           isling[num][neihbour]=1;isling[neihbour][num]=1;
            drawline(num,neihbour);//劃線
            union(num,neihbour);
         
        }
    }
  </script>
</html>

實現效果:



方塊移動

這部分我采用的方法不是動態真的移動,而是一格一格的跳躍。也就是當走到下一個格子將當前格子的方塊擦掉,在移動的那個格子中再畫一個方塊。選擇方塊是因為方塊更方便擦除,可以根據像素大小精準擦除。

另外,再移動中要注意不能穿墻、越界。那么怎么判斷呢?很好辦,我們再前面會判斷兩個格子是否聯通,如果不連通我們將把這個墻拆開。再拆的時候把這個墻的時候記錄這兩點拆墻可走即可(數組)

另外,事件的監聽上下左右查一查就可以得到,添加按鈕對一些事件監聽,這些不是最主要的。

為了豐富游戲可玩性,將方法封裝,可以設置關卡(只需改變迷宮大小)。這樣就可以實現通關了。另外,如果寫成動態存庫那就更好了。


結語

在線嘗試地址,代碼直接查看網頁源代碼即可!

以上所述是小編給大家介紹的使用數據結構給女朋友寫個Html5走迷宮游戲,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

標簽:聊城 阿壩 萍鄉 綏化 中山 金昌 赤峰 盤錦

巨人網絡通訊聲明:本文標題《使用數據結構給女朋友寫個Html5走迷宮游戲》,本文關鍵詞  使用,數據結構,給,女朋友,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《使用數據結構給女朋友寫個Html5走迷宮游戲》相關的同類信息!
  • 本頁收集關于使用數據結構給女朋友寫個Html5走迷宮游戲的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    亚洲欧美另类图片小说| 激情久久久久久久久久久久久久久久| 午夜一区二区三区视频| 国产成人精品免费一区二区| 欧美性感一类影片在线播放| 国产夜色精品一区二区av| 亚洲www啪成人一区二区麻豆| 国产不卡视频一区二区三区| 欧美一卡2卡3卡4卡| 亚洲理论在线观看| 国产很黄免费观看久久| 欧美一区二区三区精品| 亚洲一区二区三区激情| 99精品视频免费在线观看| 久久人人爽人人爽| 日韩—二三区免费观看av| 91福利资源站| 最新中文字幕一区二区三区 | 91福利国产精品| 国产喷白浆一区二区三区| 免费成人在线网站| 欧美在线999| 亚洲色欲色欲www| 成人高清免费观看| 国产日韩欧美制服另类| 精品亚洲porn| 欧美大胆人体bbbb| 另类小说一区二区三区| 51精品国自产在线| 亚洲永久精品国产| 91色|porny| 日韩一区在线免费观看| 成人高清免费观看| 欧美国产成人在线| 国产a视频精品免费观看| 欧美精品一区二区三区蜜桃| 捆绑调教一区二区三区| 日韩天堂在线观看| 麻豆免费精品视频| 日韩欧美在线影院| 另类小说一区二区三区| 另类综合日韩欧美亚洲| 欧美精品777| 日欧美一区二区| 欧美日韩另类一区| 亚洲国产wwwccc36天堂| 欧美视频在线观看一区| 亚洲国产欧美日韩另类综合| 欧美午夜一区二区三区免费大片| 一区二区三区在线不卡| 色婷婷国产精品久久包臀| 亚洲女性喷水在线观看一区| 91玉足脚交白嫩脚丫在线播放| 中文字幕日本乱码精品影院| 色综合天天性综合| 亚洲一区在线播放| 欧美精选午夜久久久乱码6080| 视频一区视频二区在线观看| 日韩欧美国产成人一区二区| 国产精品资源网| 国产精品无人区| 91原创在线视频| 亚洲午夜电影网| 欧美一区二区三区婷婷月色| 精彩视频一区二区| 成人免费高清在线观看| 国产精品素人视频| 日本中文字幕一区| 日韩精品专区在线| 日本一区中文字幕| 91精品福利在线一区二区三区 | 精品一区二区三区免费毛片爱 | 日本中文一区二区三区| 欧美不卡一二三| 国产精品一区二区视频| 成人免费在线视频观看| 欧美少妇一区二区| 日韩电影免费在线看| 2023国产一二三区日本精品2022| 国产大陆精品国产| 一区二区三区精品| 欧美一级片在线观看| 国产成人免费9x9x人网站视频| 国产精品久久777777| 欧美三片在线视频观看| 六月丁香婷婷久久| 国产精品久久久久久久久搜平片| 91成人网在线| 另类中文字幕网| 国产精品第一页第二页第三页| 欧美日韩一区二区欧美激情| 极品少妇一区二区| 亚洲伦理在线免费看| 日韩一级二级三级精品视频| 成人教育av在线| 婷婷六月综合亚洲| 中文字幕免费不卡| 538prom精品视频线放| 丁香婷婷综合色啪| 偷拍一区二区三区| 中文字幕欧美激情一区| 欧美精品777| 粉嫩高潮美女一区二区三区 | 日韩视频中午一区| 99久精品国产| 久久精品国产久精国产爱| 日本久久一区二区三区| 亚洲123区在线观看| 精品久久久久香蕉网| 色婷婷综合激情| 激情综合五月婷婷| 亚洲一级片在线观看| 久久久久久久久一| 欧美日韩和欧美的一区二区| 粉嫩久久99精品久久久久久夜| 天堂蜜桃一区二区三区| 中文字幕亚洲不卡| 欧美成人一区二区三区片免费| 色婷婷久久久久swag精品| 国产高清不卡一区二区| 首页亚洲欧美制服丝腿| 亚洲人成精品久久久久久| 精品国产乱码久久久久久影片| 精品污污网站免费看| 成人av资源站| 国产在线视视频有精品| 日韩高清不卡一区二区三区| 亚洲精品国产第一综合99久久 | 日本美女一区二区| 成人免费在线观看入口| 久久久亚洲精品石原莉奈| 在线不卡一区二区| 99re成人在线| 国产很黄免费观看久久| 久久激情五月激情| 婷婷六月综合网| 一级日本不卡的影视| 欧美极品美女视频| 精品sm在线观看| 欧美一区二区三区视频免费播放| 在线观看视频欧美| 97久久超碰国产精品| 国产ts人妖一区二区| 国产麻豆精品95视频| 久久国产乱子精品免费女| 午夜视频在线观看一区二区 | 不卡在线视频中文字幕| 国产成人精品免费一区二区| 国内精品不卡在线| 精品一区二区三区视频在线观看| 日本欧美肥老太交大片| 午夜伊人狠狠久久| 夜夜操天天操亚洲| 一区二区三区影院| 亚洲人成7777| 日韩伦理免费电影| 色噜噜狠狠成人中文综合| 国产成人自拍网| 韩国v欧美v日本v亚洲v| 欧美一二三在线| 丝袜诱惑亚洲看片| 日本乱人伦aⅴ精品| 中文字幕精品一区二区三区精品| 精品人伦一区二区色婷婷| 欧美一区二区三区视频在线 | 亚洲手机成人高清视频| 自拍偷自拍亚洲精品播放| 中文字幕欧美国产| 国产精品久久久久aaaa樱花| 亚洲欧洲精品天堂一级| 亚洲欧美日韩在线不卡| 一区二区三区在线视频播放| 亚洲自拍欧美精品| 亚洲成人免费视频| 亚洲va国产天堂va久久en| 天堂成人免费av电影一区| 天天亚洲美女在线视频| 日本在线不卡视频一二三区| 美女网站色91| 国产剧情在线观看一区二区| 国产成人一级电影| 成人av网站大全| 91精品福利视频| 欧美高清你懂得| 精品国产一区二区三区久久久蜜月| 久久影院电视剧免费观看| 欧美激情在线免费观看| 亚洲日本成人在线观看| 亚洲综合清纯丝袜自拍| 天涯成人国产亚洲精品一区av| 日韩成人av影视| 国产精品1区2区3区在线观看| 丁香五精品蜜臀久久久久99网站| 99久久免费精品高清特色大片| 91高清视频免费看| 91麻豆精品国产自产在线 | 日本中文在线一区| 国产真实乱子伦精品视频| 成人av综合在线| 欧美私人免费视频|