2012年6月25日月曜日

爆裂くまさん

ゲームをするのに忙しくて更新をさぼってました! hidesukeです。
 さて、6月の頭に @mikito0521 が新作を9leapにアップロードしていました。
 その名も『爆裂くまさん』です。

  Osaki.jsの時間中に、みんなで遊んだのですが、部屋のアチラコチラからレバガチャの音が聞こえてきてジワジワ来る一時を楽しめました。 

よろしければ遊んでみてください。
 enjoy!

2012年5月5日土曜日

[Metal Bear Solid] enchant.js でまずは動くものを

enchant.js を使っていち早くゲームらしきものを作るという目的で Metal Bear Solid なる完全に名前先行のゲームを作成しました。



すべてのソースコードは jsdo.it に記載しております。
(大変申し訳ありませんが、chrome で正常に動きません。safari、スマホ実機なら動きます。次回からはこの点注意して作成します。)











まずは本ブログにも記載しております、タップした位置に熊が移動するというプログラムを活用しました。

参照: 2. タップした方向に向かって、クマが進むようにしましょう



当たり死亡判定つきの針群


Metal Gear Solid のように隠れるだけではなく、隠れている壁にも当たり死亡判定をつけたらどうかと思いましたので、そこのところを実装しました。明らかに当たってはダメそうな針の画像を使用しました。








背景(マップ)は下記のように実装できますし、壁としての当たり判定をつける記述方法もあるようですが、当たった後に死亡させるためには、針はマップとしてではなく、Sprite として作成しました。


背景はタイル図柄で埋めました。

    var map = new Map(game.blockSize, game.blockSize);
    map.image = game.assets['./images/map0.gif'];
    map.loadData([
      [  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5],
      [  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5],

                         (中略)

      [  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5],
      [  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5]
    ]);
    game.rootScene.addChild(map);


針画像は同じものをいくつも作るのでクラス化しました。

var objs = new Array(1);

  var ObjectA = Class.create(Sprite, {
    initialize: function(x, y, n){
      Sprite.call(this, 16, 16);
      this.image = game.assets['./images/map0.gif'];
      this.frame = 16;
      this.moveTo(x, y);
      objs[n] = this;
      game.rootScene.addChild(this);
    },
  });



ObjectA という見事にダメな例の代表みたいな名前が付いておりますが、下記のように、x 座標、y 座標、objs で呼び出すための番号を引数として渡すことで、配置と for 文を利用した当たり判定をつけることができました。


var obj00 = new ObjectA(0, 50, 0);



      for(i = 0; i < objs.length; i++){
        if(this.within(objs[i], 16) == true){
            this.isDead = true;
            break;
        }
      }





敵キャラ見つかり判定 


左右に移動している敵キャラ(girl)に熊が見つかった際に死亡する記述です。





熊と敵キャラが同じ直線上に存在した場合に、爆発画像(bomb)が熊の上に乗っかることで熊の死亡を表しています。
爆発画像は死亡時以外は画面外に置いておき、熊死亡 or 敵キャラ死亡時にリサイクルできるようにしています。

ユーザから見た場合、はじめはなぜ熊が死亡しているかがいまいち直観的でないように実装してしまったため、次回から改善したいと思います。


    var girlEnterFrameFunc = function(){
      
      if(this.x <= 0){
        this.movex = 1;
      }else if(this.x >= 203){
        this.movex = -1;
      }
      if(this.x > 16 && this.x < 64){
        if(bear.x > 16 && bear.x < 64){
          bear.isDead = true;
          bomb.moveTo(bear.x + 8, bear.y + 8);
        }
      }else if(this.x > 96 && this.x < 144){
        if(bear.x > 96 && bear.x < 144){
          bear.isDead = true;
          bomb.moveTo(bear.x + 8, bear.y + 8);
        }
      }else if(this.x > 176){
        if(bear.x > 176){
          bear.isDead = true;
          bomb.moveTo(bear.x + 8, bear.y + 8);
        }
      }
      
      
      
      this.x += this.movex * this.speed;
    };
    
    girl.addEventListener("enterframe", girlEnterFrameFunc);






