
Moving 2D Sprite: SO on my previous post i showed you the code to display a 2D sprite using OpenGl with SDL. Now i’ll show how to move a 2D Sprite using opengl with sdl. There will be some minor changes in the code and rest will be the same.
I’ll write the new changes in black and bold and rest are the same as in previous code on my previous post.
Here is the full code:
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_opengl.h"
#include <stdio.h>
GLuint texture=NULL; //this is a handle to our texture object
GLenum texture_format=NULL;
GLint nofcolors;
SDL_Event event;
bool LEFT=false;
bool RIGHT=false;
float x=100.0,y=100.0;
int loadImage()
{
SDL_Surface *surface; // this surface will tell us the details of the image
if ( (surface = IMG_Load("flower.png")) ) {
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image.bmp's width is not a power of 2\n");
}
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image.bmp's height is not a power of 2\n");
}
//get number of channels in the SDL surface
nofcolors=surface->format->BytesPerPixel;
//contains an alpha channel
if(nofcolors==4)
{
if(surface->format->Rmask==0x000000ff)
texture_format=GL_RGBA;
else
texture_format=GL_BGRA;
}
else if(nofcolors==3) //no alpha channel
{
if(surface->format->Rmask==0x000000ff)
texture_format=GL_RGB;
else
texture_format=GL_BGR;
}
else
{
printf("warning: the image is not truecolor...this will break ");
}
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, nofcolors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels );
}
else {
printf("SDL could not load image.bmp: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
// Free the SDL_Surface only if it was successfully created
if ( surface ) {
SDL_FreeSurface( surface );
}
}
void drawImage()
{
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
glTranslatef( x, y, 0 );
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
glBegin( GL_QUADS );
// Top-left vertex (corner)
glTexCoord2i( 0, 0 );
glVertex3f( 100, 100, 0 );
// Bottom-left vertex (corner)
glTexCoord2i( 1, 0 );
glVertex3f( 228, 100, 0 );
// Bottom-right vertex (corner)
glTexCoord2i( 1, 1 );
glVertex3f( 228, 228, 0 );
// Top-right vertex (corner)
glTexCoord2i( 0, 1 );
glVertex3f( 100, 228, 0 );
glEnd();
glLoadIdentity();
SDL_GL_SwapBuffers();
}
int init()
{
SDL_Surface *screen;
// Slightly different SDL initialization
if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
}
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL|SDL_FULLSCREEN);
if ( !screen ) {
printf("Unable to set video mode: %s\n", SDL_GetError());
return 1;
}
}
void init_GL()
{
// Set the OpenGL state after creating the context with SDL_SetVideoMode
glClearColor( 0, 0, 0, 0 );
glEnable( GL_TEXTURE_2D ); // Need this to display a texture
glViewport( 0, 0, 640, 480 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, 640, 480, 0, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
void clean_up()
{
glDeleteTextures( 1, &texture );
SDL_Quit();
}
int main(int argc, char *argv[])
{
//Make sure the program waits for a quit
bool quit = false;
init();
init_GL();
loadImage();
drawImage();
while( quit == false )
{
if( SDL_PollEvent( &event ) )
{
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_LEFT:
LEFT=true;
break;
case SDLK_RIGHT:
RIGHT=true;
break;
case SDLK_ESCAPE:
quit=true;
break;
}
}
//If a key was released
else if( event.type == SDL_KEYUP )
{
switch( event.key.keysym.sym )
{
case SDLK_LEFT:
LEFT=false;
break;
case SDLK_RIGHT:
RIGHT=false;
break;
}
}
}
if(LEFT==true){
x-=2;
drawImage();
}
else if(RIGHT==true){
x+=2;
drawImage();
}
}
clean_up();
return 0;
}
In above code i have used two bool variable(LEFT and RIGHT) and two float variables(x and y) to store the position of sprite. In the main function inside the loop we are taking the key input from the user. So when the user press left arrow key “LEFT bool variable is assigned TRUE” and when user releases the left arrow key ” LEFT bool variable is assigned FALSE”. Same applies for pressing right arrow key. So in this code :
if(LEFT==true){
x-=2;
drawImage();
}
else if(RIGHT==true){
x+=2;
drawImage();
}
when left arrow key is pressed “LEFT bool variable becomes TRUE” and x position of sprite is incremented by 2. Then we draw the sprite again. And when left arrow key is released “LEFT bool variable becomes FALSE” which means x position of sprite should not be updated. Same concept applies for moving right.
Now we have code to update the x and y position of sprite. But how to render the sprite with updated x and y coordinates. This is done by gTranslatef(x,y,z) function. It translates the position of sprite. So we’ll be updating x and y to move the sprite, and z will be zero. So in this code:
void drawImage()
{
// Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );
glTranslatef( x, y, 0 );
// Bind the texture to which subsequent calls refer to
glBindTexture( GL_TEXTURE_2D, texture );
glBegin( GL_QUADS );
// Top-left vertex (corner)
glTexCoord2i( 0, 0 );
glVertex3f( 100, 100, 0 );
// Bottom-left vertex (corner)
glTexCoord2i( 1, 0 );
glVertex3f( 228, 100, 0 );
// Bottom-right vertex (corner)
glTexCoord2i( 1, 1 );
glVertex3f( 228, 228, 0 );
// Top-right vertex (corner)
glTexCoord2i( 0, 1 );
glVertex3f( 100, 228, 0 );
glEnd();
glLoadIdentity();
SDL_GL_SwapBuffers();
}
when we update the position of x and y then we call the above function where we have included new code glTranslatef(x,y,z) which will make the sprite to be drawn in given x.y and z location.
So thats it. I hope this will give u some pretty basic idea. Now you can write your own code for moving 2d Sprite.
Gracias.