FPSゲームブロック透視原理分析及び実現-C++言語

18089 ワード

最近2ヶ月間暇で無事にボックス透視の原理を研究しました(ここでは単機ゲームのボックス透視だけを議論し、ネットゲームには触れず、皆さんの研究に供します)、あまり深い内容ではないことを発見し、この機会に皆さんと一緒に研究しました.本人はもともとJava専門で、研究成果は最近2ヶ月の研究ですが、間違いがあればご指摘ください.
透視原理分類
  • FOVボックスFOVボックスの原理は、FOV視野角を計算し、角演算を求めることによって、画面上の敵の位置を取得することである.この方式で透視を実現するボックスは必ずしも正確ではなく,異なる視点で別々に処理するのは面倒である.現在、多くの透視はこのような方法で実現されていません.私も深く研究していません.ここでは
  • を多く議論しています.
  • マトリクスボックスこの透視の原理は、ゲームマトリクスと敵xyzを取得することによって、画面上の敵の座標を特定のアルゴリズムで得ることであり、現在多くの人が使用している方法である.このようにして得られる敵座標は、異なる視点と異なる距離でボックスサイズが変化しないため(特定のアルゴリズムによって)、角を求める必要がなくなるなど便利です.欠点は、自動照準を書いてボックス内の敵を狙うと、正面の敵だけが指定された位置を狙う可能性があるということです(例えば頭).側面になると敵の頭が偏る可能性があります.枠の中のある点を狙っているので、敵は横向きになっていません.
  • ボーンボックスという透視の仕方もよく使われていますが、私はあまり研究していません.ここでは、マトリクスに対するボーンのメリットは、敵が横向きであれば、自動照準が敵のボーン座標であれば偏らないに違いありません.マトリクスボックスであれば、照準が間違っている可能性があります.骨格の利点は、敵がどんな姿勢であっても、特定の骨格の位置を狙えば、壁がない限り、決して当たらないことはありません.

  • ピボットインプリメンテーション分類
    実装方式によって外部透視と内部透視に分けられ,内部透視は注入される.描画方法によってGDIパースとDXパースに分けることができます.
    コード実装
    敵のxyzや本人のxyzなど、敵と自分のデータを透視するには、マウスのxyが必要です.ここでは、これらのデータをどのように取得するかについては議論しません.明日はインターネットの授業があるので、ここにはコアコードの部分しか展示されていません.ソースコードは私がネットディスクに入れました(ネットディスクアドレスは一番下にあります).開発環境はVS 2019で、ゲームはCS起源です.コードはC++で実現されています.C++で実現されているとはいえ、CとJavaとC#しか習っていないので、文法はやはりC文法を使っています.
    void Esp(PlayerData* MY, PlayerData* EL)
    {
    	//        XY  
    	float EnemyXY[2];
    	//    xyz         xy  
    	WordToScreen(EL->Position, EnemyXY);
    	DrawEsp(EnemyXY[0], EnemyXY[1], MY, EL);
    }
    
    //         
    BOOL WordToScreen(float from[3], float to[2])
    {
    	//             。
    	float w = g_Matrix[3][0] * from[0] + g_Matrix[3][1] * from[1] + g_Matrix[3][2] * from[2] + g_Matrix[3][3]; //Calculate the angle in compareson to the player's camera.
    	if (w > 0.001) //        .
    	{
    		float fl1DBw = 1 / w;
    		to[0] = ((g_winRect.right - g_winRect.left) / 2) + (0.5f * ((g_Matrix[0][0] * from[0] + g_Matrix[0][1] * from[1] + g_Matrix[0][2] * from[2] + g_Matrix[0][3]) * fl1DBw) * (g_winRect.right - g_winRect.left) + 0.5f); 
    		to[1] = ((g_winRect.bottom - g_winRect.top) / 2) - (0.5f * ((g_Matrix[1][0] * from[0] + g_Matrix[1][1] * from[1] + g_Matrix[1][2] * from[2] + g_Matrix[1][3]) * fl1DBw) * (g_winRect.bottom - g_winRect.top) + 0.5f); 
    		return true;
    	}
    	return false;
    }
    
    void SetRect(float* rect, float myPos[3], float elPos[3], float width, float height)
    {
    	//          
    	float distance = GetDistance3D(myPos, elPos);
    	//     
    	if (width != 0 && height == 0)
    	{
    		rect[0] = (rect[0] + width) / distance;
    		return;
    	}
    	//     
    	else if (height != 0 && width == 0)
    	{
    		rect[1] = (rect[1] + height) / distance;
    		return;
    	}
    	//       
    	else if (height != 0 && width != 0)
    	{
    		rect[0] = (rect[0] + width) / distance;
    		rect[1] = (rect[1] + height) / distance;
    		return;
    	}
    	//        
    	else
    	{
    		rect[0] = rect[0] / distance;
    		rect[1] = rect[1] / distance;
    		return;
    	}
    }
    

    上のコードは、それぞれワールド座標回転スクリーン座標、ブロック描画(一部)、距離に応じて矩形サイズを設定しています.すべてのFPSが共通しています.
    まとめ
    実はとても奥深い原理ではありませんて、多く研究して会を研究して、もし兴味があるならばいっしょに学ぶことができるQQ交流群に参加することができます:1018547561ソースコード私も群の中に置いて、各位の学习に便利です.また、私は易言語の精易モジュールとスーパーモジュールを参考にしてC++のライブラリを実現しました.私の精力は限られていて、授業があるので、このライブラリの大部分は完成していません.もし皆さんがこのプロジェクトに興味があれば、グループを追加することもできます.このライブラリを実現する主な目的は後世の人を便利にするためで、また各位の大物に多く支持してもらいます!ソースコード:ダイヤル抽出コード:vtjd有効期間7日間