クリア演出


ゴールには明らかに取るといいことありそうな宝箱の画像を使用しました。






クリア後におめでたい感じを出すために、エヴァの最終回風演出をするんだ!と先に意気込んで決めていましたが、時間差でおめでとうコメントを出すのに苦戦しました。






まずは、針と同様におめでとうクラスを作成し、x 座標、y 座標、Array に入れるための番号、セリフを引数としました。

var Omedeto = Class.create(Label, {
  initialize: function(x, y, n, word){
    Label.call(this, word);
    this.moveTo(x, y);
    omes[n] = this;
  },
});



次に、1 回の実行ごとにセリフを画面に表示させる function を実装。

var omeCount = 0;
var omes = new Array(1);
function omedeto(){
  
  if(omeCount == omes.length){
    clearInterval(omeInterval); 
  }else{
    game.rootScene.addChild(omes[omeCount]);
  }
  
  omeCount++;
}




最後に、1 秒に 1 回上記を実行するように実装。

    var ending = function(){
      
      
      var clearLabel = new Label("CLEAR!");
      clearLabel.font = "50px cursive";
      clearLabel.moveTo(30, 100);
      game.rootScene.addChild(clearLabel);
      
      
      var ome00 = new Omedeto(30, 250, 0, "おめでとう");
      var ome01 = new Omedeto(60, 220, 1, "めでたいな");
      var ome02 = new Omedeto(140, 260, 2, "おめでとさーん");
      var ome03 = new Omedeto(160, 230, 3, "クエックエッ");
      
      
      function startInterval(){
        omeInterval = setInterval("omedeto()", 1000);
      }
      startInterval();
      
    };







なんとかゲームの形をしたものができました。

その他、死亡後に画面タップでゲームリセットできるようにしました。リセット時に敵キャラの位置が毎回デフォルト位置に戻っているよりも熊だけがデフォルト位置に戻っていることにより、毎回同じスタートにならないようになっております。


次回作へ向けて 

  •  説明のいらない直観的ゲーム作りを徹底
  • chrome、safari で正常動作するか確認しながら実装
  • 実は熊の左右の向きが頑健なプログラムではないため、そこを改良
  • 面白いゲーム作り 

友人にスマホでプレイしてもらったところ、画面をタップしっぱなしにすることでそこに熊が付いてくると判断したようです。

今回の実装では、タップし直すことによる熊の再移動はありますが、タップしっぱなしによる熊の再移動は実装していなかったため、直観的動きにするためには、やはりタップしっぱなし対応が必要かと思いました。


Metal Bear Solid 2 をご期待ください。

2012年4月22日日曜日

enchant.js meetup 東京 vol.2 で LTしてきてた

enchant.js meet up 東京 vol.2 でLTをしてきました!



聴衆をマッハで置いてけぼりな感じのLTをしてきたので、自分のブログに解説を書きました。きっと、更に凄い勢いでいろんな人を置いてけぼりにするはずです。(コードをかけばいくらかマシなんでしょうがその元気はない……)

enchant.js meetup 東京 vol.2でLTしてきた。 - 名称未定ドキュメント"Que"

他にもたくさん面白い話を聞けたので、機会があればまとめたいなーとおもいます。

とりあえず、gl.enchant.jsやばい。MMDを読み込んでIKまで実装してあるってのをみて鼻血が止まらなくなるかとおもった。

2012年4月17日火曜日

jsdo.it で avatar.enchant.js を使うには


enchant.js にはキャラや背景を手軽に使うための仕組みである
avatar.enchant.js というものがあります。

どんなものかというのはこのへんを見てもらえると分かるかと思います。
http://wise9.jp/archives/7060 とか
http://osakijs.blogspot.jp/2012/04/avaterenchatjs.html とか(ステマ)

