2016-08-08 11 views
0
で描かれたスプライトを移動

私が結合して、二つの三角形が私Sprite.cppをint型で構成される四角形を描画するためにFBOとVBOを使用し、ここに私のinitメソッドであるSDL2 OpenGLはC++がVBOとFBO

void Sprite::init(float x, float y, float width, float height) { 

_x = x; 
_y = y; 
_width = width; 
_height = height; 

if (_vboID == 0) { 

    glGenBuffers(1, &_vboID); 

} 



vertexData[0] = x + width; 
vertexData[1] = y + height; 

vertexData[2] = x; 
vertexData[3] = y + height; 

vertexData[4] = x; 
vertexData[5] = y; 

vertexData[6] = x + width; 
vertexData[7] = y + height; 

vertexData[8] = x; 
vertexData[9] = y; 

vertexData[10] = x + width; 
vertexData[11] = y; 


glBindBuffer(GL_ARRAY_BUFFER, _vboID); 

glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_DYNAMIC_DRAW); 

glBindBuffer(GL_ARRAY_BUFFER, 0); 

}

、ここでは、私ははっきりといくつかの非常に明白な共同をしないのですdrawメソッド

void Sprite::draw() { 

glBindBuffer(GL_ARRAY_BUFFER, _vboID); 
glEnableVertexAttribArray(0); 


glVertexAttribPointer(0, 2, 0x1406, GL_FALSE, 0, 0); 
glDrawArrays(GL_TRIANGLES, 0, 6); 

glDisableVertexAttribArray(0); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 

}

です私はどこでも解決策を見つけることができないので、ncept、私の問題は私が私の四角形を押し下げるときです。 (S IはWASD移動を使用しているため)。ここで、入力ハンドラ

void InputHandler::handleInput(SDL_Event* event, Sprite *toMove) { 

switch (event->type) { 

case SDL_KEYDOWN: 
{ 
    if (event->key.keysym.sym == SDLK_a) { 
     toMove->setMovementBooleans(MovementTuples::LEFT, true); 
     std::cout << "Set left "; 
    } 
    if (event->key.keysym.sym == SDLK_d) { 
     toMove->setMovementBooleans(MovementTuples::RIGHT, true); 
     std::cout << "Set right "; 
    } 
    if (event->key.keysym.sym == SDLK_s) { 
     toMove->setMovementBooleans(MovementTuples::DOWN, true); 
     std::cout << "Set down "; 
    } 
    if (event->key.keysym.sym == SDLK_w) { 
     toMove->setMovementBooleans(MovementTuples::UP, true); 
     std::cout << "Set up "; 
    } 
    break; 

} 

case SDL_KEYUP: 
{ 
    if (event->key.keysym.sym == SDLK_a) { 
     toMove->setMovementBooleans(MovementTuples::LEFT, false); 
    } 
    if (event->key.keysym.sym == SDLK_d) { 
     toMove->setMovementBooleans(MovementTuples::RIGHT, false); 
    } 
    if (event->key.keysym.sym == SDLK_s) { 
     toMove->setMovementBooleans(MovementTuples::DOWN, false); 
    } 
    if (event->key.keysym.sym == SDLK_w) { 
     toMove->setMovementBooleans(MovementTuples::UP, false); 
    } 
} 

} 

}

ためのコードは、この方法は、静的にアクセスされています。ここで私がダウンしてクリックすると、あなたが私のスプライトのcpp

