2017-08-04 13 views
0

私はタワー防衛ゲームに取り組んでいます。ユーザーがマウスをクリックするタイルを選択する必要があります(今はタイルの周りに枠線を描いています)。今ではコードが時々動作していますし、それをよりうまく動作させる方法がわかりません。今すぐ領域をクリックすると、タイルが選択され、時にはすぐ​​に選択解除され、それ以外の時間には選択解除されるコードがあります。私はマウスを押し下げたままの状態で、マウスを「クリック」します。私が必要とするのは、マウスボタンが押されている時間に関係なく、タイルを選択せず​​にタイルを選択することです。私はセットアップにmouseinputと同様に格納する変数を持っている私のゲームのクラスでSDL C++マウス入力処理トグル効果

MouseInput.h

#pragma once 

#include <SDL.h> 

class MouseInput 
{ 
public: 
    MouseInput(); 
    ~MouseInput(); 

    void Update(); 

    bool GetMouseButton(int index); 
    SDL_Event GetEvent(); 

    bool GetPressed(); 
    bool GetReleased(); 

private: 
    void GetButtonStates(); 

private: 
    bool mouseArray[3]; 
    int x, y; 
    bool justReleased; 
    bool justPressed; 
    SDL_Event e; 
}; 

MouseInput.cpp

#include "Input.h" 

MouseInput::MouseInput() 
    : 
    x(0), 
    y(0), 
    justReleased(false), 
    justPressed(false) 
{ 
    SDL_PumpEvents(); 

    for (int i = 0; i < 3; i++) 
    { 
     mouseArray[i] = false; 
    } 
} 

MouseInput::~MouseInput() 
{ 

} 

void MouseInput::Update() 
{ 
    SDL_PollEvent(&e); 

    justReleased = false; 
    justPressed = false; 

    if (e.type == SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_LEFT) 
     justPressed = true; 
    else if (e.type == SDL_MOUSEBUTTONUP && e.button.button == SDL_BUTTON_LEFT) 
     justReleased = true; 
} 

bool MouseInput::GetPressed() 
{ 
    return justPressed; 
} 

bool MouseInput::GetReleased() 
{ 
    return justReleased; 
} 

bool MouseInput::GetMouseButton(int index) 
{ 
    if (index <= 3 && index >= 1) 
    { 
     return mouseArray[index - 1]; 
    } 

    return false; 
} 

SDL_Event MouseInput::GetEvent() 
{ 
    return e; 
} 

void MouseInput::GetButtonStates() 
{ 
    SDL_PollEvent(&e); 

    if (e.type == SDL_MOUSEBUTTONDOWN) 
    { 
     // 1 = Left; 2 = Center; 3 = Right 
     mouseArray[e.button.button - 1] = true; 
    } 

    if (e.type == SDL_MOUSEBUTTONUP) 
    { 
     mouseArray[e.button.button - 1] = false; 
    } 
} 

:私のマウス入力クラスは、次のように設定されていますクリックされたタイルの座標。また、マウスが押されたかどうかを確認する変数pressedがあります。私の更新機能では、マウスが押されていないかどうかを確認します。マウスが押されていない場合は、マウスが押されたかどうかを確認して、ゲームがマウス位置の座標を取得できるかどうかを確認します。私のゲームでは

マウスクラス

bool clicked; // In my custom Mouse.h file and set to false in constructor 
MouseInput input; // In my custom Mouse.h file 

Mouseクラスの更新()

input.Update(); // Calls the MouseInput updating 

if (input.GetPressed() && !clicked) 
{ 
    clicked = !clicked; 
    printf("OK"); 
} 
//else if (clicked && input.GetReleased()) 
else if (clicked && input.GetPressed()) // Somewhat works. It works almost like before. If I click the mouse it shows up then sometimes when I click again it works, and other times I have to click a couple times 
{ 
    clicked = !clicked; 
} 

std::pair<int, int> coords; // Will store the coordinates of the tile position that the mouse rests in 
bool pressed; // If the mouse was pressed (i should call it toggle because it's true if the mouse was pressed once, then false if the mouse was pressed again, then true...ect.) 

更新機能:私はので、ここでクレイジーに聞こえる私のコードのいくつかを知っていますクラス私はちょうどマウスのクリックがtrueであるかどうかを確認し、必要なものを描画します

if (mouse.GetClicked()) 
{ 
    // Draw what I need here. 
    // Currently is only drawn when I hold down the mouse 
    // And not drawn when I release the mouse. 
} 

