I am trying to move a ball using time. The ball must move 5 pixel per second.
In my code the ball is moving faster. Why is it moving faster? What is wrong with my code?

#include <allegro.h>
#include <cstdlib>
#include <time.h>

int ball_x = 320;
int ball_y = 240;

int ball_tx;
int ball_ty;

BITMAP *buffer; //This will be our temporary bitmap for double buffering
float timer(){

	clock_t cur_time,start_time;
	cur_time = clock();
	start_time = cur_time + 1;
	return difftime(start_time,cur_time);

}
void moveBall(){

	ball_tx = ball_x;
	ball_ty = ball_y;
	int speed = timer() * 5;

	if(key[KEY_LEFT])ball_x = ball_x - speed;
	else if(key[KEY_RIGHT])ball_x = ball_x + speed;
	else if(key[KEY_UP])ball_y = ball_y - speed;
	else if(key[KEY_DOWN])ball_y = ball_y + speed;


	acquire_screen();
	textprintf(buffer,font,10,10,makecol(255,255,255),"ball x = %d" "ball y = %d",ball_x,ball_y);
	circlefill ( buffer, ball_tx, ball_ty, 5, makecol( 0, 0, 0));	
	circlefill ( buffer, ball_x, ball_y, 5, makecol( 255, 255, 255));
	draw_sprite( screen, buffer, 0, 0);
	release_screen();


}
int main(){

	allegro_init();
	install_keyboard();
	set_color_depth(16);
	set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
	buffer = create_bitmap( 640, 480); 

	while( !key[KEY_ESC]){

		moveBall();

	}

	return 0;

}
END_OF_MAIN();

I doubt that using difftime with clock_t is a good idea. difftime works with data of type time_t, which is obtained from the function time(). The clock() function returns clock ticks since the start of the program, and if I'm not mistaken, the clock ticks are only those counted towards this program (it is not a measure of real time elapsing, it is a measure of how much time this program has spent executing stuff, which is only a fraction of the overall time the computer spends executing stuff (which is real time consumption)).

To get the difference between clock ticks, you can do:

return float(cur_time - start_time) / float(CLOCKS_PER_SEC);

To use time() instead of clock, you can do:

float timer(){
  time_t cur_time, start_time;
  cur_time = time();
  start_time = cur_time + 1; //???? THIS MAKES NO SENSE AT ALL ?????
  return difftime(start_time,cur_time);
}

The above just fixes the obvious problem (that you shouldn't mix time_t and clock_t). However, I cannot, for the life of me, understand how your function is supposed to work. Right now, all the timer() function does is return a constant value, whose value is undefined (implementation-specific). What did you expect the function to do? If you expected that function to cause the program to sleep for X amount of time, you are mistaken. You need to use a sleep function for that (Sleep() in Windows, and usleep() in Linux). Essentially, this program you have executes at the maximum speed it can, and the value of "speed" will be constant and will be anything.

My guess is that this is the function you are looking for:

float timer(){
  static time_t start_time = time(); //initialize the start_time once only.
  time_t cur_time = time(); //get the current time
  float result = difftime(cur_time,start_time); //take the time-difference
  start_time = cur_time; //record the current time as the start of next iteration.
  return result; //return the time-difference that was measured.
}

I am trying to move the ball 5 pixel per second. The problem must be in the timer. I am trying to create a timer to move the ball 5 pixels per second. How can I fix the timer? Thanks in advance.

Edited 5 Years Ago by Mr. K: n/a

I fixed the timer. After I fixed the timer I found another error. I discovered that 5 pixels per second is too slow. Now it is moving 100 pixels per second.
When ball_x < 100, Ball_y changes. Why does it changes? What is wrong with my code?

#include <allegro.h>
#include <time.h>

int speed = 100;
double ball_x = 320;
double ball_y = 240;


BITMAP *buffer; //This will be our temporary bitmap for double buffering
clock_t final, initial;
double elapsed;

void moveBall(){

	circlefill ( buffer, ball_x, ball_y, 5, makecol( 0, 0, 0));	//Erase the old ball

	if(key[KEY_LEFT] && ball_x > 0 + 5)
		ball_x = ball_x - speed*elapsed;
	else if(key[KEY_RIGHT] && ball_x < 640 -5)
		ball_x = ball_x + speed*elapsed;
	if(key[KEY_UP] && ball_y > 0 + 5)
		ball_y = ball_y - speed*elapsed;
	else if(key[KEY_DOWN] && ball_y < 480 - 5)
		ball_y = ball_y + speed*elapsed;

	textprintf(buffer,font,10,10,makecol(255,255,255),"ball x = %d, ball y = %d",(int)ball_x,(int)ball_y);
	circlefill ( buffer, ball_x, ball_y, 5, makecol( 255, 255, 255));

	acquire_screen();
	draw_sprite( screen, buffer, 0, 0);
	release_screen();


}
int main(){

	allegro_init();
	install_keyboard();
	set_color_depth(16);
	set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
	buffer = create_bitmap( 640, 480); 
	initial = clock();
	final = clock();
	while( !key[KEY_ESC]){

		elapsed = (double)(clock() - initial)/(double) CLOCKS_PER_SEC;
		initial = clock();

		moveBall();
		
		rest(20);
	}

	return 0;

}
END_OF_MAIN();
This question has already been answered. Start a new discussion instead.