Re: 元のマスに戻ったあと前のマスに行けない ( No.8 ) |
- 名前:マーク42 日時:2019/09/29 04:56
紺帽子さん、どうもありがとうございます!
今現在の問題が2つあり、今まで通りに書いているのですが、なぜかうまくいきません。
addattacktime中で敵が右向きになっているのにキーYを押しても敵にダメージが入らない事と、addattacktimeの値の変更がされていないことです。
addattacktime中で敵が右向きになっているのにキーYを押しても敵にダメージが入らない事に関しては
if (addattacktime <= 500 && addattacktime > 0)//addattacktimeが0になるまでの間に攻撃があればaddattacktimeは20に戻る
{//★addattacktimeが500以下で0より大きい時—1されていく、そして500以下ならばかつ0より大きいならばずっと処理されるということ。
--addattacktime;
//addattackimage = addattackimage - 1;
if (Key[KEY_INPUT_K] == 1 && Kcount == 50 && enemyImage == enemyGHandle[5]) {//攻撃がキックだった場合
Kcount = Kcount - 50;//キーKを押すたびに50だけ引く
enemyImage = enemyGHandle[5];
if (enemyImage == enemyGHandle[5])//攻撃を食らうと右向きになるようにする
{
enemyHP = enemyHP - 50;
playerImage = playerGHandle[4];
addattacktime = 500;
}
}
}
のように500から0に書けて、攻撃が成功するとaddattacktimeが減っていくのですが、その減っていく最中にキーYを押すと追加攻撃できるように作った
つもりなのですが、うまく機能しません。何がダメなのでしょうか。
もう一つ、addattacktimeの値の変更がされていないことに関してです。
if (addattacktime == 0) {//addattacktime == 0だと初期値と被ってしまうので0より小さいとした。
playerX = preplayerX;
playerImage = playerGHandle[4];
addattacktime = 501;//addattacktimeが0にると、元の位置に戻る
//if (count < 50) ++count;//これにより連続で攻撃してもif (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])を考慮して連続攻撃ができる!
//★あるフレームが進んでから画像がを動くまでを遅くした、ならば、あるフレームが進んだら数字も次の数字に移るまで遅くできるのは?と考えた。
if (addattacktime = 501 && count < 50) ++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if (frames % 5 == 0) {
++count; if (count > 50) { count = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}
if (addattacktime = 501 && Kcount < 50) ++frames;
if (frames % 20 == 0) {
++Kcount; if (Kcount > 50) { Kcount = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}//★++が>よりも優先順位により優先されるため、というか単純に+1されいくため、その先で条件によって(&&とは違い強制ではなく)Kcount > 50ならばcount = 50となっただけである。
}
のように、addattacktime = 501の部分がaddattacktime = 500では他のif文で引っかかり永遠にaddattacktimeをループするので、そうならないために
addattacktime = 501と置きました。addattacktimeが0になったら501になるように書いたのですが、これは何がいけなかったのでしょうか。
以上二つですがどうかよろしくお願いいたします。
以下は全体のコードです。
pastebin.com/9kvrT4Ra
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.9 ) |
- 名前:管理人 日時:2019/09/29 06:30
> これはaddattacktimeが0の時は真と偽であり結果的には&&により偽となるため、addattacktimeの値はでないと考えていたのですが、
> これは<やーーなどの演算子の優先順位とかによって結果が偽であっても値が出てくるのでしょうか。
はい、-- や ++ は if文の条件が成立してもしなくても評価されただけで適用されます
例えば、仮に
if (++addattacktime < 500)
{
というプログラムを実行した場合、addattacktime が 500 未満の場合のみ addattacktime に 1 が足される…ではなく、
addattacktime が 500 未満でも以上でも関係なく( 条件が成立してもしなくても関係なく ) addattacktime に 1 が足されます
なので
if (addattacktime <= 500 && --addattacktime > 0)
と書いてしまうと、--addattacktime > 0 の式が評価された時点で条件が成立してもしなくても addattacktime から 1 が
引かれてしまうのです
> addattacktime中で敵が右向きになっているのにキーYを押しても敵にダメージが入らない事と、addattacktimeの値の変更がされていないことです。
キーKではなくキーYですか?
> もう一つ、addattacktimeの値の変更がされていないことに関してです。
変更されていないというのはどういうことでしょうか?
addattacktime の値は最初は 501 でキーAを押すと 500 になり、その後 -1 され続け 0 に近づきますが
どの時点で『変更されない』状態になるのでしょうか?
> addattacktime = 501と置きました。addattacktimeが0になったら501になるように書いたのですが、これは何がいけなかったのでしょうか。
仕様が理解できていなくてすみません、何故 addattacktime が 0 になったら 501 を代入するのでしょうか?
0 のままでは駄目なのでしょうか?
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.10 ) |
- 名前:Tatu 日時:2019/09/29 14:11
仕様とコードの整理をおすすめします。
//1フレームで行う処理
while (ProcessMessage() == 0) {
フレーム数を1増やす。
キー入力状態を更新。
メニュー画面の場合の処理
戦闘画面の場合
//プレイヤーに関する処理
プレイヤーが通常状態(addattacktimeが0)の場合
移動
ロックオン
ロックオンした状態で攻撃キーを押すと敵の前に移動して攻撃。addattacktimeを500にする。
countが減っている場合、(フレーム数 % 5)が0ならcountを1増やす。
Kcountが減っている場合、(フレーム数 % 20)が0ならKcountを1増やす。
プレイヤーが追加攻撃状態(addattacktimeが0でない)の場合
addattacktimeを1減らす。
前の行によってaddattacktimeが0になった場合はプレイヤーを元の位置に戻す。
そうでない場合はキックキーまたは攻撃キーを押すと対応する追加攻撃を行う。
プレイヤーの足踏み(通常状態のみ足踏みさせるなら通常状態で行う処理に入れる)
//敵に関する処理
敵が動けない(stopenemytimeが0でない)場合
stopenemytimeを減らす。(プレイヤーの攻撃時に1ではなく、止めたい時間を設定するようにする。)
敵が動ける(stopenemytimeが0)場合
敵を動かす。
敵の足踏み
各種描画処理
}
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.11 ) |
- 名前:マーク42 日時:2019/09/29 17:54
返信どうもありがとうございます!
管理人様、わかりにくくてすいません。
すいません間違っていました。キーKです。
変更されないというのは
if (addattacktime == 0)の中身よりaddattacktimeが 0になり自分が元のマスに戻った後
addattacktimeが501に変更されないことを言っています。
また、
addattacktimeが0のままだと以下のプログラムより他のマスに自分が移動できないので、
0になったら501にして以下のifの条件に引っかからないようにしました。
if (addattacktime == 0) {
playerX = preplayerX;
playerImage = playerGHandle[4];
addattacktime = 501;
Tatuさん、アドバイスありがとうございます。
整理というのは構造体やクラスを使ってまとめるということでしょうか。
違うとしたらどのようにまとめればいいでしょうか。
学習能力が低く構造体とクラスが理解できても実用的な使い方ができず、
今のまま進んでいます。
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.12 ) |
- 名前:Tatu 日時:2019/09/29 19:54
整理の意味について
どの状態でどういう処理が行われるかをわかりやすくしましょうという意味で書きました。
No.10の書き方ではわかりにくかったですか?
それならマーク42さんがわかりやすいやり方でやってみるとよいでしょう。
addattacktimeが501に変更されないことについて
攻撃で500
追加攻撃状態で1減って499
addattacktimeの文字の描画時も1減って498
...
addattacktimeが0になるのは追加攻撃状態の処理の時かaddattacktimeの文字の描画の時かどっちでしょう?
addattacktimeの文字の描画時に1減らす理由はありますか?
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.13 ) |
- 名前:管理人 日時:2019/09/29 23:37
> if (addattacktime == 0)の中身よりaddattacktimeが 0になり自分が元のマスに戻った後
> addattacktimeが501に変更されないことを言っています。
『if (addattacktime == 0)の中身』の該当箇所はこちらの処理ですよね?
if (addattacktime == 0) {//addattacktime == 0だと初期値と被ってしまうので0より小さいとした。
playerX = preplayerX;
playerImage = playerGHandle[4];
addattacktime = 501;//addattacktimeが0にると、元の位置に戻る
こちらの if文の中に入れば間違いなく addattacktime は 501 になると思いますが、
こちらの if文の中に来ていないのでしょうか?
お使いのプログラム環境が VisualStudio でしたら
addattacktime = 501;//addattacktimeが0にると、元の位置に戻る
の行にブレークポイントを設置して( addattacktime = 501; の行で キーF9 を押す )から
デバッグ実行( キーF5 )してみてください、addattacktime = 501; の行でプログラムが
止まれば addattacktime = 501; の行に来ていて、止まらなければ来ていないことになります
ただ、アップしていただいたプログラム
pastebin.com/9kvrT4Ra
を拝見する限りでは addattacktime は一度 500 になれば確実に 1 づつ減らされて何れ 0 に
なるはずなので、addattacktime = 501; の行に来ないのが不思議ですが…
> addattacktimeが0のままだと以下のプログラムより他のマスに自分が移動できないので、
> 0になったら501にして以下のifの条件に引っかからないようにしました。
ご説明ありがとうございます、了解しました
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.14 ) |
- 名前:マーク42 日時:2019/09/30 00:22
>>addattacktimeが0になるのは追加攻撃状態の処理の時かaddattacktimeの文字の描画の時かどっちでしょう?
addattacktimeが0になるのは追加攻撃がなにも起こらずそのまま数値が減っていくと0になります。そしてそのまま0と描画されます。
>>addattacktimeの文字の描画時に1減らす理由はありますか?
はい、減っていき0になるまでの間に追加攻撃できることを表すので1減らす過程を描画しました。
追加攻撃に関しては押すキーを勘違いしてYだと思っていました。実際はKで押したら動きました。
すいません、なぜ以下のaddattacktime = 501が働かないのか未だにわかりません。
それ以外のcountやKcountはちゃんと動きのでaddattacktimeは0ではなく、501となっていると思ったのですが、
実際に値を見てみると0のままでした。
if (addattacktime == 0) {//addattacktime == 0だと初期値と被ってしまうので0より小さいとした。
playerX = preplayerX;
playerImage = playerGHandle[4];
addattacktime = 501;//addattacktimeが0にると、元の位置に戻る
//if (count < 50) ++count;//これにより連続で攻撃してもif (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])を考慮して連続攻撃ができる!
//★あるフレームが進んでから画像がを動くまでを遅くした、ならば、あるフレームが進んだら数字も次の数字に移るまで遅くできるのは?と考えた。
if (addattacktime = 501 && count < 50) ++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if (frames % 5 == 0) {
++count; if (count > 50) { count = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}
if (addattacktime = 501 && Kcount < 50) ++frames;
if (frames % 20 == 0) {
++Kcount; if (Kcount > 50) { Kcount = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}//★++が>よりも優先順位により優先されるため、というか単純に+1されいくため、その先で条件によって(&&とは違い強制ではなく)Kcount > 50ならばcount = 50となっただけである。
}
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.15 ) |
- 名前:Tatu 日時:2019/09/30 02:23
デバッグ機能を使って検証してみました。
addattacktimeが0になる時、
206行目のaddattacktime==0は満たされる。
214行目でなぜかaddattacktimeが1になる。
描画処理の時にaddattacktimeが0になり0と描画される。
以降、繰り返し。
214行目でaddattacktimeが1になった理由は addattacktime = 501 && count < 50で
501 && count < 50の計算結果が代入されたからです。
>>addattacktimeが0になるのは追加攻撃状態の処理の時かaddattacktimeの文字の描画の時かどっちでしょう?
addattacktimeの文字の描画の時ですが、今の現象には関係がありませんでした。
追加攻撃状態の処理をしなければプレイヤーの位置を戻す処理も行わないのではないかと勘違いしていました。
>>addattacktimeの文字の描画時に1減らす理由はありますか?
こちらについては現在のaddattacktimeを表示するのが目的であるので
そこでaddattacktimeを減らす意味はないと考えます。
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.16 ) |
- 名前:マーク42 日時:2019/09/30 14:56
Tatuさんありがとうございます。
>>214行目でaddattacktimeが1になった理由は addattacktime = 501 && count < 50で
>>501 && count < 50の計算結果が代入されたからです。
に関して
申し訳ないのですが、addattacktimeが1になった理由が説明を読んでもいまいち理解できません。
addattacktime = 501 && count < 50のどのような計算結果が代入されたのでしょうか。もう少し細かく教えて頂けないでしょうか。
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.17 ) |
- 名前:はるかぜ 日時:2019/09/30 17:43
流し読みなので間違ったこと言ってたらごめんなさい
addattacktime = 501 && count < 50
は
addattacktime = (501 && count < 50)
これと同義です
つまり、(501 && count < 50)の計算結果をaddattacktimeに代入する
という命令になっています。
なので(501 && count < 50)が真の時はaddattacktimeに1が代入され、そうでなければaddattacktimeに0が代入される
という風になっていると思います。
ちなみにここの「501」というのはC++では比較時にはtrueとして扱われます。
つまり(501 && count < 50)の場合はcountが50未満の時はtrue、それ以外はfalseです。
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.18 ) |
- 名前:マーク42 日時:2019/09/30 17:48
どうもありがとうございます!
>>なので(501 && count < 50)が真の時はaddattacktimeに1が代入され
なぜ真のときは501ではなく、1が代入されるのでしょうか。
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.19 ) |
- 名前:どん 日時:2019/09/30 17:50
演算子の優先順位の問題です
代入演算子より論理ANDのほうが優先度が高いので,
addattacktime = 501 && count < 50
は,count < 50 が先に行われ,次に501 && count < 50となり,最後に,代入が行われます.
なので,cout < 50の真偽と501の倫理積の結果がaddattacktimeに代入されます.
さらっとコードを見ただけなので,わかりませんが
addattacktime = 501 の部分は代入ではなく==だと思います.
addattacktime = 501の評価値は常に501となってしまうので,以前に501を代入をしているのならば,
代入だとその部分は冗長だと思います
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.20 ) |
- 名前:どん 日時:2019/09/30 17:52
条件式の結果は真偽(1or0)でしか帰ってきません
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.21 ) |
- 名前:Tatu 日時:2019/09/30 18:09
addattacktime = 501 && count < 50については
はるかぜさんとどんさんが書いている通りです。ありがとうございます。
さて、修正の提案ですが
if (addattacktime == 0) {//addattacktime == 0だと初期値と被ってしまうので0より小さいとした。
playerX = preplayerX;
playerImage = playerGHandle[4];
addattacktime = 501;//addattacktimeが0にると、元の位置に戻る
//if (count < 50) ++count;//これにより連続で攻撃してもif (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])を考慮して連続攻撃ができる!
//★あるフレームが進んでから画像がを動くまでを遅くした、ならば、あるフレームが進んだら数字も次の数字に移るまで遅くできるのは?と考えた。
if (addattacktime = 501 && count < 50) ++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if (frames % 5 == 0) {
++count; if (count > 50) { count = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}
if (addattacktime = 501 && Kcount < 50) ++frames;
if (frames % 20 == 0) {
++Kcount; if (Kcount > 50) { Kcount = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}//★++が>よりも優先順位により優先されるため、というか単純に+1されいくため、その先で条件によって(&&とは違い強制ではなく)Kcount > 50ならばcount = 50となっただけである。
}
を
if(addattacktime == 0) {
playerX = preplayerX;
playerImage = playerGHandle[4];
addattacktime = 501;//addattacktimeが0にると、元の位置に戻る
}
if(addattacktime == 501){
//★あるフレームが進んでから画像がを動くまでを遅くした、ならば、あるフレームが進んだら数字も次の数字に移るまで遅くできるのは?と考えた。
if(count < 50) ++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if(frames % 5 == 0) {
++count; if(count > 50) { count = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}
if(Kcount < 50) ++frames;
if(frames % 20 == 0) {
++Kcount; if(Kcount > 50) { Kcount = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}//★++が>よりも優先順位により優先されるため、というか単純に+1されいくため、その先で条件によって(&&とは違い強制ではなく)Kcount > 50ならばcount = 50となっただけである。
}
としてみてはどうでしょうか。
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.22 ) |
- 名前:マーク42 日時:2019/09/30 18:20
代入演算子より論理ANDのほうが優先度が高いので,
addattacktime = 501 && count < 50
は,count < 50 が先に行われ,次に501 && count < 50となり,最後に,代入が行われます.
なので,cout < 50の真偽と501の倫理積の結果がaddattacktimeに代入されます.
count < 50が先に行われてしまうので501を代入した後では、働かないのですね。
どんさんのアドバイスに従いaddattacktime = 501 の部分を==としたところ、addattacktimeが0になったら501になりました!
しかし
if (addattacktime == 501 && count < 50) ++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if (frames % 5 == 0) {
++count; if (count > 50) { count = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}
に書いたように優先的な問題でcount < 50は働きません。
これを解決するにはif文の条件式の優先順位を変える必要があると思いますが、
優先順位を工夫してaddattacktime == 501とした後でcount < 50を持ってきてcountを+1していき50にする方法はないでしょうか。
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.23 ) |
- 名前:マーク42 日時:2019/09/30 18:23
Tatuさんのと私の投稿が被って気が付きませんでした。
どうもありがとうございます!
早速使わせて頂きます。
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.24 ) |
- 名前:マーク42 日時:2019/09/30 18:35
どうもありがとうございます!
おかげで希望通りの動きが出来ました。なるほど優先順位が問題だったのですね。
管理人様、Tatu様、はるかぜ様、どん様、本当にありがとうございます。
ただ一つ疑問があるのですが、
if(addattacktime == 501){
//★あるフレームが進んでから画像がを動くまでを遅くした、ならば、あるフレームが進んだら数字も次の数字に移るまで遅くできるのは?と考えた。
if(count < 50) ++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if(frames % 5 == 0) {
++count; if(count > 50) { count = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}
if(Kcount < 50) ++frames;
if(frames % 20 == 0) {
++Kcount; if(Kcount > 50) { Kcount = 50; }//★上限はないためcountが49より大きくなったらcount = 50により50にする。
}//★++が>よりも優先順位により優先されるため、というか単純に+1されいくため、その先で条件によって(&&とは違い強制ではなく)Kcount > 50ならばcount = 50となっただけである。
}
の部分はaddattacktime == 501となるのですが、countが50になってからKcountが50になります。
同時に+1ずつ上がっていくことは出来ないのでしょうか。私の方で、同じif文としてまとめてみたり、
二つに分けて試したのですが、countが50になってからでないとKcountが50になりません。
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.25 ) |
- 名前:マーク42 日時:2019/09/30 18:51
優先順位としては&&、++、<、==で良いでしょうか。
例えば、if (addattacktime <= 500 && --addattacktime > 0)においては
左が真の場合、右が偽でも&&が優先され、右のモノが優先されます。
そして、右にはーーがあるため<=と>よりも--が次に優先されてしまうため
addattacktimeは500から減っていき負の数になった後、if(addattacktime<0){addattacktime=1}の場合に持っていかれて1になります。
という説明で正しいでしょうか。
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.26 ) |
- 名前:マーク42 日時:2019/09/30 19:01
if (addattacktime == 501 && count < 50)においては
&& により先にcount < 50が評価されるはずですが、addattacktimeが501であったため、先に評価されてしまい
count < 50が評価されず、addattacktimeが501になってもcountは+1されることはなかったということでしょうか。
是非詳しく言教えてください。
(※addattacktimeが501にならなかった理由として、addattacktime = 501が==でなかったということがあります。)
|
Re: 元のマスに戻ったあと前のマスに行けない ( No.27 ) |
- 名前:どん 日時:2019/09/30 19:16
>>同時に+1ずつ上がっていくことは出来ないのでしょうか
同フレーム内で変化させたいのであれば,
countとKcountがともに50未満のときにframeが2回++されているのが原因なので,
if(count < 50) ++frames;
if(frames % 5 == 0) {
++count; if(count > 50) { count = 50; }
}
if(Kcount < 50 && count >= 50) ++frames;//すでに足されているときはしない
if(frames % 20 == 0) {
++Kcount; if(Kcount > 50) { Kcount = 50; }
}
とすることで,できると思います
演算子の優先順位は「C言語 優先順位」とかで調べれば出てきます
if (addattacktime <= 500 && --addattacktime > 0)
は先に優先順位が高い--addattacktimeが行われます.その次に&&の左右の比較が行われ,最後に,&&が行われます
if (addattacktime == 501 && count < 50)
では,addattacktime==501が行われ,count < 50が行われ,&&が実行されます
演算子の優先順位がわかりにくければ,括弧を使って,明確にしたり,ifを入れ子にすることで,わかりやすくするなどの
工夫をしたほうがいいと思います.
|