Sign in to follow this  
Toadhead

moving a image

Recommended Posts

Toadhead    244
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
Toadhead    244
DisplayImage(image, screen,0,0);

should be

DisplayImage(image, screen,xpos,ypos);




but now I cant use left and right, only up and down that will move the screen to up/left and down/right :(

Share this post


Link to post
Share on other sites
Gaiiden    5710
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
Toadhead    244
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
Toadhead    244
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
tentoid    364
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
Toadhead    244
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
Joakim_ar    192
I suggest you follow the link tentoid posted, it is the documentation for that paticuliar SDL function. Or you could go on with your tutorial, as I'm sure it'll come to this at some point...

Share this post


Link to post
Share on other sites
Toadhead    244
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
tentoid    364
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
Toadhead    244
yeah it is..
I will also try SDL_FreeSurface(image); now instead of SDL_FillRect(); and see whats will happen :/

edit: damn it will completely delete the image and not clear the draw :(

Share this post


Link to post
Share on other sites
Toadhead    244
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
tentoid    364
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   
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
Gaiiden    5710
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
Toadhead    244
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
c-gibson-s    313
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
Toadhead    244
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
randomZ    163
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