void Sprite::update() { 

if (movementBooleans[MovementTuples::DOWN]) { 
    _x -= .1f; 
    init(_x, _y, _width, _height); 
    std::cout << "Moved to: (" << _x << ", " << _y << ")"<< std::endl; 
} 

にSキーをクリックしたときにスプライトを下に移動するためのコードは、私の矩形が完全に消えて、で、_x値は同じままです。私は入力をテストし、正確に私がそれをしたい、私はちょうど移動する矩形を取得するように見えることはできません動作します。誰も私のスプライトを移動する方法を把握するのに役立つことができます、ありがとう!

答えて

1

私はOpenGLを使用しています。ユーザが実装した入力ハンドラを使用しているのでSDLを使用していませんが、コンセプトは同じでなければなりません。

現在使用しているゲームエンジンには、EngineクラスがSingletonオブジェクトであるEngineクラスオブジェクトから継承されたGameクラスオブジェクトがあります。このゲームエンジンの構造上、 Engineクラスでは、Gameクラスが仮想keyboardInput関数を実装する必要があります。ここではプロトタイプが見えるものである

のようなエンジンクラス

class Engine : public Singleton { 
protected: 
    // Protected Members 
private: 
    // Private Members 

public: 
    // virtual destructor & public functions 
protected: 
    // explicit protected Constructor & protected functions 
private: 
    bool messageHandler(unsigned uMsg, WPARAM wParam, LPARAM lParam); 

    virtual void keyboardInput(unsigned vkCode, bool isPressed) = 0; 

    // Other Private Functions 

}; // Engine 

ここ
class Game sealed : public Engine { 
private: 
    // private members here 

public: 
    // Constructor and virtual Destructor 

private: 
    virtual void keyBoardInput(unsigned vkCode, bool isPressed) override; 
}; // Game 

がついに

// ---------------------------------------------------------------------------- 
// messageHandler() 
bool Engine::messageHandler(unsigned uMsg, WPARAM wParam, LPARAM lParam) { 
    switch(uMsg) { 
     case WM_CLOSE: { 
      PostQuitMessage(0); 
      return true; 
     } 
     case WM_SYSKEYDOWN : { 
      if ((VK_MENU == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_RMENU; // Alt Key 
      } 
      // Fall Through 
     } 
     case WM_KEYDOWN: { 
      if ((VK_RETURN == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_SEPARATOR; 

      } else if ((VK_CONTROL == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_RCONTROL; 
      } 

      if (0 == (lParam & 0x40000000)) { // Supress Key Repeats 
       keyboardInput(wParam, true); 
      } 
      return true; 
     } 
     case WM_SYSKEYUP: { 
      if ((VK_MENU == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_RMENU; // Alt Key 
      } 
      // Fall Through 
     } 
     case WM_KEYUP: { 
      if ((VK_RETURN == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_SEPARATOR; 

      } else if ((VK_CONTROL == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_RCONTROL; 
      } 

      keyboardInput(wParam, false); 

      return true; 
     } 
     case WM_MOUSEMOVE: { 
      // Mouse Motion Detected, Coordinates Are WRT Window Therefore 
      // 0,0 Is The Coordinate Of The Top Left Corner Of The Window 
      m_mouseState.position = glm::ivec2(LOWORD(lParam), HIWORD(lParam)); 
      mouseInput(); 
      return true; 
     } 
     case WM_LBUTTONDOWN: { 
      m_mouseState.isButtonPressed[MOUSE_LEFT_BUTTON] = true; 
      mouseInput(); 
      return true; 
     } 
     case WM_LBUTTONUP: { 
      m_mouseState.isButtonPressed[MOUSE_LEFT_BUTTON] = false; 
      mouseInput(); 
      return true; 
     } 
     case WM_RBUTTONDOWN: { 
      m_mouseState.isButtonPressed[MOUSE_RIGHT_BUTTON] = true; 
      mouseInput(); 
      return true; 
     } 
     case WM_RBUTTONUP: { 
      m_mouseState.isButtonPressed[MOUSE_RIGHT_BUTTON] = false; 
      mouseInput(); 
      return true; 
     } 
     case WM_MBUTTONDOWN: { 
      m_mouseState.isButtonPressed[MOUSE_MIDDLE_BUTTON] = true; 
      mouseInput(); 
      return true; 
     } 
     case WM_MBUTTONUP: { 
      m_mouseState.isButtonPressed[MOUSE_MIDDLE_BUTTON] = false; 
      mouseInput(); 
      return true; 
     } 
     case WM_MOUSEWHEEL: { 
      // Mouse Wheel Moved 
      // wParam Contains How Much It Was Moved 
      return true; 
     } 
     default: { 
      return false; // Did Not Handle The Message 
     } 
    } 
} // messageHandler 

のWindows

用MessageHandlerの()関数であるゲームのクラスt彼はkeyboardInput()関数です

// ---------------------------------------------------------------------------- 
// keyboardInput() 
void Game::keyboardInput(unsigned vkCode, bool isPressed) { 
    std::ostringstream strStream; 
    strStream << "Key 0" << std::hex << vkCode << " was " << (isPressed ? "Pressed" : "Released"); 
    Logger::log(strStream); 

    if (VK_ESCAPE == vkCode) { 
     PostQuitMessage(0); 
    } 

    static bool keyPressed[256] = { 0 }; 
    if (vkCode < 256) { 
     keyPressed[vkCode] = isPressed; 
    } 

    if (isPressed) { 
     return; 
    } 

    switch (vkCode) { 
     case VK_DOWN: 
     case 'S' : { 
      // do logic here 
      break; 
     } 
     case VK_LEFT: 
     case 'A' : { 
      // do logic here 
      break; 
     } 
     case VK_RIGHT: 
     case 'D' : { 
      // do logic here 
      break; 
     } 
     case VK_UP: 
     case 'W' : { 
      // do logic here 
      break; 
     } 
    } 

} // handleKeyboard 

コードをよく見てみましょう。キーが押されたときにポーリングするのではなく、キーがリリースされたときに照会または待機するのを待っています。この論理の理由はこれです。キーを押し下げると、上の状態になることなく繰り返し押すことができます。これは、画面に表示される同じキーが表示されるテキストエディタで同じキーを押した場合と同じです。これを回避したり、この動作を回避するには私たちは反対の論理をします。

キーがリリースされた時期を調べます。キーは一度だけ離すことができ、解除状態に再び入るためにはもう一度押す必要があります。このようにして、各キーを押すごとにプログラムの動作が1回発生し、リリースされます。

あなたが気づいたら、キーが押された状態にあるかどうかを確認し、それが元に戻っていればそれを確認します。このことが重要なのは、キー押下状態がデフォルトですでに解放状態になっているため、プログラムが自動的にメッセージハンドラ内の処理を実行するためです。したがって、ここで何が起きるかは、Game::keyboardInput()Engine::messageHandler()の関数が呼び出されたときにレンダリングフレームまたは更新フレームの間に起こります。そして、keypressが状態をtrueに変更したことを検出した場合、関数から戻り、キー;キーが解放され、状態が解放された状態に戻されると、ifステートメントをスキップして、処理しているキーのswitch文に移動します。

+0

+1は努力していますが、これは文字通り私の質問とは何の関係もありません。あなたは何をしているのですか?私の質問は私のスプライトを動かす方法です。 – Luke

+0

あなたが私に説明していたことから: "... ...私の問題は、私が私の四角形を押し下げるときです..." "あなたはあなたの' inputHandler() 'のロジックを見せてから、 「私がクリックすると、四角形は完全に消え、_xの値は変わらず、キーが繰り返し押されているように振る舞います。あなたの 'Sprite :: update()'では、 '0.1f'から' 0.05f'までのより小さい値を使い、 '_x'変数を変更するのではなく、' _y'で置き換えてみてください。垂直方向に移動したい場合は、ベクトルのY成分を増減します。 –

+0

これらの関数を呼び出す場所のコードも表示されていません。 –

1

OpenGLシェイプを移動したい場合は、実際に行列の変換を行う必要があります。

私は個人的にGLMを使って重労働をしています。そのため、変換が完了した後に行列をGLSLに渡すだけです。

関連する問題