RPGの歩きについて<省略のアドバイス>

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
パコネコ

RPGの歩きについて<省略のアドバイス>

#1

投稿記事 by パコネコ » 15年前

今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の歩きについて<省略のアドバイス>

#2

投稿記事 by パコネコ » 15年前

=======補足(漢字あってます?)=========
全部同じような条件なので一番上のやつについて解説?
まず
左ボタンを押していて
右ボタンを押していない もしくは 右ボタンより左ボタンのほうが押してる時間が短い なをかつ(お?を?)上ボタンを押していない もしくは 上ボタンより左ボタンのほうが押してる時間が短い なをかつ
下ボタンを押していない もしくは 下ボタンより左ボタンのほうが押してる時間が短い なら
左に移動
という感じです。
残りはボタンが違うだけです。

やっくん

Re:RPGの歩きについて<省略のアドバイス>

#3

投稿記事 by やっくん » 15年前

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の歩きについて<省略のアドバイス>

#4

投稿記事 by シエル » 15年前

後から押したボタンの方へ動くプログラムを書けばよいと思います。
いや、ふざけてるわけではないです。

やっくん

Re:RPGの歩きについて<省略のアドバイス>

#5

投稿記事 by やっくん » 15年前

コンパイルしてないので正しいかわかりませんが、ループを使ったら以下のような感じです。
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の歩きについて<省略のアドバイス>

#6

投稿記事 by バグ » 15年前

あんまりスッキリはしてないかも…?(苦笑)
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の歩きについて<省略のアドバイス>

#7

投稿記事 by パコネコ » 15年前

皆さんありがとうございます。
>>シエルさんへ
?どういうことでしょう?
押されていて(0でなくて)、もっとも値が小さいものが最後に押されたものだと思ったのですが…
押されたときにフラグを立てて他のボタンが押されたときにフラグを交代させて、
フラグに対応するボタンが押されていなければうごかなくする…という感じでしょうか?
↑の場合、「右→左→左離す→右」の最後の右が対応してくれないんですよね…
どのようなやり方がいいと思いますか?

>>やっくんさんへ
そのままコピー&ペーストして使わせていただきました。
残念ながら…自分より下のボタンには対応してくれないようです…
例えば、
「左→右」対応してます。
「右→左」対応しません。
みたいな感じで…

>>バグさんへ
まだ試してないです…でもちょっとにがてかもです。
理解が及ばないところがいくつか…「&=とかもわからないです。」

バグ

Re:RPGの歩きについて<省略のアドバイス>

#8

投稿記事 by バグ » 15年前

>>「&=とかもわからないです。」

あまり難しく考えないでください。

「a+=1」は分りますよね?ようは、あれと同じなんですよ。

つまり、「a&=1」は「a=a&1」と同じです。

今回はtrueで初期化したbool型変数に対して使っているので、全てtrueでなければ、戻り値はfalseになるという訳です。

パコネコ

Re:RPGの歩きについて<省略のアドバイス>

#9

投稿記事 by パコネコ » 15年前

//つまり、「a&=1」は「a=a&1」と同じです。
こうなるのはなんとなくわかるのですが…それ以前に「a&1」が何を意味しているのかがわかりません…
/*
今回はtrueで初期化したbool型変数に対して使っているので、全てtrueでなければ、戻り値はfalseになるという訳です。
*/
残念ながらまだbool型を知りません…

シエル

Re:RPGの歩きについて<省略のアドバイス>

#10

投稿記事 by シエル » 15年前

ビット演算でググりましょう。

シエル

Re:RPGの歩きについて<省略のアドバイス>

#11

投稿記事 by シエル » 15年前

これ同時押しは考慮してないんですか?

それと、この仕様に固執せず、もっと簡単に考えればもっといいプログラムが書けると思います。
まず私はキー同士のカウントを比較することはやめますね。

というか押してる間はキーカウントを増やすっていう仕組みを利用するのを止めます。

追記:
文章が変だったので訂正 画像

