• Advertisement
Sign in to follow this  

SDL how to move an object by holding a button rather then pressing the button over and over

This topic is 1864 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've already tried looking this up but I can't find anything to help.
I just learned how to move an object which was successful. You press a button once to move it, but you can't hold it down to keep the object moving, you have to keep tapping the button to make move more.

Is there a certain way or certain code to make it so that you can just hold the button to keep moving and let go whenever you want to stop?

Share this post


Link to post
Share on other sites
Advertisement
Sure, there are two common ways:

[b]A)[/b] On button press, set bool "move" to true. On button release, set bool "move" to false. (You have to create such a bool yourself). Every frame, if "move" is true, move the player. Realistically, you'll want several bools, because you can move in several directions, or alternatively, two ints (x,y) holding the amount to move each frame, positively or negatively.

[b]B) [/b]Let SDL handle the "move" boolean for you, and instead call [url="http://sdl.beuc.net/sdl.wiki/SDL_GetKeyState"]SDL_GetKeyState[/url]() which returns a bool array of most of the keyboard keys and whether they are currently being held or not (see documentation link). Every frame you can then check if the key is held down, and move the player. Edited by Servant of the Lord

Share this post


Link to post
Share on other sites
(sigh) Now I'm hitting some more problems, things may be a little mixxed up. Now it won't move at all! It shows but doesn't respond in movement. Heres the code I wrote if you or anyone can see what I'm doing wrong

[sharedmedia=core:attachments:12623][CODE]
#include "SDL.h"
int main(int argc, char *argv[])
{
bool bRun = true;
SDL_Surface *screen , *ship;
SDL_Rect shipRect;
shipRect.x = 100 ;
shipRect.y = 100 ;

SDL_WM_SetCaption("Fryday", NULL);
screen = SDL_SetVideoMode( 256 , 224 , 32 , SDL_DOUBLEBUF|SDL_HWSURFACE|SDL_ANYFORMAT);

SDL_FillRect(screen , NULL , 0x221122);
ship = SDL_LoadBMP("./ship.bmp");
SDL_SetColorKey( ship, SDL_SRCCOLORKEY, SDL_MapRGB(ship->format, 255, 0, 255) );
SDL_BlitSurface( ship , NULL , screen , &shipRect );
SDL_Flip(screen);
SDL_Event event;
while(bRun) {
bool keysHeld[323] = {false}; // everything will be initialized to false

if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
bRun = false;
}
if (event.type == SDL_KEYDOWN)
{
keysHeld[event.key.keysym.sym] = true;
}
if (event.type == SDL_KEYUP)
{
keysHeld[event.key.keysym.sym] = false;
}

if ( keysHeld[SDLK_ESCAPE] )
{
bRun = false;
}
if ( keysHeld[SDLK_LEFT] )
{
shipRect.x -= 1;
}
if ( keysHeld[SDLK_RIGHT] )
{
shipRect.x += 1;
}
if ( keysHeld[SDLK_UP] )
{
shipRect.y -= 1;
}
if (keysHeld[SDLK_DOWN])
{
shipRect.y += 1;
}
}
}; // while(bRun) { END
return 0;
}
[/CODE]

Share this post


Link to post
Share on other sites
I am a pygame person, but typically it's done as this:
[CODE]
if event.key == event.keydown:
if event.ket == event.K_UP:
ship.location.x -= 10 // Pygame takes (0,0) top left screen MAX_width,MAX_height) to be bottom right screen
[/CODE]

Your code handles keydown alone versus handling with some specific key being pressed AND held. Hope this helps. Edited by Cdrandin

Share this post


Link to post
Share on other sites
Also, you only draw the ship once. You need to clear and redraw the ship every time it moves (also you need to include code that prevents the ship from being moved too quickly, as you are probably going to get 100+ FPS when you are only drawing one picture)

Share this post


