最近,我一直在尝试在pygame中创建一个弹跳球,并且我已经成功使用了sprite rect碰撞,但是当涉及到浮动块时,该球不知道是反转水平速度还是垂直速度,或者是否知道碰到一个角,所以我开始使用碰撞点,但是经过多次失败尝试后,当球应该垂直固定时,球才开始振动。
这是我处理冲突的代码:
def HitHorizontal(self):
self.velocity[0] = self.velocity[0] * self.bounce
self.velocity[1] = -self.velocity[1] * self.bounce
self.move_y = self.velocity[1]
def HitVertical(self):
self.velocity[0] = -self.velocity[0] * self.bounce
self.velocity[1] = self.velocity[1] * self.bounce
self.move_x = self.velocity[0]
def move_checker(self,obj):
rect = obj.rect
#hits left or right of ball
horizontal = False
vertical = False
if rect.collidepoint((self.rect.topleft[0]+self.move_x,self.rect.topleft[1])):
vertical = True
elif rect.collidepoint((self.rect.topright[0]+self.move_x,self.rect.topright[1])):
vertical = True
elif rect.collidepoint((self.rect.bottomleft[0]+self.move_x,self.rect.bottomleft[1])):
vertical = True
elif rect.collidepoint((self.rect.bottomright[0]+self.move_x,self.rect.bottomright[1])):
vertical = True
#hits top or bottom of ball
if rect.collidepoint((self.rect.topleft[0],self.rect.topleft[1]+self.move_y)):
horizontal = True
elif rect.collidepoint((self.rect.topright[0],self.rect.topright[1]+self.move_y)):
horizontal = True
elif rect.collidepoint((self.rect.bottomleft[0],self.rect.bottomleft[1]+self.move_y)):
horizontal = True
elif rect.collidepoint((self.rect.bottomright[0],self.rect.bottomright[1]+self.move_y)):
horizontal = True
#hits corner of wall
if rect.collidepoint((self.rect.topleft[0]+self.move_x,self.rect.topleft[1]+self.move_y)):
vertical = True
horizontal = True
elif rect.collidepoint((self.rect.topright[0]+self.move_x,self.rect.topright[1]+self.move_y)):
vertical = True
horizontal = True
elif rect.collidepoint((self.rect.bottomleft[0]+self.move_x,self.rect.bottomleft[1]+self.move_y)):
vertical = True
horizontal = True
elif rect.collidepoint((self.rect.bottomright[0]+self.move_x,self.rect.bottomright[1]+self.move_y)):
vertical = True
horizontal = True
if horizontal:
self.HitHorizontal()
if vertical:
self.HitVertical()
这是完整的代码:
import sys, pygame, random, math, time
pygame.init()
xsize = 800
ysize = 600
startx = 600
starty = 100
class Wall(pygame.sprite.Sprite):
def __init__(self, x, y, w, h):
super().__init__()
self.image = pygame.Surface((w, h))
self.image.fill((0,0,0))
self.rect = self.image.get_rect(topleft=(x, y))
class Ball(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.velocity = [0, 0]
self.image = pygame.image.load('ball.png')
self.image = pygame.transform.scale(self.image,(50,50))
self.gravity = 9.81
self.bounce = 0.8
self.rect = self.image.get_rect()
self.put(startx, starty)
self.collision = [False] * 9
self.velocity[0] = 0
self.velocity[1] = 0
def put(self, x, y):
self.rect.x = x
self.rect.y = y
def push(self, x, y):
self.velocity[0]= x
self.velocity[1] = y
def Get_Move(self):
self.move_x = self.velocity[0]
self.velocity[1] += (self.gravity * 0.2)
self.move_y = self.velocity[1]
def update(self):
self.rect.x += self.move_x
self.rect.y += self.move_y
def HitHorizontal(self):
self.velocity[0] = self.velocity[0] * self.bounce
self.velocity[1] = -self.velocity[1] * self.bounce
self.move_y = self.velocity[1]
def HitVertical(self):
self.velocity[0] = -self.velocity[0] * self.bounce
self.velocity[1] = self.velocity[1] * self.bounce
self.move_x = self.velocity[0]
def move_checker(self,obj):
rect = obj.rect
#hits left or right of ball
horizontal = False
vertical = False
if rect.collidepoint((self.rect.topleft[0]+self.move_x,self.rect.topleft[1])):
vertical = True
elif rect.collidepoint((self.rect.topright[0]+self.move_x,self.rect.topright[1])):
vertical = True
elif rect.collidepoint((self.rect.bottomleft[0]+self.move_x,self.rect.bottomleft[1])):
vertical = True
elif rect.collidepoint((self.rect.bottomright[0]+self.move_x,self.rect.bottomright[1])):
vertical = True
#hits top or bottom of ball
if rect.collidepoint((self.rect.topleft[0],self.rect.topleft[1]+self.move_y)):
horizontal = True
elif rect.collidepoint((self.rect.topright[0],self.rect.topright[1]+self.move_y)):
horizontal = True
elif rect.collidepoint((self.rect.bottomleft[0],self.rect.bottomleft[1]+self.move_y)):
horizontal = True
elif rect.collidepoint((self.rect.bottomright[0],self.rect.bottomright[1]+self.move_y)):
horizontal = True
#hits corner of wall
if rect.collidepoint((self.rect.topleft[0]+self.move_x,self.rect.topleft[1]+self.move_y)):
vertical = True
horizontal = True
elif rect.collidepoint((self.rect.topright[0]+self.move_x,self.rect.topright[1]+self.move_y)):
vertical = True
horizontal = True
elif rect.collidepoint((self.rect.bottomleft[0]+self.move_x,self.rect.bottomleft[1]+self.move_y)):
vertical = True
horizontal = True
elif rect.collidepoint((self.rect.bottomright[0]+self.move_x,self.rect.bottomright[1]+self.move_y)):
vertical = True
horizontal = True
if horizontal:
self.HitHorizontal()
if vertical:
self.HitVertical()
class Game:
def __init__(self):
self.AllSprites = pygame.sprite.Group()
self.Walls = pygame.sprite.Group()
self.total_shots = 0
self.putting = False
self.LoadLevel()
def LoadLevel(self):
self.GetWalls()
def start(self):
self.ball.Moving = True
def GetWalls(self):
self.wall_list = [[0,300,xsize,600],[0,-30,xsize,30],[-30,0,30,ysize],[xsize,0,30,ysize],[0,100,300,20 ]]
def CreateWalls(self):
for wally in self.wall_list:
new_wall = Wall(wally[0],wally[1],wally[2],wally[3])
self.Walls.add(new_wall)
self.AllSprites.add(new_wall)
def CreateBall(self):
self.ball = Ball()
self.ball.put(300,100)
self.AllSprites.add(self.ball)
def DetectWallCollide(self):
for wall in self.Walls:
if self.ball.rect.colliderect(wall.rect):
self.ball.move_checker(wall)
def main():
screen = pygame.display.set_mode((xsize, ysize), 0, 32)
clock = pygame.time.Clock()
game = Game()
game.CreateWalls()
game.CreateBall()
game.start()
# The main loop
while True:
# Test for exit
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# Update the screen
screen.fill((255, 255, 0))
game.ball.Get_Move()
game.DetectWallCollide()
game.ball.update()
game.AllSprites.draw(screen)
pygame.display.update()
clock.tick(50)
main()
谢谢您的帮助,亚当。