I am trying to move a ball using time. What do I need to know to move the ball?
How can I move the ball 20 pixel per second?

#include <allegro.h>


int ballx = 320;
int bally = 240;

 void ball(){

	 if(key[KEY_RIGHT]){

	 }
	else if(key[KEY_LEFT])
	{

	 }


	acquire_screen();
	circlefill(screen,ballx,bally,5,makecol(255,255,255));
	release_screen();

}

 int main(){

	allegro_init();
	install_keyboard();

	set_gfx_mode( GFX_AUTODETECT, 480, 480, 0, 0);

	while(!key[KEY_ESC]){
		ball();
	}

return 1;
 }
END_OF_MAIN();

Dani AI

Generated

Short answer: use a delta-time update. Compute how many seconds passed since the last frame and move the ball by speed_in_pixels_per_second * delta_seconds. That keeps motion independent of frame rate and makes "20 pixels per second" exact.

Key bugs in the posted code

  • already hinted at an uninitialized variable; sec or start left uninitialized yields undefined behavior.
  • Integer division/truncation: expressions like clock() / CLOCKS_PER_SEC will truncate if both operands are integers. Cast to double first.
  • Wrong scope/semantics: passing start by value and trying to change it inside update() does not update main()'s variable. Use a persistent lastTime (static/global) or return the new value.
  • Blocking/wait loops (do/while or busy waiting) freeze the main loop and produce strange timing. Do not wait inside the main loop for "0.05" seconds; compute and apply the elapsed time each frame.
  • clock() measures processor time in the standard C API; for higher precision or wall-clock time use a high-resolution timer or your framework's timer. and pointed this out.

Minimal working pattern (conceptual)

double last = static_cast<double>(clock()) / CLOCKS_PER_SEC;
const double SPEED = 20.0; // pixels per second

while (!key[KEY_ESC]) {
  double now = static_cast<double>(clock()) / CLOCKS_PER_SEC;
  double dt = now - last;
  last = now;

  if (key[KEY_RIGHT]) ballx += SPEED * dt;
  if (key[KEY_LEFT])  ballx -= SPEED * dt;

  clear_to_color(screen, makecol(0,0,0));
  circlefill(screen, static_cast<int>(ballx), static_cast<int>(bally), 5, makecol(255,255,255));
  rest(1); // small yield to avoid 100% CPU
}

Extra tips

  • Keep ballx/bally as floats; cast to int only when drawing.
  • Clamp dt (for example max 0.1s) so a pause or breakpoint does not fling the ball far.
  • If you need deterministic physics, use a fixed timestep (tick at 60 Hz) and accumulate remainder. Otherwise the variable-dt approach above is fine.
  • and gave good high-level advice about two-time variables and structuring updates; combine that with the code pattern above to fix the disappearing/too-fast behavior.

Recommended Answers

All 11 Replies

QueryPerformanceCounter

20 pixel per second = 1ms x 50 per pixel. Perform the check via subtraction and if the time difference exceeds 50, move one pixel. Of course, you'll then need to reset the "clock" so to speak.

Alternatively, you could just grab the time via Clock(), that measures the amount of time your program has been running. The same logic would apply.

Clock() should be even less performance intensive as it only grabs other variables. Clock measures in seconds, however you should have no trouble grabbing milliseconds.

This assumes you're using windows. If not, please say so. I've never used allergo so I couldn't say it's compatibilities.

Clock measures in seconds, however you should have no trouble grabbing milliseconds.

I think that clock() actually returns the number of clock cycles since the program started, not any actual unit of time. You can get an estimate of the time that passed by using CLOCKS_PER_SEC You can read more about clock() .

I think that clock() actually returns the number of clock cycles since the program started, not any actual unit of time. You can get an estimate of the time that passed by using CLOCKS_PER_SEC You can read more about clock() .

You're correct, I forgot to clarify that.

I am trying to move the ball. But the ball refuses to move.
Why does my ball does not move? How can the problem be solved?

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

int sec;

int ballx = 320;
int bally = 240;



 void ball(){

	int speed = 20 * sec;

	 if(key[KEY_RIGHT]){
		ballx += speed;
	 }
	else if(key[KEY_LEFT])
	{

	 }


	acquire_screen();
	circlefill(screen,ballx,bally,5,makecol(255,255,255));
	release_screen();

}
 void reset(){

	 if(sec >= 1)sec--;

 }
void timer (){

  clock_t endwait;
  endwait = clock () + 1 * CLOCKS_PER_SEC ;
  if (clock() > endwait) sec++;

}
 int main(){

	allegro_init();
	install_keyboard();
	
	set_gfx_mode( GFX_AUTODETECT, 480, 480, 0, 0);
	


	while(!key[KEY_ESC]){
		timer();
		ball();
		reset();

	}

return 1;
 }
END_OF_MAIN();

You never intialized sec. Anyways, you should be doing something like this :

class Vector2F{
private:
 float pos[2];
public:
 Vector2F() : pos(){}
 Vector2F(float x, float y) { pos[0] = x; pos[1] = y; }
 float getX(){ return pos[0]; }
 float getY(){ return pox[1]; }
 void setX(float x){ pos[0] = x; }
 void setY(float y){ pos[1] = y; }
 void translate(float dx, float dy){ pos[0] += dx; pos[1] += dy;}
};

