2010-11-22 26 views
0

IF制御構造を使用する前に、さらにネストされたIFで遭遇したことがない状況に遭遇しました。通常、ネストされたIFは私が細かい細かいディテールでチェックしているものを分解しますが、この例では実際には外側の条件と矛盾します - マウスのクリックを確認しています。ここで条件付き実行の場合

はコードです -

if (mouseState.LeftButton == ButtonState.Pressed) 
{ 
    if (mouseState.LeftButton == ButtonState.Released) 
    { 
      //move sprite to clicked position 
      spritePos.X = mouseState.X; 
      spritePos.Y = mouseState.Y; 
    } 
} 

私は質問のカップルを持っています。私は、条件付き引数が1回だけチェックされ、trueと評価された場合、次のステートメントが実行されることを教えられました。 これは本当にですか、ブロック内のすべてのステートメントを実行する前に実際にチェックされていますか? - 後者は明らかに私の入れ子のifと衝突するでしょう。

これが当てはまる場合、なぜ私のボタンクリック方法は機能しませんか? Spriteは、マウスのリリースが決して実行されないかのように動きません。 両方の条件のチェックを実行する間に遅延が小さいので、その時間内に物理的にボタンを放すことができないためですか?私はこれについてちょっとハックすることができますは、時間遅延でそれを克服することができます入れ子条件をチェックするまでにマウスボタンのリリースを許可するために十分な大きさかもしれない?

私が見たマウスクリックアクションのメソッドは、前のフレームからマウスのプロパティを使用し、新しいフレームと比較してマウスクリックを確認します。しかし、この方法では、アクションを実際に処理するために、少なくとも1つのフレームの遅延を導入する必要があります。これはフレームレートの高いものでは目立たないかもしれませんが、議論のために私はゲームを20fpsでレンダリングしました。 UpdateInput()はフレームをレンダリングする前に呼び出され、位置は更新され、フレームは最後にレンダリングされます。

完全なマウスクリック操作が1/20秒未満で実行できる場合は、最初のプレスで変数を保存するのではなく、すぐにアクションを処理し、次のフレーム?これは確かに入力の遅延を導入するよりも良いでしょう。

これは他の人にも考慮されているはずです。実際にコードの実行を一時停止する時間遅延操作については正しく考えていないと思います。 時間遅れは、コードのプロセッサ実行を一時停止することができますか、またはレンダリングや入力を受け付けるなどの実行の結果だけを一時停止できますか?それらは私が使用経験があるものではなく、遅延がどのように働くのか混乱するかもしれません。

ありがとう、 Andrew。

+0

どの言語をプログラミングしていますか、どのAPIを使用していますか。これは実際にmouseState.LeftButtonの評価がmouseStateの状態を変更できる(または更新されるまで待つ)副作用を持つかどうかによって異なります。 –

+0

あなたの質問は技術的な質問よりもエッセイに似ています。焦点が合わずに答えにくいです。それをたくさん下げてください。コードスニペットはあなたのものか、どこかで見つけましたか?それは動作しますか?それがうまくいかない場合、実際には何が起こりますか?何が起こると思いますか?ここにある問題(もしあれば)はif文の評価ではありません。 –

+0

申し訳ありませんが、私はそれが十分に短いと思った。私は、私が考えていたことについて言及しようとしましたが、それは効果があるかもしれません。コードスニペットは私のものです - ちょうどその下に述べたようには機能しません。その結果、任意にアニメーション化されたスプライトが、クリックした場所に表示されるのではなく、動き続けます。それはちょうど入門を学ぶための入門です。言語はXNA 3.1を使用するC#です。 –

答えて

1

アンドリュー文が動作している場合、あなたの問題は、道とは何の関係もありません。 mouseStateは、GetState()が呼び出されたときのマウスの状態を表します。マウスが状態を変えるだけで変化しません。コードスニペットが期待どおりに動作するためには、各if文の前にGetState()を呼び出さなければなりません。マウスの状態は、ポーリングするか手動で設定した場合にのみ変化します。

+0

私は気づいていないのでとても馬鹿だそれ。それを私に指摘してくれてありがとう。 –

+0

@Drew:Er、マウスを押し下げて、最初の条件がチェックされてから2番目の条件がチェックされるまでの間にナノ秒以内にリリースする必要があります。 –

-1

左ボタンを押すと、プログラムチェックの前に解除する方法がないため、if (mouseState.LeftButton == ButtonState.Released)の条件が機能しません。

遅延は、マウスやキーボードによって

入力遅延が目立たないプロセッサにコードの 実行を一時停止時間を計ることができます。

私は左ボタンの状態に各フレームを格納する変数を使用したい:

while (1) // ininity loop 
{ 
    if (mouseState.LeftButton == ButtonState.Pressed) 
    { 
     button_left_pressed = 1; // is pressed 
    } 
    else // Left Button is not pressed 
    { 
     if (button_left_pressed) // but was pressed (is released) 
     { 
      spritePos.X = mouseState.X; 
      spritePos.Y = mouseState.Y; 
      button_left_pressed = 0; // is not pressed 
     } 
    } 
    // do another action   
} 
+0

