Skip to main content
GameDev.net gamedev.net
🔒 Locked

Collision not working right

Started by brain21 Dec 6, 2008 at 11:57 PM 0 replies 550+ views
Original Post
brain21
brain21
Hi, I wrote this program to simulate circles accumulating into lanes on a conveyor, but after adding 300 circles, the lanes start to collapse. I'm not sure what's happening here. The code is posted below and I'm using a simple form of collision detection, but I've also implemented a circle to circle sweep function that I found on gamedev, and that did the same thing at the code below. After running the code, press 'A' to add 10 circles. They will move to the right of the screen and stop near the end. This is where they should accumulate. After adding about 300, they lanes start to collapse. Can anyone find what's wrong with this? It's made with Allegro, but that's not the part that's not working.

#include <stdio.h>
#include <stdlib.h>
#include <allegro.h>
#include <winalleg.h>
#include <list>
#include <cmath>

using namespace std;

class Circ
{
public:
	double m_x, m_y, m_size;
};

BITMAP *buffer = 0;
int last_clock_tick = 0;
int delta_clock = 0;
int clock_ticks = 0;
char ons = 0;
double speed = 150.0;

list<Circ> CList;


double Collision( Circ *c )
{
	list<Circ>::iterator index;
	Circ *p;
	double l1, l2, res;
	double dx, dy;

	for ( index = CList.begin(); index != CList.end(); ++index )
	{
		p = &(*index);
		if ( p != c )
		{
			dx = ( p->m_x - c->m_x );
			dy = ( p->m_y - c->m_y );
			l1 = ( dx * dx ) + ( dy * dy );
			l2 = p->m_size + c->m_size;

			if ( l1 < ( l2 * l2 ) )  //Collision
			{
				res = ( l2 - sqrt(l1) );
				return res;
			}
		}
	}

	return 0;
}

void UpdateCircles( int milliseconds )
{
	list<Circ>::iterator index;
	Circ *p;
	double spd, res;

	for ( index = CList.begin(); index != CList.end(); ++index )
	{
		p = &(*index);
		spd = speed * ( (double)milliseconds / 1000.0 );

		if ( p->m_x < 635.0 )
			p->m_x += spd;
		res = Collision( p );
		if ( res > 0 )
			p->m_x -= ( res + 0.1 );
	}
}

void DrawCircles( BITMAP *dest )
{
	list<Circ>::iterator index;
	Circ *p;

	for ( index = CList.begin(); index != CList.end(); ++index )
	{
		p = &(*index);
		circlefill( dest, p->m_x, p->m_y, p->m_size, makecol( 255, 0, 0 ) );
	}
}


void AddCircle( double x, double y, double size )
{
	Circ p;
	p.m_x = x;
	p.m_y = y;
	p.m_size = size;
	CList.push_back( p );
}

char Init()
{
	if (allegro_init() != 0)
		return 1;
	install_timer();
	install_keyboard();

	set_color_depth( 32 );
	if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0) != 0) 
	{
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Unable to set any graphic mode\n%s\n", allegro_error);
		return 1;
	}

	/* allocate the memory buffer */
	buffer = create_bitmap(SCREEN_W, SCREEN_H);

	return 0;
}

void Destroy()
{
	if ( buffer )
		destroy_bitmap( buffer );

	allegro_exit();
}

int main(void)
{
	//Initialize the application
	if ( Init() )
	{
		Destroy();
		return -1;
	}

	last_clock_tick = GetTickCount();

	//Press ESCAPE to get out
	while( !key[ KEY_ESC ] )
	{
		clock_ticks = GetTickCount();
		delta_clock = clock_ticks - last_clock_tick;
		last_clock_tick = clock_ticks;

		if ( key[ KEY_A ] && ons == 0 )
		{
			AddCircle( 50, 120, 5 );
			AddCircle( 50, 140, 5 );
			AddCircle( 50, 160, 5 );
			AddCircle( 50, 180, 5 );
			AddCircle( 50, 200, 5 );
			AddCircle( 50, 220, 5 );
			AddCircle( 50, 240, 5 );
			AddCircle( 50, 260, 5 );
			AddCircle( 50, 280, 5 );
			AddCircle( 50, 300, 5 );
			ons = 1;
		}
		if ( !key[ KEY_A ] )
			ons = 0;

		UpdateCircles( delta_clock );

		DrawCircles( buffer );			

		textprintf( buffer, font, 10, 10, makecol( 255, 255, 255 ), "Circles = %d", CList.size() );
		//Flip the double buffer
		blit( buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h );
		clear_bitmap( buffer );
	}

	Destroy();

	return 0;
}
END_OF_MAIN()




Thanks, Brain21 [Edited by - brain21 on December 7, 2008 12:18:01 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.