4 Replies - 629 Views - Last Post: 26 May 2013 - 12:54 PM Rate Topic: -----

#1 mralex94  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 08-May 13

SDL: Unable to move sprite

Posted 08 May 2013 - 06:26 PM

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.(Although I'm good with BASIC and VB.NET (then again who isn't :hehe:/> ))

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;
}


So the program compiles fine, which means logic errors on my part. Any ideas as to why the sprite doesn't actually move?

Is This A Good Question/Topic? 0
  • +

Replies To: SDL: Unable to move sprite

#2 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1009
  • View blog
  • Posts: 4,208
  • Joined: 14-February 08

Re: SDL: Unable to move sprite

Posted 09 May 2013 - 02:33 AM

Hi,

Wow! I don't even know where to start with your code.

This code below is the wrong order really, you want to fill the screen and then draw to it and then update it (you should look into double buffering also).
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



I don't want to copy and paste it but your animation handling is a little crazy. If you know the height and width of each frame then why can't you just increment by that each time you update?

But anyway that is not your current issue, your problem is that you are resetting the position of the sprite to 0 every time you call doPlayer() (which is every frame)

player.spriteRect.x = 0;



And yeah it does go on to update the position, but next time round will be exactly the same as you have reset the position again.
Was This Post Helpful? 0
  • +
  • -

#3 mralex94  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 08-May 13

Re: SDL: Unable to move sprite

Posted 09 May 2013 - 06:47 AM

View Poststayscrisp, on 09 May 2013 - 02:33 AM, said:

Hi,

Wow! I don't even know where to start with your code.

This code below is the wrong order really, you want to fill the screen and then draw to it and then update it (you should look into double buffering also).
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



I don't want to copy and paste it but your animation handling is a little crazy. If you know the height and width of each frame then why can't you just increment by that each time you update?

But anyway that is not your current issue, your problem is that you are resetting the position of the sprite to 0 every time you call doPlayer() (which is every frame)

player.spriteRect.x = 0;



And yeah it does go on to update the position, but next time round will be exactly the same as you have reset the position again.


Yeah I'm quite awful with C.
As for the code, at the moment I'm just trying to get it to work, then clean it up/make it more efficient. I've just been struggling to get movement which has thrown me off a bit.

Anyway I've seen what was wrong now, removing
player.spriteRect.x = 0;
has allowed the sprite to move but also has a weird bug now:
http://www.freegifhu.../i/example1.gif

As you can see, just tapping the key will make the sprite move (and carry on moving) till it collides with the wall. Then when going in the opposite direction it does the same, but trying to turn it around it just gets stuck in its initial position.
It also moves quite a lot of distance.
Was This Post Helpful? 0
  • +
  • -

#4 mralex94  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 08-May 13

Re: SDL: Unable to move sprite

Posted 10 May 2013 - 03:19 PM

Hope double posting is allowed, but just an update to let you know I've solved it after cleaning up my code and modularizing it :bigsmile:
Was This Post Helpful? 0
  • +
  • -

#5 stayscrisp  Icon User is offline

  • フカユ
  • member icon

Reputation: 1009
  • View blog
  • Posts: 4,208
  • Joined: 14-February 08

Re: SDL: Unable to move sprite

Posted 26 May 2013 - 12:54 PM

Quote

Anyway I've seen what was wrong now, removing
player.spriteRect.x = 0;

has allowed the sprite to move


Pretty sure that is what I said :online2long:/>

Quote

just an update to let you know I've solved it after cleaning up my code and modularizing it


Ah, so doing it properly has allowed it to work properly. Who'd have thunk it :P
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1