ホームページ  >  記事  >  ウェブフロントエンド  >  HTML5 で 3D 迷路を実装するコード ケースの詳細な紹介

HTML5 で 3D 迷路を実装するコード ケースの詳細な紹介

黄舟
黄舟オリジナル
2017-03-24 15:41:082231ブラウズ

機能説明:

左右の方向キーはプレイヤーの方向を制御し、上下の方向キーはプレイヤーの前後移動を制御します。

効果プレビュー:

HTML5 で 3D 迷路を実装するコード ケースの詳細な紹介

実装原理:

上記の効果プレビューでは、右側が2D平面マップであり、左側が最初のマップであることがわかります。人の 3D ビュー、これら 2 つの画像の関係は非常に密接です。本質的に、3D 視覚を実現するプロセスは、2D マップ に基づいてマップを一人称視点に変換するプロセスです。

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);

この効果には 2 つの

キャンバス

が必要なためです。 (1 つは地図を表示し、もう 1 つは 3D ビジュアル マップを表示します)。まず、3D ビジュアル マップ上にキャンバスを取得し、地面と空を描画します。

//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)    
    }
その後、各ピクセル ラインのループを開始して、オブジェクトのコンテンツを描画できます。各ピクセル ラインを処理する過程で、レイが空ではない領域 (getPosValue (x, y) > 0) に遭遇すると、レイの長さを 1 ピクセルずつ増加させ、成長を停止し、これを記録します。タイム レイの長さ。これは、プレーヤーからピクセル ラインのコンテンツまでの実際の距離です。

上記のコードでは、コメントされた

部分が実際に放出される光線を描画するために使用されます。必要に応じて、コードのこの部分を復元すると、プレイヤーの視覚範囲を確認できます。

視平面は人間の眼球とは異なるため(球ではなく平面である)、そのため、魚眼効果を避けるために距離にプレイヤーの視角のコサインを乗算する必要もあることに注意してください。

最後に、より良い結果を得るために、3D ビジュアル マップ上にプレイヤー (銃を持つ手) を描画することもできます。

以上がHTML5 で 3D 迷路を実装するコード ケースの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。