Хорошо, давайте пройдемся по этому шагу за шагом.
Сначала давайте изменим порядок вашего кода, чтобы у нас был хороший стандартный основной цикл event handling -> state update -> draw
.Мы видим, что у вас есть функция draw
, но вы не рисуете все в этой функции.Кроме того, вы звоните pygame.display.flip()
до draw
.screen.mainloop()
не имеет смысла, и sys.exit()
также не будет работать, потому что вы не импортируете sys
.
Шаг 1:
import pygame
def main():
pygame.init()
width = 500
height = 400
#pygame.title("Ping Pong Level 1")
screen = pygame.display.set_mode((width, height))
y = 30
g = 30
x = 40
f = 100
velxX = 2
velfF = 2
velX = 50
velF = 20
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w] and y > 0:
y -= 5
if pressed[pygame.K_s] and y < height - 100:
y += 5
if pressed[pygame.K_UP] and g > 0:
g -= 5
if pressed[pygame.K_DOWN] and g < height - 100:
g += 5
velF += velfF
velX += velxX
if velF < 0 or velF > height - 5:
velfF *= -1
if velX < 0 or velX > width - 5:
velxX *= -1
screen.fill((0, 0, 0))
pygame.draw.circle(screen, (0, 255, 0), (velX, velF), 5)
player = pygame.draw.rect(screen, (255, 255, 255), (30, y, 30, 100))
player1 = pygame.draw.rect(screen, (255, 255, 255), (440, g, 30, 100))
line = pygame.draw.rect(screen, (0, 0, 255), (250, 0, 10, 400))
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()
Далее,давайте посмотрим на ваше состояние игры и рисунок.У вас есть куча переменных со странными именами и переменные, которые вы не используете или не имеете смысла (например, velxX
, f
или player1
). Вы также рисуете некоторые ректы, так что давайте исправим это с помощьюиспользуя правильные структуры данных: полезные Rect
и Vector2
классы.
Шаг 2:
import pygame
def main():
pygame.init()
screen = pygame.display.set_mode((500, 400))
screen_rect = screen.get_rect()
left_paddle = pygame.Rect((30, 30, 30, 100))
right_paddle = pygame.Rect((440, 30, 30, 100))
ball_position = pygame.Vector2((50, 20))
ball_direction = pygame.Vector2((1, 1)).normalize()
ball_speed = 5
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]: left_paddle.move_ip(0, -5)
if pressed[pygame.K_s]: left_paddle.move_ip(0, 5)
if pressed[pygame.K_UP]: right_paddle.move_ip(0, -5)
if pressed[pygame.K_DOWN]: right_paddle.move_ip(0, 5)
# keep paddles on the screen
left_paddle.clamp_ip(screen_rect)
right_paddle.clamp_ip(screen_rect)
ball_position += ball_direction * ball_speed
# flip direction on edge
if ball_position[1] < 0 or ball_position[1] > screen_rect.height - 5:
ball_direction = pygame.Vector2(ball_direction[0], -ball_direction[1])
if ball_position[0] < 0 or ball_position[0] > screen_rect.width - 5:
ball_direction = pygame.Vector2(-ball_direction[0], ball_direction[1])
screen.fill((0, 0, 0))
pygame.draw.rect(screen, (255, 255, 255), left_paddle)
pygame.draw.rect(screen, (255, 255, 255), right_paddle)
pygame.draw.rect(screen, (0, 0, 255), (250, 0, 10, 400))
pygame.draw.circle(screen, (0, 255, 0), [int(v) for v in ball_position], 5)
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()
Все идет нормально.Теперь реализовать обнаружение столкновений легко.Мы могли бы рассчитать, где мяч будет на следующем шаге, а затем проверить, не столкнутся ли они с веслом.Поскольку мы используем класс Rect
, легко проверить наличие столкновений (collidepoint
) и увеличить их (inflate
,потому что размер шара больше одного пикселя).
Шаг 3:
import pygame
def main():
pygame.init()
screen = pygame.display.set_mode((500, 400))
screen_rect = screen.get_rect()
left_paddle = pygame.Rect((30, 30, 30, 100))
right_paddle = pygame.Rect((440, 30, 30, 100))
ball_position = pygame.Vector2((150, 120))
ball_direction = pygame.Vector2((1, 1)).normalize()
ball_speed = 5
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
pressed = pygame.key.get_pressed()
if pressed[pygame.K_w]: left_paddle.move_ip(0, -5)
if pressed[pygame.K_s]: left_paddle.move_ip(0, 5)
if pressed[pygame.K_UP]: right_paddle.move_ip(0, -5)
if pressed[pygame.K_DOWN]: right_paddle.move_ip(0, 5)
# keep paddles on the screen
for paddle in (left_paddle, right_paddle):
paddle.clamp_ip(screen_rect)
ball_position += ball_direction * ball_speed
# flip direction on edge
if ball_position[1] < 0 or ball_position[1] > screen_rect.height - 5:
ball_direction = pygame.Vector2(ball_direction[0], -ball_direction[1])
if ball_position[0] < 0 or ball_position[0] > screen_rect.width - 5:
ball_direction = pygame.Vector2(-ball_direction[0], ball_direction[1])
next_ball_position = ball_position + ball_direction * ball_speed
for paddle in (left_paddle, right_paddle):
if paddle.inflate(5, 5).collidepoint(next_ball_position):
ball_direction = pygame.Vector2(-ball_direction[0], ball_direction[1])
screen.fill((0, 0, 0))
for paddle in (left_paddle, right_paddle):
pygame.draw.rect(screen, (255, 255, 255), paddle)
pygame.draw.rect(screen, (0, 0, 255), (250, 0, 10, 400))
pygame.draw.circle(screen, (0, 255, 0), [int(v) for v in ball_position], 5)
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()
![enter image description here](https://i.stack.imgur.com/ejUy0.gif)
Обратите внимание, что это работаеттолько если мяч ударяет по лопатке спереди, но вы можете легко проверить положение шара относительно лопатки, чтобы определить, хотите ли вы изменить направление y
или x
направления мяча.
И так какмы используем вектор для направления шара, также легко позволить шару двигаться под углами, отличными от 45 °.