Jump to content

  • Log In with Google      Sign In   
  • Create Account

Soundstone

Member Since 28 Jan 2013
Offline Last Active Apr 08 2014 11:40 PM

Topics I've Started

Allegro bitmaps at runtime?

19 January 2014 - 03:12 PM

Hello everyone,

 

I have recently run into a problem that I'm not sure Allegro 5 can handle. I was curious if anyone knew whether or not the following functionality existed for the Allegro graphics library.

 

I am aware that to get a scrolling background one can provide an image and load it in as a ALLEGRO_BITMAP *background. I have done this just fine. However, for the particular game I am trying to code I generate the level at random.

 

Basically I generate two arrays of points, one for my ceiling and one for my floor. These arrays are size top[333] and bottom[333]. The distance between each point is between 36 - 48 pixels, thus my final point in both arrays is someone just over 12,050 as the X coord.

 

My question is this, does Allegro have a way to create an image at runtime based on the plot placement of these randomly generated points?

I've tried looking at the Allegro5 manual and it doesn't really provide any information on bitmap creation at runtime. Does anyone have experience with this sort of thing, or am I doomed to choose a new graphics library or create static images instead of random?

 

Thanks for taking the time to read and any advice that may be offered.

 

 


Linear collision question

03 January 2014 - 08:55 PM

Hello all,

 

I have this concept that I am currently working on that creates a procedurally generated tunnel. This is done simply by starting with a start point and generating random points being offset by a variable distance over iteration. The results produce a tunnel of set length (rather long) looking something like this small portion. 

 

 

(apparently I can't put the photo here - please follow link to see if you would like to see a screen shot of the tunnel to better help you understand)

 

Each of these lines is drawn based on the new point added through the random generation.and the lines are drawn via the Allegro5 library. The issue I'm having is collision based on these random lines and a players avatar - currently a square. What I had mapped out was testing collision based on a set of points on the avatar. So I get these 8 points. 

 

1. (square.x, square.y) - Top Left Corner

2. (square.x + square.width / 2, square.y) Top Middle

3. (square.x + square.width, square.y ) Top Right Corner

4. (square.x, square.y + square.height /2) Left Middle

5. (square.x + square.width, square.y + square.height /2) Right Middle

6. (square.x, square.y + square.height) Bottom Left Corner

7. (square.x + square.width / 2, square.y + square.height) Bottom Middle

8. (square.x + square.width, square.y + square.height) Bottom Right Corner

 

as my test points for collision. To test the collision that requires finding out if any of these points lie on each of the lines. Since the lines are generated randomly at the it seems like it would be wrong to test each frame for all lines and these points. So I started with a simple test to see if checking collision is even needed this update. This was done via this code.

for (int i = 0; i < NUM_POINTS; i++)
{
	if(points[i + 1].y < points[i].y)
	{
		//preliminary check for collision, is ship within checking range?
		if( (ship.pos.x > points[i].x) &&
		    (ship.pos.x < points[i + 1].x) &&
		    (ship.pos.y > points[i + 1].y) &&
       		    (ship.pos.y < points[i].y))

NUM_POINTS is the array that holds all randomly generated points. Lets say it currently stores 1000 points. This brings us to 999 lines in the level. There is also a BOT_NUM_POINTS set exactly the same way to make up the bottom of the tunnel.  The initial check of:

if(points[i + 1].y < points[i]. y) 

is testing to see if the lines first point would be higher on the screen then the second. This determines if the line is sloped left or right. The next check of:

if( (ship.pos.x > points[i].x) &&
    (ship.pos.x < points[i + 1].x) &&
    (ship.pos.y > points[i + 1].y) &&
    (ship.pos.y < points[i].y))

is the preliminary check to see if collision is worth looking into. These works by checking to see if the ships upper left corner is within the x's of the line and if so if its between the height of the two as well. If this succeeds it continues on to perform collision checking for the line in question.

float slope = GetLineSlope(points[i], points[i + 1]);
				float intercept = GetYIntercept(points[i], slope);
				//if( IsOnLine(ship.pos.x, ship.pos.y, slope, intercept) )
				if(IsOnLine(ship.pos.x, ship.pos.y, points[i], points[i + 1]))
				{
					//Collide
					al_draw_textf(font, al_map_rgb(255,0,0), 100, 10, 0, "Line points (%5d, %5d)", points[i].x, points[i].y);
					al_draw_textf(font, al_map_rgb(255,0,0), 100, 35, 0, "Line points (%5d, %5d)", points[i + 1].x, points[i + 1].y);
					al_draw_textf(font, al_map_rgb(255,0,0), WIDTH / 2, HEIGHT / 2, 0, "COLLISION AT %5d, %5d", ship.pos.x, ship.pos.y);
					return true;
				}
				//else if ( IsOnLine((ship.pos.x + ship.boundx) / 2, ship.pos.y, slope, intercept) )
				else if( IsOnLine( (ship.pos.x + ship.boundx) / 2, ship.pos.y, points[i], points[i + 1]) )
				{
					//Collide
					al_draw_textf(font, al_map_rgb(255,0,0), 100, 10, 0, "Line points (%5d, %5d)", points[i].x, points[i].y);
					al_draw_textf(font, al_map_rgb(255,0,0), 100, 35, 0, "Line points (%5d, %5d)", points[i + 1].x, points[i + 1].y);
					al_draw_textf(font, al_map_rgb(255,0,0), WIDTH / 2, HEIGHT / 2, 0, "COLLISION AT %5d, %5d", ship.pos.x + ship.boundx, ship.pos.y);
					return true;
				}
				//else if ( IsOnLine(ship.pos.x + ship.boundx, ship.pos.y, slope, intercept) )
				else if( IsOnLine(ship.pos.x + ship.boundx, ship.pos.y, points[i], points[i + 1]) )
				{
					//Collide
					al_draw_textf(font, al_map_rgb(255,0,0), 100, 10, 0, "Line points (%5d, %5d)", points[i].x, points[i].y);
					al_draw_textf(font, al_map_rgb(255,0,0), 100, 35, 0, "Line points (%5d, %5d)", points[i + 1].x, points[i + 1].y);
					al_draw_textf(font, al_map_rgb(255,0,0), WIDTH / 2, HEIGHT / 2, 0, "COLLISION AT %5d, %5d", (ship.pos.x + ship.boundx) / 2, ship.pos.y);
					return true;
				}
			}
		}
		else if(points[i + 1].y > points[i].y)
		{
			//preliminary check for collision. Is ship within checking range?
			if( (ship.pos.x > points[i].x) &&
				(ship.pos.x < points[i + 1].x) &&
				(ship.pos.y < points[i + 1].y) &&
				(ship.pos.y > points[i].y))
			{
				//TODO: need to place another if statement here checking the slope of the line and if the point lies on the line. 
				//collide
				al_draw_textf(font, al_map_rgb(255,0,0), 100, 10, 0, "Line points (%5d, %5d)", points[i].x, points[i].y);
				al_draw_textf(font, al_map_rgb(255,0,0), 100, 35, 0, "Line points (%5d, %5d)", points[i + 1].x, points[i + 1].y);
				return true;
			}
		}
	}
	return false;
}

