Skip to main content
gamedev.net
🔒 Locked

hit,hit,hit!

Started by Filip 3 replies 1.4k views
Original Post
Filip
Filip
i am writing a game(trying,that is!)!But i have a colission problem.I am writing mario stile game and need help.I am interested in response.How do you actually do coll?boxes or something else?Also RESPONSE how do i make my guy not to fall through things, when you catch colission, how do you respond?i need about same tipe of colission as in mario.do you use vectors or something?also how do you make difference between collidable and passable objects?How do you model gravity?EXAMPLE:my guy walks on a plain i suppose colission stops him from falling through but he doesnt get stuck, also gravity is here.Guy walks, jumps and then hits a brick and goes down(how?).I am sorry to bother you but some easy explanations(understandable) and c++ code could help.THANKS!eternally grateful.PS:i know this is a lot nut if u can help me anyhow,its better than nothing!Most tuts are really fuzzy and theory heavy, but reality dry!
Mathematix
Mathematix
Please tell me you''re joking.
JTippetts
JTippetts
Yeah, wow.... ummmm.... hmmmmm....

Well, it sounds like you need to brush up on some of the basics. But anyway...

I''ve never done a Mario-like game, but just offhand I can see some ways of doing it. Firstly, your world is probably going to be comprised of a 2-dimensional tile-map which scrolls side to side. (I''m assuming Super Mario 1, etc... If you want to build Super Mario Sunshine, that''s a whole other wad o'' snot, brother.)

Bear in mind that nothing I am about to say is gospel, and nothing has been pondered for more than a couple of minutes on my part, so it may be as holey as Swiss cheese, and twice as rank. With that disclaimer in mind...

So, you''ve got a tile map, where each element in the map represents one "block" on the screen. This map is (conceptually, at least) one screen high, and some arbitrary length.

"Mario" is going to be an entity in this world consisting of a sprite, a location, and some various other arbitrary data, including a bounding box which encloses his entire being, and possibly a "head" and "foot" hotspot demarcating his head and feet (coincidence? I think not).

Intersections can be checked on the basis of bounding boxes; this style of game simplifies it, in that you only need to check the intersection of 2D rectangles rather than 3D boxes. (A trivial task I''ll not describe here. Look it up.) Each "block" has it''s own rectangle outlining it''s bounds. (This rectangle can easily and quickly be generated based on the block''s indices in the array, so storing this rectangle seems to me a waste of memory.)

Collisions can also be checked between one of the "hot-spots" and a block''s bounding rectangle. This provides a trivial means for checking to see if Mario is trying to fall through a block or jump through a ceiling.

As far as gravity goes, this is pretty simple. Every update cycle, apply a constant downward acceleration to Mario''s movement vector, then check for intersection of his bounding box''s lower edge (or his "foot" hot-spot) with any lower blocks when applying the movement vector to his location, and halt his downward movement if such a collision occurs. Similarly, when jumping, an "up" acceleration vector is applied to his movement vector, and similar checks are done for collision with overhead blocks (using the upper edge of his bounding box, a "head" hotpoint, or some other means.)

By using "hot-points", you reduce the complexity of collision detection to point-vs-box ("foot"/"head" hotpoint versus "block" box) at the cost of precision (ie, some "collisions" might possibly occur in situations that do not appear reasonable.) As old-school Mario never claimed precision as a feature, this might be a safe sacrifice to make.

Keeping Mario from falling through a block is easy. You have a vector which indicates what direction he is moving in a given update. This vector is a combination of forward/backward movement generated by forward/backward keys, and up/down movement generated by gravity/jump accelerations. This vector is added to Mario''s current location, and the resulting "hot-spot" locations are checked for any collisions. Collisions with blocks indicate that Mario can not move there, so do not update Mario''s position. Also , if a head collision is indicated to halt upward movement, then pending upward acceleration is cancelled, allowing gravity to take over. (It seemeth to me that segregating forward/backward and up/down velocity vector data might be in the cards, to allow movement up/down to continue even if a forward/backward movement is blocked. Think on that. )

If collision data indicates the move is valid, this might then be a good time to update Mario''s position, then check for enemy collisions. Bounding-box testing would possibly be best here, perhaps composited with a more detailed pixel-by-pixel comparison if the initial bounding-box test indicates a possible collision. Again, this is a question of how precise you wish to be, so you may not find it necessary and just stick with simple BB collision.

When Mario is "standing still", he is actually constantly trying to move downward, but "foot hot-spot" collision with the block he is standing on prevents this.

Jumping seems to me the trickiest part, but should be relatively easy. When a jump is begun, the upward acceleration begins at some value. Every update thereafter, after the acceleration is applied, this factor is decreased gradually toward 0, so that eventually upward movement halts and gravity reasserts itself. (I may be misleading you somewhat with the use of the term acceleration. What you may elect to use might not be acceleration in the "real" sense, but rather simple translation by constant values; whereas acceleration implies an ever-increasing/decreasing velocity. These are design issues you will have to work out for yourself through experimentation.)

I am certain I have overlooked a lot of things, misdirected you on other things, and in general confused the issue beyond any sane man''s ability to comprehend. That''s what you get for asking others to do your work for you. So there.


Josh
vertexnormal AT linuxmail DOT org


Check out Golem at:
My cheapass website
nonnus29
nonnus29
Thats a really good, detailed answer. The only thing I will add is to clarify when VertexNormal talks about movement vector he means you dx and dy variables, if your using those.

Ah what the heck, here''s a code sample that I use:

void updateposition_b() {
int tempx,tempy;
tempx=posx+dx;
tempy=posy+dy;
if(dy==0 && !map.collide(posx,posy+4,w,h)) dy=2;
if(dy<0) {
posy=tempy;
dy+=2;
}

else if(dy>0 && !map.collide(posx,tempy,w,h)) {
dy+=2;
if(dy>16) dy=16;
posy=tempy;
tempy+=dy;
}
else {
//System.out.println("hit "+posx+" "+posy);
dy=-dy/2;
posy=((posy+dy+32)/32)*32-(2+w-32); //this puts your position at even tile so you don''t fall thru

}

if(dx<0 && !map.collide(tempx,tempy-4,w,h)) {
posx=tempx;
if(dy==0) dx=dx+2;
}
else if(dx>0 && !map.collide(tempx,tempy-4,w,h)) {
posx=tempx;
if(dy==0) dx=dx-2;
}
else {
if(dy!=0) dx=-dx/4;
}

}



The hard coded values will come out when I finalize the bounding rectangle part. map.collide() checks the map for collisions by passing it the objects bounding rectangle.
Filip
Filip
THanks!To you all!Mathematix, i was not joking!!!I already had a working game(SDL+ no colission), so i see i should code some sample vector class?!nonnus29 and VertexNormal, you were very helpful, with also providing some easy code and directions!It is very clear to me what i should do, this clarifies the issue!
So, do you think i should check for coll in both dimensions?

Topic Locked

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

Sign in to reply to this topic.