So I am currently working on a 2D platformer game and i have realized a big issue with my collision programming. You see, to find out collisions with the player I just moved the player rect around, then when colliding i pushed the player away by looking at the x and y acceleration on him. The problem is though, when using this method, the player speed can make the player skip over targets he is supposed to collide with because the rect he is supposed to collide with is too small. For example if the platform is 9px in size and the speed the player is going at is 11px, there is a chance he will skip the target. This usually happens with bullets the player is shooting which are small and go quickly (And i don't want them to be instantaneous because of the nature of the game). So i thought about it and came up with a solution of drawing a line from the position of the bullet was previously at to the one he it is in right now, then checking if the target rect collides with it. I searched on methods to do something like this, but i haven't found any good explanation of how to implement this into Pygame. Do i use pixel masking? If yes, how to? Is there some function already in Pygame to use this method with? I could really use some help.
相关问题
- Django __str__ returned non-string (type NoneType)
- How to postpone/defer the evaluation of f-strings?
- ImportError shows up with py.test, but not when ru
- Comparing pd.Series and getting, what appears to b
- Django Attribute error 'datetime.timedelta'
相关文章
- Airflow depends_on_past explanation
- Raspberry Pi-Python: Install Pandas on Python 3.5.
- Numpy array to TFrecord
- How to split a DataFrame in pandas in predefined p
- Error following env.render() for OpenAI
- AttributeError: 'Series' object has no att
- ImportError: cannot import name 'joblib' f
- How to save a file downloaded from requests to ano
many gaming systems have 2 "callback" methods:
used to update game data, and
used to render data on screen
The infamous "tunnel" effect happens when the speed of an object is too big so distance being computed like
So the x & y variations may be too high and artificially "cross" thin obstacles/targets.
You can deduce experimentally a threshold elapsed time value beyond which this effect will happen (it happens in "Pac-Man" in the later stages, so happens even to the best coders :)
Example of an update wrapper in C which guarantees that
update
is not called with a too big elapsed time:Simple linear AABB collision detection
Below is a solution for intercepting a moving box with many stationary boxes. The boxes must have sides parallel to the x and y axis.
It solves the problem of high speed movement by finding the first intercept between two frame, no matter how thin the obstacle is or how fast the object is moving the correct intercept is found. (Note the boxes must have a positive width and height)
Line box intercept
It works by representing the moving box's path as a single line. Rather than adding the width and height to the line the width and height of the moving box is added to the obstacle boxes, this greatly reduces the amount of work needed to solve the problem. (the demo graphically shows some of the intermediate abstraction including the expansion of obstacle boxes)
To use in game the line in the demo is just the game's current object position to the position in the next frame along delta x and y.
The intercept sets the x,y distance from the current position to the intercept (if any). The normal (a vector pointing away from the side hit) is provided as well to aid collision response. You also have the distance squared to the intercept point. You can divide that distance with the line length squared to give you a unit time of when the intercept occurred. ie a value of 0.5 means that it happened mid way between two frames. 0 it happened at the start and 1 it happened at the end. If there is no intercept then the normal will be zero length.
The demo
The demo is javascript, but the math and logic is what is important. The functions of interest are at the top of the snippet and well commented (I hope). Below that is just boilerplate and support.
To use the demo, left click drag to create a box. Then left click and drag to mark out a line. The start position is the light green box, the other green box is the intercept, if there is one. There are also some yellow marks indicating calculated intercepts that were too far away. Full page to see more boxes.
Limits and adaptations
You may notice that if the start position is touching a box that the intercept point is before the start position (backward in time) This is the correct behaviour, you should not be overlapping a box (inside a wall) at the start
If you have moving obstacles and they move along the x or y axis you can adapt the solution by simply expanding the boxes in the direction of movement (not perfect but works for slow moving obstacles (watch out for overlapping in the next frame).
You can also test a moving circle. this can be done by checking if the intercept point is within the circle radius distance of a corner. If so then do a line circle intercept with the circle center at the box real corner and radius same as the moving circle.
Clear as mud I know so do ask if you have any questions.