Search code examples
python-3.xpygamepython-3.8game-developmentrect

hey,I coudn't use the midbottom function in my pygame program. Every time I run my program I get to see my rect object on the bottom left


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)

This is the code where ai_game is the instance from the main class. everytime I run my code I see my rect object on the bottom left corner of the screen ,whereas the midbottom function should have placed my rect object (i.e the ship here) on the midbottom portion of the screen


Solution

  • It is not sufficient to set self.rect.midbottom = self.screen_rect.midbottom. You also need to set self.x with self.screen_rect.centerx

    self.rect.midbottom = self.screen_rect.midbottom
    self.x = self.screen_rect.centerx
    

    Note that in the update method, self.rect.x is set by self.x. Therefore the self.x attribute needs to be initialized correctly

    If you don't need the floating point accuracy you can completely remove the self.x attribute and use slef.rect.centerx instead.

    Class Ship:

    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()
    
            # 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.centerx += self.settings.ship_speed
            if self.moving_left and self.rect.left > 0:
                self.centerx -= self.settings.ship_speed
    
        def blitme(self):
            """Draw the ship at the current location."""
            self.screen.blit(self.image, self.rect)