2012年10月7日日曜日

150行でここまでできる!Three.jsによる3Dタイピングゲーム

このエントリーをはてなブックマークに追加

はじめに

エンジニアの@ryooo321です。
よろしくお願いします。

2012/10/4に@ITにThree.jsの入門記事があがりました。
これがとってもわかりやすかったこともあり、私もThree.jsで投稿することにしました。
多彩な表現力のWebGLを扱いやすくする「Three.js」
今回は上の記事で取り上げられていなかった3Dフォントを中心に紹介したいと思います。

Happy Elements株式会社では勉強会が活発に行われており、
その中の1つに「1.5時間で○○を作る」エンジニア向けワークショップがあります。(毎週開催@京都)
※ ○○は毎週かわり、設計/実装方法などは自由です。

今回はワークショップのお題「もぐらたたき」で作成した「もぐらたたき改め3Dタイピング練習ゲーム」を紹介します。
(お題を改めてしまいましたが、インスピレーション次第なんで比較的自由です)
※ 関連:WebGL(by Three.js)、coffeescript

目次

1. 3Dタイピング練習ゲーム
2. 3DフォントでHello World
3. 所感
4. 関連情報


1. 3Dタイピング練習ゲーム

紹介

文字が水面の上に飛び出してくるので、飛び出した文字をタイプするゲームです。
下記程度のアウトプットを、150行程度のコーディングで可能でした。
※ タイプされた文字は赤くなります。
※ マウスで画面をドラッグすると、カメラのアングルが変わります。
※ 見切れてしまっていますが、一番上にスコア(タイプ数)が表示されます。

ソース

簡単な説明(ゲームの実装部分は省略)

カメラ
# PerspectiveCamera以外にOrthographicCameraがあります。
# 引数: 視野角(垂直)、描画範囲の縦横比、カメラから一番近い描画点、カメラから一番離れた描画点
@camera = new THREE.PerspectiveCamera(40, document.width / document.height, 1, 10000)
# カメラの位置
@camera.position.y = 300
@camera.position.z = 1000

レンダラー(sceneの描画を行うためのオブジェクト)
# WebGLRenderer以外にCanvasRenderもあります。
# 引数のオプションは下記を参照
# https://github.com/mrdoob/three.js/wiki/WebGLRenderer
@renderer = new THREE.WebGLRenderer({antialias: true})
@renderer.setSize(document.width, document.height)
@renderer.setClearColor(@scene.fog.color, 1)

# htmlのbodyにcanvasタグを差し込んでいる処理
document.body.appendChild(@renderer.domElement)

光源とコントローラー
# 環境光
# 光源はデフォルトのレンダラーでは4つまでしか配置できません。
light = new THREE.DirectionalLight(0xFFFFFF)
light.position = {x:100, y:1000, z:1000}
@scene.add(light)
# スポットライト
@pointLight = new THREE.PointLight(0xffffff, 1.5)
@pointLight.position.set(0, 100, 90)
@pointLight.color.setHSV(Math.random(), 0.95, 0.85)
@scene.add(@pointLight)

# マウスでカメラ操作するためのコントローラー
# カメラ位置を再計算するために、一定時間ごとに@control.update()が必要
@control = new THREE.TrackballControls(@camera, @renderer.domElement)


# meshに形状の情報(Geometry)と材質の情報(Material)を渡します。
plane = new THREE.Mesh(
  new THREE.PlaneGeometry(10000, 10000),
  new THREE.MeshBasicMaterial({
    color: 0xffffff,
    opacity: 0.8,
    transparent: true
  })
)
# 位置や角度を指定
plane.position.y = 100
plane.rotation.x = - Math.PI / 2
# meshをsceneに追加
@scene.add(plane)

描画
# Stageクラスにrenderを実装
render: ->
  # コントローラー、tween、レンダラーの再描画
  @control.update()
  TWEEN.update()
  @renderer.render(@scene, @camera)

〜〜略〜〜
@stage = new Stage()
@addEventListener "DOMContentLoaded", ->
  # 上述のrender()を100msごとに実行
  @stage.render()
  ((stage) ->
    setInterval ->
      stage.render()
    , 100
  ) @stage

2. 3DフォントでHello World

ソース

簡単な説明

htmlで下記ファイルを読み込んで、js(coffeescriptで書いています)で下記のようにすることで、A-Zの3Dフォントが配置ができます。


# 3D文字を作成
textGeo = new THREE.TextGeometry('Hello World!', {
  size: 70,
  height: 20,
  curveSegments: 4,
  font: "optimer",
  weight: "bold",
  style: "normal",
  material: 0,
  extrudeMaterial: 1
})

# 文字の質感を設定
textMaterialFront = new THREE.MeshBasicMaterial({
  color: 0x66ff66,
  opacity: 1,
})
textMaterialSide = new THREE.MeshBasicMaterial({
  color: 0x00aa00,
})
textGeo.materials = [textMaterialFront, textMaterialSide]

# メッシュオブジェクトを作成
mesh = new THREE.Mesh(textGeo, new THREE.MeshFaceMaterial())
mesh.position = {x: 0, y: 0, z: 0}
mesh.rotation.x = 0
mesh.rotation.y = Math.PI * 2
scene.add(mesh)


3. 所感

[3Dの世界を簡単に表現できる]
カメラやレンダラーや光と陰、鏡面反射などの3D表現は本当に簡単にできます。
(ドラッグで動くカメラが2行で実装できるなど。)
一方で、プロパティの変化によってどのように表示が変わるのかイメージしづらく、修正と表示を繰り返して慣れるまでは時間がかかりました。
(カメラ位置や光の具合など)
[WebGLの時代はまだ先か]
主要ブラウザでもデフォルト無効であったり、IEに至っては未対応です。
※ ChromeやFireFoxでは対応されています。

Android、iPhoneも現時点で基本的に未対応です。
※ Androidでは端末によっては動く場合もあるようです。
※ iPhoneでは4.2以降のiAdやUIWebViewで対応されているようです(デフォルト無効)。
ソニーエリクソンがAndroidをWebGL対応させるソースを公開していたり、iPhoneでも機能制限されているだけの状態ですので、
GPUの発達や今後の流れ次第で対応されるのを期待しています。

Three.jsにはCanvasRendererというレンダラーがあり、WebGLを使わず3Dゲームを表示することもできます。
※ マテリアルなど一部使えない機能があるとのことです。
※ CanvasRendererを使えばiPhoneでも動くのですが、だいぶ重いので小さめのキャンバスにするなど工夫が必要です。
[安定のcoffeescript]
coffeescriptを使うことでクラス化やリファクタリングが楽になり、
単純にタイピング量も減りました。


4. 関連情報


・Three.jsサンプル集
http://mrdoob.github.com/three.js/

・Github
mrdoob / three.js

・coffeescript
http://coffeescript.org/


一緒に働きたい方、絶賛 募集中
京都で開発してみたいというエンジニアの皆さん、ご応募お待ちしています!
技術力を伸ばしたい学生さん、アルバイトも可能なのでご応募お待ちしています!
大阪、滋賀、神戸から通勤実績あり


以上、長文にお付き合い下さいましてありがとうございました。

0 件のコメント:

コメントを投稿