Не получается переместить изображение в правую часть экрана в Pygame

Рейтинг: -2Ответов: 1Опубликовано: 17.07.2023

Всем доброго времени суток!

Я новичок в Python, познаю азы по учебнику Эрика Мэтиза. Сейчас делаю один из проектов учебника - "Alien Invasion". В конце каждого раздела есть контрольные задания. Столкнулся с проблемой в задании 13.1. Звезды: найдите изображение звезды. Создайте на экране сетку из звезд.

Решил выполнить задание по своему. Я отталкиваюсь от задания 12.6. Боковая стрельба: напишите игру, в которой корабль размещается у левого края экрана, а игрок может перемещать корабль вверх и вниз. При нажатии клавиши «пробел» корабль стреляет и снаряд двигается вправо по экрану. Проследите за тем, чтобы снаряды удалялись при выходе за край экрана.

У меня не получается разместить противника у правого края экрана, получается следующее: введите сюда описание изображения

Код: test_dino.py

import sys
import pygame

from settings1 import Settings
from ship1 import Ship
from bullets1 import Bullet
from cactus import Cactus

class Dino():
    """Класс для управления ресурсами и поведением игры."""
    def __init__(self):
        """Инициализирует игру и создает игровые ресурсы."""
        pygame.init()
        self.settings  = Settings()

        """это экран игры"""
        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height
        pygame.display.set_caption("Dino on fire!")

        self.ship = Ship(self.screen)
        self.bullets = pygame.sprite.Group()
        self.cactus = pygame.sprite.Group()

        self._create_fleet()
        
    def run_game(self):
        """Основной цикл игры."""
        while True:
            self._check_events()
            self.ship.update()
            self._update_bullets()
            self._update_screen()

    
    def _check_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self, event):
        """Реагирует на нажатие клавиш."""
        if event.key == pygame.K_UP:
            self.ship.moving_top = True
        elif event.key == pygame.K_DOWN:
            self.ship.moving_bottom = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()
    
    def _check_keyup_events(self, event):
        """Реагирует на отпускание клавиш."""
        if event.key == pygame.K_UP:
            self.ship.moving_top = False
        elif event.key == pygame.K_DOWN:
            self.ship.moving_bottom = False

    def _fire_bullet(self):
        """Создание нового снаряда и включение его в группу bullets."""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """Обновляет позиции снарядов и уничтожает старые снаряды."""
        # Обновление позиций снарядов.
        self.bullets.update()

        # Удаление снарядов, вышедших за край экрана.
        for bullet in self.bullets.copy():
            if bullet.rect.right > 1400:
                self.bullets.remove(bullet)

    def _create_fleet(self):
        """Создает флот cactus."""
        # Создание cactus и вычисление количества cactus в ряду.
        # Интервал между соседними пришельцами равен ширине пришельца.
        cactus = Cactus(self)
        cactus_width, cactus_height = cactus.rect.size
        available_space_x = self.settings.screen_width - (2 * cactus_width)
        number_cactus_x = available_space_x // (2 * cactus_width)

        """Определяет количество рядов, помещающихся на экране."""
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height -
                                (3 * cactus_height) - ship_height)
        number_rows = available_space_y // (2 * cactus_height)

        # Создание подразделения ЧВК Кактус
        for row_number in range(number_rows):
            for cactus_number in range(number_cactus_x):
                self._create_cactus(cactus_number, row_number)

    def _create_cactus(self, cactus_number, row_number):
        """Создание cactus и размещение его в ряду."""
        cactus = Cactus(self)
        cactus_width, cactus_height = cactus.rect.size
        cactus_height = cactus.rect.width
        cactus.y = cactus_width + 2 * cactus_height * cactus_number
        cactus.rect.y = cactus.y
        cactus.rect.x = cactus.rect.height + 2 * cactus.rect.height * row_number
        self.cactus.add(cactus)

    def _update_screen(self):
        """Обновление экрана."""
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.cactus.draw(self.screen)

        # Отображение последнего прорисованного экрана.   
        pygame.display.flip()

if __name__ == "__main__":
    td = Dino()
    td.run_game()

Модуль cactus.py:

import pygame
from pygame.sprite import Sprite

class Cactus(Sprite):
    """Класс, представляющий один кактус."""
    
    def __init__(self, td_game):
        """Инициализирует кактус и задает его начальную позицию."""
        super().__init__()
        self.screen = td_game.screen
        
        # Загрузка изображения cactus и назначение атрибута rect.
        self.image = pygame.image.load('images/cactus.bmp')
        self.rect = self.image.get_rect()

        # Каждый новый кактус появляется в правом верхнем углу экрана.
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        # Сохранение точной вертикальной позиции пришельца.
        self.y = float(self.rect.y)

Полагаю, что размещать остальные модули смысла нет, так как проблема именно в cactus.py. Вероятно, необходимо что-то сделать с self.rect.x = self.rect.width, self.rect.y = self.rect.height. Однако, все опробованные варианты не помогли, сломаю голову уже двое суток. Прошу подсказать, как возможно сместить ряды кактусов в правую часть поля. Заранее спасибо! Прошу не судить строго, тяжело дается работа с Pygame.

Ответы

▲ 0Принят

Чтобы переместить изображение в правую часть экрана в Pygame, вам нужно изменить координату x объекта Cactus. В вашем коде, вы задаете начальную позицию кактуса с помощью следующих строк:

self.rect.x = self.rect.width
self.rect.y = self.rect.height

Чтобы переместить кактус в правую часть экрана, вам нужно изменить значение self.rect.x. Вместо self.rect.width, вы должны использовать self.settings.screen_width - self.rect.width. Таким образом, ваш код будет выглядеть следующим образом:

self.rect.x = self.settings.screen_width - self.rect.width
self.rect.y = self.rect.height

Теперь ваш кактус будет размещен у правого края экрана. Если вы хотите разместить весь флот кактусов у правого края экрана, вам нужно изменить функцию _create_cactus в вашем классе Dino. Вместо:

cactus.rect.x = cactus.rect.height + 2 * cactus.rect.height * row_number

Используйте следующий код:

cactus.rect.x = self.settings.screen_width - (cactus.rect.height + 2 * cactus.rect.height * row_number)

Теперь весь флот кактусов будет размещен у правого края экрана. Удачи вам в изучении Pygame и программировании! Если у вас возникнут еще вопросы, не стесняйтесь обращаться.