enchant.jsで動くゲームを作ってみた

恒例の年末プログラミング。今年はenchant.jsを使ったゲームを書いてみた。

BUBBLE BURST

7年前に作ったゲームの移植。
enchant.jsを使うのは初めてだったのだけれども、簡単に絵が出るのでほとんど時間をかけずに作ることができた。メモリ周りがちょっと不安だけれども。

オリジナル版のソースを紛失したので、パラメータを新たに設定しなおしているのだけれども、結構挙動が違ってる。”大きい泡に対して効果が薄いので小さい泡を狙うべし。”なんかは今回実装してない。”(たまに左右、下から強襲してくる)”コレどうやって実装したんだっけ、、、

WiiU用プラグインがリリースされていたので組み込んでみたけど、うまく動いていない。一応、WiiUで操作する場合は、左スティックで移動、Yでダッシュ、Bで謎の波動。

twigadge ver2.0 beta2

先日OAuth対応版をリリースしましたが、もうひとつ大きな機能追加を入れましたのでbeta2としてリリースします。
追加した機能ですが、上のスクリーンショットのとおり、黒い外観に変更できるようになりました。
また、リツイート(公式RT)機能に対応しています。

変更点:

  • スキン機能追加(あわせて黒系スキン追加)
  • リツイート(公式RT)機能追加
  • バグ修正

ダウンロードページ
利用方法

もう少し様子を見て、問題なければ正式リリースしたいと思います。

TwitterクライアントのOAuth対応(Javascript編)

6月にBasic認証が廃止されるということで、twitterクライアントのOAuth対応が必須となっています。twigadgeの方でもversion2.xとして対応しているわけですが、いろいろ資料を探してもJavascriptでの実装例をあまり見かけなかったので、メモとして残しておきます。
基本的な流れはTwitter API を OAuth で認証するスクリプトを 0 から書いてみたの通りなので、ここではコードの解説を主に書いていきます。

使用ライブラリ

Google CodeのOAuthライブラリ
# javascriptのものはSource->Browse以下に置いてあります。

JQuery
# ここで使っているのはAjax送信部分だけです。

認証手順

  1. Twitterでアプリケーション申請をして、Consumer Key/Consumer Secretを発行してもらう (ここでは省略)
  2. Request Token/Request Token Secretを取得する
  3. ユーザをTwitterに誘導してPINを取得してもらう
  4. Request Token/Request Token SecretとPINを元にAccess Token/Access Token Sceretを取得する
  5. Access Token/Access Token Secretを元にAPIにアクセスする

Request Token/Request Token Secretを取得する

まず、http://twitter.com/oauth/request_tokenにConsumer Keyを送ります。
他のパラメータとして、oauth_signature_methodはHMAC-SHA1、時刻とNonceはOAuth.setTimestampAndNonceで設定しています。パラメータを設定後、OAuth.SignatureMethod.signでConsumer Secretを使って署名を加えた後、OAuth.addToURLでURLにパラメータを付加し、そこにアクセスしています。パラメータのソートはライブラリがやってくれているので気にする必要はありません。どのAPIに対するアクセスも基本的には同じで、送るパラメータ、署名のkeyが変わるだけとなります。


TwitterAPI.prototype.getRequestToken = function() {
var accessor = {
consumerSecret: this.consumer.consumerSecret,
tokenSecret: ''
};

var message = {
method: "GET",
action: "http://twitter.com/oauth/request_token",
parameters: {
oauth_signature_method: "HMAC-SHA1",
oauth_consumer_key: this.consumer.consumerKey
}
};
OAuth.setTimestampAndNonce(message);
OAuth.SignatureMethod.sign(message, accessor);
var target = OAuth.addToURL(message.action, message.parameters);
var options = {
type: message.method,
url: target,
success: function(d, dt) { /* 返り値からRequest Token/Request Token Secretを取り出して、PINを取得するためのURLを作成 */ },
};
$.ajax(options); // 送信
};

Access Token/Access Token Sceretを取得する

見て分かる通り、Request Token取得のコードとほとんど同じです。異なる点は以下になります

  • API”http://twitter.com/oauth/access_token”変更
  • 署名のkeyがConsumer Secret&Request Token Secretになる
  • パラメータoauth_tokenとしてRequest Tokenを送る
  • パラメータoauth_verifierとしてユーザが入力したPINを送る

取得したAccess Token / Access Token Secretをクライアントで保存しておけば、再度取得する必要はありません。

TwitterAPI.prototype.getAccessToken = function(pin) {
var accessor = {
consumerSecret: this.consumer.consumerSecret,
tokenSecret: this.token_secret // Request Token Secret
};

var message = {
method: "GET",
action: "http://twitter.com/oauth/access_token",
parameters: {
oauth_signature_method: "HMAC-SHA1",
oauth_consumer_key: this.consumer.consumerKey,
oauth_token: this.token, // Request Token
oauth_verifier: pin
}
};
OAuth.setTimestampAndNonce(message);
OAuth.SignatureMethod.sign(message, accessor);
var target = OAuth.addToURL(message.action, message.parameters);
var options = {
type: message.method,
url: target,
success: function(d, dt) { /* 返り値からAccess Token/Access Token Secretを取り出す */ },
};
$.ajax(options); // 送信
};

GET/POSTを行う

Access Token / Access Token Secretを取得したら、それを使ってAPIにアクセスします。以下の点が変わります

  • 署名のkeyがConsumer Secret&Access Token Secretになる
  • パラメータoauth_tokenとしてAccess Tokenを送る
  • 送信データ全てを含めて署名をつける

下のコードがTweetを送信している部分になります。

TwitterAPI.prototype.post = function(api, content, callback) {
var accessor = {
consumerSecret: this.consumer.consumerSecret,
tokenSecret: this.atoken_secret // Access Token Secret
};

var message = {
method: "POST",
action: api,
parameters: {
oauth_signature_method: "HMAC-SHA1",
oauth_consumer_key: this.consumer.consumerKey,
oauth_token: this.atoken // Access Token
}
};
// 送信するデータをパラメータに追加する
for ( var key in content ) {
message.parameters[key] = content[key];
}
OAuth.setTimestampAndNonce(message);
OAuth.SignatureMethod.sign(message, accessor);
var target = OAuth.addToURL(message.action, message.parameters);
var options = {
type: message.method,
url: target,
dataType: 'json',
success: function(d, dt) { callback(d, dt); },
};
$.ajax(options); // 送信
}

// (中略)

/**
* update the status of user
* @param[in] uptext - user status to update
* @param[in] reply_to - target status id for reply
*/
updateStatus: function(uptext, reply_to) {
var content = {status: uptext, source: 'twigadge'};
if(reply_to != '') {
content.in_reply_to_status_id = reply_to;
}
twitterapi.post('http://twitter.com/statuses/update.json', content, Twigadge.dummy);
System.Gadget.Flyout.show = false;
},