熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java游戲編程殺手:3D跳棋游戲

2013-11-23 18:53:01  來源: Java核心技術 
這章用一個Java D例子來描述一個D跳棋這個例子建立了一個場景包括由一個暗綠色和蘭色格相交平鋪的並帶有標簽的X軸和Z軸形成的平面一個蘭色背景一個可以在兩個不同方向浮動的球體用戶可以通過鼠標來浏覽(拉近放遠)場景左邊的截圖顯示最初視圖右邊的圖是用戶視圖移動一些之後的效果

  


Figure Initial view and later

  D跳棋闡述了Java D編程中一些常用的方法和一些小竅門例如D場景使用CanvasD類來實現顯示(這個類和Swing組件結合使用)所有的Java D程序需要一個場景圖D跳棋說明了如何增加基本圖形燈光背景這些場景圖形成了文件的可視形式記錄這些場景信息的文本版本通過Daniel Selman的JavadTree包很容易就能實現(在這節的最後我會詳細介紹)

  地板和球體使用了JavaD的QuadArray TextD and Sphere幾何類地板是由QuadArray的一系列四邊形組成標簽是用TextD對象沿著地板上的主軸形成用戶通過一個觀察點查看這個D世界你將看到如何初始放置觀察點在使用JavaD的OrbitBehavior 類時候如何移動觀察點

  D跳棋類圖

  圖的類圖說明了D跳棋程序的public和private數據項和方法

  


