2015-10-18 197 views
0

我試圖檢測玩家和地板之間的碰撞。這是我學校項目的一部分,所以任何見解都會有所幫助。此外,有關改進代碼的建議將不勝感激。這裏是我的代碼:pygame中的碰撞檢測

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

如果你使用pygame sprite來完成你的任務,那會更好。

爲了管理地板碰撞問題,只需在下面的代碼中檢測碰撞,如果玩家和地板發生碰撞,只需將玩家移回到之前的位置。

這裏是我的代碼:

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的信息,請點擊this

如果您有任何問題,請通過評論下面的評論來告訴我,我會盡我所能幫助您解決您的問題。

保持pygaming :)