silentassasin114
silentassasin114

Reputation: 13

Collisions detection in pygame

I'm trying to detect collisions between the player and the floor. This is part of my school project so any insight would be helpful. Also suggestions to improve the code will be appreciated. Here is my code:

import pygame

#initialise pygame

pygame.init()

#variables

level = 0

velx = 0
vely = 0

health = 1
floor_group = set([])

clock = pygame.time.Clock()

#collisions
def detectCollisions(x1, y1, w1,h1, x2, y2, w2, h2):
    if (x2 + w2 >= x1 >= x2 and y2 + h2 >= y1 >= y2):
        return True
    elif (x2 + w2 >= x1 + w1 >= x2 and y2 + h2 >= y1 >= y2):
        return True
    elif (x2 + w2 >= x1 >= x2 and y2 + h2 >= y1 + h1 >= y2):
        return True
    elif (x2 + w2 >= x1 + w1 >= x2 and y2 + h2 >= y1+ h1 >= y2):
        return True
    else:
        return False

#screen size the same size as my background

window = pygame.display.set_mode((900,563))

#Load Images: Backgrounds

background0 = pygame.image.load("background0.png").convert()

#Load Sprites

halfspike = pygame.image.load("halfspike.png").convert_alpha()
spike = pygame.image.load("spike.png").convert_alpha()
platform = pygame.image.load("platform.png").convert_alpha()
spider = pygame.image.load("spider.png").convert_alpha()
char1 = pygame.image.load("char1.png").convert_alpha()
char2 = pygame.image.load("char2.png").convert_alpha()

#Window title

pygame.display.set_caption("Super Boshy Brothers")

# character class
class Sprite:
    def __init__(self,x,y):
        self.x = x
        self.y = y
        self.width = 42
        self.height = 44
        self.velx = 0
        self.vely = 0
        self.image0 = pygame.image.load("char1.png")
        self.image1 = pygame.image.load("char2.png")
        self.timeTarget = 10
        self.timeNumber = 0
        self.currentImage = 0


    def update(self):
        self.timeNumber += 1
        if (self.timeNumber == self.timeTarget):
            if (self.currentImage == 0):
                self.currentImage = 1
            else:
                self.currentImage = 0
            self.timeNumber = 0
        self.render()

    def render(self):
        if (self.currentImage == 0):
            window.blit(self.image0, (self.x, self.y))
        else:
            window.blit(self.image1, (self.x, self.y))


# Floor class
class Floor:
    def __init__(self,x,y):
        self.x = x
        self.y = y
        self.width = 43
        self.height = 44
        self.image0 = pygame.image.load("floor.png")

    def update(self):
        self.render()

    def render(self):
        window.blit(self.image0, (self.x, self.y))

def floor_spawner(row):
    global floor_group
    for i in range(0,946,43):
        floor_group.add(Floor(i,row))



#Create first level floor        
floor_spawner(519)
floor_spawner(475)

#player
player = Sprite(0,431)

#create our main loop

gameloop = True

while gameloop:

    for event in pygame.event.get():       #get function handles events
        if  (event.type == pygame.QUIT):   #if Quit (red x) pressed exit loop
            gameloop = False

        if (event.type == pygame.KEYDOWN):      #If a key is pressed down

            if (event.key ==pygame.K_LEFT):      #If Left Arrow
                velx = -7

            if (event.key ==pygame.K_RIGHT):     #If Right Arrow
                velx = 7

            if (event.key ==pygame.K_UP):        #If Up Arrow

                vely = -7


        if (event.type == pygame.KEYUP):      #If a key is pressed down

            if (event.key ==pygame.K_LEFT):      #If Left Arrow
                velx = 0
            if (event.key ==pygame.K_RIGHT):     #If Right Arrow
                velx = 0
            if (event.key ==pygame.K_UP):        #If Up Arrow
                vely = 0


    #Level 0
    if level == 0:
        window.blit(background0, (0,0))    #Bottom bricks
        for f in list(floor_group):
            f.render()

        if player.x <= 0:                      #Left side collision
            player.x = 0

        if player.x >= 900:                    #Level change
            level = 1
            player.x = 0

    #Level 1
    if level == 1:
        window.blit(background0, (0,0))    #Bottom bricks
        for f in list(floor_group):
            f.render()

    player.x += velx
    player.y += vely
    player.update()


    clock.tick(50)                         #Tick Tock Tick Tock

    pygame.display.flip()                  #Updates the window

pygame.quit()

Upvotes: 0

Views: 283

Answers (1)

Laschet Jain
Laschet Jain

Reputation: 744

It's better if you use pygame sprite to do your assignment.

For managing the floor collision problem, just detect the collision as I do in the code below, if a collision between player and floor occurs then simply move the player back to the previous position.

