乒乓球拍有一些奇怪的错误阻止让玩家得分
Pong paddles have some weird bug preventing from letting a player score
我做了一个乒乓球游戏。现在的问题是,当我移动球拍时,球并没有越过球拍,而是在一些看不见的墙上弹跳。这是我的代码,你自己 运行 你可以看到问题所在(你必须稍微移动一下桨)
# Pong
# Importing libraries
import pygame
import random
import time
# Initializing PyGame
pygame.init()
# Creating a font
font = pygame.font.SysFont(None, 30)
# Set the height and width of the screen
window_width = 700
window_height = 500
size = [window_width, window_height]
game_win = pygame.display.set_mode(size)
# Creating a messaging system
def message(sentence, x, y):
sentence = font.render(sentence, True, white)
game_win.blit(sentence, [x, y])
# Creating a color
white = (225, 225, 225)
black = (0, 0, 0)
# Setting up ball
ball_size = 25
class Ball:
"""
Class to keep track of a ball's location and vector.
"""
def __init__(self):
self.x = 0
self.y = 0
self.change_x = 0
self.change_y = 0
def make_ball():
ball = Ball()
# Starting position of the ball.
# Take into account the ball size so we don't spawn on the edge.
ball.x = 350
ball.y = 250
# Speed and direction of rectangle
ball.change_x = 5
ball.change_y = 5
return ball
def main():
# Scores
left_score = 0
right_score = 0
pygame.init()
pygame.display.set_caption("Ping Pong")
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
ball_list = []
ball = make_ball()
ball_list.append(ball)
# Right paddle coordinates
y = 200
y_change = 0
x = 50
# Left paddle coordinates
y1 = 200
y1_change = 0
x1 = 650
while not done:
# --- Event Processing
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
y_change = -5
elif event.key == pygame.K_s:
y_change = 5
elif event.key == pygame.K_UP:
y1_change = -5
elif event.key == pygame.K_DOWN:
y1_change = 5
elif event.type == pygame.KEYUP:
y_change = 0
y1_change = 0
y += y_change
y1 += y1_change
if y > window_height - 100:
y -= 5
if y < 50:
y += 5
if y1 > window_height - 100:
y1 -= 5
if y1 < 50:
y1 += 5
message("Left player score: " + str(left_score), 10, 10)
message("Right player score: " + str(right_score), 490, 10)
# Drawing a left paddle
pygame.draw.rect(game_win, white, [x, y, 25, 100])
# Drawing a right paddle
pygame.draw.rect(game_win, white, [x1, y1, 25, 100])
# Updating screen to changes take place
pygame.display.update()
# Logic
for ball in ball_list:
# Move the ball's center
ball.x += ball.change_x
ball.y += ball.change_y
# Bounce the ball if needed
if ball.y > 50 - ball_size or ball.y < ball_size:
ball.change_y *= -1
if ball.x > window_width - ball_size:
ball.change_x *= -1
left_score += 1
if ball.x < ball_size:
ball.change_x *= -1
right_score += 1
# Here is the part where it all becomes weird and buggy
if ball.x-ball_size <= x <= ball.x + ball_size:
ball.change_x *= -1
if ball.x-ball_size <= x1 <= ball.x + ball_size:
ball.change_x *= -1
if ball.y-ball_size <= y <= ball.y + ball_size:
ball.change_x *= -1
if ball.y-ball_size <= y1 <= ball.y + ball_size:
ball.change_x *= -1
if right_score == 10:
message('RIGHT PLAYER HAS WON!!', 300, 200)
time.sleep(10)
done = True
elif left_score == 10:
message("LEFT PLAYER HAS WON!!", 300, 200)
time.sleep(10)
done = True
# Drawing
# Set the screen background
game_win.fill(black)
# Draw the balls
for ball in ball_list:
pygame.draw.circle(game_win, white, [ball.x, ball.y], ball_size)
# Wrap-up
# Limit to 60 frames per second
clock.tick(60)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Close everything down
pygame.quit()
if __name__ == "__main__":
main()
当我把球拍移开时,球仍然可以从一些看不见的墙上弹回来。其他的都很好,就是我放# Bounce if needed
.
的部分
我建议计算球和球拍的边界矩形,并使用 pygame.Rect
and colliderect()
检测球和球拍之间的碰撞。
另见 .
例如:
def main():
# [...]
while not done:
# [...]
# Logic
for ball in ball_list:
# [...]
ball_rect = pygame.Rect(ball.x-ball_size, ball.y-ball_size, ball_size*2, ball_size*2)
left_paddle_rect = pygame.Rect(x, y, 25, 75)
if ball.change_x < 0 and ball_rect.colliderect(left_paddle_rect):
ball.change_x = abs(ball.change_x)
right_paddle_rect = pygame.Rect(x1, y1, 25, 75)
if ball.change_x > 0 and ball_rect.colliderect(right_paddle_rect):
ball.change_x = -abs(ball.change_x)
此外,window 的高度是 500 而不是 50_
if ball.y > 50 - ball_size or ball.y < ball_size:
if ball.y > 500 - ball_size or ball.y < ball_size:
我建议分别删除对 pygame.display.flip()
的多次调用 pygame.display.update()
。在主应用程序循环结束时只更新一次显示。查看完整示例:
# Importing libraries
import pygame
import random
import time
# Initializing PyGame
pygame.init()
# Creating a font
font = pygame.font.SysFont(None, 30)
# Set the height and width of the screen
window_width = 700
window_height = 500
size = [window_width, window_height]
game_win = pygame.display.set_mode(size)
# Creating a messaging system
def message(sentence, x, y):
sentence = font.render(sentence, True, white)
game_win.blit(sentence, [x, y])
# Creating a color
white = (225, 225, 225)
black = (0, 0, 0)
# Setting up ball
ball_size = 25
class Ball:
"""
Class to keep track of a ball's location and vector.
"""
def __init__(self):
self.x = 0
self.y = 0
self.change_x = 0
self.change_y = 0
def make_ball():
ball = Ball()
# Starting position of the ball.
# Take into account the ball size so we don't spawn on the edge.
ball.x = 350
ball.y = 250
# Speed and direction of rectangle
ball.change_x = 5
ball.change_y = 5
return ball
def main():
# Scores
left_score = 0
right_score = 0
pygame.init()
pygame.display.set_caption("Ping Pong")
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
ball_list = []
ball = make_ball()
ball_list.append(ball)
# Right paddle coordinates
y = 200
y_change = 0
x = 50
# Left paddle coordinates
y1 = 200
y1_change = 0
x1 = 650
while not done:
# --- Event Processing
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
y_change = -5
elif event.key == pygame.K_s:
y_change = 5
elif event.key == pygame.K_UP:
y1_change = -5
elif event.key == pygame.K_DOWN:
y1_change = 5
elif event.type == pygame.KEYUP:
y_change = 0
y1_change = 0
y += y_change
y1 += y1_change
if y > window_height - 100:
y -= 5
if y < 50:
y += 5
if y1 > window_height - 100:
y1 -= 5
if y1 < 50:
y1 += 5
message("Left player score: " + str(left_score), 10, 10)
message("Right player score: " + str(right_score), 490, 10)
# Logic
for ball in ball_list:
# Move the ball's center
ball.x += ball.change_x
ball.y += ball.change_y
# Bounce the ball if needed
if ball.y > 500 - ball_size or ball.y < ball_size:
ball.change_y *= -1
if ball.x > window_width - ball_size:
ball.change_x *= -1
left_score += 1
if ball.x < ball_size:
ball.change_x *= -1
right_score += 1
# Here is the part where it all becomes weird and buggy
ball_rect = pygame.Rect(ball.x-ball_size, ball.y-ball_size, ball_size*2, ball_size*2)
left_paddle_rect = pygame.Rect(x, y, 25, 75)
if ball.change_x < 0 and ball_rect.colliderect(left_paddle_rect):
ball.change_x = abs(ball.change_x)
right_paddle_rect = pygame.Rect(x1, y1, 25, 75)
if ball.change_x > 0 and ball_rect.colliderect(right_paddle_rect):
ball.change_x = -abs(ball.change_x)
if right_score == 10:
message('RIGHT PLAYER HAS WON!!', 300, 200)
time.sleep(10)
done = True
elif left_score == 10:
message("LEFT PLAYER HAS WON!!", 300, 200)
time.sleep(10)
done = True
# Drawing
# Set the screen background
game_win.fill(black)
# Drawing a left paddle
pygame.draw.rect(game_win, white, [x, y, 25, 100])
# Drawing a right paddle
pygame.draw.rect(game_win, white, [x1, y1, 25, 100])
# Draw the balls
for ball in ball_list:
pygame.draw.circle(game_win, white, [ball.x, ball.y], ball_size)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Wrap-up
# Limit to 60 frames per second
clock.tick(60)
# Close everything down
pygame.quit()
if __name__ == "__main__":
main()
我做了一个乒乓球游戏。现在的问题是,当我移动球拍时,球并没有越过球拍,而是在一些看不见的墙上弹跳。这是我的代码,你自己 运行 你可以看到问题所在(你必须稍微移动一下桨)
# Pong
# Importing libraries
import pygame
import random
import time
# Initializing PyGame
pygame.init()
# Creating a font
font = pygame.font.SysFont(None, 30)
# Set the height and width of the screen
window_width = 700
window_height = 500
size = [window_width, window_height]
game_win = pygame.display.set_mode(size)
# Creating a messaging system
def message(sentence, x, y):
sentence = font.render(sentence, True, white)
game_win.blit(sentence, [x, y])
# Creating a color
white = (225, 225, 225)
black = (0, 0, 0)
# Setting up ball
ball_size = 25
class Ball:
"""
Class to keep track of a ball's location and vector.
"""
def __init__(self):
self.x = 0
self.y = 0
self.change_x = 0
self.change_y = 0
def make_ball():
ball = Ball()
# Starting position of the ball.
# Take into account the ball size so we don't spawn on the edge.
ball.x = 350
ball.y = 250
# Speed and direction of rectangle
ball.change_x = 5
ball.change_y = 5
return ball
def main():
# Scores
left_score = 0
right_score = 0
pygame.init()
pygame.display.set_caption("Ping Pong")
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
ball_list = []
ball = make_ball()
ball_list.append(ball)
# Right paddle coordinates
y = 200
y_change = 0
x = 50
# Left paddle coordinates
y1 = 200
y1_change = 0
x1 = 650
while not done:
# --- Event Processing
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
y_change = -5
elif event.key == pygame.K_s:
y_change = 5
elif event.key == pygame.K_UP:
y1_change = -5
elif event.key == pygame.K_DOWN:
y1_change = 5
elif event.type == pygame.KEYUP:
y_change = 0
y1_change = 0
y += y_change
y1 += y1_change
if y > window_height - 100:
y -= 5
if y < 50:
y += 5
if y1 > window_height - 100:
y1 -= 5
if y1 < 50:
y1 += 5
message("Left player score: " + str(left_score), 10, 10)
message("Right player score: " + str(right_score), 490, 10)
# Drawing a left paddle
pygame.draw.rect(game_win, white, [x, y, 25, 100])
# Drawing a right paddle
pygame.draw.rect(game_win, white, [x1, y1, 25, 100])
# Updating screen to changes take place
pygame.display.update()
# Logic
for ball in ball_list:
# Move the ball's center
ball.x += ball.change_x
ball.y += ball.change_y
# Bounce the ball if needed
if ball.y > 50 - ball_size or ball.y < ball_size:
ball.change_y *= -1
if ball.x > window_width - ball_size:
ball.change_x *= -1
left_score += 1
if ball.x < ball_size:
ball.change_x *= -1
right_score += 1
# Here is the part where it all becomes weird and buggy
if ball.x-ball_size <= x <= ball.x + ball_size:
ball.change_x *= -1
if ball.x-ball_size <= x1 <= ball.x + ball_size:
ball.change_x *= -1
if ball.y-ball_size <= y <= ball.y + ball_size:
ball.change_x *= -1
if ball.y-ball_size <= y1 <= ball.y + ball_size:
ball.change_x *= -1
if right_score == 10:
message('RIGHT PLAYER HAS WON!!', 300, 200)
time.sleep(10)
done = True
elif left_score == 10:
message("LEFT PLAYER HAS WON!!", 300, 200)
time.sleep(10)
done = True
# Drawing
# Set the screen background
game_win.fill(black)
# Draw the balls
for ball in ball_list:
pygame.draw.circle(game_win, white, [ball.x, ball.y], ball_size)
# Wrap-up
# Limit to 60 frames per second
clock.tick(60)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Close everything down
pygame.quit()
if __name__ == "__main__":
main()
当我把球拍移开时,球仍然可以从一些看不见的墙上弹回来。其他的都很好,就是我放# Bounce if needed
.
我建议计算球和球拍的边界矩形,并使用 pygame.Rect
and colliderect()
检测球和球拍之间的碰撞。
另见
例如:
def main():
# [...]
while not done:
# [...]
# Logic
for ball in ball_list:
# [...]
ball_rect = pygame.Rect(ball.x-ball_size, ball.y-ball_size, ball_size*2, ball_size*2)
left_paddle_rect = pygame.Rect(x, y, 25, 75)
if ball.change_x < 0 and ball_rect.colliderect(left_paddle_rect):
ball.change_x = abs(ball.change_x)
right_paddle_rect = pygame.Rect(x1, y1, 25, 75)
if ball.change_x > 0 and ball_rect.colliderect(right_paddle_rect):
ball.change_x = -abs(ball.change_x)
此外,window 的高度是 500 而不是 50_
if ball.y > 50 - ball_size or ball.y < ball_size:
if ball.y > 500 - ball_size or ball.y < ball_size:
我建议分别删除对 pygame.display.flip()
的多次调用 pygame.display.update()
。在主应用程序循环结束时只更新一次显示。查看完整示例:
# Importing libraries
import pygame
import random
import time
# Initializing PyGame
pygame.init()
# Creating a font
font = pygame.font.SysFont(None, 30)
# Set the height and width of the screen
window_width = 700
window_height = 500
size = [window_width, window_height]
game_win = pygame.display.set_mode(size)
# Creating a messaging system
def message(sentence, x, y):
sentence = font.render(sentence, True, white)
game_win.blit(sentence, [x, y])
# Creating a color
white = (225, 225, 225)
black = (0, 0, 0)
# Setting up ball
ball_size = 25
class Ball:
"""
Class to keep track of a ball's location and vector.
"""
def __init__(self):
self.x = 0
self.y = 0
self.change_x = 0
self.change_y = 0
def make_ball():
ball = Ball()
# Starting position of the ball.
# Take into account the ball size so we don't spawn on the edge.
ball.x = 350
ball.y = 250
# Speed and direction of rectangle
ball.change_x = 5
ball.change_y = 5
return ball
def main():
# Scores
left_score = 0
right_score = 0
pygame.init()
pygame.display.set_caption("Ping Pong")
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
ball_list = []
ball = make_ball()
ball_list.append(ball)
# Right paddle coordinates
y = 200
y_change = 0
x = 50
# Left paddle coordinates
y1 = 200
y1_change = 0
x1 = 650
while not done:
# --- Event Processing
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
y_change = -5
elif event.key == pygame.K_s:
y_change = 5
elif event.key == pygame.K_UP:
y1_change = -5
elif event.key == pygame.K_DOWN:
y1_change = 5
elif event.type == pygame.KEYUP:
y_change = 0
y1_change = 0
y += y_change
y1 += y1_change
if y > window_height - 100:
y -= 5
if y < 50:
y += 5
if y1 > window_height - 100:
y1 -= 5
if y1 < 50:
y1 += 5
message("Left player score: " + str(left_score), 10, 10)
message("Right player score: " + str(right_score), 490, 10)
# Logic
for ball in ball_list:
# Move the ball's center
ball.x += ball.change_x
ball.y += ball.change_y
# Bounce the ball if needed
if ball.y > 500 - ball_size or ball.y < ball_size:
ball.change_y *= -1
if ball.x > window_width - ball_size:
ball.change_x *= -1
left_score += 1
if ball.x < ball_size:
ball.change_x *= -1
right_score += 1
# Here is the part where it all becomes weird and buggy
ball_rect = pygame.Rect(ball.x-ball_size, ball.y-ball_size, ball_size*2, ball_size*2)
left_paddle_rect = pygame.Rect(x, y, 25, 75)
if ball.change_x < 0 and ball_rect.colliderect(left_paddle_rect):
ball.change_x = abs(ball.change_x)
right_paddle_rect = pygame.Rect(x1, y1, 25, 75)
if ball.change_x > 0 and ball_rect.colliderect(right_paddle_rect):
ball.change_x = -abs(ball.change_x)
if right_score == 10:
message('RIGHT PLAYER HAS WON!!', 300, 200)
time.sleep(10)
done = True
elif left_score == 10:
message("LEFT PLAYER HAS WON!!", 300, 200)
time.sleep(10)
done = True
# Drawing
# Set the screen background
game_win.fill(black)
# Drawing a left paddle
pygame.draw.rect(game_win, white, [x, y, 25, 100])
# Drawing a right paddle
pygame.draw.rect(game_win, white, [x1, y1, 25, 100])
# Draw the balls
for ball in ball_list:
pygame.draw.circle(game_win, white, [ball.x, ball.y], ball_size)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Wrap-up
# Limit to 60 frames per second
clock.tick(60)
# Close everything down
pygame.quit()
if __name__ == "__main__":
main()