与旋转对象Pygame的碰撞

时间:2017-12-04 15:20:39

标签: python pygame collision pong

我正在尝试与我的乒乓对象和旋转的桨对象进行像素完美碰撞。然而,我意识到乒乓球仍在击中旋转的桨状物体的矩形。 As you can see, the ball is hitting the rect of the paddle, instead of the actual paddle

这是我的pong类,定义了碰撞检测。请检查checkCollision()函数,因为我使用的是pygame.sprite.colliderect()函数。

class Pong(pygame.sprite.Sprite):

def __init__(self, screensize):

    pygame.sprite.Sprite.__init__(self)

    self.screensize = screensize

    self.centerx = screensize[0] // 2
    self.centery = screensize[1] // 2
    self.radius = 25
    self.rect = pygame.Rect(self.centerx-self.radius,
                            self.centery-self.radius,
                            self.radius*2, self.radius*2)

    self.image = pygame.image.load("pokeball.png").convert()
    self.colorkey = self.image.get_at((0,0))
    self.image = pygame.transform.scale(self.image, (self.radius, self.radius))

    #Create the mask
    self.mask = pygame.mask.from_surface(self.image)

    self.color = (100,100,255)
    self.direction = [-2,1]

    self.speedx = 2
    self.speedy = 3

    self.hit_edge_left = False
    self.hit_edge_right = False

def checkCollision(self, player_paddle, ai_paddle):

    col = pygame.sprite.collide_rect(self, player_paddle)

    return col 

def collisionFormula(self, player_paddle, ai_paddle):

    if self.checkCollision(self, player_paddle):
        relative_IntersectionY = player_paddle.centery - self.rect.centery
        normal_IntersectionY = relative_IntersectionY / (player_paddle.height /2)
        bounce_angle = normal_IntersectionY * (5*math.pi/ 12 )


        self.direction[0] = math.cos(bounce_angle)
        self.direction[1] = -1 * math.sin(bounce_angle)



def update_ball_position(self):
    #update the position of the ball 
    self.centerx += self.direction[0]*self.speedx
    self.centery += self.direction[1]*self.speedy
    self.rect.center = (self.centerx, self.centery)


def reset_ball(self):
    if self.rect.right >= self.screensize[0]-1:
        self.hit_edge_right = True
        self.__init__(self.screensize)
    elif self.rect.left <= 0:
        self.hit_edge_left = True
        self.__init__(self.screensize)

def collision_checks(self, player_paddle, ai_paddle):

    #if the ball hits the top or bottom of the screen, change the y direction
    if self.rect.top <= 0 or self.rect.bottom >= self.screensize[1] - 1:
        self.direction[1] *= -1

    #if the pong hits the paddles, change how the pong ball moves 
    if self.rect.colliderect(player_paddle.rect) or self.rect.colliderect(ai_paddle.rect):
        self.collisionFormula(player_paddle, ai_paddle)

def update(self, player_paddle, ai_paddle):

    self.update_ball_position()
    self.reset_ball()
    self.collision_checks(player_paddle, ai_paddle)


def render(self, screen):
    screen.blit(self.image, (self.centerx, self.centery))<!-- Paste the part of the code that shows the problem. 

这是我的PlayerPaddle类,它定义了旋转函数。

