<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【CSON原創】HTML5實現3D迷宮

      功能描述:

        左右方向鍵控制玩家的方向,上下方向鍵控制玩家的前進和后退。

      效果預覽:

        

       

      實現原理:

        在上面的效果預覽中,可以看到右邊是2D的平面地圖,而左邊的則是第一人稱的3D視圖,這兩幅圖的關系是非常密切的,實質上,實現3D視覺的過程,就是依據2D地圖把地圖轉換成第一人稱視覺的過程

        在之前的一篇文章:《javascript實現3D房間》中,3D效果的實現只局限于平面(意思是從側面看沒有立體效果),在這種有局限性的3D效果中,我們以一個個物體為單位,通過不同物體平面之間的視覺差實現3D。而在這次的效果中,為了使物體從不同角度看都能具有立體效果,我們把單位從平面改成線。

        首先,我們創建一個叫視覺平面的東西,它像一面鏡子,把實物投影到一個平面上,首先初始化該平面的尺寸:

      screenSize:[320,240],//視覺屏幕尺寸

        之后,我們可以以1像素為單位,只要知道物體每個像素在該視覺平面上顯示出來的高度,就可以繪制出物體在第一人稱視覺上的效果。

        以視覺平面上的第一個像素線段為例,根據比例可得知:玩家到視覺平面的距離/玩家到物體的實際距離=物體在視覺平面上的高度/物體的實際高度。由于玩家到視覺平面的距離和物體的實際高度我們可以自己定義,因此我們只要知道玩家到物體的距離,就可以知道物體該像素在視覺平面的高度。

        怎樣知道玩家到物體的實際距離呢?這時我們就需要借助和3D視覺圖密切相關的2D地圖了。首先,我們定義玩家的最大視覺角度為60度(意思是玩家的視覺范圍角度),由于我們現在處理的是平面的第一條像素線,因此該像素線相對于玩家的角度就為-30度。在地圖上,我們可以知道玩家的X,Y位置和玩家的方向,因此我們就可以知道第一條像素線在地圖上的方向。

        在2D地圖上怎么表示3D視覺平面上的一條像素線呢?其實仔細想想就可以發現,3D視覺平面中的一條像素線,相當于2D地圖上特定方向上發出的一條射線,射線與物體的交點就是3D視覺平面中的那條像素線的內容。因此,只要我們計算出該射線的長度(起點:玩家位置 終點:射線和物體相交的位置),就可以知道玩家與物體的距離,從而求得改像素的物體在視覺平面上的高度。

        最后只要循環遍歷視覺平面上的每一條1px寬的像素線,并根據2D地圖上對應射線的長度,就可以求得視覺平面上所有視覺范圍內的物體每一像素的高度,形成3D視覺效果。


      代碼分析:

        主要看實現的核心代碼,循環遍歷視覺平面上每條像素線,繪制出該像素線上的物體內容:

        

          var context=this.screenContext;

      context.clearRect(0,0,this.screenSize[0],this.screenSize[1]);
      context.fillStyle="rgb(203,242,238)";
      context.fillRect(0,0,this.screenSize[0],this.screenSize[1]/2);
      context.fillStyle="rgb(77,88,87)";
      context.fillRect(0,this.screenSize[1]/2,this.screenSize[0],this.screenSize[1]/2);

       

         由于該效果需要兩個canvas(一個顯示地圖,一個顯示3D視覺圖),因此我們首先獲取3D視覺圖上的canvas,并繪制地面和天空。

        

          //cnGame.context.beginPath();
      for(var index=0,colCount=this.screenSize[0]/this.viewColWidth;index<colCount;index++){
      screenX=-this.screenSize[0]/2+index*this.viewColWidth;//該豎線在屏幕的x坐標
      colAngle=Math.atan(screenX/this.screenDistant);//玩家的視線到屏幕上的豎線所成的角度
      colAngle%=2*Math.PI;
      var angle=this.player.angle/180*(Math.PI)-colAngle;//射線在地圖內所成的角度
      angle%=2*Math.PI;
      if(angle<0){
      angle+=2*Math.PI;
      }
      distant=0;
      x=0;
      y=0;
      centerX=this.player.x+(this.player.width)/2;//玩家中點X坐標
      centerY=this.player.y+(this.player.height)/2;//玩家中Y坐標
      while(this.map.getPosValue(centerX+x,centerY-y)==0){
      distant+=1;
      x=distant*Math.cos(angle);
      y=distant*Math.sin(angle);
      }
      //如果射線在地圖遇到墻壁,則畫線
      /*cnGame.context.strokeStyle="#000";
      cnGame.context.moveTo(centerX,centerY);
      cnGame.context.lineTo(centerX+x,Math.floor(centerY-y));
      cnGame.context.closePath();
      */

      distant*=Math.cos(colAngle);//防止魚眼效果

      heightInScreen=this.screenDistant/(distant)*this.wallSize[2];//根據玩家到墻壁的距離計算墻壁在視覺平面的高度
      var img=cnGame.loader.loadedImgs[srcObj.stone2];
      context.drawImage(img,0,0,2,240,this.viewColWidth*index,(this.screenSize[1]-heightInScreen)/2, this.viewColWidth,heightInScreen)
      }

        之后,就可以開始循環遍歷每條像素線,繪制出物體內容。在處理每條像素線的過程中,我們讓射線每次增加1像素的長度,當射線遇到非空地的時候(getPosValue(x,y)>0),就停止增長,并記錄下此時射線的長度,該長度就是玩家到該像素線內容的實際距離。

        上面代碼中,注釋掉的部分其實就是用于繪制出發射的射線,如果大家有需要,可以恢復該部分的代碼,就可以看到玩家的視覺范圍。

        需要注意的是,由于視覺平面有區別人的眼球(是一個平面而非球體),因此我們還需要使距離乘上玩家視覺角度的余弦值,從而避免了魚眼效果。

        最后,我們還可以在3D視覺圖上繪制出玩家(拿槍的手),達到更好的效果。

       

        完整demo下載:點擊下載

       

        參考文章

        使用HTML5的Canvas和raycasting創建一個偽3D游戲(part1)

          Creating pseudo 3D games with HTML 5 canvas and raycasting

        Ray-Casting Tutorial For Game Development And Other Purposes

        

        歡迎轉載,請標明出處:http://www.rzrgm.cn/Cson/archive/2012/02/26/2368955.html

        

      posted @ 2012-02-27 00:24  Cson  閱讀(9426)  評論(6)    收藏  舉報
      主站蜘蛛池模板: 久久日产一线二线三线| 东京一本一道一二三区| 国产国语一级毛片| 久久精品国产一区二区蜜芽| 亚洲成av人最新无码不卡短片| 性欧美牲交在线视频| 国产欧美一区二区精品久久久 | 国产美女遭强高潮免费| 国产精品美女久久久久久麻豆| 日韩人妻无码精品系列| 国产亚洲中文字幕久久网| 精品人妻蜜臀一区二区三区| 忍着娇喘人妻被中出中文字幕 | 国产麻豆一精品一av一免费| 国产精品麻豆va在线播放| 欧洲亚洲精品免费二区| 日本牲交大片免费观看| 曰韩精品无码一区二区三区视频| 欧美野外伦姧在线观看| 国产欧美久久一区二区三区| 国产视频一区二区三区麻豆| 中文字幕日韩精品有码| 石屏县| 日本人妻巨大乳挤奶水免费 | 色综合久久久久综合99| 最近中文字幕国产精品| 日韩精品一区二区三区在| 夜鲁鲁鲁夜夜综合视频| 东京热一精品无码av| 亚洲综合国产成人丁香五| 国产成人麻豆亚洲综合无码精品| 免费观看欧美猛交视频黑人| 亚洲一区二区三区丝袜| 精品亚洲没码中文字幕| 无套内射视频囯产| 和黑人中出一区二区三区| 亚洲AV无码国产永久播放蜜芽 | 激情综合网激情五月伊人| 亚洲国产精品毛片在线看| 亚洲人成亚洲人成在线观看| 国产区一区二区现看视频|