パコネコ

Re:RPGの歩きについて<省略のアドバイス>

#12

投稿記事 by パコネコ » 15年前

調べてきました…
そして起動してみました。
うごき方も同じようなもの(みた感じ)だったので参考にさせていただきます。
どっちが早いですかね?

同時押しと言いますと?
右ボタンを押している間に左ボタンを押すというのはOKですよ…
ただ右と左を同時に押されると…どちらかを離すまでうごけませんね。

シエル

Re:RPGの歩きについて<省略のアドバイス>

#13

投稿記事 by シエル » 15年前

たとえば右と上キーを同時に押すと止まるんじゃないですか?

パコネコ

Re:RPGの歩きについて<省略のアドバイス>

#14

投稿記事 by パコネコ » 15年前

ついかです
キーのカウントを使ってなかったころにどんなに考えてもわからなかったので…
カウントなしになんとかできますか?
簡単に考えると言っても…簡単そうなプログラムしか使ってませんよ?
簡単に考えて同じような結果を得られるようなプログラムを教えていただけませんか?
私にはわからなかったので、よろしくお願いします。(例題でいいので)

パコネコ

Re:RPGの歩きについて<省略のアドバイス>

#15

投稿記事 by パコネコ » 15年前

右を押してる間に上を押せば上に行きます。
上に押してる間に右を押せば右に行きます。
同時に押した後に、上を離せば右に行きます。
同時に押した後に、右を離せば上に行きます。

バグ

Re:RPGの歩きについて<省略のアドバイス>

#16

投稿記事 by バグ » 15年前

1:キー押下フラグを更新する

2:上下左右の内、2箇所以上が押下状態であれば、何もしない

3:押された方向へ移動

4:1へ戻る


このフローでは駄目かな?多分、カウンタは不要になりそうだけど…(^_^;)

へろりくしょん

Re:RPGの歩きについて<省略のアドバイス>

#17

投稿記事 by へろりくしょん » 15年前

元々の要求仕様をさらう限り、キーカウントを利用するのがもっともスマートだと思いますよ。

キーが現時点で押されていなかったら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の歩きについて<省略のアドバイス>

#18

投稿記事 by パコネコ » 15年前

斜めは移動の幅が大きいので嫌いです。(√2倍ぐらい?)
へろりさんのきれいでいいですね、使わせてもらいます。(確認はしてないけど…)
バグさんのは書いてない部分で止まりそうな気がする…
1マス単位で移動するかの判定してるので…これはすぐ直せるのでどうでもいいんですけどね。
ただ「上→下→左→左離す→?」のときに下へは行かず多分左に行くと思います(み確認)

個人的に、昔できなくて妥協してボタンごとに優先順位みたいなのがついてしまいました…
だからできるなら今度は、後から押したボタンを優先的に使いたいんですよね…

いい形を教えていただけたので、一応解決にさせていただきます。
ありがとうございました。

へろりくしょん

Re:RPGの歩きについて<省略のアドバイス>

#19

投稿記事 by へろりくしょん » 15年前

解決した後なのでなんですが。

>斜めは移動の幅が大きいので嫌いです。(√2倍ぐらい?)

これは、x・yともに1移動させた場合ではないでしょうか。
直角二等辺三角形の線分の比は1:1:√2ですから。


斜めに1移動させるわけですから、x・y・移動量はそれぞれ、cos 角度、sin 角度、1の関係が成り立ちます。

45度に1移動する場合は、xにcos 45度、yにsin 45度移動させればよいだけでは。

パコネコ

Re:RPGの歩きについて<省略のアドバイス>

#20

投稿記事 by パコネコ » 15年前

斜めの移動量を調節すればいいのもわかっているのですが…
移動用のフラグを増やさないといけないのは今からでは面倒なので、
また作るときの参考にさせていただきます。

移動のプログラムもいじる必要がありますし…
今のマップ設定だとトウリ抜けされる可能性が出てくるので、今回は使えません。
教えていただきありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る