LOCKYOUで学ぶ

行き当たりばったりゲーム制作

戻る

さて、画像が表示されてるだけだととてもゲームとはいえないよね
クレイジーバス未満だよ
flashのときとセリフまるごと同じじゃねえか
いやぁすいませ~ん
それはともかくとして、とにかく
キーボードで入力して 画面クリック(スマホの場合は画面タッチ)の場合はまた後で
キャラを動かさなきゃゲームにならないよね
キー入力を受け取るための関数はこれ
var isPress = key.getKey('left');
getKeyの引数は上下左右の英語、もしくはキーコード
この場合、左矢印キーが押されていればisPressにtrue、押されていなければfalseが入ります
で、ただ単にそのまま書いてもflashとおんなじ不具合が起きちゃうまあそのまま書くことはできないんだけど
確か、1フレーム目にしか書かれていないからそれ以降に入力しても反応しない、だったな
厳密にはflashとphina.jsで挙動が違うからちょっと違うんだけど、
どう頑張ってもゲームさんサイドがキー入力を受け付けてくれないっていうのは同じだよ
だから毎フレームごとにキーが押されているかの判断をしなきゃならんって話だよな
flashだとonEnterFlameだったがphina.jsにも同じような関数が用意されてんのか?
そんなこともあろうかと!
ちゃんと用意されてるよ
updateっていう関数……じゃなくてプロパティ
ここに「右が押されたら右に動かす」っていう処理をする
え~っと、作ったキャラのプロパティにupdateっていうのがあるから
その中に左を押したら左に、つまりxの位置を小さくする関数を放り込んであげる
右もおんなじようにね
    var taiann = Sprite('taiann').addChildTo(this);
    taiann.x = 30;  // x座標を指定
    taiann.y = 30;  // y座標を指定
    
    taiann.update = function(app) {
      
      var key = app.keyboard;
      
      if (key.getKey('left')) {
        taiann.x -= 5;
      }
      if (key.getKey('right')) {
        taiann.x += 5;
      }
      
    };
canvas非対応
updateに渡す関数にappっていう引数あるけど
その中にkeyboardっていう変数があってその中にキーを押したかどうかの判定をする関数があるんだよね
これで動くようになったな
めでたしめでたしだね
というわけで今回は以上!次をお楽しみにね~





















とでも思っているのか!!
だろうな
やけに短いと思ったわ せっかく表情頑張ったのにその淡白な反応はないと思うの
で、上のはなんか問題があるのか?
いや、そういうわけじゃないけど、
例えばテトリスのテトリミノを右に1マスだけ動かしたいときとかは上のやつをそのまま使っちゃダメだよね?
まあそうだな
そんなこともあろうかと!
こんな感じに「押した瞬間だけ動かしたい」ときは別の関数を使うよ
とりあえず↓ボタンにその関数を使ってみるね
    var taiann = Sprite('taiann').addChildTo(this);
    taiann.x = 30;  // x座標を指定
    taiann.y = 30;  // y座標を指定
    
    taiann.update = function(app) {
      
      var key = app.keyboard;
      
      if (key.getKey('left')) {
        taiann.x -= 5;
      }
      if (key.getKey('right')) {
        taiann.x += 5;
      }
      if (key.getKeyDown('down')) {
        taiann.y += 5;
      }

    };
canvas非対応
押されている瞬間を調べたいときにはgetKeyDownになるだけで
それ以外は特に変わらないな
さらにもう一発!
しばらくキーを押してようやく動き出すパターンも作ってみよう
こっちは……
キーが押されてからの経過時間が必要だけど
これにも関数があるのか?
んーにゃ、残念ながらphina.jsにそういう関数は無い、と思う
そうなのか
ソオオオオオォォォォナンス!!!!!!!
うるせえな……
こういう場合は押している間のチャージ時間を持っておくための
変数を用意しなきゃいけないから、こんな感じのコードになるね
    var taiann = Sprite('taiann').addChildTo(this);
    taiann.x = 30;  // x座標を指定
    taiann.y = 100;  // y座標を指定
    taiann.count = 0;  // 上ボタンを押している時間
taiannスプライトにcountプロパティを作ってんのか
勝手に作って良いもんなのか?
んーと、xやyとかの位置情報とか、widthやheightとかの縦横の大きさとかphina.jsで
すでに使ってる名前 こういうのも予約語っていうのかな?
はダメだけど
countならphina内部では使われてないからセーフだね
そして、押されたらcountに1加算、押されてないならcountを0にするよ
移動する条件はキーが押されている状態に加えて……
countが適当な数以上、という条件も入れると
正解<エサクタ>
コードはこんな感じだね
せっかくだからコード全体を載せるよ
// phina.js をグローバル領域に展開
phina.globalize();

