Surface detection in the 2nd game?

I am working on a 2D platform, and I was wondering what is the best (performance) way to implement surface detection (Collision).

For now, I'm going to create a list of level objects built from a list of strings, and draw fragments along the strings.

alt text http://img375.imageshack.us/img375/1704/lines.png

I think that every object holds the identifier of the surface on which it walks, in order to easily manipulate its position while walking up / down.

Something like that:

//Player/MovableObject class MoveLeft() { this.Position.Y = Helper.GetSurfaceById(this.SurfaceId).GetYWhenXIs(this.Position.X) } 

Thus, the logic that I use to determine "turning / walking on the surface" is a simple point (lower legs of the player) - checking the line (on the surface) (with some approximation of safety - say, 1-2 pixels per line).

Is this approach OK? I am having difficulty finding reading materials for this problem, so feel free to leave links / tips.

+4
source share
8 answers

Working with multi-faceted 2D platformers for a long time, let me give you some tips:

Create a platform platformer.

Now, to directly answer your collision detection question:

You need to make your world geometry “solid” (you can get away so that your player puts a point, but it's better to make it solid). By "solid" I mean - you need to determine whether the player’s object intersects the geometry of the world.

I tried "does the player make the intersection of the edge of this world geometry", and in practice it does not work (although it may seem that it works on paper - problems with floating point precision will not be your only problem).

There are many instructions on the Internet on how to perform intersection tests between different forms. If you are just starting out, I recommend using Axis-Aligned Bounding Boxes (AABB).

Many, many, many, many, many are easier to make a platform platformer than with arbitrary geometry. So, start with tiles, find intersections with AABB, and then, as soon as you get this work, you can add other shapes (like slopes).

As soon as you find an intersection, you must perform a collision reaction. Again, the platform platformer is the easiest - just move the player right outside the tile you are facing (are you moving above it or from the side?), It will depend on the collision - I will leave how to do it. exercises).

(PS: you can only get amazing results with square plates - for example, look at Knytt Stories).

+4
source

See how this is done in the XNA Platformer Starter Kit project. Basically, tiles have an enumeration to determine if a tile is passable, impassable, etc., and then at your level you GetBounds tiles of tiles, and then check the intersections with the player and determine what to do.

+1
source

I had wonderful moments of pleasure associated with detecting two-dimensional collisions. What seems like a simple problem can easily become a nightmare if you don't plan it ahead of time.

The best way to do this in the OO sense is to make a common object, for example. classMapObject. It has a position coordinate and a slope. From this, you can expand it to include other shapes, etc.

From this, let it work with collisions with a Solid object. Assuming only a block, say 32x32, you can hit it on the left, right, top, and bottom . Or, depending on how you code, hit it top and left at the same time. So, how do you determine in which direction the character should go? For example, if a character falls into a block from above to stand incorrectly encoded, you may inadvertently bring the character to the side.

So what should you do? What I did for my 2D game, I looked at the person before positioning before deciding how to react to the collision. If the symbol is Y-position + Height above the block and moving west, then I would first check the first collision, and then the left collision. However, if the position of the Y + height symbol is below the top of the block, I would check the left collision.

Now let's say that you have a block with a slope. The block is 32 pixels wide, 32 pixels high with x = 32, 0 pixels high with x = 0. With this, you MUST assume that the character can hit and collide with this block from above to stand. With this block you can return a FALSE collision if it is a left / right / bottom collision, but if this collision is on top, you can indicate that if the character is at X = 0, return the collision point Y = 0. If X = 16 , Y = 16, etc.

Of course, this is all relative. You will check for multiple blocks, so what you need to do is save all possible changes in the direction of the characters to a temporary variable. So, if the symbol overlaps the block by 5 in the X direction, subtract 5 from this variable. Accumulate all possible changes in the X and Y direction, apply them to the current character position and reset to 0 for the next frame.

Good luck. I could provide more samples later, but I'm on my Mac (my code is on WinPC). This is the same type of collision detection used in the classic MRC Man IIRC games. Here is a video of this in action: http://www.youtube.com/watch?v=uKQM8vCNUTM

+1
source

You can try using one of the physical engines, for example Box2D or Chipmunk . They have their own advanced collision detection systems and many different bonuses. Of course, they do not speed up your game, but they are suitable for most games on any modern devices.

0
source

It's not easy to create your own collision detection algorithm. One simple example of difficulty: what if your character moves at a high enough speed, what between two frames will he move from one side of the line to the other? Then your algorithm would not have time to pass between them, and a collision will never be detected.

I agree with Tiendil: use the library!

0
source

I would recommend Farseer Physics . This is a great and powerful physics engine that should be able to take care of everything you need!

0
source

I would do it like this:

  • There are strictly no lines for collision. Only solid shapes (boxes and triangles, possibly spheres)
  • 2D BSP, a 2D partition for storing all levels, or a sweep and crop algorithm. Each of them will be very strong. Markup and cropping combined with insertion sorting can easily transport thousands of potentially colliding objects (if not hundreds of thousands), and dividing 2D space will quickly get all potentially colliding shapes on demand.

The easiest way to make objects walk on surfaces is to make them drop a few pixels on each frame, then get a list of objects on the surfaces they encounter and move the object in the direction normal to the surface. In 2d, it is perpendicular. This approach will cause objects to slide down on non-horizontal surfaces, but you can fix this by slightly changing the normal position. In addition, you will have to run collision detection and execute “push objects away” several times per frame, rather than once. This applies to situations where objects are on the heap, or if they are in contact with multiple surfaces.

0
source

I used a limited collision detection approach that worked on a completely different basis, so I will post it here if this helps:

The second image, black and white. Exceptional pixels are white. Build a character mask that just sets any pixels. To evaluate the intended move, read the pixels of this mask from the secondary image and see if white returns.

The same approach is used to detect collisions with other objects, but instead of Boolean sources, it is enough to use depth to cover all possible objects. Draw each object on the whole again in the "color" of this object number. When you read the mask and get a non-zero pixel, the “color” is the number of the object you click.

This resolves all possible collisions in O (n) time, rather than O (n ^ 2) interaction calculations.

0
source

Source: https://habr.com/ru/post/1311854/


All Articles