python中的多个墙碰撞

时间:2013-08-01 02:26:34

标签: python pygame pacman

我正在创建一段代码,其中包含一个迷宫和门,当按钮被击中时它会打开。问题是,当我放入门时,玩家碰撞检测到门但不再检测到迷宫。我把所有代码放在这里,希望如果人们能看到任何其他问题,他们可以帮助谢谢:)

import pygame, sys, random, time


#Setting up the colours
black = (0,0,0)
white = (255,255,255)
blue = (0,0,255)
green = (0,255,0)
red = (255,0,0)
orange = (248,100,1)
slateG = (112,128,144)
pink = (255,20,147)
dTurq = (0,206,209)
honeyD = (240,255,240)
maroon = (128,0,0)
goldenrod = (218,165,32)
sGreen = (0,255,127)
Fus = (255,0,255)


class player(pygame.sprite.Sprite):
    change_x=0
    change_y=0

    #initialise the class
    def __init__(self,x,y):

        pygame.sprite.Sprite.__init__(self)
        #the player will be 13x13
        self.image = pygame.Surface([13,13])
        self.image.fill(maroon)

        self.rect = self.image.get_rect()
        self.rect.top = y
        self.rect.left = x

    def changespeed(self,x,y): #this function changes the speed of the player
        self.change_x+=x
        self.change_y+=y

    def updateWall(self,walls): #This is a collision detection function
        old_x=self.rect.left
        new_x = old_x+self.change_x
        self.rect.left = new_x

        collide = pygame.sprite.spritecollide(self,walls,False)
        if collide:
            self.rect.left = old_x

        old_y = self.rect.top
        new_y = old_y+self.change_y
        self.rect.top = new_y

        collide = pygame.sprite.spritecollide(self,walls,False)
        if collide:
            self.rect.top = old_y

    def updateBarrier1(self,barriers):
        gx=self.rect.left
        nx = gx+self.change_x
        self.rect.left = nx

        collide = pygame.sprite.spritecollide(self,barriers,False)
        if collide:
            self.rect.left = gx

        gy = self.rect.top
        ny = gy+self.change_y
        self.rect.top = ny

        collide = pygame.sprite.spritecollide(self,barriers,False)
        if collide:
            self.rect.top = gy






class Wall(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height,color): #this sets up for the x/y coordinates, the width and the height and the colour of the wall

        pygame.sprite.Sprite.__init__(self)
        #how big will the wall be
        self.image = pygame.Surface([width,height])
        #what colour will the wall be
        self.image.fill(color)

        #initialising the x/y coordinates
        self.rect = self.image.get_rect()
        self.rect.top = y
        self.rect.left = x

class Bar(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height,color):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface([width,height])

        self.image.fill(color)


        self.rect = self.image.get_rect()
        self.rect.top = y
        self.rect.left = x


class Button(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height,color):

        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([width,height]) #the buttons dimensions
        self.image.fill(color) #colour of the button

        #x/y coordinates
        self.rect = self.image.get_rect()
        self.rect.top=y
        self.rect.left=x

#Setting up the walls for the maze
def maze1():
    wall_list = pygame.sprite.RenderPlain()
    #Walls of maze
    walls = [[0,0,20,390,goldenrod],[0,410,20,390,goldenrod],[0,0,1000,20,goldenrod],
             [980,0,20,800,goldenrod],[0,780,980,20,goldenrod],[20,40,940,10,dTurq],
             [950,40,10,350,dTurq],[950,410,10,350,dTurq],[40,750,370,10,dTurq],
             [430,570,10,210,dTurq],[430,570,240,10,dTurq],[660,570,10,210,dTurq],
             [690,550,10,210,dTurq],[690,750,260,10,dTurq],[400,550,10,210,dTurq],
             [40,410,10,350,dTurq],[20,100,30,10,dTurq], [40,100,10,290,dTurq],
             [50,410,460,10,green],[50,380,350,10,green],[430,380,100,10,green],
             [530,380,10,100,green],[500,410,10,100,green],[500,510,60,10,green],
             [550,510,10,30,green],[580,510,10,30,green],[400,540,160,10,dTurq],
             [580,540,120,10,dTurq],[530,480,150,10,green],[680,430,10,60,green],
             [580,510,130,10,green],[710,460,10,60,green],[680,430,250,10,green],
             [710,460,190,10,green],[920,430,10,300,green],[890,460,10,230,green],
             [820,720,100,10,green],[820,690,80,10,green],[810,690,10,40,green],
             [550,410,400,10,sGreen],[550,210,10,200,sGreen],[250,210,300,10,sGreen],
             [250,210,10,120,sGreen],[250,330,180,10,sGreen],[430,330,10,50,sGreen],
             [580,380,370,10,sGreen],[580,180,10,200,sGreen],[220,180,360,10,sGreen],
             [220,180,10,180,sGreen],[220,360,180,10,sGreen],[390,360,10,20,sGreen]]

    for item in walls:
        wall = Wall(item[0],item[1],item[2],item[3],item[4])
        wall_list.add(wall)
    return wall_list


