Sign in to follow this  
Toadhead

moving a image

Recommended Posts

when I compile this I'll see an image (image.bmp in the same dir as the program), on 0*0. Why doesn't the image move when I press on the arrow keys???
#include <iostream> //header file
#include <cstdio> // header file
#include <cstdlib> //header file
#include "SDL.h" // custom header file
using namespace std; // using the standard namespace

void DisplayImage(SDL_Surface *image, SDL_Surface* screen, int xpos, int ypos);




int main(int argc, char** argv) { // start execution here
    
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) // initialize SDL VIDEO, and check if it is initialized
{
    cout << "Error: " << SDL_GetError();
    return 1;
}
atexit(SDL_Quit);  // frees up everything when program closes  
    

    SDL_Surface* screen; // The screen
    screen = SDL_SetVideoMode(800,600,16,SDL_HWSURFACE|SDL_DOUBLEBUF); //Setting screen mode
    
    if ( screen == NULL ) // check to see if the screen has been set
    {
        cout << "Failed to set the screen resolution to 800*600";
        return 1;
    }    
    
SDL_Surface* image;
image = SDL_LoadBMP("image.bmp");

int xpos = 0;
int ypos = 0;

   
    
    
    
    
    
    
    int gameloop = 0; //declarates the gameloop 
    SDL_Event event; //declarates the event
    
    while (gameloop == 0) //gameloop
    { 
        
        
        
        while ( SDL_PollEvent(&event) ) //Polling for events
        {
            if (event.type == SDL_QUIT) {gameloop = 1;}
            if (event.type == SDL_KEYDOWN)
            {
                if (event.key.keysym.sym == SDLK_q) {gameloop = 1;}
                if (event.key.keysym.sym == SDLK_LEFT) {xpos -= 1; }
                if (event.key.keysym.sym == SDLK_RIGHT) {xpos += 1; }
                if (event.key.keysym.sym == SDLK_DOWN) {ypos -= 1; }
                if (event.key.keysym.sym == SDLK_UP) {ypos += 1; }
            }
            

               
        }
        
    
        DisplayImage(image, screen,0,0);
            SDL_Flip(screen);
        

    }    
    
    
    
    
    
    
    

    return 0;
}




void DisplayImage(SDL_Surface* image, SDL_Surface* screen, int xpos, int ypos)
{
    SDL_Rect destination;
    destination.x = xpos ;
    destination.y = xpos ;
    SDL_BlitSurface(image,NULL,screen,&destination);
    SDL_Flip(screen);
   
} 

Share this post


Link to post
Share on other sites
you have a whoopsie [smile]

void DisplayImage(SDL_Surface* image, SDL_Surface* screen, int xpos, int ypos)
{
SDL_Rect destination;
destination.x = xpos ;
destination.y = xpos ; <--- DOH!! :)
SDL_BlitSurface(image,NULL,screen,&destination);
SDL_Flip(screen);
}

Share this post


Link to post
Share on other sites
Damn, my picture moves, but after it is moved the pixels won't turn black :(
They will keep the same color as the picture, just try compiling and running the program and you'll see.

Can anyone tell me why the pixels dont become black again??>

Thanks,
Rob

Share this post


Link to post
Share on other sites
Don't know what FillRect is..
I'll learn it in the future when my tutorials reach this point.

But I was just wondering if I did something wrong, I tought that the pixels would turn black automaticly after the image was moved, but I have just drawed the image on another part of the screen and my older image wasn't removed.

Share this post


Link to post
Share on other sites
SDL_FillRect
Quote:

int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
This function performs a fast fill of the given rectangle with color. If dstrect is NULL, the whole surface will be filled with color.


To turn the screen black do SDL_FillRect(my_screen, NULL, 0);
Do this before drawing your screen.

Share this post


Link to post
Share on other sites
Ah..
Thanks, thats realy usefull :P


But...
The last color, what number is what color??

And when the 2e argument is NULL the whole screen will be filled, but what can I pass other than NULL and what will happen than?

Share this post


Link to post
Share on other sites
his tutorial doesnt tell me about it, and another one about the function that i found it google doesnt explain it to me neither or I just dont understand it :P They talk about SDL_MapRGP or something :S

anyway thanks everybody for the help :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Toadhead
his tutorial doesnt tell me about it, and another one about the function that i found it google doesnt explain it to me neither or I just dont understand it :P They talk about SDL_MapRGP or something :S

anyway thanks everybody for the help :)


SDL_MapRGB


Uint32 SDL_MapRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b);


Usage:

Uint32 colour = SDL_MapRGB(my_screen->format, R, G, B);


So you pass the red, green and blue components of the colour. For example 255, 0, 0 would be bright red etc. White would be 255, 255, 255.

Example:

SDL_FillRect(my_screen, NULL, SDL_MapRGB(my_screen->format, 255, 255, 255)); // Fill the whole my_screen with red


If you want to fill the surface with black you can just pass 0 as the last parameter to SDL_FillRect.