こんにちはatlavis、私はこれがうまくいくはずだと思う、それは私が見ているユーザー入力の例に非常によく似ています。私はなぜそれが自分のやり方で動かなかったのか、ちょっと不安だった。いくつかの私の質問にお答えいただき、ありがとうございます。 –

+0

私はチュートリアルのhttp://bluwiki.com/go/XNA_Tutorials/Mouse_Inputにあるようなソリューションを実装しました。私は最後に時間遅れについてチェックしてからあなたの投稿を編集したことがわかります。私は、時間の遅れを入れて、ボタンが離されたときのカーソルの位置と、スプライトの位置を最終的に更新するときのどこに他の問題を引き起こす可能性があることを認識しています。しかし、時間の遅延が(同じブロック内であっても)コードの実行を実際に遅らせるかどうかをもう一度確認できますか?私は彼らがフレームレートが制限されることが他のどのように行うと思うが、確かにしたい。ありがとう。 –

+0

はい、遅延機能がコード実行を停止します(遅延時間(ミリ秒単位))PASCAL – atlavis

2

あああなたはおそらくif文のあなたのブロックの前に行っている

何...ここにそんなに間違ってありますされています。今GetState機能は、実際に現在を決定するものである

MouseState mouseState = Mouse.GetState(); 

それをMouseState構造体にパックします。 =では、その状態をmouseState変数に割り当てています。

mouseStateが変更される唯一の時間は、自分で変更する場合です!このように見えるようにあなたの条件:

if (mouseState.LeftButton == ButtonState.Pressed) { 
    if (mouseState.LeftButton == ButtonState.Released) { /* "do stuff" */ } 
} 

mouseState.LeftButton場合は、変更されていない、チェックしている、2つの完全に異なるものに等しいです!だから明らかに "やること"は決して走りません。

は、今私は、コードの作業を行うことによって、あなたがように見える方法を説明することができ、問題の他の部分は、それが動作するはずを考える:

if (Mouse.GetState().LeftButton == ButtonState.Pressed) { 
    // Some kind of delay, perhaps? 
    if (Mouse.GetState().LeftButton == ButtonState.Released) { /* "do stuff" */ } 
} 

ので状態は、あなたがそれをチェックするたびに更新されます。

ここにこのコードの問題があります。 2つのifステートメントの間で、マウスは「押された」状態から「解放された」状態に移行する必要があります。そうでない場合、条件はトリガーされません。

遅延の長さを長くしても、多くの理由でそれが解決されるわけではありません。まず、実際にゲームを実行するのに時間がかかります。第二に、それをフレームの時間の100%にまで増加することは不可能です。したがって、あなたの状態がトリガされない確率は常にあります。

したがって、入力を処理するより良い方法は、フレームの間の状態の状態を追跡することです。これを行う最善の方法は、すべてのチュートリアルと同じように、Update関数の呼び出しの間にMouseState lastMouseState;を格納することです。だからあなたのコードは次のようになります。

MouseState mouseState = Mouse.GetState(); 
if (lastMouseState.LeftButton == ButtonState.Pressed) 
{ 
    if (mouseState.LeftButton == ButtonState.Released) 
    { 
     /* "do stuff" */ 
    } 
} 
lastMouseState = mouseState; 

は今、あなたは言うかもしれない、これはまだあなたが最初の場所で言及した実際の問題が残ります:何の使用がこんなに早くクリックするとマウスの状態が変化していますGetStateへの呼び出しの間に戻りますか?

まあ私の最初の反応は「それを心配しないでください」です。こので、XNA入力フレームワークに関する既知の問題です。しかし、実際には、人々は一般的にクリックやタイプがあまりにも速くないので、実際には012Fに60FPSの問題が発生することがわかります。

ゲームが60FPSを大幅に下回る場合でも、60FPSでアップデートを実行できます。描画レートを下げるには、Game.SupressDrawを使用するか、Game.BeginDrawをfalseに戻します(hereおよびhereを参照)。また、60FPS未満でアップデートを実行する必要がある場合でも、60FPS(またはそれ以上)で入力を更新することはできますが、それ以上の作業です。 (そのXNA入力はメインスレッド上で実行する必要があります。)

(個人的に私はあなただけ60FPSで動作し、それを心配停止することをお勧め!)

を最後に、それがために十分でない場合あなたは、interopとメッセージポンプをフックし、WM_LBUTTONUPメッセージをキャッチすることができます。これは大規模な過剰殺害ですが、あなたが望むものを得るための「正しい」方法です。

+0

Andrew氏に感謝します。その情報は本当に便利です。私は先進的なものを試してみるつもりはありませんが、私はしばらくの間オン/オフをプログラミングしていますが、今は入りにくいので、別のショットを試してみると、それはかなり新しいことです。物を忘れなさい。スティーブに正しい答えを与えました。少し早くそこに着いたからですが、あなたが提供した情報はすばらしかったです。 –