0

I'm not putting down the runnable code (~1.7K lines), just the piece that relates to the collision. I keep many functions in a file called auxfuncs.py. The code runs in main.py. There are many variables and objects here, but the main idea is that if there's masked collision between an obstacle and the moving ship, the direction in which the ship came from and the speed are used to move it back at the same distance and opposite direction.

The problem is, this code for some reason only works in about 75% of times.

import auxfuncs
...
#check masked collision
for ws in wall_sprite_group:
                offset = (hero.rect.x - ws.rect.x, hero.rect.y - ws.rect.y)
                diff = ws.wall_mask.overlap(hero.hero_mask, offset)
                if diff:
                    auxfuncs.push_back(hero, sec)

The player's movement is

# fighter movement
        if hero.direct == "left" and hero.rect.x > 0 and not hero.collide_list[2]:
            hero.rect.x -= hero.set_speed * sec
        elif hero.direct == "right" and hero.rect.right < SCREEN_SIZE[0] and not hero.collide_list[3]:
            hero.rect.x += hero.set_speed * sec
        elif hero.direct == "up" and hero.rect.y > 0 and not hero.collide_list[0]:
            hero.rect.y -= hero.set_speed * sec
        elif hero.direct == "down" and hero.rect.bottom < SCREEN_SIZE[1] and not hero.collide_list[1]:
            hero.rect.y += hero.set_speed * sec
        elif hero.direct == "northwest" and hero.rect.top > 0 and hero.rect.left > 0 and not hero.collide_list[
            0] and not hero.collide_list[2]:
            hero.rect.x -= hero.set_speed * sec
            hero.rect.y -= hero.set_speed * sec
        elif hero.direct == "northeast" and hero.rect.top > 0 and hero.rect.right < SCREEN_SIZE[0] and not \
                hero.collide_list[0] and not hero.collide_list[3]:
            hero.rect.x += hero.set_speed * sec
            hero.rect.y -= hero.set_speed * sec
        elif hero.direct == "southwest" and hero.rect.bottom < SCREEN_SIZE[1] and hero.rect.left > 0 and not \
                hero.collide_list[1] and not hero.collide_list[2]:
            hero.rect.x -= hero.set_speed * sec
            hero.rect.y += hero.set_speed * sec
        elif hero.direct == "southeast" and hero.rect.bottom < SCREEN_SIZE[1] and hero.rect.right < SCREEN_SIZE[
            0] and not hero.collide_list[1] and not hero.collide_list[3]:
            hero.rect.x += hero.set_speed * sec
            hero.rect.y += hero.set_speed * sec

Finally, the auxfuncs.push_back function that moves the ship back in the direction it came from is

def push_back(charact, sec):
    if charact.direct == "left":
        charact.rect.x += charact.set_speed * sec
        charact.collide_list[2] = True
    elif charact.direct == "right":
        charact.rect.x -= charact.set_speed * sec
        charact.collide_list[3] = True
    elif charact.direct == "down":
        charact.rect.y -= charact.set_speed * sec
        charact.collide_list[1] = True
    elif charact.direct == "up":
        charact.rect.y += charact.set_speed * sec
        charact.collide_list[0] = True
    elif charact.direct == "northwest":
        charact.rect.x += charact.set_speed * sec
        charact.rect.y += charact.set_speed * sec
        charact.collide_list[0], charact.collide_list[2] = True, True
    elif charact.direct == "northeast":
        charact.rect.x -= charact.set_speed * sec
        charact.rect.y += charact.set_speed * sec
        charact.collide_list[0], charact.collide_list[3] = True, True
    elif charact.direct == "southwest":
        charact.rect.x += charact.set_speed * sec
        charact.rect.y -= charact.set_speed * sec
        charact.collide_list[1], charact.collide_list[2] = True, True
    elif charact.direct == "southeast":
        charact.rect.x -= charact.set_speed * sec
        charact.rect.y -= charact.set_speed * sec
        charact.collide_list[1], charact.collide_list[3] = True, True

EDIT: In the hero class there are variables that point to the directions in which the collisions occurred:

    self.collide_up = False
    self.collide_down = False
    self.collide_left = False
    self.collide_right = False
    self.collide_list = [self.collide_up, self.collide_down, self.collide_left, self.collide_right]
Alex
  • 944
  • 4
  • 15
  • 28
  • I'd skip 90% of the code and focus on one direction, for instance up or down. Never the less, you're moving your character at `set_speed` multiplied with `sec`, you're looking for a `collide_list`, but what is that collide list? I'm guessing you have a list of positions of other objects and those positions are quite specific. Most likely you're skipping 1 pixel to much and thus can't compare player pos with the collide_list. – Torxed Nov 11 '15 at 10:10
  • I've edited the question...could you specify why I'm 'skipping 1 pixel too much' – Alex Nov 11 '15 at 10:18
  • It's a hunch, usually that's where it fails. Now I see, I missunderstood the use of `collide_list` and see now that it's the `push_back` function that sets the collision. Do you ever set it to `False` again? – Torxed Nov 11 '15 at 10:30
  • Are you aware that `collide_list` does **not** contain references to the `collide_up`, etc. variables? – rodrigo Nov 11 '15 at 10:32
  • @Torxed: yes, after KEYUP event. Like I said, the code works in 75% of cases – Alex Nov 11 '15 at 11:30
  • @rodrigo: 'does not contain references' - what do you mean? – Alex Nov 11 '15 at 11:31
  • @Alex: You do `self.collide_list = [self.collide_up, ...]`, then `self.collide_list[0] = True` and maybe you expect that `self.collide_up` will become `True`, but that is not the case, because there is no connection between the list of booleans and the boolean members. – rodrigo Nov 11 '15 at 11:32
  • @rodrigo: no I don't: I use just the self.collide_list from that point on: this is obvious from the 2nd piece of code above (when checking for fighter movement) – Alex Nov 11 '15 at 11:40
  • I don't think there is enough here to debug your problem. Try printing out the state at various points and see if you can track down under what situating your collision is failing. – cmd Nov 13 '15 at 20:39

0 Answers0