Pygame乒乓球游戏:球无法移动的问题排查与修复
Hey there! Let's break down why your ball isn't moving and fix it properly.
The Root Problem
Right now, you're updating self.ball_x and self.ball_y in the move_ball method, but the self.ball_draw Rect (the object that gets drawn and used for collision checks) isn't being updated to match those new coordinates. That's why the ball stays stuck—you're moving variables that aren't tied to the visible Rect!
When you moved ball_draw = pygame.Rect(...) into draw_ball, you created a new Rect each frame using the updated ball_x/ball_y, so the ball moved. But since that Rect was a local variable inside draw_ball, your wallCollision method couldn't access it for collision checks.
Solution 1: Sync the Rect with Your Position Variables
The simplest quick fix is to update self.ball_draw's position every time you modify ball_x and ball_y. Just add two lines to your move_ball method:
def move_ball(self): self.ball_x += self.ball_speed_x self.ball_y += self.ball_speed_y # Update the Rect's position to match the new coordinates self.ball_draw.x = self.ball_x self.ball_draw.y = self.ball_y
This way, self.ball_draw always reflects the current position of the ball, so both drawing and collision checks work as expected.
Solution 2: Use the Rect Directly (Recommended)
Even better, you can eliminate the separate ball_x and ball_y variables entirely. PyGame's Rect objects have their own x and y properties, so you can use those directly to track position. This removes the need to sync variables and makes your code cleaner:
class BALL: def __init__(self): self.ball_width = 30 self.ball_height = 30 self.ball_speed_x = 7 self.ball_speed_y = 7 # Initialize the Rect with starting position self.ball_draw = pygame.Rect( screen_width/2 - self.ball_width, screen_height/2 - self.ball_height, self.ball_width, self.ball_height ) def draw_ball(self): pygame.draw.ellipse(screen, lightGrey, self.ball_draw) def move_ball(self): # Move the Rect directly instead of separate variables self.ball_draw.x += self.ball_speed_x self.ball_draw.y += self.ball_speed_y def wallCollision(self): # This method already uses self.ball_draw, no changes needed! if self.ball_draw.bottom >= screen_height: self.ball_speed_y *= -1 if self.ball_draw.top <= 0: self.ball_speed_y *= -1 if self.ball_draw.left <= 0: self.ball_speed_x *= -1 if self.ball_draw.right >= screen_width: self.ball_speed_x *= -1
With this approach, every time you move the ball, you're updating the actual Rect that's used for drawing and collisions—no syncing required!
Quick Heads-Up for Your Player Class
You might run into a similar issue with your PLAYER1 class later. Right now, you're creating a local player1_draw Rect inside draw_player1, but your move_player1 updates self.player1_y. If you ever need collision checks for the player, you'll want to make player1_draw a class attribute (like we did with the ball) so other methods can access it.
内容的提问来源于stack exchange,提问作者user14780960

