アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

Monacaを使ってスマートフォンをゲームコントローラーにする方法

こんにちは。今回はKruyが書いた英語版アシアルブログの翻訳記事をお届けします。
原文はこちら

==============================

先日、Monacaで2つのおもしろいプラグインがリリースされました。HttpServerとWebSocketServerプラグインです。

チャットアプリ、マルチプレイヤーゲーム、ゲームコントローラーなどアイデア次第でおもしろいアプリが作れます。今回は、シンプルなゲームコントローラーを作りたいと思いますが、その前に2つのプラグインについて簡単に紹介します。


■HttpServer プラグイン
このプラグインを使うと、スマートフォンをウェブサーバー化することができます。モバイルウェブサーバーです!有効にすると、どんなブラウザーからでもウェブサーバー化したスマートフォンのIPとポートを指定してアクセスできるようになり、プロジェクトフォルダ内のコンテンツを公開することができます。今回はこのプラグインを使ってhtml5のゲームを公開します。


■WebSocketServer プラグイン
このプラグインを使うと、スマートフォンをウェブソケットサーバー化することができます。これでサーバー、クライアント間でリアルタイム通信することができます。今回はこのプラグインを使ってスマートフォンから、そこに接続しているクライアントにデータを送ります。


■注意点
・WebServer プラグインは、今のところAndroidでしか動きません。
・今回紹介するコードを実行するには、プラットフォームとしてMonacaが必要です。Monacaはハイブリッドアプリ開発のためのプラットフォームで、monaca.mobiにアクセスして登録すればすぐに使い始めることができますので、是非お試し下さい。


■サンプルゲームについて
ゲームコントローラーを作るということで、ゲームを用意する必要があります。
今回はpixi.jpからシンプルなデモを選びました。スクリーンをクリックすると歩いている男の子がジャンプするという、シンプルなゲームです。デモはこちらソースコードこちらで見られます。このジャンプする男の子をコントロールするゲームコントローラーを作ります。下の図からわかるように、ユーザーが「Jump!」ボタンを押すと男の子がジャンプします!シンプルですが、今回のコンセプトを紹介するのには十分です。

■システム概要


■プロジェクト構成
クライアント用とサーバー用のコードを扱う必要がありますので、2つを分離する方がきれいです。ここでは、クライアント用のコードは全て「client」フォルダーに入れています。HttpServerプラグインに、このフォルダーからファイルを提供するようにリクエストします。


■クライアント側
ゲームのコードを「client」フォルダーに配置します。今回は自分のPCからファイルを転送するのにWebDavスクリーンショットの下方に注目)を使っています。WebDavを使うと、たくさんのファイルを速く簡単に転送することができます。

「client/index.html」を開くと、2つのスクリプトタグが存在しないフォルダーを指していることがわかります。「pixi」フォルダーを「../../src」から「client」フォルダーにコピーします。それから、2つのスクリプトタグを以下のように直します。


■サーバー側
・WebServer プラグインの有効化
最初に、WebServerプラグインを有効にします。「Config」をクリックして「Plugin Settings...」を選びます。


次に、「Monaca Http and WebSocket Server」プラグインにチェックが入っていることを確認します。


・HttpServer
それでは、HttpServerのコードを見ていきましょう。以下のコードを「www/index.html」に設置します。

アプリケーションを動かします。うまくいけば、アラートダイアログでサーバーのIPアドレスとポート番号が表示されます。


これで、サーバーがうまく動いていることが確認できました。ブラウザーからこのスマートフォンIPアドレスとポート番号を指定してアクセスします。


サーバーが動いています!ここまでのところは順調ですが、次に進んで収集がつかなくなる前に、コード構成をまとめましょう。アプリケーション用にAppネームスペースを作って、他のアプリケーションモジュールを付けられるようにします。ファイル名はapp.jsにします。


HttpServer関連のコードはhttp_server.jsに移動します。


・WebSocketサーバー
WebSocketに関するサーバー側のコードをwebsocket_server.jsに配置します。


・WebSocket クライアント
サーバーコマンドを待ち受けるクライアントが必要です。その部分のコードは、「onmessage」イベントを待ち受けます。このコードは「client/websocket_client.js」に配置します。



■完成したコード
完成したコードはgithub上のプロジェクトに設置しました。自由にダウンロードして動かしてみて下さい!
https://github.com/kruyvanna/Monaca-Game-Controller


■まとめ
今回は、MonacaのWebServerプラグインを使うとゲームコントローラーアプリケーションが簡単に作れることを紹介しました。あなたが思い描くおもしろいアプリを作るのに、この記事を役立てていただけたら幸いです。

