我正在尝试与我的乒乓对象和旋转的桨对象进行像素完美碰撞。然而,我意识到乒乓球仍在击中旋转的桨状物体的矩形。 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