linear interpolation in pong

Started by
16 comments, last by JasonL220 18 years, 6 months ago
#include <math.h>
#include <stdio.h>

int ROUND_FLOAT1(float a)
{
double intpart, floatpart;
floatpart = modf(a, &intpart);
if(floatpart >= 0.5)
intpart += 1;
return (int)floor(intpart);
}

this is the rounding code i made i cant seem to get the profiling tools to work so i cant test the speed but i t works fine.
Advertisement
Quote:Original post by jyk
I couldn't quite figure out that formula, but the idea seems to be something like this:
ball_x = center of ball = ball_sprite_x + ball_width / 2paddle_x = center of paddle = paddle_sprite_x + paddle_width / 2angle = 45 * ((paddle_x - ball_x) / paddle_extent))
The idea being that the ball bounces diagonally at the corners of the paddle, and more and more 'straight up' as it approaches the center. This isn't particularly realistic, but may be ok for a pong game - I don't know. If this is c++, it seems the use of ints rather than floats might cause some problems there. Also, it can sometimes be more useful to deal with velocities in terms of vectors rather than angles.


what is ment by paddle_extent?
Sorry about the use of the modulus in my example, it was very late for me, and Hurricane Wilma was en-route :p You have it right now tho.
Quote:Original post by Days
now, back to floor and ceil. These are the only (easy to understand) safe way of converting a float to an int that I know of.

#define ROUND_FLOAT(a) (a%1 < 0.5f ? floor(a) : ceil(a))



Float's don't have a modulus operator, so that isn't going to compile. I don't see what's wrong with the good ol' rounding formula here: int x = int(float_x + 0.5f);

I would point out however, that if you're doing this rounding specifically for drawing purposes (to avoid filtering and whatnot), you should probably try to hold off on this step until you actually send the data to be drawn (in other words, always keep track of the position/velocity with floats and cast them to ints when drawing), or you risk the possibility of significant inconsistancy between machines running at different speeds.
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Formats______________________________________________________________________________________
Quote:what is ment by paddle_extent?
Sorry, the extent in this case is half the width of the object. So:
paddle_extent = paddle_width / 2;
i have written this code:

// Pong Clone Jason Lovett#include "pong.h"	//include pong.h//increment logic_countervoid update_logic_counter(){	logic_counter++;}END_OF_FUNCTION(update_logic_counter);	//Needed in timing functions, to keep portabilityint angle(){	switch(ballspeedx)	{		case 2 :	//if ballspeedx is 4		{			int centreofball = ballleft + (ballwidth / 2);			//find centre of ball			int centreofpaddle = paddle1left + (paddlewidth / 2);	//find centre of paddle			angleofreflection = 45 * ((centreofpaddle - centreofball) / (paddlewidth / 2)); //convert to angle between 45 and -45			break;		}		case -2 :	//if ballspeedx is -4		{			int centreofball = ballleft + (ballwidth / 2);			//find centre of ball			int centreofpaddle = paddle2left + (paddlewidth / 2);	//find centre of paddle			angleofreflection = 45 * ((centreofpaddle - centreofball) / (paddlewidth / 2)); //convert to angle between 45 and -45			break;		}	}	return roundfloat(angleofreflection);}//check for collisionsint CollisionDetect(){	if((ballleft <= paddle1right) && (ballbottom >= paddle1top) && (ballright >= paddle1left) && (balltop <= paddle1bottom))	//if ball is within paddle1	{		ballspeedx = 4;		//invert xdir		ballspeedy = angle();	//calculate yspeed	}	if((ballright <= paddle2left) && (ballbottom >= paddle2top) && (ballleft <= paddle2right) && (balltop <= paddle2bottom))	//if ball is within paddle2	{		ballspeedx = -4;	//invert xdir		ballspeedy = angle();//calculate yspeed	}	if(ballright >= SCREEN_W)	{		RePosition();		p1score++;	}	if(ballleft <= 0)	{		RePosition();		p2score++;	}	return 0;}int PaddleMove(){	if(key[KEY_UP])		paddle2top -= 4;	if(key[KEY_DOWN])		paddle2top += 4;	if(key[KEY_W])		paddle1top -= 4;	if(key[KEY_S])		paddle1top += 4;	return 0;}int BallMove(){	ballleft += ballspeedx;	balltop += ballspeedy;	return 0;}int RePosition(){	balltop = (SCREEN_H / 2 + (rand()%36)) - (ballwidth / 2);	ballleft = SCREEN_W / 2 - (ballwidth / 2);	int rand1 = (rand()%1)+1;	if (rand1 == 1)	{		ballspeedx = 2;	}	else	{		ballspeedx = -2;	}	return 0;}//draw the graphics to the buffer the blit to the screenint DrawGraphics(BITMAP *buffer){	clear_bitmap(buffer); //make sure the bitmap is blank before drawing	rectfill(buffer, paddle1left, paddle1top, paddle1right, paddle1bottom, makecol(255,255,255));	rectfill(buffer, paddle2left, paddle2top, paddle2right, paddle2bottom, makecol(255,255,255));	circlefill(buffer, ballleft, balltop, (ballwidth / 2), makecol(255,255,255));	blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); //blit to screen (double buffering)	return 0; //success}//mainint main(int argv, char **argc[]){	allegro_init();		//initialise allegro	install_timer();	//initialise timer routines	install_keyboard();	//initialise keyboard routines		srand(time(NULL));	//seed the rand runction with the time to get better random numbers		set_color_depth(16);	//set colour depth	set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);	//set graphics mode to fullscreen 640x480		sint quitit = 0;			//quit variable	p1score = 0;	p2score = 0;		LOCK_VARIABLE(logic_counter);	//needed on timing variables to keep portability	LOCK_FUNCTION(update_logic_counter);	//needed on timing functions to keep portability	install_int_ex(update_logic_counter, BPS_TO_TIMER(60));	//set the timer rate to 60 frames per second (tick per second)		BITMAP *buffer = create_bitmap(640, 480);		//create buffer bitmap for extra speed	clear_bitmap(buffer);		//make sure the bitmap is empty		paddle2top = (SCREEN_H/2 - paddlewidth);		//set paddle2top	paddle2left = (SCREEN_W - paddlewidth - 10);	//set paddle2left	paddle1top = (SCREEN_H/2 - paddlewidth);		//set paddle1top	paddle1left = paddlewidth;						//set paddle1left		RePosition();				//set the starting point for the ball	ballspeedy = 1;		while(!quitit)			//if quitit = 0 loop	{		while(logic_counter)	///if logic_counter is 1 loop		{			ballbottom = balltop + ballwidth;		//set ballbottom			ballright = ballleft + ballwidth;		//set ballright			paddle1bottom = paddle1top + paddlehieght;		//set paddle1bottom			paddle1right = paddle1left + paddlewidth;		//set paddle1right			paddle2bottom = paddle2top + paddlehieght;		//set paddle2bottom			paddle2right = paddle2left + paddlewidth;		//set paddle2right			CollisionDetect();			//call the collision detection routine			PaddleMove();				//call the paddle move routine			BallMove();					//call the ball move routine			DrawGraphics(buffer);		//call the draw grpahics routine and pass the bitmap buffer			logic_counter--;			//decrement logic_counter		}		if(key[KEY_ESC]) quitit++;		//if esc is pressed then the loop will quit	}	destroy_bitmap(buffer);				//release the buffer bitmap memory	return 0;			//success}END_OF_MAIN();	//needed to keep portability///~