How to Turn Your Phone Into a Simple Game Controller using Monaca

Monaca have just released two new exciting plugins--HttpServer and WebScoketServer plugins. This will open a lots of possibilities. Think of chat application, multi-player game, game controller, the limitation is your imagination. Here we will create a simple game controller, but before that, let me give a brief introduction to the two plugins.

HttpServer Plugin


With this plugin, you can turn your phone into a web server. Yes! It’s a mobile web server! When turned on, you can point any browser to your phone’s ip address and port, and have your phone serve the content of any folder in your project. We will use this plugin to serve our html5 game.

WebSocketServer Plugin


With this plugin, you can turn your phone into a websocket server. This will enable real-time communication between server and clients. We will use this plugin to send data from the phone to any connected clients.

Notice



  • The WebServer plugin currently only work with Android.

  • The code need to be run on Monaca platform. It is easy to get started with Monaca. Just sign-up at monaca.mobi and you are good to go.



The Game


To create a game controller, obviously we need a game to control.
I have chosen a simple demo from pixi.js. It is a simple game of a walking boy who will jump when you click on the screen. You can find the demo here and the source code here. We will make a game controller that will control the jumping of the boy. As can be seen on the figure below, when a user click the “Jump!” button, the boy will jump! It is simple but is good enough to illustrate the concept.

System Overview




The Project Structure


Since we are dealing with client and server codes, it is more cleaner to separate the two. Here I put all the client code inside “client” folder. We will tell the HttpServer plugin to serve files from this folder.

The rest of the folders are codes that run on the phone.


The Client


We will put the game code in the client folder. I use WebDav(see bottom part of the screenshot) to transfer files from my machine to the IDE. It is a fast and easy way to transfer lots of file to the IDE.


If you open “client/index.html”, you will see that there are two script tags that point to a missing folder. You need to copy the “pixi” folder from “../../src” folder to the “client” folder. Then modify the two script tags as shown below.


The Server


Enable WebServer Plugin


First we need to enable the plugin. Click on “Config” and select “Plugin Settings...”.


Then make sure to check the "Monaca Http and WebSocket Server" plugin.


HttpServer


Now let’s start the HttpServer with the following code. Put the code in “www/index.html”


Run the application. If nothing goes wrong, you will see this alert message which show that the server ip address and port.


Now the server has started successfully. You can point any browser to this phone ip address and port.


Hooray!! The server is working! So far so good but before we go on, we need to manage our code structure before it grows out of control. Let’s create an App namespace for your application so that other application module can attach to it. We will name it app.js


We will also move our HttpServer related code into http_server.js


WebSocket Server


We will put our WebSocket related server code in websocket_server.js


WebSocket Client


We need the client to listen to the server command. The code to focus on is "onmessage" event. We will put the code in “client/websocket_client.js”


Complete Code


I put the complete code of the project on github. Feel free to give it a spin!
https://github.com/kruyvanna/Monaca-Game-Controller

Conclusion


We have seen how easy it is to leverage WebServer plugin of Monaca to create a Game Controller application. I hope this will help you create awesome app of your dream.

はじめての共同作業 Canvas編 (node.js + websocket)

こんにちは、中川です。
先月無事に結婚をした開発者が一名おり、近年アシアルでは徐々に既婚者が増えてきている状況です。
ということで、結婚といえば共同作業ですよね。

今までは、一人で作業していて大変なことが色々あったと思いますが、
二人(複数)でやれば、乗り越えられることもあることでしょう。
Webアプリでも最近は、より共同作業がしやすい環境ができつつあるように思います。

そこで、今回はWebSocketを使ったリアルタイム通信でのやり取りを行い、
一緒にお絵描きができるサンプルアプリを作ってみました。



■■■概要■■■
・アプリ概要
・・Canvas + WebSocket

・対応ブラウザ
・・Chrome or Safari (他、WebSocketが使えるブラウザ)

・サーバ側プログラム
・・node.js 0.2.0
・・express@1.0.0rc2
・・websocket-server@1.3.50

