2014-12-18 19:11:49

Hi, I'm wondering what the best way to implement collision detection for walls, pits, and other objects is in games when angles are involved. I've tried to do some research online, but haven't really come up with much. I've gotten walking and turning to work, and I know how I can figure out the distance an object is away, as well the angle the object is at, in relation to the player. At this point though, I've just put walls in a 2d array, which makes checking for them break in strange, annoying ways, because sometimes I'll not be facing a wall, but the game still thinks I am. Also. Does anyone know how the arc-tangent function in bgt is supposed to work? I'm really confused as to why it doesn't need two peramitors, unless it just assumes that you give it an angle, then just subtracts that angle and PI over 2 from Pi?
Sorry again if my questions seem incredibly basic smile
Any suggestions would be greatly appreciated!

Prier practice and preparation prevents piss poor performance!

2014-12-18 23:08:27

arc tangent is the inverse of tangent: you give it a tangent, and it returns the angle. You'd use this, say, if you have sets of coordinates, but need an angle. theta=arc_tangent(dy/dx) (but be sure to catch when dx is 0!), for example.

Anyway, it's hard to figure how you have things set up based on the description. Are the walls an array of Rectangles/Boxes/coordinates/something else? What about the bounds of your player?

It sounds like you might want line-line intersection. There are several ways to do that and I have no idea which is most efficient for a given situation. We can probably come up with a solution given a better idea of how you're representing walls and the player.

看過來!
"If you want utopia but reality gives you Lovecraft, you don't give up, you carve your utopia out of the corpses of dead gods."
MaxAngor wrote:
    George... Don't do that.

2014-12-19 01:52:49

Hi, oh, I didn't realize you could do that. Lots of the atan functions I've seen ask for an x and a y so...
As for walls and the player, walls are represented by a 2d array of bools, which is my problem, I think. The player is represented with a class containing an x, a y, and an angle, along with other functions for walking, weapons, stuff like that.

Prier practice and preparation prevents piss poor performance!

2014-12-19 07:12:23

A 2d array of bools should be easy: just figure out what tile you'd be hitting next, and do a check for it.
The problem is one of resolution. Should I assume that each wall/floor tile is roughly the size of the player? Does the player move with double or int precision?

It sounds like you've tried something like
targ_x=this.x+(speed*dt*cosine(this.angle));
targ_y=this.y+(speed*dt*sine(this.angle));
And [targ_x, targ_y] isn't pointing at the tiles you're expecting?

看過來!
"If you want utopia but reality gives you Lovecraft, you don't give up, you carve your utopia out of the corpses of dead gods."
MaxAngor wrote:
    George... Don't do that.

2014-12-19 08:33:45

@Dranelement, the correct way to handle this requires some knowledge of trigonometry for a simple collision detection system or calculus for a more complex system. In any case look for calculations to handle bounded boxes and bounded spheres and then you can correctly calculate if your vector collides with an object at that coordinate. While you can get away with using arrays etc that really isn't the most efficient or correct way to perform collision detection.

Sincerely,
Thomas Ward
USA Games Interactive
http://www.usagamesinteractive.com

2014-12-19 17:22:43 (edited by camlorn 2014-12-19 17:26:37)

You have gone well beyond what BGT can do for you.  Leave for C++, C#, Python, or any other language wherein you can find bindings to either ODE or Box2d.  Learn and use those; Box2d is much easier than ODE, but ODE lets you use the collision stuff separate from the physics and you can just ignore Z.  Save weeks and possibly even months off your development time.  And here's the argument for why, presented as me telling you how this kind of math works.
So long as the only things that are turning are spheres, it's not so bad.  Anything beyond spheres means that you're going to need to do a lot of fiddly coding.  Even turning boxes isn't trivial-you'll almost certainly want to have 2D transformation matrices at that point.  If you stick to turning spheres and non-turning boxes (i.e. your game tiles), you can probably manage it to some extent.  That said, sphere-box is not the most trivial thing ever, especially if you allow the difference in size between the objects to go above a certain point.  In general, if there is a really big object and an extremely small object, a lot of the naive algorithms you're going to want to use go out the window, so it's probably best to avoid that.  Another thing that will cause problems is small, quickly moving objects.
To tell what tile you are hitting next, you need to add the unit vector pointing in the direction of the player's motion times the width of a tile to the player's position and check that.
Assuming east is 0, positive x is east, positive y is north,  and angles are both counterclockwise and in radians, the unit vector pointing in the direction of the player's motion is (cos(theta), sin(theta)).  Multiplying by the tile width gives (tile_width*cos(theta), tile_width*sin(theta)).  Add in the player's position: (player_x+tile_width*cos(theta), player_y+tile_width*sin(theta))
Which, when converted to integers from floats, should be the indices.  If 0, 0 is in the top left and not the bottom left, you will need to subtract from the maximum x and y values or everything will be flipped oddly.  Otherwise, you can slightly redefine your coordinate system and go directly to a set of equations like those.  If you did not understand a word I just said, then go take a class in trigonometry or otherwise learn about it and then revisit this project: you'll really, really need to know trig well to do anything along these lines.  I can't give you the explanation of what sin and cos are without a diagram, and I can't communicate that across this forum.  This is why I am by necessity being quite terse here.  If you do understand what sin and cos are, and if the term unit vector has meaning, we might be able to effectively talk about doing this further, but the diagram wall exists right at that point and, if you've not seen them, it's near impossible to explain what's actually going on here.

My Blog
Twitter: @ajhicks1992