As you can see the first thing I try to do is to figure out the slope of the current line. This is done by checking (y2- y1) / (x2-x1). The slope is then used in the lines formula and the points of the avatar are inserted into the formula to see if they lay on the line. The code to check to see if point is on the line is as follows.

bool IsOnLine(int boxX, int boxY, Point p1, Point p2)
{
   Point temp;
   temp.x = boxX;
   temp.y = boxY;
   return ( (p1.y - temp.y) == GetLineSlope(p1, p2) * (p1.x - temp.x) );
}

where as GetLineSlope is:

float GetLineSlope(Point p1, Point p2)
{	
    return ( (p2.y - p1.y) / (p2.x - p1.x) );
}

The issue I'm having is that it hardly recognizes collision. It does recognize it from time to time but a majority of the time the debug display that should be printed doesn't indicating a collision is not taking place. I also realize that the above code doesn't test all of the test points discussed earlier. I figured if I could get it working right for an easy point like its Top Left corner (x,y) then I could theoretically get it working correctly for the rest of the points. 

 

My question is this. Am I over-thinking this or under-thinking it for that matter. Is there a better way to go about doing this? If not, does anyone recognize why this may not be working as intended. I understand that sounds like someone please do work for me, but I don't expect that from anyone. I am merely wondering if anyone has tried linear collision before and what method was taken to get it to work. Thank you in advance for your time and any assistance you may provide. 


Multiple types in a map container C++

22 April 2013 - 12:40 PM

Hi everyone, 

 

not sure if this is the proper thread to post this question to, if not I apologize and will gladly post it where it needs to be. I am having an issue with understanding how to use multiple data types in one map container. For example my code looks like this:

 

 

struct A
{
    string mName;
    int    mNumber;
};
 
struct B
{
    string mName;
    float  mFloater;
    bool   mFlag;
};
 
 
class C
{
     C();
     ~C();
 
//basically I want this map to hold a list by reference int for the entire collection of both objects from A and B.
map<int, A/B> myMultiMap;
 
}
 
so that in main..
 
int main()
{
     C* myC;
     A* myA;
     B* myB;
 
    myC->myMultiMap[0] = myA;
    myC->myMultiMap[1] = myB;
}
 
is there any easy way to do this. I haven't had much luck with getting the boost libraries to load correctly, I've only been at this about a year, and don't completely know how to do some of the things. I appreciate any help that is offered, even ifs its just a link or something. Thanks for reading. 
 
Regards,
Soundstone

PARTNERS