Figure Class diagrams for CheckersD

  CheckersD 是程序的頂層JFrame WrapCheckersD 是場景圖擁有的 JPanel 作為一個CanvasD 對象他是可視的 CheckerFloor 建立地板的子圖(例如方格軸) with所有同顏色的方格用單獨的ColoredTiles 對象表示

  提示例子的原代碼在CheckersD/目錄(可能是原書附帶光盤)

  Java D和Swing 的結合

  就向Swing文本和按紐CheckersD 是GUI控制位置的的一個 JFrame 把他放在必要的地方在這個例子中他建立一個WrapCheckersD (一個 JPanel) 實例並把他放在 BorderLayout 中間

  csetLayout( new BorderLayout( ) );
    WrapCheckersD wd = new WrapCheckersD( );   // panel for D canvas
    cadd(wd BorderLayoutCENTER);



  場景中的CanvasD 視圖建立在WrapCheckersD 類裡

  public WrapCheckersD( )
    {
      setLayout( new BorderLayout( ) );
      // other initialization code

      GraphicsConfiguration config =
                 SimpleUniversegetPreferredConfiguration( );
      CanvasD canvasD = new CanvasD(config);
      add(Center canvasD);

      // other initialization code}


  雖然 CanvasD 是一個重量級的GUI 元素(一個系統產生窗口的輕量層)還是有一些必須注意的重量級的組件沒那麼容易與Swing控件組合(Swing是一個輕量組件)這些控件主要由Java產生如果 CanvasD 對象內嵌到一個 JPanel問題就可以消除並且建立出來的panel可以安全地和Swing程序的其他部分結合
  提示: 這是在的一個關於結合 CanvasD 和Swing的詳細討論()

  相比前幾章這裡沒有update/draw循環因為Java D自身有機制來監視場景和最初視圖的變化下面以偽代碼給出算法

  while(true) {
      process user input; //用戶輸入
      if (exit request) break;
      perform behaviors;  
      if (scene graph has changed)  //場景改變
        traverse scene graph and render;  //移動場景視圖
    }



  其中的behaviors是一些影響其他部分圖象的代碼比如移動的圖形或改變燈光他們用來監視圖象傳遞給程序中非D部分詳情詳細代碼比例子中的偽代碼更加復雜Java D用多線程來並發移動和圖形描述因此對這個過程有一個概括了解會對本章其他部分的理解有幫助

  場景圖形建立

  場景圖形用 WrapCheckersD的構造函數建立


  public WrapCheckersD( )
    {
      // initialization code

      GraphicsConfiguration config =
                 SimpleUniversegetPreferredConfiguration( );
      CanvasD canvasD = new CanvasD(config);
      add(Center canvasD);
      canvasDsetFocusable(true);     // give focus to the canvas
      canvasDrequestFocus( );

      su = new SimpleUniverse(canvasD);

    
      createSceneGraph( );
      initUserPosition( );        // set users viewpoint
      orbitControls(canvasD);   // controls for moving the viewpoint

      suaddBranchGraph( sceneBG );
    }



  CanvasD 對象用從getPreferredConfiguration( );獲得的配置來初始化這個方法能取得硬件的圖形信息一些老的Java D程序沒有初始化一個GraphicsConfiguration 對象而是用null作為 CanvasD 的構造函數的參數這種編程可不太好canvasD 被設置成焦點以便鍵盤能傳遞動作給場景圖形這些動作的觸發通常是按鍵的按壓和彈起但是他們也能由定時器幀的改變和由Java D內部產生的事件觸發 CheckersD就不需要設置焦點因為他沒有任何動作因為在所有的其他程序中我們都會考慮到線條所以我沒有給出線條的描繪代碼

  su SimpleUniverse 對象建立了標准子視圖場景圖形的VirtualUniverse 和Locale 節點
createSceneGraph( ) 設置了燈光天空的背景地板還有浮動球體initUserPosition( ) 和 orbitControls( ) 處理用戶視角問題最後把配置好的 BranchGroup 加入到方法

  private void createSceneGraph( )
    {
      sceneBG = new BranchGroup( );
      bounds = new BoundingSphere(new Pointd() BOUNDSIZE);


      lightScene( );         // add the lights
      addBackground( );      // add the sky
      sceneBGaddChild( new CheckerFloor( )getBG( ) );  // add floor

      floatingSphere( );     // add the floating sphere

      pile( );   // fix the scene
    } // end of createSceneGraph( )



  使用不同的方法來增加子圖到 sceneBG以建立需要的子視圖一旦圖形被繪制完畢後並允許JavaD來優化他sceneBG 便只被編譯一次優化包括重排圖形重新組合編譯節點例如一連串的包含不同轉換的TransformGroup 節點會被編譯成一個獨立節點另一個可能的優化是把具有相同顯示屬性的圖形編成組以便能更快地描繪

  bounds是一個 BoundingSphere 類的全局實例他用來指定環境節點對燈光背景和OrbitBehavior 對象的影響跳躍的球體被放在場景的中心被賦 BOUNDSIZE 單位半徑並影響場景中所有事件

  最後的 WrapCheckersD( ) 所顯示的場景圖象在圖Floor Branch 節點是我發明出來掩藏一些細節稍後將會涉及所缺少的是場景圖形的分支部分

  場景燈光

  通過 lightScene( )把一個環境燈光兩個有向燈光加入到場景中環境燈光能到達場景中的每個角落並且強度相同

  Colorf white = new Colorf(f f f);
    // Set up the ambient light
    AmbientLight ambientLightNode = new AmbientLight(white);
    ambientLightNodesetInfluencingBounds(bounds);
    sceneBGaddChild(ambientLightNode);

  代碼設置了燈光的顏色環境燈光以bounds配置建立並加入到場景中類 Colorf( ) 的構造函數設置RGB顏色為f到f(f是全色)

  有向燈光模擬的一個從原處照射來的一束燈光並從特定方向碰上物體表面有向燈光和環境燈光的區別是有向燈光必須是方向向量

  Vectorf lightDirection  = new Vectorf(f f f);
       // left down backwards
    DirectionalLight light =  new DirectionalLight(white lightDirection);
    lightsetInfluencingBounds(bounds);
    sceneBGaddChild(light);


  


Figure Partial scene graph for CheckersD

  方向是介於()和()的向量燈光可以想象成是很多從不同方向不同來源的平行燈光匯聚而成點光和場光是Java D燈光的另外一種形式點光放置在空間中並向所有方向發射場光以特定方向朝點光聚焦

  場景的背景

  場景的背景可以指定為特定的背景(如下所示)一個靜態圖像或這是一個帶形體的幾何材質

    Background back = new Background( );
    backsetApplicationBounds( bounds );
    backsetColor(f f f);    // sky color
    sceneBGaddChild( back );

  浮動的球體

  Sphere 是來自Java D的 comsunjdutilsgeometry 包的一個工具類是Primitive 類的一個子類Primitive 類為帶有 ShapeD 孩子節點的一個 Group 節點他的幾何特性存儲在Java D的 TriangleStripArray這種類把球體看成一組可連接的三角形體我沒必要校准他的幾何特性但是他的現實和位置要改變

  Appearance 節點是一個包含很多信息的容器包含顏色線條多邊形描繪透明度和材質特性ColouringAttributes 確定形體的顏色而且不受場景燈光影響如果一個形體需要顏色和燈光的交互作用就要用到 Material 組件燈光要影響形體的顏色必須滿足三種情況
  &#;        形體的幾何特性必須是標准的
  &#;        形體的 Appearance 節點必須擁有 Material 組件
  &#;        Material 必須用 setLightingEnable( )打開他的光照允許

  用工具類 Sphere 能自動制作成標准形體所以第一種情況容易滿足

  形體顏色

  Java D Material 組件控制當一個形體被不同種類的燈光照射後的顏色

  Material mat = new Material(ambientColor emissiveColor
                                diffuseColor specularColor shininess);

  環境顏色參數指定當形體被環境燈光照射後的顏色他給對象統一的顏色放射性顏色貢獻形體生成的顏色這個參數經常被設置成黑色(相當於關閉)當照射的時候發散顏色就是對象的顏色他的強度取決於光波照射到形體的角度

  提示發散燈光和環境燈光通常被設置成相同這與真實世界中的對象被照射時候的顏色一樣

  鏡子顏色參數的強度與從形體的光亮區域反射出的多少有關他由控制reflective highlight尺寸的發光參數組合成

  提示鏡子顏色通常設置成白色符合真實世界中大部分對象產生的顏色

  CheckersD類中有兩個不同方向的光他們在球體頂部建立了兩個不同的光路(如圖地板在他們的顏色未在形體的幾何特性中設置前是沒有被照射到的

  floatingSphere( ) 中處理形體現實的代碼如下

  Colorf black = new Colorf(f f f);
    Colorf blue = new Colorf(f f f);
    Colorf specular = new Colorf(f f f); // near white

    Material blueMat= new Material(blue black blue specular f);
    blueMatsetLightingEnable(true);

    Appearance blueApp = new Appearance( );
    blueAppsetMaterial(blueMat);

  布置形體

  形體放置一般是在TransformGroup 下放置圖形節點(參見圖 sphere Group)一個 TransformGroup 用來放置旋轉和度量旗下節點他由Java D TransformD 對象定義其格式

  TransformD td = new TransformD( );
    tdset( new Vectorf());     // place at ()
    TransformGroup tg = new TransformGroup(td);
    tgaddChild(new Sphere(f blueApp));
           // set the spheres radius and appearance
           // and its normals by default
    sceneBGaddChild(tg);


  set( ) 方法將形體的中心放置在()重置先前的旋轉和度量在重置其他格式的時候set( ) 能用來改變度量和角度方法setTranslation( ) setScale( )和setRotation( ) 只能對已給格式起作用

  與其他D畫圖程序包不同的是Java D中的Y軸是垂直方向而水平面由xoz決定如圖球體的位置被設置為()在XOZ面中心上方個單位

  

  圖Java D中的坐標系

  完請等待Part


From:http://tw.wingwit.com/Article/program/Java/hx/201311/25930.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.