I hope I've been helpful..

Oh and learn to use the SDL documentation. It will perhaps take some time but you can't really live without it [smile]

Share this post


Link to post
Share on other sites
Btw can anyone tell me the difference between:


Uint8 keys[500];
keys = SDL_GetKeyState(NULL);
if ( keys[SDLK_LEFT] ) {xpos -= 1; }
if ( keys[SDLK_RIGHT] ) {xpos += 1; }
if ( keys[SDLK_DOWN] ) {ypos += 1; }
if ( keys[SDLK_UP] ) {ypos -= 1; }




and:


if ( event.key.keysym.sym == SDLK_LEFT ) {xpos -= 1; }
if ( event.key.keysym.sym == SDLK_RIGHT] ) {xpos += 1; }
if ( event.key.keysym.sym == SDLK_DOWN] ) {ypos += 1; }
if ( event.key.keysym.sym == SDLK_UP] ) {ypos -= 1; }





I'm not noticing any difference :(

Share this post


Link to post
Share on other sites
Quote:

I will also try SDL_FreeSurface(image); now instead of SDL_FillRect(); and see whats will happen :/


FreeSurface() destroys the image and frees the memory (it can't be used anymore, it doesn't exist in the memory). You need to call SDL_FreeSurface() on all your surfaces before your app closes (so there won't be any memory leaks).

SDL_FillRect() fills a rectangular area with a certain colour.

Quote:
Original post by Toadhead
Btw can anyone tell me the difference between:

*** Source Snippet Removed ***

and:

*** Source Snippet Removed ***


I'm not noticing any difference :(


I think the latter one is the "correct way" to do it (browse the documentation wiki, there's something about it I think). You might want try using a switch().

switch(event.key.keysym.sym) {
case SDLK_LEFT: MoveLeft(); break; // always remember to break
// blah .
// blah .
case SDLK_UP: MoveUp(); break;
default: break;
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Toadhead
Btw can anyone tell me the difference between:

*** Source Snippet Removed ***

and:

*** Source Snippet Removed ***


I'm not noticing any difference :(

I would recommend creating a user controls array which holds flags of every control that the user needs. Update it inside the while loop and then make use of it outside. This way you have the ability to easily change the user controls if needed.

Share this post


Link to post
Share on other sites
Quote:
Original post by Toadhead
Btw can anyone tell me the difference between:

*** Source Snippet Removed ***

and:

*** Source Snippet Removed ***


I'm not noticing any difference :(

The first method is called polling and the second method uses messaging. The second method is better than the first, in this case, because instead of asking SDL every single game loop whether a key has been pressed, you can just wait for SDL to tell you when a key has been pressed. So obviously polling is less efficient. It does have its uses, but not here.

Share this post


Link to post
Share on other sites
a thanks.

The reason why I didnt noticed any differences was becuase I first had this code:

keys = SDL_GetKeyState(NULL);

if (event.type == SDL_KEYDOWN)
{
if ( keys[SDLK_LEFT] ) {xpos -= 5; }
if ( keys[SDLK_RIGHT] ) {xpos += 5; }
if ( keys[SDLK_DOWN] ) {ypos += 5; }
if ( keys[SDLK_UP] ) {ypos -= 5; }
}



And after I noticed that I forgot to remove the:

"
if ( keys[SDLK_LEFT] ) {xpos -= 5; }
if ( keys[SDLK_RIGHT] ) {xpos += 5; }
if ( keys[SDLK_DOWN] ) {ypos += 5; }
if ( keys[SDLK_UP] ) {ypos -= 5; }
"

from the PollEvent loop :D
So now it's working :P (I can now hold a button to move the object)

Share this post


Link to post
Share on other sites
Ok, bump. I was reading this from the archives, but i have a question. When moving an image, isnt there some more efficient way than wiping the whole dang screen every loop pass? I mean, why not just tell it where you want the image to write over, and do it there instead?

How would you implement this, considering that the place that you want to fill in with black (where the surface 'used' to be) could be in any direction around your current surface.

Any ideas?

Share this post


Link to post
Share on other sites
sorry if I don't understand you're question, but you want to know if there is another way to clean the trail behind the image when it moves than clearing the whole screen and than draw everything again?

Well.. you should make some other variables: oldxpos and oldypos, that holds the coördinates before it's moved. Than you can draw the background on that old coordinates only so you don't need to draw the whole background again.

How it axactly works I dunno but it was somewere explain on cone3d.gamedev.net.


Share this post


Link to post
Share on other sites
However, if you draw a lot of stuff every frame, only clearing the parts that have changed last frame *might* make sense. This technique is called "dirty rects". You basically collect the rectangles that have been changed ("dirtied") in the last frame and redraw those.

You might want to google for it.

However, I should also note that in a large class of games (those that change their whole screen every frame), implementing this would only cost you lots of time and add overhead. For the rest of games, always updating the whole screen usually suffices, too.

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