This is an example of a ground sprite with a height line. The ground that is shown on the screen is represented by the green and the "height line" is the black segments. The black segments are not actually part of the sprite, but they represent where the "hight lines" will be.
With that out of the way, here is the math you will need:
Y=m*X+b
You will have to determine the "m" value which is the slope of the line. The slope of a line is:
m=(Y1-Y2)/(X1-X2)
where the X1,Y1 is the first point on the line and X2,Y2 is the second. Next you will have to determine the "b" value which is known as the "Y-intercept".
b=Y-m*X
Use either X1,Y1 or X2,Y2 to plug into the formula.
Repeat this for each of the segments of the "hight line" and put all that info into a class (hope you understand classes).
class SEGMENT{
public:
int X,Y;
float m,b;
};
class GROUND{
public:
char *FileName;
int SpriteNumber;
int NumberOfSegments;//use up to 6 segments
SEGMENT Segs[7];
}Ground[]={"GroundSprite01.jpg",1,6
,0,16,0,0//these zeros will be filled in later
,33,16,0,0//in the code using our formulas
,64,3,0,0//I discussed earlier
,88,3,0,0
,190,19,0,0
,237,4,0,0//by the way the last "red" line is not needed.
,255,4,0,0//it's just for the calculations
"GroundSprite02.jpg",2,3
,..... blah blah blah
repeat the above for however many ground sprites you have.
};
int NumberOfGroundSprites=(the amount you make)
That is a quick and efficient way to make level sprites with height lines. Simply add more and more until you have all the ground sprites you want. These are repeatable and easily placed if you have all the sprites the same size. You can have gaps in a sprite to represent a pit. Just make a line going (almost) straight down and then accross then back up to the other side.
Now for the rest:
Make a loop at the beginning of you game to do the slope info:
for (int i=0;i<NumberOfGroundSprites;i++){
Ground[i].m=(Ground[i].Y-Ground[i+1].Y)/(Ground[i].X-Ground[i+1].X);
Ground[i].b=Ground[i].Y-Ground[i].m*Ground[i].X;
}
You know how to move the ground under the player, so as you do, you will need to have something to hold the info for where the "blocks" are on the screen-- I would use a class:
class ASSIGNEDBLOCKS{
public:
int GroundNumber;//this is a reference to the GROUND class we made earlier
int X,Y;//the upper left corner of the sprite
}Blocks[]={0,0,700
,1,256,700
..... and so on....
};
This is an efficient way to place them on the level, but for a large game this may not work as well as you think. You may want to make a level and save it to disk and then start over with a fresh code for the next one.... Whatever suits you.
As you character moves, change the location of each of the sprites to be moving in the other direction.
For the collision itself (yea... a lot to prepare for this):
Determine which sprite you are over. Here is where it gets kinda weird. The "Blocks" will not move. The values you put in for them are static and you will have coordinates for you character that will move even though he doesn't. Each frame you will check the character's X value and doing a little math determine which block he is over and where on the block he is.
int TheBlockHeIsOver=Player.X/256;//I chose 256 cause that's the size of my block.
int WhereOnTheBlock=Player.X%256;//this will give the remainder of the block value (look up modulus).
Once you know which block he is over, you can check the segments to see if he is beyond each of the segments.
int SN=-1;
for (int s=0;s<Ground[Blocks[TheBlockHeIsOver].Ground].NumberOfSegments;s++){
if (Ground[Blocks[TheBlockHeIsOver].Ground].Segs[s].X<Player.X) SN=s;
}
if (SN>-1){//found a segment
int SpotY=(Ground[Blocks[TheBlockHeIsOver].Ground].Segs[SN].X+Blocks[TheBlockHeIsOver].X)*Ground[Blocks[TheBlockHeIsOver].Ground].Segs[SN].m+Ground[Blocks[TheBlockHeIsOver].Ground].Segs[SN].b+Blocks[TheBlockHeIsOver].Y;
//this calc determins what the Y-value of the ground below the character
if (Player.Y>SpotY) Player.Y=SpotY;
if (Player.Y<SpotY){//do your gravity here
}
}
I hope this gets you started.....
The fastest code is the code never written.