class PlayerPaddle(pygame.sprite.Sprite):
def __init__(self, screensize):

    pygame.sprite.Sprite.__init__(self)
    self.screensize = screensize

    self.centerx = 50
    self.centery = screensize[1]//2

    self.height = 100
    self.width = 20

    self.imageMaster = pygame.image.load("naruto.png").convert()
    self.colorkey = self.imageMaster.get_at((0,0))
    self.imageMaster = pygame.transform.scale(self.imageMaster, (100, 200))
    self.image = self.imageMaster

    #mask
    #self.maskMaster = pygame.mask.from_surface(self.image)
    #self.mask = self.maskMaster 

    self.rect = self.image.get_rect()
    self.rect.center = (screensize[0]//2, screensize[1]//2)
    self.dir = 0 


    self.color = (100,255,100)
    self.speed = 3
    self.direction = 0

    self.update()

def update(self):
    #Rotate functions
    oldCenter = self.rect.center
    self.image = pygame.transform.rotate(self.imageMaster, self.dir).convert()
    self.image.set_colorkey(self.colorkey)
    self.rect = self.image.get_rect()
    #self.rect.center = oldCenter
    self.mask = pygame.mask.from_surface(self.image)


    self.centery += self.direction*self.speed

    self.rect.center = (self.centerx, self.centery)
    if self.rect.top < 0:
        self.rect.top = 0

    if self.rect.bottom > self.screensize[1]-1:
        self.rect.bottom = self.screensize[1]-1

def render(self, screen):

    screen.blit(self.image, (self.rect.x, self.rect.y))


def turnLeft(self):
    self.dir += 45
    if self.dir > 360:
        self.dir = 45

def turnRight(self):
    self.dir -= 45
    if self.dir < 0:
        self.dir = 315

我在main()的while循环中写这个。

        if pygame.sprite.spritecollide(pong_sprite, paddleGroup, False, pygame.sprite.collide_mask):
        print("Collided")

我不确定为什么会这样,但我想知道如何让像素完美碰撞,这样我就可以避免图像问题了。

编辑: 我更改了PlayerPaddle类的更新功能。

def update(self):
    #Rotate functions
    oldCenter = self.rect.center
    self.image = pygame.transform.rotate(self.imageMaster, self.dir)
    self.rect = self.image.get_rect()
    self.rect.center = oldCenter
    self.mask = pygame.mask.from_surface(self.image)



    self.centery += self.direction*self.speed

    self.rect.center = (self.centerx, self.centery)
    if self.rect.top < 0:
        self.rect.top = 0

    if self.rect.bottom > self.screensize[1]-1:
        self.rect.bottom = self.screensize[1]-1

这是我的主要():

def main():
    pygame.init()

    screensize = (640,700)
    screen = pygame.display.set_mode(screensize)

    background = pygame.Surface(screen.get_size())
    background.fill((0, 255, 0))

    clock = pygame.time.Clock()

    pong_sprite = Pong(screensize)
    player_paddle = PlayerPaddle(screensize)
    ai_paddle = AIPaddle(screensize)


    paddleGroup = pygame.sprite.Group()
    paddleGroup.add(player_paddle)
    pongGroup = pygame.sprite.Group()
    pongGroup.add(pong_sprite)


    running = True

    keymap = {pygame.K_u: False}

    while running:
        #fps limiting/reporting phase
        clock.tick(64)
        screen.fill((100,100,100))
        #event handling phase
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False

            if event.type == KEYDOWN:
                if event.key in keymap:
                    keymap[event.key] = True
                if event.key == K_UP:
                    player_paddle.direction = -1
                elif event.key == K_DOWN:
                    player_paddle.direction = 1
                elif event.key == K_LEFT:
                    player_paddle.turnLeft()
                elif event.key == K_RIGHT:
                    player_paddle.turnRight()


            if event.type == KEYUP:

                if event.key in keymap:
                    keymap[event.key] = False
                if event.key == K_UP and player_paddle.direction == -1:
                    player_paddle.direction = 0
                elif event.key == K_DOWN and player_paddle.direction == 1:
                    player_paddle.direction = 0

        #object updating phase
        ai_paddle.update(pong_sprite, player_paddle)
        #player_paddle.update()
        #pong.update(player_paddle, ai_paddle)

        if pygame.sprite.spritecollide(pong_sprite, paddleGroup, False, pygame.sprite.collide_mask):
            print("Collided")


        if pong_sprite.hit_edge_left:
            print("You won")
            #running = False
        elif pong_sprite.hit_edge_right:
            print("You Lose")
            #running = False

        #rendering phase
        ai_paddle.render(screen)
        player_paddle.render(screen)
        #pong.render(screen)

        paddleGroup.clear(screen, background)
        paddleGroup.update()
        paddleGroup.draw(screen)

        pongGroup.clear(screen,background)
        pongGroup.update(player_paddle, ai_paddle)
        pongGroup.draw(screen)

        pygame.display.flip()

    pygame.quit()

这是我的图片enter image description here: 这是naruto.jpg图片

这是pokeball.jpg enter image description here

0 个答案:

没有答案