ページ 1 / 1
RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 17:17
by パコネコ
今RPGを作ってるのですが(ずっと前から作っているやつのDXライブラリバージョン)、
後から押されたボタンを優先して移動するプログラムなのですが…
気に行っているやつがあるんですが、(ifの条件が)少し長くて…
「こっちのほうがスマートに書けるよ」という方がいらっしゃったら教えてくれませんか?
お願いします。
int get_work(void){
int a;
if(Key[KEY_INPUT_LEFT]!=0 &&
(Key[KEY_INPUT_RIGHT]==0 || Key[KEY_INPUT_LEFT]<Key[KEY_INPUT_RIGHT]) &&
(Key[KEY_INPUT_UP]==0 || Key[KEY_INPUT_LEFT]<Key[KEY_INPUT_UP]) &&
(Key[KEY_INPUT_DOWN]==0 || Key[KEY_INPUT_LEFT]<Key[KEY_INPUT_DOWN]))
a=4;
else if(Key[KEY_INPUT_RIGHT]!=0 &&
(Key[KEY_INPUT_LEFT]==0 || Key[KEY_INPUT_RIGHT]<Key[KEY_INPUT_LEFT]) &&
(Key[KEY_INPUT_UP]==0 || Key[KEY_INPUT_RIGHT]<Key[KEY_INPUT_UP]) &&
(Key[KEY_INPUT_DOWN]==0 || Key[KEY_INPUT_RIGHT]<Key[KEY_INPUT_DOWN]))
a=2;
else if(Key[KEY_INPUT_UP]!=0 &&
(Key[KEY_INPUT_LEFT]==0 || Key[KEY_INPUT_UP]<Key[KEY_INPUT_LEFT]) &&
(Key[KEY_INPUT_RIGHT]==0 || Key[KEY_INPUT_UP]<Key[KEY_INPUT_RIGHT]) &&
(Key[KEY_INPUT_DOWN]==0 || Key[KEY_INPUT_UP]<Key[KEY_INPUT_DOWN]))
a=1;
else if(Key[KEY_INPUT_DOWN]!=0 &&
(Key[KEY_INPUT_LEFT]==0 || Key[KEY_INPUT_DOWN]<Key[KEY_INPUT_LEFT]) &&
(Key[KEY_INPUT_UP]==0 || Key[KEY_INPUT_DOWN]<Key[KEY_INPUT_UP]) &&
(Key[KEY_INPUT_RIGHT]==0 || Key[KEY_INPUT_DOWN]<Key[KEY_INPUT_RIGHT]))
a=3;
else a=0;
return a;
}
・「a」は歩きフラグです。
1なら上
2なら右
3なら下
4なら左
0なら止まる
一応バグなどはありません。
情報が足りない場合は言っていただければ必要な場所を張ります。
(歩き以外はまだできてないです…)
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 17:30
by パコネコ
=======補足(漢字あってます?)=========
全部同じような条件なので一番上のやつについて解説?
まず
左ボタンを押していて
右ボタンを押していない もしくは 右ボタンより左ボタンのほうが押してる時間が短い なをかつ(お?を?)上ボタンを押していない もしくは 上ボタンより左ボタンのほうが押してる時間が短い なをかつ
下ボタンを押していない もしくは 下ボタンより左ボタンのほうが押してる時間が短い なら
左に移動
という感じです。
残りはボタンが違うだけです。
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 18:05
by やっくん
int keyTemp[4] = {Key[KEY_INPUT_LEFT ],
Key[KEY_INPUT_RIGHT],
Key[KEY_INPUT_UP ],
Key[KEY_INPUT_DOWN ],};
または
int keyTemp[4] = {KEY_INPUT_LEFT ,
KEY_INPUT_RIGHT,
KEY_INPUT_UP ,
KEY_INPUT_DOWN ,};
とまとめて、ループまわして調べるのはどうでしょう?
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 18:30
by シエル
後から押したボタンの方へ動くプログラムを書けばよいと思います。
いや、ふざけてるわけではないです。
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 18:32
by やっくん
コンパイルしてないので正しいかわかりませんが、ループを使ったら以下のような感じです。
int get_work(void)
{
int i,j;
int a = 0;
// 止まる:0,上:1,右:2,下:3,左:4 に対応
int state[5] = {0,
KEY_INPUT_UP,
KEY_INPUT_RIGHT,
KEY_INPUT_DOWN,
KEY_INPUT_LEFT,};
// "上"から順に見ていく
for(i = 1; i < 5; i++){
if(Key[state] != 0){// もし、見ようとするキーが押されているなら
for(j = 1; j < 5; j++){
// 自分以外のキーとの対応を見る
if(i != j && ( Key[state[j]] == 0 || Key[state] < Key[state[j]])){
a = i;
break;
}
}
// もし、方向が決定しているならばループ終了
if(a != 0) break;
}
}
return a;
}
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 18:39
by バグ
あんまりスッキリはしてないかも…?(苦笑)
bool key_check(int key)
{
if (Key[key] == 0)
return false;
bool ret = true;
int chk[4] = {KEY_INPUT_UP, KEY_INPUT_DOWN, KEY_INPUT_RIGHT, KEY_INPUT_LEFT};
for (int i = 0; i < 4; ++i)
if (key != chk)
ret &= (Key[chk] == 0 || Key[key] < Key[chk]);
return ret;
}
int get_work(void)
{
return key_check(KEY_INPUT_UP) ? 1 :
key_check(KEY_INPUT_RIGHT) ? 2 :
key_check(KEY_INPUT_DOWN) ? 3 :
key_check(KEY_INPUT_LEFT) ? 4 : 0;
}
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 19:25
by パコネコ
皆さんありがとうございます。
>>シエルさんへ
?どういうことでしょう?
押されていて(0でなくて)、もっとも値が小さいものが最後に押されたものだと思ったのですが…
押されたときにフラグを立てて他のボタンが押されたときにフラグを交代させて、
フラグに対応するボタンが押されていなければうごかなくする…という感じでしょうか?
↑の場合、「右→左→左離す→右」の最後の右が対応してくれないんですよね…
どのようなやり方がいいと思いますか?
>>やっくんさんへ
そのままコピー&ペーストして使わせていただきました。
残念ながら…自分より下のボタンには対応してくれないようです…
例えば、
「左→右」対応してます。
「右→左」対応しません。
みたいな感じで…
>>バグさんへ
まだ試してないです…でもちょっとにがてかもです。
理解が及ばないところがいくつか…「&=とかもわからないです。」
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 19:40
by バグ
>>「&=とかもわからないです。」
あまり難しく考えないでください。
「a+=1」は分りますよね?ようは、あれと同じなんですよ。
つまり、「a&=1」は「a=a&1」と同じです。
今回はtrueで初期化したbool型変数に対して使っているので、全てtrueでなければ、戻り値はfalseになるという訳です。
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 20:09
by パコネコ
//つまり、「a&=1」は「a=a&1」と同じです。
こうなるのはなんとなくわかるのですが…それ以前に「a&1」が何を意味しているのかがわかりません…
/*
今回はtrueで初期化したbool型変数に対して使っているので、全てtrueでなければ、戻り値はfalseになるという訳です。
*/
残念ながらまだbool型を知りません…
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 20:10
by シエル
ビット演算でググりましょう。
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 20:21
by シエル
これ同時押しは考慮してないんですか?
それと、この仕様に固執せず、もっと簡単に考えればもっといいプログラムが書けると思います。
まず私はキー同士のカウントを比較することはやめますね。
というか押してる間はキーカウントを増やすっていう仕組みを利用するのを止めます。
追記:
文章が変だったので訂正

Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 20:50
by パコネコ
調べてきました…
そして起動してみました。
うごき方も同じようなもの(みた感じ)だったので参考にさせていただきます。
どっちが早いですかね?
同時押しと言いますと?
右ボタンを押している間に左ボタンを押すというのはOKですよ…
ただ右と左を同時に押されると…どちらかを離すまでうごけませんね。
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 21:08
by シエル
たとえば右と上キーを同時に押すと止まるんじゃないですか?
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 21:15
by パコネコ
ついかです
キーのカウントを使ってなかったころにどんなに考えてもわからなかったので…
カウントなしになんとかできますか?
簡単に考えると言っても…簡単そうなプログラムしか使ってませんよ?
簡単に考えて同じような結果を得られるようなプログラムを教えていただけませんか?
私にはわからなかったので、よろしくお願いします。(例題でいいので)
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 21:18
by パコネコ
右を押してる間に上を押せば上に行きます。
上に押してる間に右を押せば右に行きます。
同時に押した後に、上を離せば右に行きます。
同時に押した後に、右を離せば上に行きます。
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 21:34
by バグ
1:キー押下フラグを更新する
2:上下左右の内、2箇所以上が押下状態であれば、何もしない
3:押された方向へ移動
4:1へ戻る
このフローでは駄目かな?多分、カウンタは不要になりそうだけど…(^_^;)
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月23日(月) 23:17
by へろりくしょん
元々の要求仕様をさらう限り、キーカウントを利用するのがもっともスマートだと思いますよ。
キーが現時点で押されていなかったら0な訳ですから、0以外のもっとも小さい値を持つキーが
もっとも後に押されたキーであることが分かります。 ので。
int a = 0, count = 0x7FFFFFFF;
if(Key[KEY_INPUT_UP] && Key[KEY_INPUT_UP] < count) a = 1, count = Key[KEY_INPUT_UP];
if(Key[KEY_INPUT_RIGHT] && Key[KEY_INPUT_RIGHT] < count) a = 2, count = Key[KEY_INPUT_RIGHT];
if(Key[KEY_INPUT_DOWN] && Key[KEY_INPUT_DOWN] < count) a = 3, count = Key[KEY_INPUT_DOWN];
if(Key[KEY_INPUT_LEFT] && Key[KEY_INPUT_LEFT] < count) a = 4, count = Key[KEY_INPUT_LEFT];
これで要求通りの事は出来るのではないかと。
斜め移動は考慮されてないようなので、私ならば単純にキーが押された方向へ動かしますが。
こういう仕様にしたのには何か特別な理由があるのでしょうか。
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月24日(火) 13:43
by パコネコ
斜めは移動の幅が大きいので嫌いです。(√2倍ぐらい?)
へろりさんのきれいでいいですね、使わせてもらいます。(確認はしてないけど…)
バグさんのは書いてない部分で止まりそうな気がする…
1マス単位で移動するかの判定してるので…これはすぐ直せるのでどうでもいいんですけどね。
ただ「上→下→左→左離す→?」のときに下へは行かず多分左に行くと思います(み確認)
個人的に、昔できなくて妥協してボタンごとに優先順位みたいなのがついてしまいました…
だからできるなら今度は、後から押したボタンを優先的に使いたいんですよね…
いい形を教えていただけたので、一応解決にさせていただきます。
ありがとうございました。
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月24日(火) 15:28
by へろりくしょん
解決した後なのでなんですが。
>斜めは移動の幅が大きいので嫌いです。(√2倍ぐらい?)
これは、x・yともに1移動させた場合ではないでしょうか。
直角二等辺三角形の線分の比は1:1:√2ですから。
斜めに1移動させるわけですから、x・y・移動量はそれぞれ、cos 角度、sin 角度、1の関係が成り立ちます。
45度に1移動する場合は、xにcos 45度、yにsin 45度移動させればよいだけでは。
Re:RPGの歩きについて<省略のアドバイス>
Posted: 2010年8月24日(火) 15:49
by パコネコ
斜めの移動量を調節すればいいのもわかっているのですが…
移動用のフラグを増やさないといけないのは今からでは面倒なので、
また作るときの参考にさせていただきます。
移動のプログラムもいじる必要がありますし…
今のマップ設定だとトウリ抜けされる可能性が出てくるので、今回は使えません。
教えていただきありがとうございました。