首頁  >  文章  >  web前端  >  如何開發優秀的HTML5遊戲-迪士尼《尋找奧茲之路》遊戲技術詳解(二)

如何開發優秀的HTML5遊戲-迪士尼《尋找奧茲之路》遊戲技術詳解(二)

黄舟
黄舟原創
2017-03-09 16:22:161668瀏覽

        (接上圖)桌上遊戲通常創建於一個核心的實體引擎。因此,要在3D世界中模擬一個柔軟的物體,需要一個完整的實體模擬器,並且建立一個可信的行為。

        WebGL和JavaScript還不能奢華到可以運作一個完全成熟的實體模擬器。因此,在這個遊戲中我們必須找到一種方式來創造風的效果。

        我們在3D模型中為每個物件嵌入「風敏度」的資訊。 3D模型的每個頂點都有一個“風屬性”,指定頂點應該受到風速多大程度的影響。所以,這指定了3D物體的風敏度。然後,我們需要創建“風”本身。

        我們透過建立包含Perlin雜訊的影像來實現。此圖片意在覆蓋一塊確定區域的風。所以,一個考慮它的好方法是,想像3D場景中一個特定矩形區域中像噪音一樣覆蓋一個畫面的雲。這張圖片每個像素的灰階值指定在一個特定的時刻3D區域中風力有多強。

        為了創造風的效果,影像以恆定的速率和特定的方向即風的方向移動。並且為了確保「風的區域」不會影響場景中的任何內容,我們將風的影像環繞邊界,限制在效果的區域內。

        一個風的簡單3D教學

        現在,讓我們透過Three.js在簡單的3D場景創造一個風的效果。

        我們將在一個簡單的「程序草」中創造風。

        首先,讓我們先建立場景。我們將有一個簡單的、質感平坦的地面。然後每一根草將簡單地用倒立的圓錐體展現。

如何開發優秀的HTML5遊戲-迪士尼《尋找奧茲之路》遊戲技術詳解(二)

佈滿小草的地面

        下方是如何在Thress.js中用CoffeeScript創造這個簡單的場景。

        首先我們要設定Three.js,並把它與相機、滑鼠,以及一些燈光結合在一起:

<br>
constructor: ->

   @clock =  new THREE.Clock()

   @container = document.createElement( &#39;p&#39; );
   document.body.appendChild( @container );

   @renderer = new THREE.WebGLRenderer();
   @renderer.setSize( window.innerWidth, window.innerHeight );
   @renderer.setClearColorHex( 0x808080, 1 )
   @container.appendChild(@renderer.domElement);

   @camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 5000 );
   @camera.position.x = 5;
   @camera.position.y = 10;
   @camera.position.z = 40;

   @controls = new THREE.OrbitControls( @camera, @renderer.domElement );
   @controls.enabled = true

   @scene = new THREE.Scene();
   @scene.add( new THREE.AmbientLight 0xFFFFFF )

   directional = new THREE.DirectionalLight 0xFFFFFF
   directional.position.set( 10,10,10)
   @scene.add( directional )

   # Demo data
   @grassTex = THREE.ImageUtils.loadTexture("textures/grass.png");
   @initGrass()
   @initTerrain()

   # Stats
   @stats = new Stats();
   @stats.domElement.style.position = &#39;absolute&#39;;
   @stats.domElement.style.top = &#39;0px&#39;;
   @container.appendChild( @stats.domElement );
   window.addEventListener( &#39;resize&#39;, @onWindowResize, false );
   @animate()

        initGrass和initTerrain函數呼叫分別以小草和地面函數呼叫場景:

<br>
initGrass:->
   mat = new THREE.MeshPhongMaterial( { map: @grassTex } )
   NUM = 15
   for i in [0..NUM] by 1
       for j in [0..NUM] by 1
           x = ((i/NUM) - 0.5) * 50 + THREE.Math.randFloat(-1,1)
           y = ((j/NUM) - 0.5) * 50 + THREE.Math.randFloat(-1,1)
           @scene.add( @instanceGrass( x, 2.5, y, 5.0, mat ) )

instanceGrass:(x,y,z,height,mat)->
   geometry = new THREE.CylinderGeometry( 0.9, 0.0, height, 3, 5 )
   mesh = new THREE.Mesh( geometry, mat )
   mesh.position.set( x, y, z )
   return mesh

        在此我們創造了一個格子,由15*15的小草組成。我們添加了一個隨機數字到每根小草的位置,讓它們不會因為排列的太整齊而有些古怪。

        此地形只是水平面,放置在這些小草的根部(Y = 2.5)。

<br>
initTerrain:->
  @plane = new THREE.Mesh( new THREE.PlaneGeometry(60, 60, 2, 2), new THREE.MeshPhongMaterial({ map: @grassTex }))
  @plane.rotation.x = -Math.PI/2
  @scene.add( @plane )

        所以到目前為止,我們所做的只是簡單地創建了一個Three.js場景,並且添加了一些小草,由程式生成的倒立圓錐創建,以及一個簡單的地面。

        目前沒有特別之處。

<br>

        現在是增加風的時候了。第一件事,我們希望把風敏度資訊嵌入到草的3D模型中。

        我們將這些資訊以自訂屬性嵌入到小草3D模型的每個頂點。我們將要使用的規則是:每個小草模型的底部(圓錐體的頂)所具有的風敏度為0,因為它貼在地面上。小草模型(圓錐體的底部)的頂部具有最大的風敏度,因為它遠離地面。

        下方是如何重寫instanceGrass函數來為小草的3D模型增加風敏度作為自訂參數。

<br>

instanceGrass:(x,y,z,height)->

  geometry = new THREE.CylinderGeometry( 0.9, 0.0, height, 3, 5 )

  for i in [0..geometry.vertices.length-1] by 1
      v = geometry.vertices[i]
      r = (v.y / height) + 0.5
      @windMaterial.attributes.windFactor.value[i] = r * r * r

  # Create mesh
  mesh = new THREE.Mesh( geometry, @windMaterial )
  mesh.position.set( x, y, z )
  return mesh

<br>

#

以上是如何開發優秀的HTML5遊戲-迪士尼《尋找奧茲之路》遊戲技術詳解(二)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn