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/


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


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

2 件のコメント:

  1. Thank for sharing!!!
    AliExpress.com là một trong những website thương mại điện tử hàng đầu của Trung Quốc, là một trong những trang web chủ lực của tập đoàn alibaba. Một điều mà bạn cần đặc biệt quan tâm đó là Aliexpress là trang thương mại điện tử chỉ bán hàng cho người nước ngoài mua hàng mà không bán trong nội địa trung quốc.
    Nhiều người nghĩ rằng Taobao và Tmall là như nhau, nhưng nó không phải là hoàn toàn đúng. Bài viết này là giúp bạn hiểu sự khác nhau giữa Taobao và Tmall, và chọn nền tảng kinh doanh tốt nhất cho việc mua sắm của bạn thông qua Taobao Focus.
    Để nhập được nguồn hàng giá rẻ thì 1688.com (hay taobao.com) là lựa chọn hàng đầu đối với những chủ cửa hàng/doanh nghiệp muốn nhập hàng Trung Quốc. 1688 chính là Alibaba.com phiên bản Tiếng Trung dành riêng cho thị trường nội địa Trung Quốc và 1688 cũng trực thuộc của tập đoàn Alibaba. Mặc dù đều là mô hình bán buôn B2B (doanh nghiệp với doanh nghiệp) nhưng hàng trên 1688 lúc nào cũng rẻ hơn rất nhiều so với Alibaba.com và cũng không quá khắt khe về yêu cầu nhập số lượng tối thiểu như Alibaba.com (bán cho khách hàng trong nước sẽ không chặt chém nhiều như khách nước ngoài, giống Việt Nam mình).
    Đối với việc mở một cửa hàng trên Tmall là trang gì, các thực thể pháp lý cần phải cung cấp tất cả các tài liệu thích hợp để xác nhận độ tin cậy, xác thực và thực tế thực sự của sự tồn tại của tổ chức, công ty, nhà sản xuất hoặc thương hiệu. Cách tiếp cận này giúp loại bỏ các nguy cơ mà một người bán vô đạo đức với các sản phẩm có chất lượng đáng ngờ sẽ được giao dịch trên Tmall.

    返信削除
  2. It's easy to learn it when you are in college. You can read it and understand all the preferences of this time.

    返信削除