2014-12-19 19:18:01 (edited by matt1211 2014-12-19 19:34:52)

Hi, that's almost what I've been trying to do. My player is moving with double precision though, so I have been having a bit of trouble. Here's my player class, it, might help explain things.
https://www.dropbox.com/s/ftt153iohif5c … r.bgt?dl=1
I have been using the unit vector method to calculate how far the player moves already. I am familiar with trig, I'm just unsure how to apply it to what I'm trying to do here. As I said in my first post. I know I can get the distance and angle between a player and, something like a wall like this.
dX = playerX-targetX dY = playerY-targetY atan(dY/dX)
I'm just, not sure how to apply that knowledge to programming. If that makes any sense.
Thanks very much for all the help and suggestions!

Prier practice and preparation prevents piss poor performance!

2014-12-19 19:48:38

Dranelement, does this mean you already have your guy walking around freely in 2D space?  So just wall collision is the issue?

Since you already have code to calculate the new X Y position of the player after he takes a step (or moves from a game loop, or whatever), this might help you.  Instead of updating the player's actual position, lets assume the new X and Y you calculated are stored in 2 temporary variables, tempX and tempY.

If your walls are stored in a 2D array of bools (I think I read that up above), round tempX and tempY and use those as the 2 coordinates for the 2D wall array to see if it returns true or false.  That should let you know if the position your guy is about to step contains a wall or not.  If it does not contain a wall, set his X and Y equal to the tempX and tempY variables and you're done.

If a wall does exist in that spot, you have 2 options. 
Option 1 is that you can just play some collision sound and do nothing.  Because the player's X and Y were never set to anything, the guy simply stops when he hits a wall.  One side effect of this is that even if the player hits a wall at a shallow angle, they will stop and stick as if the wall is sticky.  There is no automatic sliding along it.

Option 2 is to check to see if the player should be sliding along a shallow angle.  You'll be doing the same wall check as before, but this time you'll test (X, tempY) and then (tempX, Y).  One of those 2 directions should return a wall and the other will be open land.  If (X, tempY) was open land, do not update the player's X coordinate.  Only update their Y coordinate to be equal to tempY.  This is essentially saying that after hitting the wall, any momentum in the individual directions can still continue to act on the player.  The end effect is that a player can glance against a wall and continue moving, even though they technically hit something.  Perhaps a sliding sound effect or something could play during this, just to help them know they've hit something but are not actually stopped.

There are pros and cons to each method, and hopefully some of this was helpful.

- Aprone
Please try out my games and programs:
Aprone's software

2014-12-19 19:52:40

Hi, thanks very much, that was very helpful! I have actually tried to do that, however I now sometimes get the problem where even if I'm not actually facing a wall, I'll still run into the thing. I think your idea of the sliding thing may help, though, so I'll definitely give it a shot.
Thanks!

Prier practice and preparation prevents piss poor performance!

2014-12-19 19:58:47

Dranelement, I don't think I understand.  Why would you only collide with a wall you are facing?

- Aprone
Please try out my games and programs:
Aprone's software

2014-12-19 20:05:54

I,  guess I didn't really think of it that way. I should probably add some way for a player to check what's around them.

Prier practice and preparation prevents piss poor performance!

2014-12-19 20:16:37

big_smile  Sounds good man.
Whenever you feel like posting, I'm sure we're all happy to read about your progress.

- Aprone
Please try out my games and programs:
Aprone's software

2014-12-19 20:30:02

Thanks again for all the help, guys. I'm learning a lot from this, and you have been incredibly helpful.

Prier practice and preparation prevents piss poor performance!

2014-12-20 03:56:56

If no one has told you, velocities can also be represented as unit vectors times a magnitude.  I am almost certain that you know this.  You probably want to use your velocity vector as the place to check, not the vector represented by the player's facing direction.  If velocities can ever be more than one tile per tick, you'll run into teleportation through walls issues; for that reason, you may wish to only keep the unit vector and drop the magnitude.  In either case, it will fix your issues with only colliding with walls in front, at least if the player can move in other directions besides forward.
Atan2 is the function which you are thinking of: given x and y, it gives you an angle.  You will probably never use this for collision detection.  The only time the angles matter much is in displaying to the player.  Collision detection is normally implemented with rotation matrices, another concept that I spent a very long time understanding and which I cannot easily convey here.  So long as you use only the tile map and spheres, you can entirely avoid them.
But I still say use a library.  Doing this well took many people a pretty long time, and I think that if you're trying for this kind of simulation, box2d is probably the best fit.  You'll spend some time learning to understand it, and it's of course possible you don't know other languages, but it will avoid a lot of debugging and math and stuff while also giving you every feature you'd ever need and then some.  This advice is assuming that you just want a game.  I figure any programmer at the point of considering this kind of thing can probably pick up another language pretty quickly, and if it's the kind of game you're going to want to write, it's worth it, at least in my opinion.  I'd suggest at least reading some Box2d tutorials at this point--there are some things about it that might put you off, namely that you talk about forces and not velocities, but it's still worth looking at even if you decide not to.

My Blog
Twitter: @ajhicks1992

2014-12-21 00:57:50 (edited by stewie 2014-12-21 00:59:53)

I would personally use target_x-player_x, since if you do  the reverse you'll get the negative values of what they should be. Also you could rotate both the object and the point about 0 0 by the angle of the tested object, so that the tested object lies with a 0 angle to the x axis, so that if the point is within the target object, you can determine with a simple bounds check.

Deep in the human unconscious is a pervasive need for a logical universe that makes sense. But the real universe is always one step beyond logic.