//Pong Clone, Jason Lovett#include <allegro.h>	//include allegro header#include <stdlib.h>		//for rand#include <time.h>		//use for paramater to srand to get a more random number#include <roundfloat.h>	//round the angle float to an int to get a valid ballyspeedtypedef short int sint;	//type sint instead of short inttypedef long int lint;	//type lint instead of long intfloat angleofreflection;sint ballspeedx;sint ballspeedy;const sint paddlewidth = 16;const sint ballwidth = 8;const sint paddlehieght = 40;sint paddle1top, paddle2top, balltop;sint paddle1left, paddle2left, ballleft;sint paddle1bottom, paddle2bottom, ballbottom;sint paddle1right, paddle2right, ballright;sint paddlehity;sint p1score, p2score;volatile sint logic_counter;int CollisionDetect();				//CollisionDetect declaration	//doneint Angle();						//Angle declaration		//doneint PaddleMove();					//PaddleMove declaration	//doneint BallMove();						//BallMove declaration		//doneint RePosition();					//RePosition declaration	//doneint DrawGraphics(BITMAP *buffer);	//DrawGraphics declaration	//done///~


download the .exe to see the prob ,<a>http://www.jlovett.plus.com/pong.zip, thanks
have been tring to debug my code with gdb(mingw) but i have not found it particly useful, could someone give me some tips on using it?

i have found the bug but the angle calculation code does not work it always bounces of at 90* to the paddle.

int angle(){	switch(ballspeedx)	{		case 2 :	//if ballspeedx is 4		{			int centreofball = ballleft + (ballwidth / 2);			//find centre of ball			int centreofpaddle = paddle1left + (paddlewidth / 2);	//find centre of paddle			angleofreflection = 45 * ((centreofpaddle - centreofball) / (paddlewidth / 2)); //convert to angle between 45 and -45			break;		}		case -2 :	//if ballspeedx is -4		{			int centreofball = ballleft + (ballwidth / 2);			//find centre of ball			int centreofpaddle = paddle2left + (paddlewidth / 2);	//find centre of paddle			angleofreflection = 45 * ((centreofpaddle - centreofball) / (paddlewidth / 2)); //convert to angle between 45 and -45			break;		}	}	return roundfloat(angleofreflection);}


the .exe can be found at www.jlovett.plus.com/programmig/pong/pong.exe

thanks

[Edited by - JasonL220 on October 26, 2005 12:07:56 PM]
i have got the angle code working (well nearly) could you please have a look all code and .exe is at www.jlovett.plus.com/pong.zip

This topic is closed to new replies.

Advertisement