Sign in to follow this  
stannisbaratheon

Disabling keyrepeat

Recommended Posts

Hi everyone,

I'm currently using enablekeyrepeat to move my sprite back and forth. This works fine except that I don't want to use keyrepeat for the sprite jumping (i.e. one keypress one jump). I understand that by changing the first parameter in the sdl_enablekeyrepeat to 0 it is disabled but, of course, this disables keyrepeat for the back and forth motion.

Any ideas on how to solve this would be great.

Share this post


Link to post
Share on other sites
Instead of disabling key repeat you should respond to key up/down events: all keys are up by default, when a key goes to down you either begin or perform an action, and when it goes back to up you end the action if necessary. In the case of jumping, you would jump on a key down event and do nothing on key up.

Share this post


Link to post
Share on other sites
You could always run a bool to check if jump is happening and if it is, don't jump again. So something like this,

[code]
jump is false
If keypressed
if jump equals false
jump action
jump equals true
if (however you want to determine he isn't jumping anymore)
jump equals false
[/code] Edited by wicked357

Share this post


Link to post
Share on other sites
Thanks everyone.

Is this (not using keyrepeat) a good way of moving sprites back and forth?

[source lang="cpp"]
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <fstream>
using namespace std;
SDL_Surface* load (char filename[15]);

SDL_Surface* screen =NULL;
SDL_Surface* bground = NULL;
SDL_Surface* mansprite1 = NULL;
SDL_Surface* mansprite2 = NULL;


SDL_Event event;
void init()

{

SDL_Init(SDL_INIT_EVERYTHING);

screen = SDL_SetVideoMode (1200,900,32,NULL);







}

SDL_Surface* load (char filename[20])

{

SDL_Surface* loadfile = IMG_Load (filename);
SDL_Surface* optimise= SDL_DisplayFormat(loadfile);

Uint32 colorkey = SDL_MapRGB( optimise->format,200,55, 99 );

SDL_SetColorKey( optimise, SDL_SRCCOLORKEY, colorkey );
return optimise;

}


int main( int argc, char* args[] )
{
init();

SDL_Rect pos1,pos2;
pos1.x = 100,pos1.y =800;
pos2.x = 100,pos2.y =800;

bground = load("background2.png");
SDL_BlitSurface(bground,NULL,screen,NULL);

mansprite1 = load("mansprite1.png"); //facing forward
mansprite2 = load("mansprite2.png"); //facing backwards

SDL_BlitSurface(mansprite1,NULL,screen,&pos1);
SDL_Flip(screen);

SDL_Delay(1000);
bool forward=false,backward=false;
bool on=true;

while (on)
{


if( SDL_PollEvent(&event))
{

if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_RIGHT)
forward=true;


else
forward=false;



if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_LEFT)
backward=true;


else
backward=false;
}


if (forward && !backward)

{
pos1.x++;
pos2.x++;
}

if (backward && !forward)
{

pos1.x--;
pos2.x--;

}






if (forward)
{
SDL_BlitSurface(bground,NULL,screen,NULL);
SDL_BlitSurface(mansprite1,NULL,screen,&pos1);
SDL_Flip(screen);

}

if (backward)
{
SDL_BlitSurface(bground,NULL,screen,NULL);
SDL_BlitSurface(mansprite2,NULL,screen,&pos2);
SDL_Flip(screen);

}

SDL_Flip(screen);

}

return 0;
}
[/source]

Share this post


Link to post
Share on other sites
I know what you mean - when I tried to make the camera do a jump in my youtube video - it kept on flying away when I held down the space bar. How I solved this is this; I placed three booleans called jump, isJumping, and doneJumping. So when the player presses spacebar - inside the function there's a if statement checking to see if the boolean jump not true. If it's not true then set to isjumping to true then call the jump function. Now once inside the jump function - be sure to set the jump to true; so the spacebar doesn't activate again, because you already set the jump to true. Now because inside the jump function you already set the isjumping to true - this allows the if statement to....ahhh - let me write it in code.

[code]
bool jump, isjumping, donejumping; //GLOBAL DEFINATIONS.

jump = false;
isjumping = false;
donejumping = false; // INSIDE CLASS DECLARIATIONS OR UIPDATE FUNCTION.

if(keystate[DIK_SPACE] & 0x80) {
if(!jump) {

isjumping = true;
doJump();
}

}

void doJump() {
jump = true;

if(isjumping == true) {
//.... Do the jump animation here. Once done and feet has hit the ground.
// Set then reset the booleans to false for next time a player presses spacebar.
}

}
[/code]


Hope this helps! Whew! As you can see the jump function and detecting the spacebar works hand to hand.

Share this post


Link to post
Share on other sites
Stannis, you're going to have to handle the case where Jump is pressed when your player is in the air anyway, so you can keep key repeats if you want. Picture the case where the player keeps pressing the jump button; the player will keep jumping, so you need some jump control for that.

I don't think using 3 booleans is the right way to go about this. See my previous post about it [url="http://www.gamedev.net/topic/625907-2d-basic-collision-detection-help/page__view__findpost__p__4946456"]here[/url]

Also, you should be setting a velocity for your character's X and Y motions, not using a forward and backward boolean.

Here's the code I provide in that link:
[code]
// Speed player moves left or right
#define MOVEMENT_SPEED 10.0f
// initial velocity given to player when he jumps
#define JUMP_VELOCITY 20.0f
void Player::HandleInput()
{
if (LeftIsPressed()) {
this.xVelocity = -MOVEMENT_SPEED;
}
else if (RightIsPressed()) {
this.xVelocity = MOVEMENT_SPEED;
else {
this.xVelocity = 0.0f;
}
// Only jump if we're not already jumping or falling
if (JumpIsPressed() && this.OnGround) {
this.yVelocity = -JUMP_VELOCITY;
}
}
// defines amount to increase downward velocity every frame
#define GRAVITY_FORCE 4.0f
void Player::Update()
{
// Apply downward force to player
this.yVelocity += GRAVITY_FORCE;
// Move the Player
this.xLocation += this.xVelocity;
this.yLocation += this.yVelocity;

// Check we've collide with something above or below us
bool CollideBelow;
if (CheckCollisionY(CollideBelow)) {
// move us back to previous location and Stop Y Velocity
this.yLocation -= this.yVelocity;
this.yVelocity = 0.0f;
if (CollideBelow) {
this.OnGround = true;
}
}
else {
this.OnGround = false;
}
// Check if we've collided with anything on our left or right
if (CheckCollisionX()) {
// move us back to previous location and Stop X Velocity
this.xLocation -= this.xVelocity;
this.xVelocity = 0.0f;
}
}
[/code]

Basically, I don't have any jump specific booleans; rather, I check if the player is OnGround (which is the only valid time a player can jump). Once he jumps, he should have moved off the ground, and OnGround won't be true until he lands on the ground again. Edited by BeerNutts

Share this post


Link to post
Share on other sites
Stannis, everything depends on what is required in the situation. No code is wrong or right - it is just simply code. I have the booleans for now until otherwise if I run into performance issues later on then I'll decide to optimize the jumping part.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this