问题
can anyone help me with this? i am having trouble making a simple way to detect if a ball hits a paddle and then bounce it by changing the rect_change_y variable. here is code that works but the ball does not interact with paddle or die when it hits the bottom of the game.
import pygame
black = ( 0, 0, 0)
white = ( 255, 255, 255)
green = ( 0, 255, 0)
red = ( 255, 0, 0)
rect_x = 10
rect_y = 250
pad_x = 350
pad_y = 480
ball = 3
rect_change_x = 1
rect_change_y = 1
pad_x_c = 0
pygame.init()
size=[700,500]
screen=pygame.display.set_mode(size)
pygame.mouse.set_visible(0)
pygame.display.set_caption("Breakout Recreation WIP")
done=False
clock=pygame.time.Clock()
# -------- Main Program Loop -----------
while ball != 0:
# ALL EVENT PROCESSING SHOULD GO BELOW THIS COMMENT
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
keys = pygame.key.get_pressed() #checking pressed keys
if keys[pygame.K_LEFT]:
pad_x_c -= 2
elif keys[pygame.K_RIGHT]:
pad_x_c += 2
else :
pad_x_c = 0
# ALL EVENT PROCESSING SHOULD GO ABOVE THIS COMMENT
# ALL GAME LOGIC SHOULD GO BELOW THIS COMMENT
# ALL GAME LOGIC SHOULD GO ABOVE THIS COMMENT
# ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
# First, clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
screen.fill(black)
# Draw the rectangle
pygame.draw.rect(screen,white,[rect_x,rect_y,15,15])
pygame.draw.rect(screen,white,[pad_x,pad_y,50,10])
# Move the rectangle starting point
rect_x += rect_change_x
rect_y += rect_change_y
pad_x += pad_x_c
# Bounce the ball if needed
if rect_y > 480 or rect_y < 10:
rect_change_y = rect_change_y * -1
if rect_x > 680 or rect_x < 5:
rect_change_x = rect_change_x * -1
if pad_x <= 5 :
pad_x_c = 0
if pad_x >= 645 :
pad_x_c = 0
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
pygame.display.flip()
clock.tick(100)
pygame.quit ()
and then here is code that should work (to me) but doesnt.
import pygame
black = ( 0, 0, 0)
white = ( 255, 255, 255)
green = ( 0, 255, 0)
red = ( 255, 0, 0)
rect_x = 10
rect_y = 250
pad_x = 350
pad_y = 480
ball = 3
rect_change_x = 1
rect_change_y = 1
pad_x_c = 0
pygame.init()
size=[700,500]
screen=pygame.display.set_mode(size)
pygame.mouse.set_visible(0)
pygame.display.set_caption("Breakout Recreation WIP")
done=False
clock=pygame.time.Clock()
# -------- Main Program Loop -----------
while ball != 0:
# ALL EVENT PROCESSING SHOULD GO BELOW THIS COMMENT
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
keys = pygame.key.get_pressed() #checking pressed keys
if keys[pygame.K_LEFT]:
pad_x_c -= 2
elif keys[pygame.K_RIGHT]:
pad_x_c += 2
else :
pad_x_c = 0
# ALL EVENT PROCESSING SHOULD GO ABOVE THIS COMMENT
# ALL GAME LOGIC SHOULD GO BELOW THIS COMMENT
# ALL GAME LOGIC SHOULD GO ABOVE THIS COMMENT
# ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
# First, clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
screen.fill(black)
# Draw the rectangle
pygame.draw.rect(screen,white,[rect_x,rect_y,15,15])
pygame.draw.rect(screen,white,[pad_x,pad_y,50,10])
# Move the rectangle starting point
rect_x += rect_change_x
rect_y += rect_change_y
pad_x += pad_x_c
# Bounce the ball if needed
if rect_y == pad_y:
if rect_x == pad_x:
rect_change_y = rect_change_y * -1
if rect_y > 490:
ball -= 1
rect_y = 250
rect_x = 10
rect_change_x = 1
rect_change_y = 1
if rect_y < 10:
rect_change_y = rect_change_y * -1
if rect_x > 680 or rect_x < 5:
rect_change_x = rect_change_x * -1
if pad_x <= 5 :
pad_x_c = 0
if pad_x >= 645 :
pad_x_c = 0
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
pygame.display.flip()
clock.tick(100)
pygame.quit ()
finally, any suggestions on how to make the blocks and do the same thing to them, except destroying them instead of the ball?
Thanks Everyone!
回答1:
You can use the Rect
class to represent the ball and the paddle, and also take advantage of the methods this class provides:
Rect.move_ip to move the rectangles in place:
myrect = pygame.Rect(0, 0, 10, 10) myrect.move_ip(100, 50)
myrect top left corner is at (100, 50) and keeps the same width and height.
Rect.clamp_ip to ensure the rectangles are both inside the screen.
myrect = pygame.Rect(100, 0, 10, 10) bounds = pygame.Rect(0, 0, 50, 50) myrect.clamp_ip(bounds)
myrect top left corner is at (40, 0) and its bottom right corner at (10, 50), inside bounds rectangle.
Rect.colliderect to check if the ball and the paddle collide.
myrect = pygame.Rect(0, 0, 10, 10) another = pygame.Rect(5, 5, 10, 10) print(myrect.colliderect(another)) # 1
Since myrect and another overlap, when you call
colliderect
it returns 1, indicating that there is a collision between the two rectangles.
I really like Pygame, so I don't mind to rewrite your program applying these suggestions. Hope it helps:
import pygame
# Constants
WIDTH = 700
HEIGHT = 500
SCREEN_AREA = pygame.Rect(0, 0, WIDTH, HEIGHT)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
# Initialization
pygame.init()
screen = pygame.display.set_mode([WIDTH, HEIGHT])
pygame.mouse.set_visible(0)
pygame.display.set_caption("Breakout Recreation WIP")
clock = pygame.time.Clock()
# Variables
paddle = pygame.Rect(350, 480, 50, 10)
ball = pygame.Rect(10, 250, 15, 15)
paddle_movement_x = 0
ball_direction = (1, 1)
balls = 3
done = False
while not done and balls > 0:
# Process events
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
paddle_movement_x = -2
elif keys[pygame.K_RIGHT]:
paddle_movement_x = 2
else:
paddle_movement_x = 0
# Move paddle
paddle.move_ip(paddle_movement_x, 0)
paddle.clamp_ip(SCREEN_AREA)
# Move ball
ball.move_ip(*ball_direction)
if ball.right > WIDTH or ball.left < 0:
ball_direction = -ball_direction[0], ball_direction[1]
elif ball.top < 0 or ball.bottom > HEIGHT or paddle.colliderect(ball):
ball_direction = ball_direction[0], -ball_direction[1]
ball.clamp_ip(SCREEN_AREA)
# Redraw screen
screen.fill(BLACK)
pygame.draw.rect(screen, WHITE, paddle)
pygame.draw.rect(screen, WHITE, ball)
pygame.display.flip()
clock.tick(100)
pygame.quit()
来源:https://stackoverflow.com/questions/15863858/how-to-make-the-ball-bounce-only-if-it-hits-the-paddle-in-python-pygame-breako