Pygame中Ship类设置midbottom属性后船对象未显示在屏幕底部中央问题求助
Problem Description
I'm working on a Pygame program where I've defined a Ship class to manage the player's ship. I expect the ship to start at the bottom center of the screen using self.rect.midbottom = self.screen_rect.midbottom, but every time I run the program, the ship (Rect object) appears at the bottom left corner instead.
Here's my relevant code (where ai_game is an instance of the main class):
import pygame class Ship: """A class to manage the ship.""" def __init__(self, ai_game): """Initialize the ship and see its starting position.""" self.screen = ai_game.screen self.screen_rect = ai_game.screen.get_rect() self.settings = ai_game.settings # Load the ship image and get its rect. self.image = pygame.image.load('images/ship.bmp') self.rect = self.image.get_rect() # Store a decimal value for the ship's horizontal position self.x = float(self.rect.x) # Start each ship at the bottom centre of the screen self.rect.midbottom = self.screen_rect.midbottom # Movement flag self.moving_right = False self.moving_left = False def update(self): """Update the ship's position based on movement flag.""" # Update the ship's x value and not the rect. if self.moving_right and self.rect.right < self.screen_rect.right: self.x += self.settings.ship_speed if self.moving_left and self.rect.left > 0: self.x -= self.settings.ship_speed # Update rect object from self.x self.rect.x = self.x def blitme(self): """Draw the ship at the current location.""" self.screen.blit(self.image, self.rect)
Solution
The root cause here is the order of variable initialization in your __init__ method. Let's break down why this is happening:
- When you first load the ship image and grab its rect (
self.rect = self.image.get_rect()), the rect starts at the default position(0, 0)—so its x-coordinate is 0. - You immediately assign
self.x = float(self.rect.x), lockingself.xto that initial 0 value. - Then you set
self.rect.midbottom = self.screen_rect.midbottom, which correctly moves the rect to the bottom center—butself.xdoesn't get updated to match this new position. - When the
update()method runs (even without any movement input), it overwritesself.rect.xwith the outdatedself.xvalue (0), yanking the ship back to the bottom left.
To fix this, just reorder the lines so you assign self.x after setting the ship's initial centered position:
# Start each ship at the bottom centre of the screen self.rect.midbottom = self.screen_rect.midbottom # Store a decimal value for the ship's horizontal position (now uses the correct midbottom x) self.x = float(self.rect.x)
Now self.x captures the correct x-coordinate of the centered ship, and the update() method will maintain that position until movement flags are triggered.
Quick Additional Checks
If the issue persists after this fix, verify these two things:
- Your ship image (
images/ship.bmp) doesn't have an unexpected transparent border that might make the rect appear misaligned. Test this by drawing a solid colored rectangle in place of the image to confirm the rect's position. - The
ai_game.screenis initialized correctly in your main class (e.g., you're using the intended screen dimensions).
内容的提问来源于stack exchange,提问作者user16622998