Link to post
Share on other sites
As RulerOfNothing says, your game loop needs to be setup like this:
[list]
[*]Load resources
[*]Initialize game settings
[*]While (still playing)
[list=1]
[*]Get [b]all [/b]the player input ([color=#ff0000][s]if[/s][/color] [i][u][b]while[/b][/u](SDL_PollEvent(&event)) [/i])
[*]Update the game objects (by deltaTime*)
[*]Do any game thinking ([size=2]optionally part of the updating code instead[/size])
[*]Render:
[list=1]
[*]Clear the entire screen
[*]Draw every object from back to front
[*]Draw the GUI
[*]Flip the screen buffers
[/list]
[/list] [*]Uninitialize the game, if neccesary.
[*]Free game resources
[/list]
*[size=2]A simple deltaTime is 'currentTime - previousTime'. This is the amount of time passed since the last frame. See [url="http://www.libsdl.org/docs/html/sdlgetticks.html"]SDL_GetTicks[/url](). Others prefer a fixed timestep, but for beginner projects, 'currentTime - previousTime' might be simpler, and works just fine.[/size]

Your game should follow that basic pattern. 99% of games follow that basic pattern (with minor tweaks and variations here or there).

You should go through [url="http://lazyfoo.net/SDL_tutorials/"]Lazy Foo's SDL tutorials[/url].
Particularly:[list]
[*][url="http://lazyfoo.net/SDL_tutorials/lesson04/index.php"]Lesson 4: Event Driven Programming[/url]
[*][url="http://lazyfoo.net/SDL_tutorials/lesson10/index.php"]Lesson 10: Keystates[/url]
[*][url="http://lazyfoo.net/SDL_tutorials/lesson14/index.php"]Lesson 14: Regulating Frame Rate[/url]
[*][url="http://lazyfoo.net/SDL_tutorials/lesson32/index.php"]Lesson 32: Frame independent movement [/url]
[/list]
But the tutorials build off each other, so you really [i]really[/i] should go through them from the start.
You also should read [url="http://lazyfoo.net/articles/article04/index.php"]Lazy Foo's article on Game Loops[/url], and if you have any questions, ask here and we'll be glad to help.

Share this post


Link to post
Share on other sites
BigBadBear - I am no expert in the lanquage you are using, but ( IF ) I am reading your code correctly ( THEN ) in your IF Keysheld statement, Romove The Equal Sign ( = ) after your Plus/Minus ( + / - ) signs and your ship should move.

The language I use has KeyDown(Upkey) vs. KeyHit(Upkey) to test whether a key is held or simply pressed.

Share this post


Link to post
Share on other sites
@OP: The problem with your code is that:
[b]A) [/b]You do your event looping in an if() instead of a while()
[b]B) [/b]You don't ever actually initialize keyHeld[], leaving it set as false, thus never triggering the movement.
[b]C) [/b]You have your keyHeld[] code inside your event loop when it should be outside. (Polling input states should usually be outside the event loop, handling input events should be inside the event loop)

[quote name='Poigahn' timestamp='1354967035' post='5008466']
BigBadBear - I am no expert in the language you are using, but ( IF ) I am reading your code correctly ( THEN ) in your IF Keysheld statement, Romove The Equal Sign ( = ) after your Plus/Minus ( + / - ) signs and your ship should move.
[/quote]
Not in C++. [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

[b]var1 + var2[/b] doesn't change the result of 'var1', you'd have to do [b]var1 = var1 + var2[/b]. Using [b]+=[/b] is shorthand for that. [b]var1 += var2[/b] [i]does[/i] change var1 properly.

Share this post


Link to post
Share on other sites
Thank you SOTL. That ia why I Come here to learn and expand my knowlege. After reading your reply to my quote, I Checked it out. I think what I was thinking that since BigBadBear was only increasing or decreasing by 1, My trend of thought was the Increment / decrement operators in C++ of ++ or -- Example Ship.x ++ or Ship.x -- in order to increase / decrease the Ship.x by a value of 1.

Share this post


Link to post
Share on other sites
Something else to consider would be to check the Input every frame; if a key is down, mark it in an Input Object, if it's not leave blank (false); then, you can pass the Input object to anyone who wants to know about Input. Like this (pseudo-code):

[code]
struct TInput {
bool IsLeftPressed;
bool IsRightPressed;
bool IsUpPressed;
bool IsFirePressed;
bool IsJumpPressed;
};

// create this funciton to get the current keys being pressed
void GetInput(TInput& input)
{
while(PollKeyEvent(&keyEvent) {
if (keyEvent.IsPressed) {
if (keyEvent.keycode == LEFT_KEY) {
input.IsLeftPressed;
}
if (keyEvent.keycode == UP_KEY) {
input.IsUpPressed;
}
// Continue checking them all
}
}
}

// in Main loop
while(IsRunning) {
TInput input;
GetInput(input);

// now pass the input into your Update functions, which would check input.IsFirePressed to see if the user is pressing fire, etc.
Player.Update(input);

// Call other update functions for enemies, objects, background, etc as well as rendering for them.
[/code] Edited by BeerNutts

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement