Hi i am trying to create a racing game and at the moment i have keyboard input which moves the player around at the same continous speed. I am wanting it to speed the player up however the longer you hold the key down for. Any simple way i can achieve this?
#include "SDL.h"
#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>
#pragma comment(lib,"Winmm.lib")
/* ---------------------------------------------------------------------- */
/* Defines/Enumerations */
/* ---------------------------------------------------------------------- */
#define SPEED 2
#define GAMETIME 30 //inactivity for 30s quits game
/* ---------------------------------------------------------------------- */
/* Type Declarations */
/* ---------------------------------------------------------------------- */
struct PLAYER
{
//SDL_Rect pos;
SDL_Surface *sprite;
Sint32 dir;
Sint32 life;
Sint32 score;
float by;
float bx;
float pos_y;
float pos_x;
bool up, right, left, down;
bool w, s, a, d;
};
struct BALL
{
//SDL_Rect pos;
SDL_Surface *sprite;
float bx, by;
float pos_x, pos_y;
};
/* ---------------------------------------------------------------------- */
/* Global Data */
/* ---------------------------------------------------------------------- */
/// The start time
SDL_Surface *SCREEN;
/// Some Sprites
SDL_Surface *background, *intro, *numbers;
PLAYER playerA, playerB;
BALL ball;
SDL_Joystick *joy0;
Uint32 iTicksLastKey=0; //inactivity counter
Uint32 TicksElapsed=0; //ticks elapsed since last update
Sint16 iMoveX;
Sint16 iMoveY;
Sint16 iMoveXOld; //for comparing the last value
Sint16 iMoveYOld;
float ballspeed=85; //ball speed, number of pixels ball travels in one second
SDL_Surface *level;
/* ---------------------------------------------------------------------- */
/* Helper */
/* ---------------------------------------------------------------------- */
void go();
/// Handle events
bool handleEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
{
switch(event.key.keysym.sym)
{
case SDLK_UP: { playerB.up = true; break; }
case SDLK_DOWN: { playerB.down = true; break; }
case SDLK_LEFT: { playerB.left = true; break; }
case SDLK_RIGHT: { playerB.right = true; break; }
case SDLK_w: { playerA.w = true; break; }
case SDLK_s: { playerA.s = true; break; }
case SDLK_a: { playerA.a = true; break; }
case SDLK_d: { playerA.d = true; break; }
case SDLK_SPACE:
{
if (ball.bx == 0 && ball.by == 0)
{
go();
playerA.life = 3;
playerB.life = 3;
playerA.score = 0;
playerB.score = 0;
}
}
break;
case SDLK_ESCAPE: { return false; } // quits
default: { break; }
}
}
break;
case SDL_KEYUP:
{
iTicksLastKey=SDL_GetTicks(); //remember the time of last key release
switch(event.key.keysym.sym)
{
case SDLK_UP: { playerB.up = false; break; }
case SDLK_DOWN: { playerB.down = false; break; }
case SDLK_LEFT: { playerB.left = false; break; }
case SDLK_RIGHT: { playerB.right = false; break; }
case SDLK_w: { playerA.w = false; break; }
case SDLK_s: { playerA.s = false; break; }
case SDLK_a: { playerA.a = false; break; }
case SDLK_d: { playerA.d = false; break; }
{ playerA.dir = 0; break; }
default: { break; }
}
}
break;
case SDL_QUIT: { return false; }
default: { break; }
}
}
return true;
}
/// Draws the score and life status
void overlay()
{
char buffer[16];
SDL_Rect dst, src;
Sint32 i;
src.y = 0; src.w = 12; src.h = 14;
dst.y = 0; dst.w = 12; dst.h = 14;
sprintf(buffer, "%04d", playerA.score);
for(i=0; buffer[i]; i++)
{
src.x = ((Sint32) buffer[i] - (Sint32) '0') * 12;
dst.x = i * 12;
SDL_BlitSurface(numbers, &src, SCREEN, &dst);
}
sprintf(buffer, "%04d", playerB.score);
for(i=0; buffer[i]; i++)
{
src.x = ((Sint32) buffer[i] - (Sint32) '0') * 12;
dst.x = 320 - (4-i) * 12;
SDL_BlitSurface(numbers, &src, SCREEN, &dst);
}
dst.y = 0; dst.w = (ball.sprite)->w; dst.h = (ball.sprite)->h;
for(i=0; i<playerA.life; i++)
{
dst.x = 50 + i * (dst.w + 2);
SDL_BlitSurface(ball.sprite, NULL, SCREEN, &dst);
}
for(i=0; i<playerB.life; i++)
{
dst.x = 270 - (3-i) * (dst.w + 2);
SDL_BlitSurface(ball.sprite, NULL, SCREEN, &dst);
}
}
void go()
{
ball.bx = 0;
while (ball.bx == 0) ball.bx = (rand() % 3) - 1;
ball.by = (rand() % 3) - 1;
ball.bx=1;
ball.by=1;
(ball.pos_x) = 160-(ball.sprite)->w/2;
(ball.pos_y) = 120-(ball.sprite)->h/2;
TicksElapsed=SDL_GetTicks();
}
//rounds a float to an int
int iRound(float f)
{
return int(f + 0.5);
}
/* ---------------------------------------------------------------------- */
/* Main Program */
/* ---------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
PlaySound("cirque.wav",NULL,SND_FILENAME|SND_ASYNC | SND_LOOP);
Sint32 delta;
// --------------------------------------------------
// SDL initialisation
// --------------------------------------------------
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK) < 0)
{
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
return -1;
}
SCREEN = SDL_SetVideoMode(500, 340, 24, SDL_DOUBLEBUF /*|SDL_FULLSCREEN*/);
if (!SCREEN)
{
printf("Couldn't set 320x240, 24bit video mode: %s\n", SDL_GetError());
return -2;
}
SDL_WM_SetCaption("Pony Pong", "Pony Pong");
SDL_EnableKeyRepeat(10, SDL_DEFAULT_REPEAT_INTERVAL);
SDL_ShowCursor(0);
// --------------------------------------------------
// Game initialisation
// --------------------------------------------------
srand(12345);
playerA.sprite = SDL_LoadBMP("player1.bmp");
SDL_SetColorKey(playerA.sprite, SDL_SRCCOLORKEY, 0x000000); //makes black transparent
playerB.sprite = SDL_LoadBMP("player2.bmp");
SDL_SetColorKey(playerB.sprite, SDL_SRCCOLORKEY, 0x000000); //makes black transparent
ball.sprite = SDL_LoadBMP("ball.bmp");
SDL_SetColorKey(ball.sprite, SDL_SRCCOLORKEY, 0x000000); //makes black transparent
background = SDL_LoadBMP("background.bmp");
level = SDL_LoadBMP("level.bmp");
intro = SDL_LoadBMP("intro.bmp");
numbers = SDL_LoadBMP("numbers.bmp");
//Check for joysticks:
int num_joy;
num_joy=SDL_NumJoysticks();
printf("%d joysticks found\n", num_joy);
for (int i=0;i<num_joy;i++) { printf(" %s\n", SDL_JoystickName(i)); }
if (SDL_NumJoysticks()>0) joy0=SDL_JoystickOpen(0);
if (joy0)
{
printf("Opened Joystick 0\n");
printf(" Name: %s\n", SDL_JoystickName(0));
printf(" Number of Axes: %d\n", SDL_JoystickNumAxes(joy0));
printf(" Number of Buttons: %d\n", SDL_JoystickNumButtons(joy0));
// printf(" Number of Balls: %d\n", SDL_JoystickNumBalls(joy0));
}
else { printf("Couldn't open Joystick 0\n"); }
(playerA.pos_x) = 8;
(playerA.pos_y) = 120-((playerA.sprite)->h/2);
//(playerA.pos).w = (playerA.sprite)->w;
//(playerA.pos).h = (playerA.sprite)->h;
(playerB.pos_x) = 312-((playerB.sprite)->w);
(playerB.pos_y) = 120-((playerB.sprite)->h/2);
// (playerB.pos).w = (playerB.sprite)->w;
// (playerB.pos).h = (playerB.sprite)->h;
/*(ball.pos_x) = 160-(ball.sprite)->w/2;
(ball.pos_y) = 120-(ball.sprite)->h/2;
//(ball.pos).w = (ball.sprite)->w;
//(ball.pos).h = (ball.sprite)->h;*/
// --------------------------------------------------
// Game loop
// --------------------------------------------------
while (handleEvents())
{
// --------------------------------------------------
// Game logic
// --------------------------------------------------
//after 30s of inactivity quit game
if ((SDL_GetTicks()-iTicksLastKey)>(GAMETIME*1000)) { break; }
if (((SDL_JoystickGetButton(joy0, 0)) || //fire, start game
(SDL_JoystickGetButton(joy0, 1)) ||
(SDL_JoystickGetButton(joy0, 2)) ||
(SDL_JoystickGetButton(joy0, 3)) ||
(SDL_JoystickGetButton(joy0, 4)) ||
(SDL_JoystickGetButton(joy0, 5)) ||
(SDL_JoystickGetButton(joy0, 6)) ||
(SDL_JoystickGetButton(joy0, 7))) &&
((ball.bx==0) && (ball.by==0)))
{
iTicksLastKey=SDL_GetTicks(); //remember the time of last key press
go();
playerA.life=playerB.life=3;
playerA.score=playerB.score=0;
}
int Delta=SDL_GetTicks()-TicksElapsed;
// Update position of sprites
if (joy0) //if joystick connected
{
//SDL_JoystickUpdate();
iMoveXOld=iMoveX;
iMoveYOld=iMoveY;
iMoveX=SDL_JoystickGetAxis(joy0, 0); //move joy 0 axxis 0 (-32768 to 32768)
iMoveY=SDL_JoystickGetAxis(joy0, 1); //move joy 0 axxis 1 (-32768 to 32768)
(playerA.pos_y)=(int)(((((float)iMoveX)/65335)+0.5)*(240-(playerA.sprite)->h));
(playerB.pos_y)=(int)(((((float)iMoveY)/65335)+0.5)*(240-(playerB.sprite)->h));
if ((iMoveX!=iMoveXOld) || (iMoveY!=iMoveYOld)) { iTicksLastKey=SDL_GetTicks(); } //remember the time of last movement
}
else //otherwise keyboard
{
if (playerA.dir != 0)
{
(playerA.pos_y)+=((Delta*ballspeed)/1000)*playerA.dir;
if ((playerA.pos_y) >= 240-(playerA.sprite)->h)
{
(playerA.pos_y) = 240-(playerA.sprite)->h;
}
else if ((playerA.pos_y) <= 0)
{
(playerA.pos_y) = 0;
}
}
if (playerB.dir != 0)
{
(playerB.pos_y)+=((Delta*ballspeed)/1000)*playerB.dir;
if ((playerB.pos_y) >= 240-(playerB.sprite)->h)
{
(playerB.pos_y) = 240-(playerB.sprite)->h;
}
else if ((playerB.pos_y) <= 0)
{
(playerB.pos_y) = 0;
}
}
}
if (playerB.up == true) {
(playerB.pos_y)-=((Delta*ballspeed)/1000);
}
if (playerB.down == true) {
(playerB.pos_y)+=((Delta*ballspeed)/1000);
}
if (playerB.left == true) {
(playerB.pos_x)-=((Delta*ballspeed)/1000);
}
if (playerB.right == true) {
(playerB.pos_x)+=((Delta*ballspeed)/1000);
}
if (playerB.pos_y > level->h - playerB.sprite->h) {
playerB.pos_y = level->h - playerB.sprite->h ;
}
if (playerB.pos_y < 0) {
playerB.pos_y = 0;
}
if (playerB.pos_x > level->w - playerB.sprite->w) {
playerB.pos_x = level->w- playerB.sprite->w;
}
if (playerB.pos_x < 0) {
playerB.pos_x = 0;
}
if (playerA.w == true){
(playerA.pos_y)-=((Delta*ballspeed)/1000);
}
if (playerA.s == true){
(playerA.pos_y)+=((Delta*ballspeed)/1000);
}
if (playerA.a == true){
(playerA.pos_x)-=((Delta*ballspeed)/1000);
}
if (playerA.d == true){
(playerA.pos_x)+=((Delta*ballspeed)/1000);
}
if (playerA.pos_y > level->h - playerA.sprite->h) {
playerA.pos_y = level->h - playerA.sprite->h ;
}
if (playerA.pos_y < 0) {
playerA.pos_y = 0;
}
if (playerA.pos_x > level->w - playerA.sprite->w) {
playerA.pos_x = level->w- playerA.sprite->w;
}
if (playerA.pos_x < 0) {
playerA.pos_x = 0;
}
// Update ball
//(ball.pos_x) += ball.bx;
//(ball.pos_y) += ball.by;
(ball.pos_x)+=((Delta*ballspeed)/1000)*ball.bx;
(ball.pos_y)+=((Delta*ballspeed)/1000)*ball.by;
TicksElapsed=SDL_GetTicks();
// (*) Reflection on top and bottom of screen
if ((ball.pos_y) <= 0 || (ball.pos_y) >= 240-(ball.sprite)->h)
{
ball.by = -ball.by;
}
//player A paddle Reflektion:
delta=(ball.pos_y)-(playerA.pos_y);
if (((ball.pos_x)<=8+(playerA.sprite)->w) && //in reach of the paddle
((ball.pos_x)>=8) && //not too far left
(delta>=0) && //not above paddle
(delta<=(playerA.sprite)->h) && //not below
(ball.bx<0)) //ball flies to the left
{
if (ball.bx < 0) { ball.bx = 1; } else { ball.bx = -1; }
//ball.bx *= (2+abs((delta - ((playerA.sprite)->h/2))) / 6);
//ball.by = (delta - ((playerA.sprite)->h/2)) / 4;
playerA.score++;
}
if ((ball.pos_x)<0) //left out
{
playerA.life--;
playerB.score += 10;
if (playerA.life == 0)
{
//Restart game:
ball.bx = 0;
ball.by = 0;
(ball.pos_x) = 160-(ball.sprite)->w/2;
(ball.pos_y) = 120-(ball.sprite)->h/2;
}
else { go(); }
}
//player B paddle Reflektion:
delta=(ball.pos_y)-(playerB.pos_y);
if (((ball.pos_x)+(ball.sprite)->w>=312-(playerB.sprite)->w) && //in reach of the paddle
((ball.pos_x)+(ball.sprite)->w<=312) && //not too far right
(delta>=0) && //not above paddle
(delta<=(playerB.sprite)->h) && //not below
(ball.bx>0)) //ball flies to the right
{
if (ball.bx < 0) { ball.bx = 1; } else { ball.bx = -1; }
//ball.bx *= (2+abs((delta - ((playerB.sprite)->h/2))) / 6);
//ball.by = (delta - ((playerB.sprite)->h/2)) / 4;
playerB.score++;
}
if ((ball.pos_x)+(ball.sprite)->w>320) //right out
{
playerB.life--;
playerA.score += 10;
if (playerB.life == 0)
{
//Restart game:
ball.bx = 0;
ball.by = 0;
(ball.pos_x) = 160-(ball.sprite)->w/2;
(ball.pos_y) = 120-(ball.sprite)->h/2;
}
else go();
}
// --------------------------------------------------
// Draw game screen
// --------------------------------------------------
if (ball.bx == 0 && ball.by == 0) { SDL_BlitSurface(intro, NULL, SCREEN, NULL); }
else { SDL_BlitSurface(background, NULL, SCREEN, NULL); }
SDL_Rect halfscreen;
halfscreen.x=0;
halfscreen.y=0;
halfscreen.w=SCREEN->w/2;
halfscreen.h=SCREEN->h;
SDL_Rect levelrect;//Left hand side screen
levelrect.x=iRound(playerB.pos_x-SCREEN->w/4);
levelrect.y=iRound(playerB.pos_y-SCREEN->h/2);
levelrect.w=SCREEN->w/2;
levelrect.h=SCREEN->h;
SDL_BlitSurface(level, &levelrect, SCREEN, &halfscreen);
halfscreen.x=SCREEN->w/2;
levelrect.x=iRound(playerA.pos_x-SCREEN->w/28);//right hand side screen
levelrect.y=iRound(playerA.pos_y-SCREEN->h/10);
levelrect.w=SCREEN->w;
levelrect.h=SCREEN->h;
SDL_BlitSurface(level, &levelrect, SCREEN, &halfscreen);
overlay();
SDL_Rect p1;
p1.x=(SCREEN->w/4-playerA.sprite->w/5);
p1.y=(SCREEN->h/2-playerA.sprite->h/2);
p1.w=(playerA.sprite)->w;
p1.h=(playerA.sprite)->h;
SDL_BlitSurface(playerA.sprite, NULL, SCREEN, &p1);
SDL_Rect p2;
p2.x=(SCREEN->w/2+SCREEN->w/4-playerB.sprite->w/2);
p2.y=(SCREEN->h/2-playerB.sprite->h/2);
p2.w=(playerB.sprite)->w;
p2.h=(playerB.sprite)->h;
SDL_BlitSurface(playerB.sprite, NULL, SCREEN, &p2);
SDL_Rect r;
r.x=iRound(ball.pos_x);
r.y=iRound(ball.pos_y);
r.w= (ball.sprite)->w;
r.h= (ball.sprite)->w;
SDL_BlitSurface(ball.sprite, NULL, SCREEN, &r);
SDL_Flip(SCREEN);
}
// --------------------------------------------------
// Clean up
// --------------------------------------------------
if ((joy0) && (SDL_JoystickOpened(0))) { SDL_JoystickClose(joy0); }
SDL_Quit();
return 0;
}