こんなに便利な avatar.enchant.js ですが、現在 jsdo.it の Majjor Library にはありません。
(遠からず入るかと思いますが)

でも使いたいよーという紳士淑女の方々がいらっしゃると思いますので
こうすると使えるよ!というのが今回の記事の趣旨です。いざ本題へ。

1. まず avatar.enchant.js を用意します
  1.1 Start coding して JavaScript タブに avatar.enchant.js のコードをまるっと貼り付けます
      (https://github.com/shi3z/enchant.js の plugins 以下にあります)



  1.2 背景やモンスター画像を使いたい人は Files に画像を追加しておきましょう
      (https://github.com/shi3z/enchant.js の images 以下にあります)














  1.3 保存します

2. 上記で作成した avatar.enchant.js を使います
  2.1 Start coding して Add Library で enchant.js を追加します

















  2.2 Add Library で avatar.enchant.js を追加します(「1.」で作成したもの)

















  2.3 enchant.js のコードをもりもり書きます









(」・ω・)」うー!(/・ω・)/にゃー!

2012年4月11日水曜日

ターミナルプレクサーのお話(1)

依頼があってから寝かせすぎた感のあるターミナルマルチプレクサのお話です。

マルチプレクサってなに?って人は一回Linux系にターミナルログインしてscreen って打ってからC-a c って打ってみたらいいとおもう。

一般的によくあるたーみなるまるちぷれくさ についてデス
今のところ僕が知る限りではこれぐらいあります

  • GNU screen
  • tscreen
  • tmux
  • byobu
個人的に大枠でくくると

1)GNU Screen tscreen byoubu
2)tmux

の2グループにわけられる。いや分けたと思った。
違いはScreenの拡張 か、個別の機能があるかってちがいです。

screen自体が「古い」って言われるのはたぶん枯れきって開発がほぼ終了してんじゃね?ってぐらい(実は別の人がかいはつを続けているっぽいですが)それに比べるとtmuxの方が更新頻度が高いからなんじゃないかなーと思っています。

んなわけでScreen系とtmux系の違いはどこーってなるとこんな感じかな?とおもっとります