// 外部から画像を読み込む
var ASSETS = {
  image: {
    'taiann': './images/taiann.png',
  },
};

// MainScene クラスを定義
phina.define('MainScene', {
  superClass: 'CanvasScene',
  init: function() {
    // 親クラス初期化
    this.superInit({
      // 画面サイズ
      width: 400,
      height: 300,
    });
    // 背景色を指定
    this.backgroundColor = '#FFF';
    
    // 大安を表示
    var taiann = Sprite('taiann').addChildTo(this);
    taiann.x = 30;  // x座標を指定
    taiann.y = 100;  // y座標を指定
    
    taiann.count = 0;  // 上ボタンを押している時間
    
    taiann.update = function(app) {
      
      var key = app.keyboard;
      
      if (key.getKey('left')) {
        taiann.x -= 5;
      }
      if (key.getKey('right')) {
        taiann.x += 5;
      }
      if (key.getKeyDown('down')) {
        taiann.y += 5;
      }
      
      if (key.getKey('up')) {
        if (taiann.count >= 15) {
          taiann.y -= 5;
        }
        taiann.count++;
      } else {
        taiann.count = 0;
      }
    };
  },
});

// メイン処理
phina.main(function() {
  // アプリケーション生成
  var app = GameApp({
    startLabel: 'main', // メインシーンから開始する
    fit: false, // フィットさせない
    query: '#sample01', // キャンバスのIDを指定
    width: 400, //縦のサイズ
    height: 300, //横のサイズ
    assets: ASSETS,
  });
  // アプリケーション実行
  app.run();
});
canvas非対応
phina.jsは1秒30フレームだからこの場合は0.5秒間押し続ければ動き出すね
応用すればカービィみたいに右を2回素早く押せばダッシュ、みたいなこともできるようになるよ
いろいろとやりようがあるんだな
言っておくけどキャラの移動には押しっぱなし式、
パズルゲームとか、あと項目の選択とかには押した瞬間式のやつがいいよ
適材適所ね
キャラの移動のために何回も連打するとか、そんなゲーム誰もやりりたくないよね?
そりゃそうだ
それで、キャラの移動の次は何をやるんだ?
何にしようか……
ブロック崩しが一応今回のゴールだから、ボールを相手のゴールに
…… シュゥゥゥーーーーーーーーーーッ!!
超!エキサイティンッッッッッッッッッッッッッッッッッッッッ!!

じゃなくて、ボールを動かしたり壁で反射させたりっていうのをやりたいけど
けど?
ただ無機質な四角が動いてるだけだと面白くないよね?
だから次はキャラをアニメーションさせるっていうのをやりたいと思ってるよ
前回言ってたspritesheetのことか?
それそれ、spritesheet
これを使って歩くモーションさせたりするよ
じゃあ、次回もお楽しみにね~
小休止
あ、そうそう(黒バラ風に)
今回もやっぱ言いたいことがあるんだけど
なんだ
まず一個目
今回十字キーを使うことになったんだけど、そのせいでちょっと弊害が……
十字キーを押すことによる弊害……?
あー、スクロールか?
正解<エサクタ>
本来ならページを開いてる状態で十字キーを押すとスクロールしちゃうんだけど、
このページじゃならないよね
その秘密はこれ!
// phina.js をグローバル領域に展開
phina.globalize();

// 外部から画像を読み込む
var ASSETS = {
  image: {
    'taiann': './figure/ikiatariphina/images/taiann.png',
  },
};

// キー本来の動きを止める
document.onkeydown = function (e){
  // phina.js使用時
  e.stop();

  // phina.js不使用時
  e.preventDefault();
  e.stopPropagation();
};
phinaとは直接関係ないけど、「
ブラウザの本来のキーの動作 矢印キーでスクロールの他には
バックスペースで戻る、ctrl+Sでページ保存など色々あります
」を止めたいときは
e.preventDefault()とe.stopPropagation()を使えば良いんだよね
まあ全部のキーを一括で止めちゃってるから作者は
F12 開発者用ツールを開くショートカットキー
F12じゃなくてもメニューバーから開けます
が効かなくてあれ?あれ?ってなったらしいけど
二個目
作るときにはあんまり関係ないけど、今回このページには3つのcanvasがあるよね?
それで実際に動かしたらわかるんだけど、3つ全部がおんなじようにキー入力を受け取っちゃうんだよね
スクロールしなきゃそれぞれを見れないから少し面倒くさいが
見てみると同じように動くな
解決法はあるのか?
知らぬ!そもそもわかってたら実装してるし……
後々解決法わかったらまた後でね
この2つについてはまた色々詳細がわかったらどこかで書くかもね
じゃ、次回をお楽しみに~