4
votes

first time poster here.

Ill try to keep this as simple as possible. I am trying to make a game in pygame but it seems my collision detection is acting up. I have a player class that detects whether or not the player is colliding with the ground or any other objects in the environment list, and I have an enemy class that collides with anything in the same list. The enemies work out what direction they need to travel in in order to try and hit the player. There is gravity which is very likely to play a major part in the problem.

The problem is that when the 'flies' are placed in and fall to the ground, they immediately jump off screen, even though their X and Y values seem (according to logs of items on the screen) to not move at all?

As clarification, the two 'flies' are placed into a secondary list to allow for collision detection. Also, as a side note, the 'glitch' doesn't occur if there is no left and right collide detection... Thanks to anyone who can provide help :)

def collisions():

#Detection Working as intended
    for fly in Fly.List:
        fly_proj = pygame.sprite.spritecollide(fly, Projectile.List, True)
        if len(fly_proj) > 0:
            for hit in fly_proj:
                fly.health -= 100

        X = pygame.sprite.spritecollide(fly, current_level.object_list, False)
        if len(X) == 0: #Gravity here:
            if (fly.vspeed == 0):
                fly.vspeed = 1
                print("Gravity")
            else:
                fly.vspeed += 0.35
        if len(X) > 1: 
            for hit in X:

                if fly.vspeed > 0:            
                    fly.rect.bottom = hit.rect.top +1
                    fly.vspeed = 0
                elif fly.vspeed < 0:    
                    fly.rect.top = hit.rect.bottom -1
                elif fly.hspeed > 0:
                    fly.rect.right = hit.rect.left
                    fly.hspeed = 0
                elif fly.hspeed < 0:            
                    fly.rect.left = hit.rect.right
                    fly.hspeed = 0

        print(len(X),framecounter, fly.vspeed, fly.hspeed)
#Kill fly if health reaches 0            
        if fly.health <= 0:
            fly.destroy(Fly)

 #Detect where the player is
        if window_rect.contains(fly.rect):
            fly.playersnapshot = player.rect.x
        if fly.rect.x - player.rect.x >= -10:
            #print("LEFTING")
            fly.hspeed = -2
        if fly.rect.x - player.rect.x <= 10:
            fly.hspeed = 2
        fly.truefalse = True
        event = None

        fly.rect.y += fly.vspeed
        fly.rect.x += fly.hspeed
1
can fly has hspeed != 0 and vspeed != 0 at the same time ? Now you check hspeed only if vspeed is zero. - furas

1 Answers

1
votes

I think your if/else is incorrect.

Probably when fly touch ground you set vspeed to zero and then if/else checks hspeed and it use ground left/right to change fly left/right.

I know one method.

  1. move fly vertically
  2. check collision and use if/else with vspeed
  3. move fly horizontally
  4. check collision and use if/else with hspeed

--

EDIT:

 # move horizontally only

 fly.rect.x += fly.hspeed

 X = pygame.sprite.spritecollide( ... )

 for hit in X:
     if fly.hspeed > 0:
         fly.rect.right = hit.rect.left
     else:
         fly.rect.left = hit.rect.right

 # move vertically only

 fly.rect.y += fly.vspeed

 X = pygame.sprite.spritecollide( ... )

 for hit in X:
     if fly.vspeed > 0:
         fly.rect.bottom = hit.rect.top
     else:
         fly.rect.top = hit.rect.bottom

     # on_ground = True

I found this method in source code of "Platform Jumper" on ProgramArcadeGames.com

see page with: platform_jumper.py