
さて、画像が表示されてるだけだととてもゲームとはいえないよね
クレイジーバス未満だよ
クレイジーバス未満だよ

flashのときとセリフまるごと同じじゃねえか

いやぁすいませ~ん
それはともかくとして、とにかく
キー入力を受け取るための関数はこれ
それはともかくとして、とにかく
キーボードで入力して
画面クリック(スマホの場合は画面タッチ)の場合はまた後で
キャラを動かさなきゃゲームにならないよね
キー入力を受け取るための関数はこれ
var isPress = key.getKey('left');
この場合、左矢印キーが押されていればisPressにtrue、押されていなければfalseが入ります

で、ただ単にそのまま書いてもflashとおんなじ不具合が起きちゃうまあそのまま書くことはできないんだけど

確か、1フレーム目にしか書かれていないからそれ以降に入力しても反応しない、だったな

厳密にはflashとphina.jsで挙動が違うからちょっと違うんだけど、
どう頑張ってもゲームさんサイドがキー入力を受け付けてくれないっていうのは同じだよ
どう頑張ってもゲームさんサイドがキー入力を受け付けてくれないっていうのは同じだよ

だから毎フレームごとにキーが押されているかの判断をしなきゃならんって話だよな
flashだとonEnterFlameだったがphina.jsにも同じような関数が用意されてんのか?
flashだとonEnterFlameだったがphina.jsにも同じような関数が用意されてんのか?

そんなこともあろうかと!
ちゃんと用意されてるよ
updateっていう関数……じゃなくてプロパティ
ここに「右が押されたら右に動かす」っていう処理をする
ちゃんと用意されてるよ
updateっていう関数……じゃなくてプロパティ
ここに「右が押されたら右に動かす」っていう処理をする

え~っと、作ったキャラのプロパティにupdateっていうのがあるから
その中に左を押したら左に、つまりxの位置を小さくする関数を放り込んであげる
右もおんなじようにね
その中に左を押したら左に、つまり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;
}
};

updateに渡す関数にappっていう引数あるけど
その中にkeyboardっていう変数があってその中にキーを押したかどうかの判定をする関数があるんだよね
その中にkeyboardっていう変数があってその中にキーを押したかどうかの判定をする関数があるんだよね

これで動くようになったな

めでたしめでたしだね
というわけで今回は以上!次をお楽しみにね~
というわけで今回は以上!次をお楽しみにね~

とでも思っているのか!!

だろうな
やけに短いと思ったわ
せっかく表情頑張ったのにその淡白な反応はないと思うの


で、上のはなんか問題があるのか?

いや、そういうわけじゃないけど、
例えばテトリスのテトリミノを右に1マスだけ動かしたいときとかは上のやつをそのまま使っちゃダメだよね?
例えばテトリスのテトリミノを右に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;
}
};

押されている瞬間を調べたいときには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なら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();
});

phina.jsは1秒30フレームだからこの場合は0.5秒間押し続ければ動き出すね
応用すればカービィみたいに右を2回素早く押せばダッシュ、みたいなこともできるようになるよ
応用すればカービィみたいに右を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とは直接関係ないけど、「
e.preventDefault()とe.stopPropagation()を使えば良いんだよね
まあ全部のキーを一括で止めちゃってるから作者は
ブラウザの本来のキーの動作
矢印キーでスクロールの他には
バックスペースで戻る、ctrl+Sでページ保存など色々あります
」を止めたいときは
バックスペースで戻る、ctrl+Sでページ保存など色々あります
e.preventDefault()とe.stopPropagation()を使えば良いんだよね
まあ全部のキーを一括で止めちゃってるから作者は
F12
開発者用ツールを開くショートカットキー
F12じゃなくてもメニューバーから開けます
が効かなくてあれ?あれ?ってなったらしいけど

F12じゃなくてもメニューバーから開けます

二個目
作るときにはあんまり関係ないけど、今回このページには3つのcanvasがあるよね?
それで実際に動かしたらわかるんだけど、3つ全部がおんなじようにキー入力を受け取っちゃうんだよね
作るときにはあんまり関係ないけど、今回このページには3つのcanvasがあるよね?
それで実際に動かしたらわかるんだけど、3つ全部がおんなじようにキー入力を受け取っちゃうんだよね

スクロールしなきゃそれぞれを見れないから少し面倒くさいが
見てみると同じように動くな
解決法はあるのか?
見てみると同じように動くな
解決法はあるのか?

知らぬ!そもそもわかってたら実装してるし……
後々解決法わかったらまた後でね
後々解決法わかったらまた後でね

この2つについてはまた色々詳細がわかったらどこかで書くかもね
じゃ、次回をお楽しみに~
じゃ、次回をお楽しみに~