class Circle{
private:
 Vector2F position;
 Vector2F velocity;
public:
 explicit Circle(float x = 0, float y = 0) : position(x,y){}; 
 void draw(BITMAP *screen){
   //default color is black, you can encapsulate color if you want also,
   circlefill(screen, position.getX(), position.getY(), makecol(0,0,0) );
 }
 void move(float dx, float dy ){
   position.translate(dx,dy);
   draw();
 }
}circle;

void update(Circle& circle, float dt){
 //use some sort of numerical update method
}
void display(){
 //..stuff
 circle.draw( screen );
 //calculate dt, i.e time difference
 const int UPDATE_INTERVAL = 100; //milliseconds
 if( timer.getElapsed() > UPDATE_INTERVAL){   
   update(circle, 1.0f ); //
 }
}

The ball is moving too fast (5 pixel per second). Is the timer working?
PLease check my code.

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

float ballx = 320;
float bally = 240;



 void ball(float unit){

	float speed = 5 * unit;

	 if(key[KEY_RIGHT]){
		ballx += speed;
	 }
	else if(key[KEY_LEFT])
	{
		ballx -= speed;
	 }

	acquire_screen();
	clear_to_color(screen,makecol(0,0,0));
	circlefill(screen,ballx,bally,5,makecol(255,255,255));
	release_screen();

}
void update (){//is it working?

	clock_t start;
	start = clock();
	float time = start / CLOCKS_PER_SEC;

	while(time > 1){
		time--;

	}
	ball(time);
	acquire_screen();
	textprintf(screen,font,10,10,makecol(255,255,255),"%d",(int)time);
	release_screen();
}
 int main(){

	allegro_init();
	install_keyboard();
	
	set_gfx_mode( GFX_AUTODETECT, 480, 480, 0, 0);
	
	while(!key[KEY_ESC]){
		update();

	}

return 1;
 }
END_OF_MAIN();

The problem is you're moving it at 5 times the rate of time, as opposed to simply using time to tell you when to move it.

You don't need to subtract from time because time is automatically calculated by the computer, that's the whole point of using it.

You need two variables, one for the current time(as you have), and one for the starting time. Get the starting time in int Main and pass it to your function, then, in your function, get the present time every time it's ran. compare that to the starting time. Remember, 20 pixels per second = 1ms x 50 per pixel. Because you're measuring in seconds, it will be .05 seconds per pixel. So, you need an if statement to check and see if the present time has a .05 difference from the starting time. If it does, increment your movement by 1 pixel, then, set the present time as the starting time. You shouldn't even need to pass time to your movement. Instead, just pass a float for speed equal to 1 pixel. Speed += 1.

The ball refuses to move. The timer is not changing. int start doesn`t change.
What formula are you using to calculate distance and time? Where can I find information about those formulas? What is wrong with my code?

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

float ballx = 320;
float bally = 240;



 void ball(float unit){

	float speed = unit * 1;

	 if(key[KEY_RIGHT]){
		ballx += speed;
	 }
	else if(key[KEY_LEFT])
	{
		ballx -= speed;
	 }

	acquire_screen();
	clear_to_color(screen,makecol(0,0,0));
	textprintf(screen,font,10,10,makecol(255,255,255),"%d",(int)unit);
	circlefill(screen,ballx,bally,5,makecol(255,255,255));
	release_screen();

}
void update (int starting_time){

	clock_t start;
	start = clock();
	double time = start / CLOCKS_PER_SEC;

	starting_time = time + 0.05;

} 
int main(){

	allegro_init();
	install_keyboard();
	
	set_gfx_mode( GFX_AUTODETECT, 480, 480, 0, 0);
	
	float start = 0;


	while(!key[KEY_ESC]){
		update(start);
		ball(start);
	}

return 1;
 }
END_OF_MAIN();

Run this simple program. Look at the code and look at what it's doing exactly to delay the time. Then apply it to your code.

#include <iostream>
#include <time.h>

using std::cout;

int main()
{
 clock_t startTime,curTime = 0;

 //Grabs clock time at the beginning of the program
 startTime = clock() / CLOCKS_PER_SEC;
 cout << startTime << "\n";
 curTime = clock() / CLOCKS_PER_SEC;
 while (curTime - startTime < 5) //waits 5 seconds.
 {
  curTime = clock() / CLOCKS_PER_SEC;  //Loops, grabbing the time.
 }
 cout << "\n5 seconds later! " << curTime << "\n";
 return 0;
}

The ball is not moving 5 pixels per second. When I move the ball it disappears. Maybe the ball is moving too fast. What is wrong with my code? Why is the ball moving too fast? Thanks in advance.

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

float ballx = 320;
float bally = 240;



 void ball(float unit){

	float speed = unit;

	 if(key[KEY_RIGHT]){
		ballx += speed;
	 }
	else if(key[KEY_LEFT])
	{
		ballx -= speed;
	 }

	acquire_screen();
	clear_to_color(screen,makecol(0,0,0));
	textprintf(screen,font,10,10,makecol(255,255,255),"%d",(int)unit);
	circlefill(screen,ballx,bally,5,makecol(255,255,255));
	release_screen();

}
void update (int starting_time){

	clock_t start;
	start = clock();
	double time = start / CLOCKS_PER_SEC;
	do{
	ball(start);
	}
	while(!starting_time == start + 0.5);


} 
int main(){

	allegro_init();
	install_keyboard();
	
	set_gfx_mode( GFX_AUTODETECT, 480, 480, 0, 0);
	
	float start = 0;


	while(!key[KEY_ESC]){
		update(start);
	
	}

return 1;
 }
END_OF_MAIN();
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.