Collision Help Please...
Moderator: BigEvilCorporation
-
- Interested
- Posts: 10
- Joined: Wed Oct 26, 2016 1:27 am
Collision Help Please...
Hi, I'm pretty new when it comes to programming the collision's for the Sega genesis, all I want to do is make a platformer, with a few specific sprites/ platform tiles, that when you overlap them or collide with x will happen, like an enemy killing you or walking in front of a door sprite and press say B to open doors, etc. can anyone help me understand it better? perhaps code snippet examples. and I already seen kaneda's, It just seem's I can't get it to work in sgdk, there truly needs to be more tutorial's/better ones, since I haven't got 68k asm to compile yet. well I'd rather use C anyways.
Re: Collision Help Please...
First of all collision means detecting if two sprites/objects/entities are overlapping, since you question is that general perhaps you are adding other issues.
Usually in 16bits you have two types of collisions:
A) one sprite with another sprite
B) one sprite with the ground (tiles)
To solve A you just need to check if two rectangles (bounding boxes) are intersecting. Search for intersecting rectangles on internet for code, it's just 4 compares.
To work out B you set a few strategic points surrounding the sprite and check if they are inside a solid or hollow tile. An algorithm for this last one depends very much on how you structured your levels, it could be as easy as:
bool solid = level[ player.x / 8 ][ player.y / 8 ];
About collision response:
To interact with you level, open doors and things like this, usually with your tiles indexes, or even groups of tiles indexes, are accompanied with collision information so when you collide with a tile you known what to do next. So you can extend the information described previously as Solid and Hollow, into Water, Stairs, Button, Door, etcetera.
On the other hand sprites are classified into types, like player, power up, foe, shoot, etcetera so you can write a common way of working with them. A matrix, managing every possible intersection could do the work.
Usually in 16bits you have two types of collisions:
A) one sprite with another sprite
B) one sprite with the ground (tiles)
To solve A you just need to check if two rectangles (bounding boxes) are intersecting. Search for intersecting rectangles on internet for code, it's just 4 compares.
To work out B you set a few strategic points surrounding the sprite and check if they are inside a solid or hollow tile. An algorithm for this last one depends very much on how you structured your levels, it could be as easy as:
bool solid = level[ player.x / 8 ][ player.y / 8 ];
About collision response:
To interact with you level, open doors and things like this, usually with your tiles indexes, or even groups of tiles indexes, are accompanied with collision information so when you collide with a tile you known what to do next. So you can extend the information described previously as Solid and Hollow, into Water, Stairs, Button, Door, etcetera.
On the other hand sprites are classified into types, like player, power up, foe, shoot, etcetera so you can write a common way of working with them. A matrix, managing every possible intersection could do the work.
HELP. Spanish TVs are brain washing people to be hostile to me.
-
- Interested
- Posts: 10
- Joined: Wed Oct 26, 2016 1:27 am
Re: Collision Help Please...
Miquel wrote:First of all collision means detecting if two sprites/objects/entities are overlapping, since you question is that general perhaps you are adding other issues.
Usually in 16bits you have two types of collisions:
A) one sprite with another sprite
B) one sprite with the ground (tiles)
To solve A you just need to check if two rectangles (bounding boxes) are intersecting. Search for intersecting rectangles on internet for code, it's just 4 compares.
so the collision's of other sprites I can do
Code: Select all
// Returns true if two rectangles overlap
static void doOverlap(Sprite* rect_a,Sprite* rect_b)
{
// If one rectangle is on left side of other
if (rect_a->x > rect_b->x || rect_b->x > rect_a->x)
Overlap = false;
// If one rectangle is above other
if (rect_a->y < rect_b->y || rect_b->y < rect_a->y)
Overlap = false;
else
Overlap = true;
}
Code: Select all
doOverlap(sprites[0],sprites[1]);
doOverlap(sprites[0],sprites[2]);
it doesn't seem to work for me though.
btw I'm using it with the sonic example.
Re: Collision Help Please...
Here is the usual algorithm for detecting if 2 rectangles overlap:
Your code is not taking the size of the rectangles into consideration, so the function will only set "Overlap" to true if the 2 sprites are perfectly aligned.
Actually, since your first if statement is completely disregarded, it'll set "Overlap" to true whenever they are aligned on the x axis. I'm puzzled by this and why a global variable is being used instead of a return value.
Now there is another problem. Sprite has no width or height. Looking in SGDK source the individual frames store a width and height in pixels. So this may work instead of rect_a->width and rect_a->height:
rect_a->frame[0]->w
rect_a->frame[0]->h
Then plugging it in
or:
Consider creating an object struct that contains the sprite, speed values and a collision rectangle which can be reused for players, objects and enemies. Collision in games gets much more complicated, especially platformers, and often you may want an object's "hit box" to be smaller than the actual sprite.
Code: Select all
if (RectA.X1 < RectB.X2 && RectA.X2 > RectB.X1 &&
RectA.Y1 < RectB.Y2 && RectA.Y2 > RectB.Y1)
Actually, since your first if statement is completely disregarded, it'll set "Overlap" to true whenever they are aligned on the x axis. I'm puzzled by this and why a global variable is being used instead of a return value.
Code: Select all
// Returns true if two rectangles overlap
static u8 doOverlap(Sprite* rect_a,Sprite* rect_b)
{
return rect_a->x < rect_b->x + rect_b->width &&
rect_a->x + rect_a->width > rect_b->x &&
rect_a->y < rect_b->y + rect_b->height &&
rect_a->y + rect_a->height > rect_b->y;
}
rect_a->frame[0]->w
rect_a->frame[0]->h
Then plugging it in
Code: Select all
if(doOverlap(sprite[0], sprite[1]) {
// Collided
}
if(doOverlap(sprite[0], sprite[2]) {
// Collided
}
Code: Select all
#define NUM_SPRITES 3
for(u16 i = 1; i < NUM_SPRITES; i++) {
if(doOverlap(sprite[0], sprite[i])) {
// Collided
}
}
Re: Collision Help Please...
This is how I do it:AnthonyPython wrote: and just check if Overlap is true right?
it doesn't seem to work for me though.
btw I'm using it with the sonic example.
Code: Select all
bool bColision = false;
if( ! ( (pActor->boundingBox.left.integer > pActor2Test->boundingBox.right.integer) ||
(pActor->boundingBox.right.integer < pActor2Test->boundingBox.left.integer) ||
(pActor->boundingBox.top.integer > pActor2Test->boundingBox.bottom.integer) ||
(pActor->boundingBox.bottom.integer < pActor2Test->boundingBox.top.integer) ) )
{
bColision = true;
}
pActor is a pointer to a Sprite struct currently being actualized.
pActor2Test is the other sprite currently being compared with.
boundingBox is a struct with 4 values (fixed points): left, right, top, bottom.
a fixed point has a integer and a decimal, last one not used in this code.
Last edited by Miquel on Sun Nov 06, 2016 5:00 am, edited 1 time in total.
HELP. Spanish TVs are brain washing people to be hostile to me.
-
- Interested
- Posts: 10
- Joined: Wed Oct 26, 2016 1:27 am
Re: Collision Help Please...
Thanks a bunch guys, got sprite collision working, now I just need Tile collision.
I'll get back with you guys when I get some real tiles made and put in the game, and not use that bitmap of a sonic level.
Glad to finally make some progress, I was pulling my hair out over this for days.
I'll be sure to add this valuable info into the new MegaDrive Wiki I made on my website, since it seems there was two others, but I'll try my very best to keep this one up, I doubt there will be many spammers on this one guys. Since you have to have an account and to confirm your email to edit/make pages.
http://mdwiki.virtualpython.com
I'll get back with you guys when I get some real tiles made and put in the game, and not use that bitmap of a sonic level.
Glad to finally make some progress, I was pulling my hair out over this for days.
I'll be sure to add this valuable info into the new MegaDrive Wiki I made on my website, since it seems there was two others, but I'll try my very best to keep this one up, I doubt there will be many spammers on this one guys. Since you have to have an account and to confirm your email to edit/make pages.
http://mdwiki.virtualpython.com
-
- Interested
- Posts: 10
- Joined: Wed Oct 26, 2016 1:27 am
Re: Collision Help Please...
uh? I don't quite understand that piece of code snippet, I haven't had anything a bool being set to something other than false or true work right as of it.Miquel wrote: To work out B you set a few strategic points surrounding the sprite and check if they are inside a solid or hollow tile. An algorithm for this last one depends very much on how you structured your levels, it could be as easy as:
bool solid = level[ player.x / 8 ][ player.y / 8 ];
About collision response:
To interact with you level, open doors and things like this, usually with your tiles indexes, or even groups of tiles indexes, are accompanied with collision information so when you collide with a tile you known what to do next. So you can extend the information described previously as Solid and Hollow, into Water, Stairs, Button, Door, etcetera.
On the other hand sprites are classified into types, like player, power up, foe, shoot, etcetera so you can write a common way of working with them. A matrix, managing every possible intersection could do the work.
and exactly how would one retrieve this tile index info after you collide/ overlap with it/ extra collision info? I was looking around the sgdk source code, but it's getting pretty late right now, and I'm pretty tired from being up all day. so I'm going to go on and get some rest talk later. thanks for all the help so far guys, I appreciate you all helping a noob when it comes to doing this sort of stuff.
Re: Collision Help Please...
In a few hours I'm going to fully answering you, now I'm going to sleep, but meanwhile if you can answer those it will help:AnthonyPython wrote: uh? I don't quite understand that piece of code snippet, I haven't had anything a bool being set to something other than false or true work right as of it.
and exactly how would one retrieve this tile index info after you collide/ overlap with it/ extra collision info? I was looking around the sgdk source code, but it's getting pretty late right now, and I'm pretty tired from being up all day. so I'm going to go on and get some rest talk later. thanks for all the help so far guys, I appreciate you all helping a noob when it comes to doing this sort of stuff.
¿What kind of platformer are you designing?
¿Do you plan to do a level editor?
¿Have you thought a structure for you levels?
¿What kind of information do you need to perform like you designed it?
HELP. Spanish TVs are brain washing people to be hostile to me.
-
- Interested
- Posts: 10
- Joined: Wed Oct 26, 2016 1:27 am
Re: Collision Help Please...
1.(for theme it is a 1960's looking facilities , failed human experiments of an unknown cell type), it is a mixture of shooting, and puzzle's(sort of like megaman 7), with two character's you play as at different points in the game(with switching between two different realities), one character at a time.Miquel wrote:
In a few hours I'm going to fully answering you, now I'm going to sleep, but meanwhile if you can answer those it will help:
¿What kind of platformer are you designing?
¿Do you plan to do a level editor?
¿Have you thought a structure for you levels?
¿What kind of information do you need to perform like you designed it?
2. yes, I do, I use the Game Boy Map editor/ tile designer at the moment, if you have something else better to recommend say so.
3.Not quite yet, working on it
4. Enemies, doors, ladder's, lever's, button's(wall or floor), some pallet switching for the different realities/different sprite for the enemies, projectiles, health of course, weapon changes upon player absorbs the weapon(firstplayer) The second character will be able to pull in enemies/projectiles/powerups with a sort of whip like device(invisible multiple hands), but can't be seen by normal people(only herself can see them, and the player playing)
That's about it I think, I don't think I'll be using slops at the time.
oh btw I'm prototyping in unity at the time(for pc, linux, mac, and ps vita), but my group of friends ultimate goal is a 16bit-retro game, that can play on
the sega genesis/megadrive, we are all passionate with older games. (me-programming mostly but I pitch in to help with the overall desgin/gameplay, my friend the concept helper/gameplay designer , My musician friend he has been loving deflemask, My other friend is a audio mixer, mostly but can help create music as well, but is good at programming too) we don't have a pixel artist really, as I can draw on paper well, but anything computer wise I suck. We all are going to see this through though.
We all appreciate you, and anyone helping us in our endeavors greatly.
Re: Collision Help Please...
In the most basic scheme you only need to know if this tile is solid or not (bool).AnthonyPython wrote: uh? I don't quite understand that piece of code snippet, I haven't had anything a bool being set to something other than false or true work right as of it.
Code: Select all
bool g_Level[ 128 ][ 128 ];
void MoveCharacterFunction( Sprite* pSprite, int speedX, int speedY )
{
while( speedX || speedY )
{
if( speedX > speedY )
{
const int sX = speedX % 8;
if( g_Level[ (pSprite->x + sX) / 8 ][ pSprite->y / 8 ] )
{
return;
}
speedX -= sX;
pSprite->x += sX;
}
else
{
const int sY = speedY % 8;
if( g_Level[ pSprite->x / 8 ][ (pSprite->y + sY) / 8 ] )
{
return;
}
speedY -= sY;
pSprite->y += sY;
}
}
}
Every time you need more info just expand you data structures:AnthonyPython wrote: and exactly how would one retrieve this tile index info after you collide/ overlap with it/ extra collision info? I was looking around the sgdk source code, but it's getting pretty late right now, and I'm pretty tired from being up all day. so I'm going to go on and get some rest talk later. thanks for all the help so far guys, I appreciate you all helping a noob when it comes to doing this sort of stuff.
Code: Select all
typedef struct _Cell
{
bool bSolid;
uint /*u16 in MD*/ tileIndex;
} Cell;
Cell g_Level[ 128 ][ 128 ];
void MoveCharacterFunction( Sprite* pSprite, int speedX, int speedY )
{
while( speedX || speedY )
{
if( speedX > speedY )
{
const int sX = speedX % 8;
if( g_Level[ (pSprite->x + sX) / 8 ][ pSprite->y / 8 ].bSolid )
{
return;
}
speedX -= sX;
pSprite->x += sX;
}
else
{
const int sY = speedY % 8;
if( g_Level[ pSprite->x / 8 ][ (pSprite->y + sY) / 8 ].bSolid )
{
return;
}
speedY -= sY;
pSprite->y += sY;
}
}
}
Code: Select all
typedef enum _Terrain
{
Air,
Water,
Door,
Button
} Terrain;
typedef struct _Cell
{
Terrain terrain[ 2 ][ 2 ];
uint tileIndex[ 2 ][ 2 ];
} Cell;
But only if this meets your requirements, of course. Once you realize you are out of memory, talk to me again.
Edit: I forgot, in MD tiles indexes are like:
Code: Select all
typedef union _PlaneCell
{
struct
{
u16 priority : 1; // -> z order in relation to other planes and sprites
u16 palete : 2;
u16 flipHoritzontal : 1;
u16 flipVertical : 1;
u16 title : 11; // -> 2048 max titles
};
u16 fullValue;
} PlaneCell;
Code: Select all
typedef struct _Cell
{
Terrain terrain[ 2 ][ 2 ];
PlaneCell planeCell[ 2 ][ 2 ];
} Cell;
HELP. Spanish TVs are brain washing people to be hostile to me.
Re: Collision Help Please...
Continuing,
in 16bits I know 2 adequate ways to represent levels, let's call them the Sonic way and the Nintendo way. Both have the 2x2 tiles structure as their base.
I don't know so much about the Sonic way, since I never used it, but it works by grouping every time more tiles in every time bigger map of tiles. For example first level is 2x2 tiles, second level is 16x16 tiles (but references to the previous structure, not tiles themselves), third level is 128x128 tiles (again it points to second level), and then the final map level using previous structure. It works well for very large, repetitive (Sonic is fast enough so you don't notice) and unmodifiable levels. Most people in this forum like Sonic so they have learn very well this way.
On the other hand, in the Nintendo way we have an array of 2x2 tile structures and a map/matrix in RAM with indexes to those structures. Is that simple. The complex part is how to build the map on loading time. It works well for modifiable short levels (with 32KB of RAM using this precise method you can do 2048x2048 pixel levels).
¿There are other ways of doing it? yes ¿Are they as good as those two? probably not.
About the level editor: my recommendation is to build your own, with the characteristics you need, and spend about 50% of development time in it. And above all don't use tile based editors, they are fine to build you first level, but when you realize that there are 499 to complete your game, you are going to go crazy. And then some one changed some tiles, or even the size (in pixels) of some object, then you have to modify ALL your levels, it's just the fast first results, but never ending way.
in 16bits I know 2 adequate ways to represent levels, let's call them the Sonic way and the Nintendo way. Both have the 2x2 tiles structure as their base.
I don't know so much about the Sonic way, since I never used it, but it works by grouping every time more tiles in every time bigger map of tiles. For example first level is 2x2 tiles, second level is 16x16 tiles (but references to the previous structure, not tiles themselves), third level is 128x128 tiles (again it points to second level), and then the final map level using previous structure. It works well for very large, repetitive (Sonic is fast enough so you don't notice) and unmodifiable levels. Most people in this forum like Sonic so they have learn very well this way.
On the other hand, in the Nintendo way we have an array of 2x2 tile structures and a map/matrix in RAM with indexes to those structures. Is that simple. The complex part is how to build the map on loading time. It works well for modifiable short levels (with 32KB of RAM using this precise method you can do 2048x2048 pixel levels).
¿There are other ways of doing it? yes ¿Are they as good as those two? probably not.
About those buttons and puzzle's: to my understanding the big question is if you want to modify your levels at action time or not. If you want to, you can't use static maps. Pallets are sprites, so don't count.AnthonyPython wrote: 1.(for theme it is a 1960's looking facilities , failed human experiments of an unknown cell type), it is a mixture of shooting, and puzzle's(sort of like megaman 7), with two character's you play as at different points in the game(with switching between two different realities), one character at a time.
2. yes, I do, I use the Game Boy Map editor/ tile designer at the moment, if you have something else better to recommend say so.
3.Not quite yet, working on it
4. Enemies, doors, ladder's, lever's, button's(wall or floor), some pallet switching for the different realities/different sprite for the enemies, projectiles, health of course, weapon changes upon player absorbs the weapon(firstplayer) The second character will be able to pull in enemies/projectiles/powerups with a sort of whip like device(invisible multiple hands), but can't be seen by normal people(only herself can see them, and the player playing)
About the level editor: my recommendation is to build your own, with the characteristics you need, and spend about 50% of development time in it. And above all don't use tile based editors, they are fine to build you first level, but when you realize that there are 499 to complete your game, you are going to go crazy. And then some one changed some tiles, or even the size (in pixels) of some object, then you have to modify ALL your levels, it's just the fast first results, but never ending way.
HELP. Spanish TVs are brain washing people to be hostile to me.
Re: Collision Help Please...
Finally I left you with an example of what I said, using the "Nintendo way" (By that I mean a way of working with levels developed in 8 and 16 bits mainly in Nintendo devices). It was a competitive test for my level engine I did months ago.
There are two strong points:
- You can modify the level at any given point
- The level input is given at the object level: you say: "build a house here, with that width and height" (instead of editing tile by tile).
Tiles taken from Zelda (SNES).
Music isn't mine.
Is work in progress (awful palette).
There are two strong points:
- You can modify the level at any given point
- The level input is given at the object level: you say: "build a house here, with that width and height" (instead of editing tile by tile).
Tiles taken from Zelda (SNES).
Music isn't mine.
Is work in progress (awful palette).
- Attachments
-
- RoomTest.zip
- (183.99 KiB) Downloaded 280 times
-
- RoomTest.jpg (86.34 KiB) Viewed 9327 times
HELP. Spanish TVs are brain washing people to be hostile to me.
-
- Interested
- Posts: 16
- Joined: Thu Jan 05, 2017 10:14 pm
Re: Collision Help Please...
Here's a good tutorial on basic physics and floor collection detection using 68k assembly on the Genesis:
https://www.youtube.com/watch?v=Kalmryn9_sE
https://www.youtube.com/watch?v=Kalmryn9_sE