Screen
・ RH・Debian系なら大抵標準で入っている   <<( 重要)
・ 便利なscriptがいろんな人によってすでにそろっている。
・ tscreen やbyoubuといった拡張派生系のものがあって移行も比較的すんなりScriptもそのまま使えたりする。
・ 慣れてる人が多い(w
・ メモリくうよ・・・マジで

tmux
・標準設定のままでもそれなりに使えるステータスバー
・各ショートカットがコマンドベース
・縦分割機能搭載(僕がtmuxを知る事になった要因・・・でも最も使ってない機能)
・たまに混乱する「ペイン」って概念
・まぁ概念としてはScreen互換なんだけど・・・・・
・コピー&ペースト用のバッファを複数保持できる(これがでかい)
・sessionが複数もてて、しかも任意に切り替えが出来る(割と重要)

なかんじです。
今更ってかんじの情報ですね。

で、個人的な見解ですが、僕はLinux系のOS運用をする事が多いので基本はGNU screenつかってます。
これなら、自分の作業アカウントに「.screenrc」入れれば環境そのまま使えますので。
同じ問題でscreenscriptもあまり使わないようにしてます。

じゃぁtmuxは? って話なんですがこれは常時使用しているWSの方で使っています。
理由は、メモリの使用量の問題と上記の
「・sessionが複数もてて、しかも任意に切り替えが出来る(割と重要)」
これです。

この辺は次回もっと書いて良いよって言われたら書きます。
昼飯のあいまに書いたので今回こんなところで。

2012年4月10日火曜日

avater.enchat.jsでいろいろ遊んでみた

avater.enchant.jsがいい感じ

avater.enchant.jsがかなりイケてます。
簡単にキャラクタが表示できるというのは、絵心のないプログラマにはまさに福音!
これで「絵がかけないからゲームつくれない」なんてちょっと意味のわからない言い訳が聞けなくなりますね!

さて、このavater.enchant.js、好きなキャラメイクができるのもさることながら、デフォルトで何種類かの動きを備えています。

  • stop
  • run
  • attack
  • special
  • damage
  • dead
  • demo
それぞれ、使いたいタイミングで player.action = "damage" とか指定してあげると













こんな風にダメージうけてくれるわけです。キャワイイ!

じゃぁ、なんか作りたいよね?


さて、こんな横向きで、走ったり攻撃したりするキャラクタがいるんだから、横スクロールシューティングゲームを作りたくなるのがゲーム屋の心情というやつですよね!
というわけで、とりあえず女の子が剣を降ると、弾がでるってのを作りましょうか。
クリックしたタイミングで、弾を出すようにしてみましょう。














あ、あれー? コレじゃない感……。
こう、刀を抜いた時にズバーっと弾がでてほしいじゃないですか。
なのに、あれ?

コード読んでみる


avater.enchant.jsのコードを見てみると、attackの時のアニメーションのコマは

"attack": [ 0,2,9,10,11,5,0,0,0,-1], 
てな具合の定義がしてあります。
この配列の順序で画像を切り替えてアニメーションされるのですが、配列の先頭の0というのは、stopの時と同じ画像なんですね。

これ、配列4番目とか5番目とかその辺りで弾がでてくれたらカッコイイきがします。
なので、そのように書いてしまいましょう。JavaScriptの自由自在っぷりが発揮されます。

まず、そのキャラクタが今何のアクションをしているかはplayer.actionで取得できます。
よって、以下のようなコードで、攻撃アクション中かどうかをしることができます。

var player = new Avater("2:2:1:2076:21310:2206");

if(player.action === "attack") {
  // 攻撃中の処理をここに書く
}

これで取得できます!
さて、つぎは攻撃中のアニメーションの4コマ目あたりで弾を出したいなぁ……と思います。
また、avater.enchant.jsのコードを読むと、actionの指定がある場合、毎フレームごとにanimFrameという値を1増加させて、animPatternという配列に従って画像の表示を変えているようです。
つまり、animFrameの値 = action開始時からのフレーム数ということがわかります。
というわけで、以下のようなコードを書きました。

if(player.action === "attack"){
  if(player.animFrame === 4){
     game.rootScene.addChild(new Bullet());
  }  
}

これで、attack動作中で、4コマ目のときにBullet(弾)を表示するというコードが完成しました!
じゃぁ、動かしてみましょう!

ああ、いいですね! ばっちりです。最高です! 捏造したかのような思い通りのスクリーンショットも取れました!

まとめ

avater.enchant.js のコードを読めば、大抵のことができる。


コード読んでてハマったとこ

var w = ~~(image.width/4);

このコードが何やってるかわからなかったんですね。このチルダチルダ
いろいろ読んでいくつか解説しているページを見つけました。

なるほど。Math.floor使わないという方法があるのか。
いろいろありますなぁ〜。

ソースコードを読むのはとても勉強になりますね><

2012年4月3日火曜日

これも開発環境

Osaki.jsはenchant.jsでゲームを作ったり、遊んだりするクラブ活動です。
みんなでノートパソコンを持ち寄って、わいわいやってるんですが、すげーマシンでコード書いてる猛者がいました



どうです、こいつ!
こいつ、シャープ製 WILLCOM D4 ですよ!
こいつでコードかいてjsdo.itに貼りつけてデモしていました!



初回は、本体のキーボードでちまちま打ってたんですが、さすがに辛かったらしく、第2回はキーボードマウス、ディスプレイケーブル持参という徹底っぷり。
すごく……かっこいいです。

しかし、それより、このエンターブレインのロゴがついたキーボードはどこで手に入れたんだ……。