0
\$\begingroup\$

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?

\$\endgroup\$
1
\$\begingroup\$

It is probably because you are hitting right on the border and are not checking for that.

# if collision move opposite else move forward
if  ((((r1.x + r1.w) >= (r2.x - r1.s)) && (r1.x <= ((r2.x + r2.w) + r1.s))) && (((r1.y + r1.h) >= (r2.y - r1.s)) && (r1.y <= ((r2.y + r2.h) + r1.s)))):
    r1.move(0)
else:
    r1.move(1)

Also I think there are a couple of errors in your warp(). I think it should read:

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    <----- here
    if self.x > 1024 + 64:
         self.x = 0     <------ and here
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.