pygame中的碰撞检测

时间:2015-10-18 09:39:44

标签: python pygame collision

我正在尝试检测玩家和地板之间的碰撞。这是我学校项目的一部分,所以任何见解都会有所帮助。还将赞赏改进代码的建议。这是我的代码:

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

1 个答案:

答案 0 :(得分:1)

如果你使用pygame精灵来完成你的任务,那就更好了。

为了管理地板碰撞问题,只需像我在下面的代码中那样检测碰撞,如果玩家和地板之间发生碰撞,那么只需将玩家移回原位置即可。

这是我的代码:

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

另外还有一件事就是不要像屏幕维度那样硬编码。 要了解有关pygame的更多信息Sprites请查看this

如果您有任何问题,请在下面的评论部分发表评论告诉我,我会尽力帮您解决问题。

保持pygaming:)