Motion


mac-10

Still Fresh
Joined
Oct 27, 2006
Messages
56
Age
43
Website
Visit site
Hi there

I am with out doubt a really newbie I have started to code up a space shoot ( really original ) using the SDL. I haven’t got my GP2x yet so I am just compiling it as a win exe. The problem I am having is that the motion of the sprites seems to be jerk or any tip that would be a great help.

Code:
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "SDL/SDL.h"
#define PHYSICSFPS 90

int gLastTick;
int shipSpeed = 1;
int shipX = 20, shipY = 120;
int shipFrame = 0;
int shipMaxFrame = 3;
int Max_Main_Bullets = 10;
int Max_Small_Bullets_1 = 10;
int Max_Small_Bullets_2 = 10;
int MaxEmenies = 20;
int FrameNum = 10;


int gKeyLeft;
int gKeyRight;
int gKeyUp;
int gKeyDown;
int exsFrame;

SDL_Surface *screen, *back, *ship ,*bullet, *exs, *ena;

typedef struct EnemySprite
{
int ObjNo, X, Y, Active, Frame;
}EnemySprite;

typedef struct BulletSprite
{
int ObjNo, X, Y, Active;
}BulletSprite;

typedef struct bgElements
{
int Frame, X, Y, Active;
}bgElements;

int i;

BulletSprite bull[10];
bgElements bgS[7];
EnemySprite enS[20];

// Load in an image and convert it to the display format
// for faster blitting.
SDL_Surface * ImageLoad(char *file)
{
  SDL_Surface *temp1, *temp2;
  temp1 = SDL_LoadBMP(file);
  temp2 = SDL_DisplayFormat(temp1);
  SDL_FreeSurface(temp1);
  return temp2;
}
void addBullet(void){
int flag = 1;
	for(i=1;i < Max_Main_Bullets; i++)
	{
	if(flag &&  bull[i].Active == 0){ 
			bull[i].Active = 1; 
			flag = 0;
			bull[i].X = shipX + 45;
			bull[i].Y = shipY + 15;			  
		  }
	   
	}
}

void DrawIMG(SDL_Surface *img, int x, int y)
{
  SDL_Rect dest;
  dest.x = x;
  dest.y = y;
  SDL_BlitSurface(img, NULL, screen, &dest);
}

void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int x2, int y2)
{
  SDL_Rect dest;
  dest.x = x;
  dest.y = y;
  SDL_Rect dest2;
  dest2.x = x2;
  dest2.y = y2;
  dest2.w = w;
  dest2.h = h;
  SDL_BlitSurface(img, &dest2, screen, &dest);
}

void aniexs(){

exsFrame += 1;
	if(exsFrame > 3) exsFrame = 0;
	 DrawIMG(exs,shipX - 8,shipY,22,26,21*exsFrame,0);  

}

void render(){

  int tick = SDL_GetTicks();

  if (tick <= gLastTick) 
  {
	SDL_Delay(1);
	return;
  }

  while (gLastTick < tick)
  {	 
  if (gKeyLeft) shipX -= shipSpeed;
  if (gKeyRight) shipX += shipSpeed;
  if (gKeyUp) shipY -= shipSpeed;
  if (gKeyDown) shipY += shipSpeed;

if(shipX > 280) shipX = 280;
if(shipX < 1) shipX = 1;
if(shipY > 215) shipY = 215;
if(shipY < 1) shipY = 1;
	SDL_FillRect(screen,0,0);

	for(i=1;i < 5; i++)
	{
		 if(bgS[i].Active){
		 bgS[i].X = bgS[i].X - 1;
		 DrawIMG(back, bgS[i].X ,bgS[i].Y,52,88,52*bgS[i].Frame,0);
		 if(bgS[i].X < -52){	
		 bgS[i].X=320+rand()%10; 
		 bgS[i].Frame = rand()%5; 
		 bgS[i].Y = rand()%160;
		 } 
		 } 
	}

	for(i=1;i < Max_Main_Bullets; i++)
	{
		if(bull[i].Active){
		   bull[i].X = bull[i].X + 2;
		   DrawIMG(bullet, bull[i].X ,bull[i].Y,9,9,0,0);
		   if(bull[i].X > 300)	bull[i].Active=0;			 
		   }
	   
	}

	for(i=1;i < MaxEmenies; i++)
	{
		 if(enS[i].Active){
		 enS[i].X = enS[i].X - 2;
		 DrawIMG(ena, enS[i].X ,enS[i].Y,34,33,34*enS[i].Frame,0);
		 if(enS[i].X < -52){	
		 enS[i].X=320+rand()%10; 
		 enS[i].Y = rand()%160;
		 } 
		 } 
	}

 aniexs();



  
	 DrawIMG(ship,shipX,shipY,43,29,0,0);
	 SDL_Flip(screen);
	 gLastTick += 1000 / PHYSICSFPS;
	 }
}

