Bounding Box Collision Glitching Problem (Pygame)

Posted by Ericson Willians on Game Development See other posts from Game Development or by Ericson Willians
Published on 2014-05-24T23:18:32Z Indexed on 2014/06/06 3:42 UTC
Read the original article Hit count: 232

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).

enter image description here

When the player goes towards the wall and press the opposite direction. (It glitches through).

enter image description here

Here is the logic I've designed before implementing it:

enter image description here

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?

© Game Development or respective owner

Related posts about collision-detection

Related posts about python