※express, websocket-server は node.js のパッケージ管理システムの npm ( http://github.com/isaacs/npm ) でインストールしました。

node.js用のwebsocketサーバは何個かあるみたいですが
( 参照: http://github.com/ry/node/wiki/modules )、
今回は、比較的更新もされていて、手軽に利用できそうな node-websocket-server を使ってみました。


■■■アプリ構成■■■


.
`-- canvas-share
    |-- public
    |   |-- index.html
    |   `-- js
    |       `-- client.js
    `-- server.js


プログラム一式ダウンロード:canvas-share.tar.gz

■■■プログラム内容■■■

・index.html


<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8"> 
  <title>Canvas Share Demo</title>
</head>
<body>
  <canvas id="layer0" class="canvas" style="position: absolute; top: 0; left: 0; border: 10px solid #dddddd;" width="900px" height="600px"></canvas>
  <input type="button" id="clear" value="Clear" style="position:absolute;" />

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="/js/client.js?t=1149"></script>
<script type="text/javascript">
$(function(){

  var painter = new Painter('layer0');
  
  // WebSocket対応の場合は、コネクションを設定
  if (window["WebSocket"]) {
    var conn = new WebSocket("ws://" + document.location.host + "/");
    painter.setConnection(conn);
  } else {
    alert('This browser is not supported.');
  }
  
  $('#clear').click(function() {
    painter.clear();
  });
  
});
</script>
</body>
</html>


・js/client.js
※通信部分関連のみ抜粋



 /**
  * マウス移動時の処理
  */
 Painter.prototype.move = function(event) {
   if (!this.isDrawing) {
     return;
   }

   var points = {
     bx: this.beforeX,
     by: this.beforeY,
     ax: event.clientX - 10,
     ay: event.clientY - 10,
     c: this.strokeStyle
   };

   if (this.conn) {
     // 各座標をjson形式でサーバに通知
     this.conn.send(JSON.stringify(points));
   } else {
     this.drawLine(points);
   }

   this.beforeX = points.ax;
   this.beforeY = points.ay;
 };

 /**
  * キャンバスのクリア処理
  */
 Painter.prototype.clear = function(conn) {
   if (this.conn) {
     // CLEAR処理をサーバに通知
     this.conn.send('@CLEAR');
   } else {
     this.clearCanvas();
   }
 };

 /**
  * WebSocketのコネクション設定
  */
 Painter.prototype.setConnection = function(conn) {
   this.conn = conn;

   this.conn.onclose = function() {console.log('Close');};
   this.conn.onopen = function(){console.log('Connected');}

   var self = this;
   //メッセージ受信時の処理(クリアと描画)
   this.conn.onmessage = function(event) {
     if (event.data.indexOf('@') > -1) {
       if (event.data.indexOf('@CLEAR') > -1) {
         self.clearCanvas();
       }
     } else {
       var d = JSON.parse(event.data);
       self.drawLine(d);
     }
   };

 };


WebSocketが有効な場合は、マウスの移動座標と色をサーバに通知するようにし、また、受信したJSONデータからCanvasへの描画処理を行います。


・server.js


var sys = require("sys"),
    ws  = require('websocket-server');

/**
 * web-server
 */
var express = require('express');
var app = express.createServer();
app.configure(function(){
  // ファイルをそのまま出力するディレクトリの設定
  app.use(express.staticProvider(__dirname + '/public'));
});

/**
 * websocket-server
 */
//var json = JSON.stringify;
var server = ws.createServer({server: app});
var points = [];

server.addListener("listening", function(){
  sys.log("Listening for connections.");
});

server.addListener("connection", function(conn){

  sys.log('Hello');
  //server.broadcast("@HELLO");

  // 全てのログを初回接続時に送信
  if (points.length > 0) {
    for(var i in points) {
      conn.send(points[i]);
    } 
  }

  // メッセージ受信処理
  conn.addListener("message", function(message){
      if (message.indexOf('@') > -1) {
        points = [];
        server.broadcast(message);
      } else {
        points.push(message);
        server.broadcast(message);
      }
  });

});

server.addListener("close", function(conn){
  //server.broadcast("@BYE");
});

server.listen(3333);


expressは、単純に静的ファイル(html,js)を出力しているだけですので、今回は特に必要性はありませんが、プログラム記述の楽がしたかっただけです。

WebSocketサーバ側の処理では、投げられたjson文字列データをログ配列に保持し、そのまま broadcast で接続中のクライアントに返すようにしています。


■■■動作確認■■■

サーバを起動します。


$ cd canvas-share/
$ node server.js


あとは、対応ブラウザを複数ウィンドウ立ち上げて、それぞれ
http: //example.com:3333/ にアクセスすれば動作します。



■■■最後に■■■

今回の実装はかなりやっつけな部分もありますがご容赦いただければと思います。

現行のIEFirefoxなど主要ブラウザがまだWebSocketに対応していませんが、socket.io などのライブラリもあるようですので、対応させることもできそうです。

node.jsを利用すれば、phpでは難しい大量の同時接続をさばくこともできますので、このようなリアルタイムコラボレーション系のWebアプリも簡単につくることができそうですね。
今後も色々と試していきたいと思います。