int main (int argc, char *argv[])
{
	char *msg;
	int done;
  srand(time(NULL));
	Uint8* keys;

	for(i=1;i < Max_Main_Bullets; i++)
	{
		bull[i].X = 0;
		bull[i].Y = 0;
		bull[i].Active = 0;
		bull[i].ObjNo = i;
	}
	
	for(i=1;i < 5; i++)
	{
		bgS[i].X = rand()%500+52;
		bgS[i].Y = rand()%160;
		bgS[i].Active = 1;
		bgS[i].Frame = rand()%4;
	}
	
		for(i=1;i < MaxEmenies; i++)
	{
		enS[i].X = rand()%500+400;
		enS[i].Y = rand()%160;
		enS[i].Active = 1;
		enS[i].ObjNo = i;
		enS[i].Frame = rand()%4;
	}

	/* Initialize SDL */
	if (SDL_Init (SDL_INIT_VIDEO) < 0)
	{
		sprintf (msg, "Couldn't initialize SDL: %s\n", SDL_GetError ());
		free (msg);
		exit (1);
	}
	atexit (SDL_Quit);

	screen = SDL_SetVideoMode (320, 240, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);
	if (screen == NULL)
	{
		sprintf (msg, "Couldn't set 320x240x16 video mode: %s\n",SDL_GetError ());
		free (msg);
		exit (2);
	}
	SDL_WM_SetCaption ("GET Lose", NULL);

  gKeyLeft = 0;
  gKeyRight = 0;
  gKeyUp = 0;
  gKeyDown = 0;
  exsFrame = 0;
  i = 0;

ship = ImageLoad("data/ship/ship.bmp");
exs = ImageLoad("data/ship/exs.bmp");
bullet = ImageLoad("data/bullet/but.bmp");
back = ImageLoad("data/bg/bg.bmp"); 
ena = ImageLoad("data/bad.bmp");

  
 SDL_SetColorKey(ship, SDL_SRCCOLORKEY,SDL_MapRGB(ship->format, 0, 255, 0));
 SDL_SetColorKey(exs, SDL_SRCCOLORKEY,SDL_MapRGB(exs->format, 0, 255, 0));
 SDL_SetColorKey(bullet, SDL_SRCCOLORKEY,SDL_MapRGB(bullet->format, 0, 255, 0));
SDL_SetColorKey(ena, SDL_SRCCOLORKEY,SDL_MapRGB(ena->format, 0, 0, 0));
 SDL_SetColorKey(back, SDL_SRCCOLORKEY,SDL_MapRGB(back->format, 0, 0, 0));
 
 gLastTick = SDL_GetTicks(); 
	done = 0;
	while (!done)
	{



   SDL_Event event;
	while (SDL_PollEvent(&event)) 
	{
	  switch (event.type) 
	  {
	  case SDL_KEYDOWN:
		switch (event.key.keysym.sym)
		{
		case SDLK_LEFT:
		  gKeyLeft = 1;
		  break;
		case SDLK_RIGHT:
		  gKeyRight = 1;
		  break;
		case SDLK_UP:
		  gKeyUp = 1;
		  break;
		case SDLK_DOWN:
		  gKeyDown = 1;
		  break;
		case SDLK_SPACE:
		 addBullet();
		  break;
		  
		}
		break;

	  case SDL_KEYUP:		  
		switch (event.key.keysym.sym)
		{
		case SDLK_ESCAPE:
		  return 0;
		case SDLK_LEFT:
		  gKeyLeft = 0;
		  break;
		case SDLK_RIGHT:
		  gKeyRight = 0;
		  break;
		case SDLK_UP:
		  gKeyUp = 0;
		  break;
		case SDLK_DOWN:
		  gKeyDown = 0;
		  break;
		}
		break;
			case SDL_QUIT:
				done = 1;
				break;
			default:
				break;
			}
		}


	   render(); 
	}

	return 0;
}


Also I have read on this forum that floating point calculation are a bad thing and should be avoided. My question is how do you produce positional vectors with out them.


Thanks


Ian Mac
 

Nagelfar

Active Member
Joined
Nov 18, 2005
Messages
684
To be honest, your code is a mess. For gods sake use telling names for your vars and methods and follow conventional coding conventions.
As for how to eliminate floating point operation: easy, use integers and avoid divisions.
 