def BarrierWhite():
    barriers = pygame.sprite.RenderPlain()
    barrier = [[500,540,10,40,white],[400,180,10,40,white]]

    for item in barrier:
        barrie = Bar(item[0],item[1],item[2],item[3],item[4])
        barriers.add(barrie)
    return barriers



def BarrierPink():
    wall_list = pygame.sprite.RenderPlain()
    walls = [[550,520,40,10,pink],[20,600,30,10,pink],[300,380,10,40,pink]]

    for item in walls:
        wall = Wall(item[0],item[1],item[2],item[3],item[4])
        wall_list.add(wall)

    return wall_list


def Buttons(): #Creating buttons
    buttons = pygame.sprite.RenderPlain()
    button1 = [[965,765,10,10,white]]
    for item in button1:
        button = Button(item[0],item[1],item[2],item[3],item[4])
        buttons.add(button)

    return buttons

def pinkButton():
    pinkB = pygame.sprite.RenderPlain()
    b = [[835,705,10,10,pink]]
    for item in b:
        button = Button(item[0],item[1],item[2],item[3],item[4])
        pinkB.add(button)
    return pinkB

#main line
pygame.init()

window = pygame.display.set_mode([1000,800])

background = pygame.Surface(window.get_size())
background = background.convert()
background.fill(black)

player = player(25,25)
movingsprt = pygame.sprite.RenderPlain()
movingsprt.add(player)

clock = pygame.time.Clock()

wall_list = maze1()
barriers = BarrierWhite()

buttons = Buttons()
B1 = pinkButton()

done = False


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

            #This makes the player move
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                player.changespeed(-6,0)
            if event.key == pygame.K_RIGHT:
                player.changespeed(6,0)
            if event.key == pygame.K_UP:
                player.changespeed(0,-6)
            if event.key == pygame.K_DOWN:
                player.changespeed(0,6)

        #This stops the player from moving
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                player.changespeed(6,0)
            if event.key == pygame.K_RIGHT:
                player.changespeed(-6,0)
            if event.key == pygame.K_UP:
                player.changespeed(0,6)
            if event.key == pygame.K_DOWN:
                player.changespeed(0,-6)

    player.updateWall(wall_list)
    player.updateBarrier1(barriers)



    window.fill(black)

    movingsprt.draw(window)
    barriers.draw(window)
    wall_list.draw(window)
    buttons.draw(window)
    B1.draw(window)


    pygame.display.flip()

    clock.tick(40)

pygame.quit()            

此外,如果有人可以告诉我如何设置一个倒数计时器,该计时器将禁用播放器并显示游戏而不是标志,这也很棒:D

1 个答案:

答案 0 :(得分:1)

在您的代码中添加门(或barriers,因为您的游戏中存在设计问题,因此墙碰撞无效。

以下是您在主循环中执行的操作:

player.updateWall(wall_list)
player.updateBarrier1(barriers)

首先检查碰撞是否有墙,然后再次检查是否有障碍物碰撞。 问题是,您使用updateWallupdateBarrier1方法合并了使角色移动的部分。

因此,例如,如果你的角色与墙碰撞而不是与门碰撞,角色仍会移动,因为updateBarrier1方法不会检测到与障碍物(门)的碰撞,并会使他移动

相反,您应该执行一些名为collides_wallcollides_barrier的方法,这些方法会返回TrueFalse,然后将以前引用的两行替换为:

if not player.collides_wall(wall_list) and not player.collides_barriers(barriers):
    player.move()

使用move方法,可以按照updateSomething方法中的方式移动播放器。

注意:有人在评论中指出,你也不需要两个单独的墙和障碍碰撞方法,因为最终它们都是精灵,你们两个都做了完全相同的操作。他们。所以只需添加collides方法。