リアルタイム対戦のできるFPSですよ。
Milkcocoaはリアルタイム通信可能なバックエンドを提供してくれるサービスです。今回はMilkcocoaでオンライン対戦のできるシューティングゲームを作った話を書きます。
なりゆき
これがわずか3時間20分でできました。
ずいぶん前の話ですが、9月24日にjThreeの開発者に初めてお会いし、一緒に夕飯を食べ、3Dコンテンツの未来についてアツく話し合いました。12時付近に帰宅、jThreeとmilkcocoaを組み合わせた、いい感じのゲームを作ろうと思い立ち、日をまたいで3時20分に完成しました。次の日になってから、いつもお世話になっているデザイナーさんが、デザインを調整してくれました。こんな簡単に3Dゲームが作れる、jThreeに感動です!
jThreeとmilkcocoaのすばらしさを少しだけご紹介します。
やったこと
jThreeは光源やカメラの位置をタグで記述することができます。
<goml>
<head>いろいろ</head>
<body>
<scene>
<obj style="rotateY: 1.57; position: 15 -35 -72;">
<mesh geo="#sky" mtl="#sky-mtl" />
<mesh geo="[type='Circle']" mtl="#ground-mtl" style="positionY: -.5; rotateX: -1.57;" />
</obj>
<light type="Amb" style="light-color: #f0f0f0;" />
<light type="Dir" style="light-color: #5a5a5a; position: 1 1 1;" />
<light type="Dir" style="light-color: #5a5a5a; position: -1 1 1;" />
<camera style="position: 0 15 40; lookAtY: 15;"/>
</scene>
<body>
</goml>
そしてjQueryのように、簡単に3Dモデルを操れます。
j3("scene").append('<obj id="objid" style="rotateY: 1.57; position: 15 0 0;"><mesh geo="#geoid" mtl="#mtlid" /></obj>');
j3("#objid").css("position", [ 0, 0, 0 ]);
milkcocoaのsend関数で、プレイヤーの位置や弾の発射を同期しています。以下は弾の発射を同期しているイメージです。弾を撃つshoot関数では、send関数を利用してデータの送信を行っています。自分も含めた複数のクライアントが、それを受け取り描画を開始します。send関数でのデータの送信から他のクライアントが受け取るまでの間隔は、平均して20ms〜30msでした。
var ds_bullet = milkcocoa.dataStore("bullet");
ds_bullet.on("send", function(e) {
draw_shooting(e.value.bullet_id, e.value.pos, e.value.vec);
});
function draw_shooting(id, pos, direction) {
//弾を描画する処理
}
function shoot() {
ds_bullet.send({
bullet_id : "unique id",//id
pos : {}//位置
vec : {}//方向
});
}
Playerの移動はちょっと難しかったです。send関数でPlayerが移動する度に位置を同期すると、1秒間に何十リクエストという通信をしてしまい、結果的に遅延が発生してしまいます。そこで1秒ごとに位置の同期を行い、前の動きから次の動きを予想するようにしています。
ソースコードはこちらです。
ぜひ触ってみてください!
まとめ
こんな簡単にオンラインゲームが作れる点は、感動ものです。
*追記
こんなのも作りました。
マルチプレイゲームライブラリ:https://github.com/milk-cocoa/multiplay-game-with-milkcocoa