Bounding Box Collision Glitching Problem (Pygame)
- by Ericson Willians
So far the "Bounding Box" method is the only one that I know. It's efficient enough to deal with simple games. Nevertheless, the game I'm developing is not that simple anymore and for that reason, I've made a simplified example of the problem. (It's worth noticing that I don't have rotating sprites on my game or anything like that. After showing the code, I'll explain better).
Here's the whole code:
from pygame import *
DONE = False
screen = display.set_mode((1024,768))
class Thing():
def __init__(self,x,y,w,h,s,c):
self.x = x
self.y = y
self.w = w
self.h = h
self.s = s
self.sur = Surface((64,48))
draw.rect(self.sur,c,(self.x,self.y,w,h),1)
self.sur.fill(c)
def draw(self):
screen.blit(self.sur,(self.x,self.y))
def move(self,x):
if key.get_pressed()[K_w] or key.get_pressed()[K_UP]:
if x == 1:
self.y -= self.s
else:
self.y += self.s
if key.get_pressed()[K_s] or key.get_pressed()[K_DOWN]:
if x == 1:
self.y += self.s
else:
self.y -= self.s
if key.get_pressed()[K_a] or key.get_pressed()[K_LEFT]:
if x == 1:
self.x -= self.s
else:
self.x += self.s
if key.get_pressed()[K_d] or key.get_pressed()[K_RIGHT]:
if x == 1:
self.x += self.s
else:
self.x -= self.s
def warp(self):
if self.y < -48:
self.y = 768
if self.y > 768 + 48:
self.y = 0
if self.x < -64:
self.x = 1024 + 64
if self.x > 1024 + 64:
self.x = -64
r1 = Thing(0,0,64,48,1,(0,255,0))
r2 = Thing(6*64,6*48,64,48,1,(255,0,0))
while not DONE:
screen.fill((0,0,0))
r2.draw()
r1.draw()
# If not intersecting, then moves, else, it moves in the opposite direction.
if not ((((r1.x + r1.w) > (r2.x - r1.s)) and (r1.x < ((r2.x + r2.w) + r1.s))) and (((r1.y + r1.h) > (r2.y - r1.s)) and (r1.y < ((r2.y + r2.h) + r1.s)))):
r1.move(1)
else:
r1.move(0)
r1.warp()
if key.get_pressed()[K_ESCAPE]:
DONE = True
for ev in event.get():
if ev.type == QUIT:
DONE = True
display.update()
quit()
The problem:
In my actual game, the grid is fixed and each tile has 64 by 48 pixels. I know how to deal with collision perfectly if I moved by that size. Nevertheless, obviously, the player moves really fast.
In the example, the collision is detected pretty well (Just as I see in many examples throughout the internet). The problem is that if I put the player to move WHEN IS NOT intersecting, then, when it touches the obstacle, it does not move anymore. Giving that problem, I began switching the directions, but then, when it touches and I press the opposite key, it "glitches through". My actual game has many walls, and the player will touch them many times, and I can't afford letting the player go through them.
The code-problem illustrated:
When the player goes towards the wall (Fine).
When the player goes towards the wall and press the opposite direction. (It glitches through).
Here is the logic I've designed before implementing it:
I don't know any other method, and I really just want to have walls fixed in a grid, but move by 1 or 2 or 3 pixels (Slowly) and have perfect collision without glitching-possibilities. What do you suggest?