is the size of my tile messing up the collision?

Started by
8 comments, last by Khatharr 11 years, 1 month ago

hi all, so i am trying to do a tile map and get my character to collide with them and jump from one to another etc, my character is 128,128px but my tiles that i found online (free) are only 32x32px , will this cause problems when doing collision?

the collision theory i am following is 2 rectangles one for character(r1) and one for each tile(r2)

this is example for if its touching top of the other

if (r1.Bottom >= r2.Top - 1 &&

r1.Bottom <= r2.Top + (r2.Height / 2) &&
r1.Right >= r2.Left &&
r1.Left <= r2.Right );
now am i right in thinking surely if my rectangle for character is 128,128 and the rectangle for each tile is only 32,32 this collision isnt going to work (which it doesnt atm) ? how do you normally work this out? my character looks good on screen 1600x900px at 128x128... so should i make tiles bigger or shouldnt it matter?
Advertisement

With a little work, anything can be done.

I think your problem lies here:


1.Bottom <= r2.Top + (r2.Height / 2)

This code looks like it's checking to see if your character is within 16 pixels above your brick, which I'm guessing you don't want to happen.

Can you explain a little more about what part of collision detection isn't working? What issues are you having? Have you accounted for the fact that if the character is on top of more than one brick that you will receive multiple accounts of collision detection? Look over other parts of your code too, because the problem may be sitting in not only the detection code, but the response to detection.

Stay gold, Pony Boy.

yes, basically when i have the collision for top,bottom,left and right i jump onto a tile and i end up half way up screen lol i tried using fixed numbers to work out whats happening but i must be missing something , also when it shoots half way up screen it will slowly fall down very slowly, i will relook over the coding and if im struggling by tonight i will post what i have got up and see whats wrong :)

thanks

No matter the size, if two quads are overlapping, they're overlapping....

What I've always done for BB checks that don't rotate is first check if the quads overlap, then check where they overlap. I split my quads up into two points , the upper left and the lower right corners.

obj1.x1

obj1.y1

obj1.x2

obj1.y2

and do the same for object 2 (the second quad).

then to check if the two quads overlapp

 
if (obj1.x1 <= obj2.x2 && obj1.x2 >= obj2.x1)
{
    if (obj1.y1 <= obj2.y2 && obj1.y2 >= obj2.y1)
    {
        // Quads overlapped
    }
}
 

The overlap assumes that if they overlap the object 2's left side will always be to the right of object 1's left side and so on for the rest of the sides. Then to check which side collided you would use the same concepts, just that it's possible for shapes to collided on multiple sides even all sides with this check, but it's fast and simple, just needs a little babbying which can be done with a sweep test to find the exact point when they collided so it doesnt overlapp so much that it'll collide with multiple sides.

if object 2 hit the top of object 1, you can assume the top of object 2 should be above object 1, else it probably hit the bottom of it.

if (obj2.y1 < obj2.y1)
   // object 2 hiot the top of object 1

I've been getting rusty on my writting, so if any of that doesnt make sense, just ask and ill try to specify.

[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.

ok i admit that sounds confusing but could be because i been staring at the computer for last few hours , i think i can see where my problem is.... i am using an 2d array to create my map not a file(maybe my first mistake?)

here is an example of the map i using atm to test collision

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,2,2,1,2,2,2,2,2,2},
{0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2},
{0,0,0,0,1,0,0,0,1,0,0,2,2,2,2,2,2,2,2,2},
}, 90);
now in the tutorial i used they used 64 as that final value for the size of width and height but then my camera has the map zoomed out far but when i changed it to 90 it made the tiles closer to the screen, but thew now when it comes to the collision the values are all weird, so my tiles width and height is 90x90 but my character is 128x128... i need to try work out the if statements for the collision.... so frustrating , guess this is the problem following an tutorial and then changing things it forces you to learn and understand each line of code to find the problems guess thats supposed to be part of the fun lol

does anyone have any tutorials on collision with tiles? my player touching left of a tile works fine here is that code

