I've got my sprite animation but now I'm lacking any actual movement on the screen. Sorry about pasting around 200 lines of code but it's all relevant in the case (at least I think it is!). I think the issue might be the way I'm using spriteRect. Is it valid to use player.SpriteRect.x? If for example in the switch case I use just spriteRect.x and declare spriteRect.x = 150 say, in main() as opposed to player.spriteRect.x then it works and there's actual movement. If player.spriteRect.x isn't valid how do I go about using the struct format?
Sorry about my iffy wording, I'm still very new to C and they way we're being taught C at uni is them giving us a bunch of code examples and making us follow instructions, which isn't the greatest way.
The code:
#include <stdlib.h>
#include <SDL/SDL.h>
//Definitions
const int WINDOW_WIDTH = 720;
const int WINDOW_HEIGHT = 540;
const int SPRITE_SIZE = 36;
const int GRAVITY_SPEED = 9.81;
const int MAX_FALL_SPEED = 20;
const int PLAYER_SPEED = 4;
const char* WINDOW_TITLE = "Krumm's Adventure";
int gameover;
struct Entity player;
struct Input input;
SDL_Rect srcRect;
/* While looking around about different struct formations, I found that many people believe
typedef structs in C are a bad idea since it pollutes the global namespace.
This is a relatively small program so not many namespaces are being used up, but I can see
issues arriving in larger C programs. */
struct Input
{
int left, right, jump;
};
// In gaming terms, an entity is anything that can be interacted with.
struct Entity
{
int w, h, onGround;
int thinkTime;
float x, y;
SDL_Rect spriteRect;
};
void initPlayer() //Initialises the player
{
player.x = player.y = 0;
player.spriteRect.x = player.spriteRect.y = 0;
player.w = SPRITE_SIZE;
player.h = SPRITE_SIZE;
player.thinkTime = 0;
}
/*
* This section of functions deals with all the player information, mainly movement and gravity
*/
void doPlayer()
{
if (player.thinkTime == 0)
{
player.spriteRect.x = 0;
/* Gravity always pulls the player down */
player.spriteRect.y += GRAVITY_SPEED;
if (player.spriteRect.y >= MAX_FALL_SPEED)
{
player.spriteRect.y = MAX_FALL_SPEED;
}
if (input.left == 1)
{
player.spriteRect.x -= PLAYER_SPEED;
}
else if (input.right == 1)
{
player.spriteRect.x += PLAYER_SPEED;
}
if (input.jump == 1)
{
if (player.onGround == 1)
{
player.spriteRect.y = -11;
}
input.jump = 0;
}
}
if (player.thinkTime > 0)
{
player.thinkTime--;
if (player.thinkTime == 0)
{
initPlayer();
}
}
}
/*
* This function handles users input, while at the same time controlling sprite animation
*/
void HandleEvent(SDL_Event event) //Waits for messages and then processes them
{
switch (event.type) {
case SDL_QUIT: //Someone hits the close button
gameover = 1;
break;
//Handle keyboard events
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE: //ESC key
case SDLK_q: //Q key
gameover = 1;
break;
case SDLK_LEFT: //Left Arrow Key
if ( srcRect.x == 360 )
srcRect.x = 324, srcRect.y = 36;
else if ( srcRect.x == 324 )
srcRect.x = 288, srcRect.y = 36;
else if ( srcRect.x == 288 )
srcRect.x = 252, srcRect.y = 36;
else if ( srcRect.x == 252 )
srcRect.x = 216, srcRect.y = 36;
else if ( srcRect.x == 216 )
srcRect.x = 180, srcRect.y = 36;
else if ( srcRect.x == 180 )
srcRect.x = 144, srcRect.y = 36;
else if ( srcRect.x == 144 )
srcRect.x = 108, srcRect.y = 36;
else if ( srcRect.x == 108 )
srcRect.x = 72, srcRect.y = 36;
else if ( srcRect.x == 72 )
srcRect.x = 36, srcRect.y = 36;
else if ( srcRect.x == 36 )
srcRect.x = 0, srcRect.y = 36;
else
srcRect.x = 360;
input.left = 1;
break;
case SDLK_RIGHT: //Right Arrow Key
if ( srcRect.x == 0 )
srcRect.x = 36, srcRect.y = 0;
else if ( srcRect.x == 36 )
srcRect.x = 72, srcRect.y = 0;
else if ( srcRect.x == 72 )
srcRect.x = 108, srcRect.y = 0;
else if ( srcRect.x == 108 )
srcRect.x = 144, srcRect.y = 0;
else if ( srcRect.x == 144 )
srcRect.x = 180, srcRect.y = 0;
else if ( srcRect.x == 180 )
srcRect.x = 216, srcRect.y = 0;
else if ( srcRect.x == 216 )
srcRect.x = 252, srcRect.y = 0;
else if ( srcRect.x == 252 )
srcRect.x = 288, srcRect.y = 0;
else if ( srcRect.x == 288 )
srcRect.x = 324, srcRect.y = 0;
else if ( srcRect.x == 324 )
srcRect.x = 360, srcRect.y = 0;
else
srcRect.x = 0;
input.right = 1;
break;
case SDLK_UP: //Up arrow key
input.jump = 1;
break; //Down arrow key
case SDLK_DOWN:
break;
}
break;
}
}
/*
* The main function handles all of SDL's initializations
*/
int main(int argc, char* argv[])
{
SDL_Surface *screen, *temp, *sprite;
int colorkey;
SDL_Init(SDL_INIT_VIDEO); //Initialize SDL
SDL_WM_SetCaption(WINDOW_TITLE, 0); //Window title
screen = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0); //Create window frame
SDL_EnableKeyRepeat(70, 70); //Keyboard Repeat
temp = SDL_LoadBMP("sprite.bmp"); //Load the actual sprite
sprite = SDL_DisplayFormat(temp);
SDL_FreeSurface(temp);
/* setup sprite colorkey and turn on RLE */
colorkey = SDL_MapRGB(screen->format, 160, 136, 128); //Make this RGB color transparent, so sprite isn't surrounded by a colored box
SDL_SetColorKey(sprite, SDL_SRCCOLORKEY | SDL_RLEACCEL, colorkey);
/* set animation frame */
srcRect.x = 0;
srcRect.y = 0;
srcRect.w = SPRITE_SIZE;
srcRect.h = SPRITE_SIZE;
gameover = 0;
initPlayer();
/* message pump */
while (!gameover)
{
SDL_Event event;
doPlayer();
/* look for an event */
if (SDL_PollEvent(&event)) {
HandleEvent(event);
}
/* collide with edges of screen */
if (player.spriteRect.x <= 0)
player.spriteRect.x = 0;
if (player.spriteRect.x >= WINDOW_WIDTH - SPRITE_SIZE)
player.spriteRect.x = WINDOW_WIDTH - SPRITE_SIZE;
if (player.spriteRect.y <= 0)
player.spriteRect.y = 0;
if (player.spriteRect.y >= WINDOW_HEIGHT - SPRITE_SIZE)
player.spriteRect.y = WINDOW_HEIGHT - SPRITE_SIZE;
SDL_BlitSurface(sprite, &srcRect, screen, &player.spriteRect); //Blit the Krumm sprite
SDL_UpdateRect(screen, 0, 0, 0, 0); //Update screen with new sprite
SDL_FillRect(screen, NULL, 0x000000); //Fixes the ghosting issue
}
/* clean up */
SDL_FreeSurface(sprite);
SDL_Quit();
return 0;
}