Here's my code:

import pygame
import random

BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 255, 0)
WHITE = (255, 255, 255)

#Sprite are basically game images in pygame
#Through sprites collision detection and rendering becomes much easier
class Block(pygame.sprite.Sprite):
#Here I've a block class which is a subclass of the pygame's sprite class 
    def __init__(self, image):
        pygame.sprite.Sprite.__init__(self) 
        # Here I've initialised he superclass Sprite
        self.image = image
        #Image of sprite  = image .. that's it
        self.rect = self.image.get_rect()
        #It get's all dimesion's of image which will help it in detecting collision

pygame.init()
infoObject = pygame.display.Info()
# pygame.display.Info() provides us with the information about cureent resolution and a bunch of other stuff
screen = pygame.display.set_mode((infoObject.current_w, infoObject.current_h))

char1 = pygame.image.load("char1.png").convert_alpha()
char2 = pygame.image.load("char2.png").convert_alpha()

char2_list = pygame.sprite.Group()
# Sprite groups are sets for sprites 
# i.e. We have different types of object stored in different groups
# In our game the char1 and char2 are of different 
#internal interaction between all char2 does'nt matter
#It's the interaction between the char1 and char2 that we've to deal with
all_list = pygame.sprite.Group()
#I've made a group which contains all the blocks which helps me in rendering them all together

for i in range(50):
    block = Block(char1)
    block.rect.x = random.randrange(infoObject.current_w)
    block.rect.y = random.randrange(infoObject.current_h)
    charimport pygame
import random

BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 255, 0)
WHITE = (255, 255, 255)

#Sprite are basically game images in pygame
#Through sprites collision detection and rendering becomes much easier
class Block(pygame.sprite.Sprite):
#Here I've a block class which is a subclass of the pygame's sprite class 
    def __init__(self, image):
        pygame.sprite.Sprite.__init__(self) 
        # Here I've initialised he superclass Sprite
        self.image = image
        #Image of sprite  = image .. that's it
        self.rect = self.image.get_rect()
        #It get's all dimesion's of image which will help it in detecting collision

pygame.init()
infoObject = pygame.display.Info()
# pygame.display.Info() provides us with the information about cureent resolution and a bunch of other stuff
screen = pygame.display.set_mode((infoObject.current_w, infoObject.current_h))

char1 = pygame.image.load("char1.png").convert_alpha()
char2 = pygame.image.load("char2.png").convert_alpha()

char2_list = pygame.sprite.Group()
# Sprite groups are sets for sprites 
# i.e. We have different types of object stored in different groups
# In our game the char1 and char2 are of different 
#internal interaction between all char2 does'nt matter
#It's the interaction between the char1 and char2 that we've to deal with
all_list = pygame.sprite.Group()
#I've made a group which contains all the blocks which helps me in rendering them all together

for i in range(50):
    block = Block(char1)
    block.rect.x = random.randrange(infoObject.current_w)
    block.rect.y = random.randrange(infoObject.current_h)
    char2_list.add(block)
    all_list.add(block)

player = Block(char2)
running = True
clock = pygame.time.Clock()
score = 1
all_list.add(player)


while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill(BLACK)

    pos = pygame.mouse.get_pos()
    #Gets position of the mouse
    player.rect.x = pos[0]
    player.rect.y = pos[1]

    char_hit_list = pygame.sprite.spritecollide(player, char2_list, True)#Set it to false and see the result
    #Checks collision
    for block in char_hit_list:
        score += 1
        print score

    all_list.draw(screen)
    #renders(draw) all the sprites onto screen
    pygame.display.update()
    #update's display
    clock.tick(60)
    # Sets Frame Rate to 60

pygame.quit()2_list.add(block)
    all_list.add(block)

player = Block(char2)
running = True
clock = pygame.time.Clock()
score = 1
all_list.add(player)


while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill(BLACK)

    pos = pygame.mouse.get_pos()
    #Gets position of the mouse
    player.rect.x = pos[0]
    player.rect.y = pos[1]

    char_hit_list = pygame.sprite.spritecollide(player, char2_list, True)#Set it to false and see the result
    #Checks collision
    for block in char_hit_list:
        score += 1
        print score

    all_list.draw(screen)
    #renders(draw) all the sprites onto screen
    pygame.display.update()
    #update's display
    clock.tick(60)
    # Sets Frame Rate to 60

pygame.quit()

And one more thing try not to hard-code stuff like you did for screen dimension. For learning more about pygame Sprites have a look at this.

If you have any problem, let me know by commenting in the comments section below, I'll try my best to help you out with your problem.

Keep pygaming :)

Upvotes: 1

Related Questions