mac-10

Still Fresh
Joined
Oct 27, 2006
Messages
56
Age
43
Website
Visit site
is that any better ??

Code:
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "SDL/SDL.h"
#define PHYSICSFPS 90

int gLastTick;
int shipSpeed = 1;
int shipX = 20, shipY = 120;
int ship_Frame = 0;
int ship_Max_Frame = 3;

int Max_Main_Bullets = 10;
int Max_Small_Bullets_1 = 10;
int Max_Small_Bullets_2 = 10;
int Max_Emenies = 20;
int Max_Background = 5;

int  gKeyLeft = 0;
int  gKeyRight = 0;
int  gKeyUp = 0;
int  gKeyDown = 0;
int  Flame_Frame = 0;

int  i = 0;



SDL_Surface *screen, ship_image, *flame_image, *bullet_image, *background_image, *enemy_image;



typedef struct EnemySprite
{
int ObjNo, X, Y, Active, Frame;
}EnemySprite;

typedef struct BulletSprite
{
int ObjNo, X, Y, Active;
}BulletSprite;

typedef struct bgElements
{
int Frame, X, Y, Active;
}bgElements;


BulletSprite bullet[10];
bgElements bgElement[7];
EnemySprite enemy[20];

/ * Image handlers */


SDL_Surface * ImageLoad(char *file)
{
  SDL_Surface *temp1, *temp2;
  temp1 = SDL_LoadBMP(file);
  temp2 = SDL_DisplayFormat(temp1);
  SDL_FreeSurface(temp1);
  return temp2;
}

void DrawIMG(SDL_Surface *img, int x, int y)
{
  SDL_Rect dest;
  dest.x = x;
  dest.y = y;
  SDL_BlitSurface(img, NULL, screen, &dest);
}

void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int x2, int y2)
{
  SDL_Rect dest;
  dest.x = x;
  dest.y = y;
  SDL_Rect dest2;
  dest2.x = x2;
  dest2.y = y2;
  dest2.w = w;
  dest2.h = h;
  SDL_BlitSurface(img, &dest2, screen, &dest);
}

/* Initialize Images */

void init(){

ship_image = ImageLoad("data/ship/ship.bmp");
flame_image = ImageLoad("data/ship/exs.bmp");
bullet_image = ImageLoad("data/bullet/bullet.bmp");
enemy_image = ImageLoad("data/enemy.bmp");
background_image= ImageLoad("data/bg/background.bmp"); 

  /* Set Transparencies */
 SDL_SetColorKey(ship_image, SDL_SRCCOLORKEY,SDL_MapRGB(ship_image->format, 0, 255, 0));
 SDL_SetColorKey(flame_image, SDL_SRCCOLORKEY,SDL_MapRGB(flame_image->format, 0, 255, 0));
 SDL_SetColorKey(bullet_image, SDL_SRCCOLORKEY,SDL_MapRGB(bullet_image->format, 0, 255, 0));
 SDL_SetColorKey(enemy_image, SDL_SRCCOLORKEY,SDL_MapRGB(enemy_image->format, 0, 0, 0));
 SDL_SetColorKey(background_image, SDL_SRCCOLORKEY,SDL_MapRGB(background_image->format, 0, 0, 0));
}


/* create a active bullet */

void addBullet(void){
int flag = 1;
	for(i=1;i < Max_Main_Bullets; i++)
	{
	if(flag &&  bullet[i].Active == 0){ 
			flag = 0;
			bullet[i].Active = 1; 
			bullet[i].X = shipX + 45;
			bullet[i].Y = shipY + 15;			  
		  }
	   
	}
}


void animate_flames(){
Flame_Frame += 1;
	if(Flame_Frame > 3) Flame_Frame = 0;
	 DrawIMG(flame_image,shipX - 8,shipY,22,26,21*Flame_Frame,0);  
}