次に、タイルの周りに四角形を描いているとき、私はpressed = trueの場合にのみ描画します。それ以外の場合は描画されません。このコードは時々動作し、他の時は動作しません。私が望む効果を得るために、私は実際にマウスをすばやくクリックしなければなりません。私がしなければ、マウスボタンを押したままにして四角がちょうど点滅しているように見えることがあります。

+0

無関係ですが、 'GetMouseButton'では' -1 'ではなく 'index> = 1'を意味すると思います。 – hnefatl

+0

あなたは正しいです。なぜ私が-1を持っているのか分かりません。それは理にかなっていない。 – Vince

答えて

0

問題は、「マウスダウン」イベントがイベントであることです。これは一度起こり、処理され、ボタンが物理的に再度押されるまでは起こらないはずです。あなたのコードでは、一旦押されると、内部状態を「押された」に設定し、解放されるまでそれを変更しません。これは大丈夫ですが、この内部状態をポーリングするコードでは、状態ではなくイベントであるかのように扱われます。そのため、マウスボタンが押されている間は更新機能が実行されるたびに「新しいボタン押下」が表示されます。

に役立つかもしれない。この(1つのボタンとボタンのを押すだけで、画像を示すのアイデアを使用して、あなたのコードの簡易版)は、あなたはそれを視覚化:

bool buttonPressed = false; 
bool imageShown = false; 
while (true) 
{ 
    SDL_Event e; 
    SDL_PollEvent(&e); 
    if (e.type == SDL_MOUSEBUTTONDOWN) 
     buttonPressed = true; 
    else if (e.type == SDL_MOUSEBUTTONUP) 
     buttonPressed = false; 

    if (!imageShown && buttonPressed) 
     imageShown = true; 
    else if (buttonPressed) 
     imageShown = false; 
} 

あなたはどのようにするたびにループの実行を参照しています、このイテレーションでイベントが発生していない場合でも、、状態は維持されますか?これにより、imageShown変数は、 "ボタンアップ"イベントが発生して状態をリセットするまで、各繰り返しのオン/オフを繰り返し続けます。

入力コントローラの一部を再加工する必要があります。 "今すぐ"と "しばらく押されていたボタン"と区別する方法を公開する必要があります。

アイデアは、たとえば、 ButtonsPressedとメンバー(ただし、私はあなたがより適切な名前を考えることができると確信しています)。 ButtonsJustPressedのメンバーは、GetButtonStatesに電話するたびにfalseにリセットする必要があります。ButtonsPressedのメンバーは今現在行っていることですが、ループの特定の繰り返しであれば、trueです。

Aは、このことを考慮するために、上記のバージョンをひねら:

bool buttonJustPressed = false; 
bool buttonJustReleased = false; 
bool imageShown = false; 
while (true) 
{ 
    // As far as we know, this iteration no events have been fired 
    buttonJustPressed = false; 
    buttonJustReleased = false 
    SDL_Event e; 
    SDL_PollEvent(&e); 
    if (e.type == SDL_MOUSEBUTTONDOWN) 
     buttonJustPressed = true; 
    else if (e.type == SDL_MOUSEBUTTONUP) 
     buttonJustReleased = true; 

    if (!imageShown && buttonJustPressed) 
     imageShown = true; 
    else if (imageShown && buttonJustReleased) 
     imageShown = false; 
} 

ボタンがリリースされたばかり/押された場合には、このバージョンでは唯一の画像の視認性をどのように変化するかを参照してください - ボタンのが開催されている場合イベントが発生しないので、状態はfalseのままであり、イメージの状態は変わりません。

+0

ここにあなたの言うことを理解していますが、まだ問題があります。私はそれをトグルすることができた。 (ユーザがマウスを押すと)。しかし、ユーザーがマウスをもう一度押してトグルすると、今管理している問題です。 – Vince

+0

私がしようとしているのは、ユーザーがマウスをクリックするとビルド可能なタワーが表示されます。ユーザーがマウスを再びクリックすると、それは消えてしまいます。今すぐあなたが与えたあなたの例を出て、私はマウスを保持して、塔を表示させる必要があり、マウスがリリースされると消えます。 – Vince

+0

@Vinceまた、更新関数コードを 'if(!pressed && mouseInput.GetMouseButtonJustPressed(1))'の行に沿って変更しましたか?その場合、あなたの更新されたコード(入力コードと "表示コード")を含めるようにあなたの投稿を編集すれば、後でそれを見ていきます。 – hnefatl

関連する問題