if (character.playerPosition.X + 64 >= tile.Rectangle.X &&
character.rectangle.Y >= tile.Rectangle.Y &&
character.rectangle.Left <= tile.Rectangle.Left)
{
character.playerPosition.X = tile.Rectangle.Left - 64;
}
and when i switch a few things round to do the right of the tiles it shoots me to the very right of all my tiles
if (character.playerPosition.X <= tile.Rectangle.X + tile.Rectangle.Width &&
character.rectangle.Y >= tile.Rectangle.Y &&
character.rectangle.Left <= tile.Rectangle.Left)
{
character.playerPosition.X = tile.Rectangle.X + tile.Rectangle.Width;
}
any chance anyone can help me work this out?im happy with the on top and underneath but the right is causing me problems

ok forget all above here is my new problem....

i am only dealing with single tiles on floor level so i know i maybe need stricter if statments once i jump up more levels but i can jump on top of a tile and both the left and right collision work for the sides of tile

coding:

//topoff
if (character.playerPosition.Y <= tile.Rectangle.Top &&
character.playerPosition.X + (character.rectangle.Width / 2) >= tile.Rectangle.X + (tile.Rectangle.Width/5) &&
character.playerPosition.X + (character.rectangle.Width / 2) <= tile.Rectangle.Right+70)
{
character.playerPosition.Y = tile.Rectangle.Y - 64;
character.velocity.Y = 0f;
character.hasJumped = false;
}
//leave top of tile
else
if (character.playerPosition.Y <= tile.Rectangle.Top &&
character.playerPosition.X + (character.rectangle.Width / 2) <= tile.Rectangle.X)
character.hasJumped = true;
else
if (character.playerPosition.Y <= tile.Rectangle.Top &&
character.playerPosition.X + (character.rectangle.Width / 2) >= tile.Rectangle.Right)
character.hasJumped = true;
//touch left
if (character.playerPosition.X + 64 >= tile.Rectangle.X &&
character.rectangle.Y >= tile.Rectangle.Y &&
character.rectangle.Left <= tile.Rectangle.Left)
{
character.playerPosition.X = tile.Rectangle.Left - 64;
}
//touch right
if (character.playerPosition.X >= tile.Rectangle.Left &&
character.playerPosition.X <= tile.Rectangle.Right+80&&
character.rectangle.Y >= tile.Rectangle.Y
)
{
character.playerPosition.X = tile.Rectangle.Right+80;
}
but now when my character is on top of the tile it wont jump, i think i does attempt to jump but because of the on top if statement it always throws it back to the same position?
i tried saying if character.rectangle.bottom == tile.rectangle.top but i noticed when debugging that they never are the same? which i think maybe my problem?
Im going to be honest here and say youre probably bitting off more than you can chew. Im also thinking english isnt your first language. There is a lot of inconsistancies with youre explanatikns and your code. I cant help but notice all your bounds checks use different sizes for the tiles size and how you are offseting your player position.

I bet your main issue lies with the fact your using a camera to alter your view and its probably also altering the sizes of objects making your calculatikn come out wrong. You use a lot of magic numbers to describe your sizes. You should think of using a define/const/member variable instead for things like tile_width that way it will stay the same istead of jumping around between 64 and 80 like youre doing now.

Not sure of your experience/background but you might beneft from going back to the basics a little.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
Double post my phone wont post the edit for some reason.

I assume your "top off" comment block is attempting to check if the block intersects a tile. But you should really break that if state apart and think what its really checking for.

Is your player position the centr r of the player? You constantly treat the y coord as if its the top of the player but treat the x coord as if its the center. Ill try to post the simple picture that made bb checks easier for me to conceptualize when I get home.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
You keep implementing the same pattern again and again in your code. That's a signal that you need to abstract something. In this case you should abstract collision testing by writing a function for it.

Looks like you're just using boolean collision here. This is what I usually use for rect vs rect:
bool RectCollision(const Rect &A, const Rect &B) {
  if(A.left > B.right) {return false;}
  if(A.right < B.left) {return false;}
  if(A.top > B.bottom) {return false;}
  if(A.bottom < B.top) {return false;}
  return true;
}
Adjust as needed depending on your rect format.

As freeworld mentioned, this kind of thing should not be going on:

character.playerPosition.X + 64 >= tile.Rectangle.X

Your player's rect should know its own width and position and your functions should move rects in a way that maintains their information correctly. If your player has a rect then why does it also have a position? The rect includes the position as part of its data. If you want to simplify the player interface then store the rect and have inline functions for getting the x/y position from the rect. That way you don't risk having data stored in two locations which may or may not agree with one another.

Build small and simple parts that do their jobs well, then use those parts to build more complex things.
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

This topic is closed to new replies.

Advertisement