i used fbo , vbo bind , draw rectangle comprised of 2 triangles int sprite.cpp, here init method
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);
}
and here draw method
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);
}
i missing obvious concept because can't seem find solution anywhere, problem when press s rectangle not move down. (s because using wasd movement) here code input handler
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 "; } 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); } } }
}
this method statically accessed. here code moving sprite down when click s key in sprite cpp
void sprite::update() { if (movementbooleans[movementtuples::down]) { _x -= .1f; init(_x, _y, _width, _height); std::cout << "moved to: (" << _x << ", " << _y << ")"<< std::endl; }
when click down, rectangle disappear , _x value stays same. tested input , works how want to, can't seem rectangle move. can me figure out how move sprite, thanks!
i'm using opengl. although not using sdl since i'm using user's implemented input handlers concept should same.
the game engine using has game class object inherited engine class object engine class singleton object. due structure of game engine; engine class requires game class implement virtual keyboardinput function. here prototype looks like
engine class
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
game class
class game sealed : public engine { private: // private members here public: // constructor , virtual destructor private: virtual void keyboardinput( unsigned vkcode, bool ispressed ) override; }; // game
here messagehandler() function windows
// ---------------------------------------------------------------------------- // 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 wrt window therefore // 0,0 coordinate of top left corner of 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 moved return true; } default: { return false; // did not handle message } } } // messagehandler
finally keyboardinput() function
// ---------------------------------------------------------------------------- // keyboardinput() void game::keyboardinput( unsigned vkcode, bool ispressed ) { std::ostringstream strstream; strstream << "key 0" << std::hex << vkcode << " " << ( 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' : { // logic here break; } case vk_left: case 'a' : { // logic here break; } case vk_right: case 'd' : { // logic here break; } case vk_up: case 'w' : { // logic here break; } } } // handlekeyboard
when closely @ code; i'm not polling see when key pressed i'm querying or waiting see when key released. reason logic this; when press key down, can repeatedly pressed without hitting state. holding down same key in text editor see same key displayed screen. around or avoid behavior; opposite logic.
we when key released. key can released once , has pressed again in order enter release state again. way have action of program happening once each key press release.
now if noticed check see if key in pressed state , if return; important if not program automatically within message handler because key press state in released state default. happens here during either render frame or update frame when game::keyboardinput()
, engine::messagehandler()
functions invoked , if detected keypress has changed state true returns function , gets called again continuously until release key; once key released , state changed released skips on if statement , goes right switch statement key handling.
Comments
Post a Comment