void render(){
  int tick = SDL_GetTicks();
  if (tick <= gLastTick) 
  {
	SDL_Delay(1);
	return;
  }

  while (gLastTick < tick)
  {	 
  if (gKeyLeft) shipX -= shipSpeed;
  if (gKeyRight) shipX += shipSpeed;
  if (gKeyUp) shipY -= shipSpeed;
  if (gKeyDown) shipY += shipSpeed;

if(shipX > 280) shipX = 280;
if(shipX < 1) shipX = 1;
if(shipY > 215) shipY = 215;
if(shipY < 1) shipY = 1;

SDL_FillRect(screen,0,0);


/* position bgElement */

	for(i=1;i < Max_Background; i++)
	{
		 if(bgElement[i].Active){
		 bgElement[i].X = bgElement[i].X - 1;
		 DrawIMG(background_image, bgElement[i].X ,bgElement[i].Y,52,88,52*bgElement[i].Frame,0);
		 if(bgElement[i].X < -52){	
		 bgElement[i].X=320+rand()%10; 
		 bgElement[i].Frame = rand()%5; 
		 bgElement[i].Y = rand()%160;
		 } 
		 } 
	}

/* position Active Bullets */

	for(i=1;i < Max_Main_Bullets; i++)
	{
		if(bullet[i].Active){
		   bullet[i].X = bullet[i].X + 2;
		   DrawIMG(bullet_image, bullet[i].X ,bullet[i].Y,9,9,0,0);
		   if(bullet[i].X > 300)	bullet[i].Active=0;			 
		   }
	   
	}

/* position Active Emenies */

	for(i=1;i < Max_Emenies; i++)
	{
		 if(enemy[i].Active){
		 enemy[i].X = enemy[i].X - 2;
		 DrawIMG(enemy_image, enemy[i].X ,enemy[i].Y,34,33,34*enemy[i].Frame,0);
		 if(enemy[i].X < -52){	
		 enemy[i].X=320+rand()%10; 
		 enemy[i].Y = rand()%160;
		 } 
		 } 
	}

	 animate_flames();

	 DrawIMG(ship_image,shipX,shipY,43,29,0,0);
	 SDL_Flip(screen);
	 gLastTick += 1000 / PHYSICSFPS;
	 }
}

int main (int argc, char *argv[])
{
	char *msg;
	int done;
	  srand(time(NULL));
	Uint8* keys;

/* Initialize Images */

	init();


	/* Initialize SDL */
	if (SDL_Init (SDL_INIT_VIDEO) < 0)
	{
		sprintf (msg, "Couldn't initialize SDL: %s\n", SDL_GetError ());
		free (msg);
		exit (1);
	}
	atexit (SDL_Quit);

	screen = SDL_SetVideoMode (320, 240, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);
	if (screen == NULL)
	{
		sprintf (msg, "Couldn't set 320x240x16 video mode: %s\n",SDL_GetError ());
		free (msg);
		exit (2);
	}
	SDL_WM_SetCaption ("WoW there nice round here", NULL);

 
 gLastTick = SDL_GetTicks(); 
	done = 0;
	while (!done)
	{



   SDL_Event event;
	while (SDL_PollEvent(&event)) 
	{
	  switch (event.type) 
	  {
	  case SDL_KEYDOWN:
		switch (event.key.keysym.sym)
		{
		case SDLK_LEFT:
		  gKeyLeft = 1;
		  break;
		case SDLK_RIGHT:
		  gKeyRight = 1;
		  break;
		case SDLK_UP:
		  gKeyUp = 1;
		  break;
		case SDLK_DOWN:
		  gKeyDown = 1;
		  break;
		case SDLK_SPACE:
		 addBullet();
		  break;
		  
		}
		break;

	  case SDL_KEYUP:		  
		switch (event.key.keysym.sym)
		{
		case SDLK_ESCAPE:
		  return 0;
		case SDLK_LEFT:
		  gKeyLeft = 0;
		  break;
		case SDLK_RIGHT:
		  gKeyRight = 0;
		  break;
		case SDLK_UP:
		  gKeyUp = 0;
		  break;
		case SDLK_DOWN:
		  gKeyDown = 0;
		  break;
		}
		break;
			case SDL_QUIT:
				done = 1;
				break;
			default:
				break;
			}
		}


	   render(); 
	}

	return 0;
}
 

Uprising

Member
Joined
Mar 6, 2006
Messages
110
Website
Visit site
I am also pretty new to programming but i will see if i can help. :)

You want to ship to move 1 pixel every frame right?

This confuses me a bit in your render function

Code:
 if (tick <= gLastTick)
  {
	SDL_Delay(1);
	return;
  }
This is to cap the framerate i think? I would just use

while(SDL_GetTicks() - gLastTick <= 1000/PHYSICSFPS 90);

and instead of gLastTick += 1000 / PHYSICSFPS;

just put gLastTick = SDL_GetTicks(); at the end of the render function.

The next thing is this.
Code:
while (gLastTick < tick)
{	 
...
...
}
You are going to be moving the ship way more than 1 pixel per frame with this while loop, i would delete it(but still keep the code that is in it).

I hope this helps you.
 
Top