Предыдущая статья — Введение в объектно-ориентированное программирование: создание среды для нашего объекта с Pygame.
Добро пожаловать в следующую часть нашей серии статей про объектно-ориентированное программирование. В этой статье мы собираемся изучить некоторые особенности использования нашего объекта.
Вот код на момент окончания прошлой статьи:
import pygame import random WIDTH = 800 HEIGHT = 600 WHITE = (255, 255, 255) BLUE = (0, 0, 255) RED = (255, 0, 0) game_display = pygame.display.set_mode((WIDTH,HEIGHT)) pygame.display.set_caption('Blob World') clock = pygame.time.Clock() class Blob: def __init__(self, color): self.x = random.randrange(0, WIDTH) self.y = random.randrange(0, HEIGHT) self.size = random.randrange(4,8) self.color = color def move(self): self.move_x = random.randrange(-1,2) self.move_y = random.randrange(-1,2) self.x += self.move_x self.y += self.move_y if self.x < 0: self.x = 0 elif self.x > WIDTH: self.x = WIDTH if self.y < 0: self.y = 0 elif self.y > HEIGHT: self.y = HEIGHT def draw_environment(blob): game_display.fill(WHITE) pygame.draw.circle(game_display, blob.color, [blob.x, blob.y], blob.size) pygame.display.update() blob.move() def main(): red_blob = Blob(RED) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() draw_environment(red_blob) clock.tick(60) if __name__ == '__main__': main()
Для начала мы возьмем наш обычный класс и проиллюстрируем, как можно быстро сгенерировать множество объектов данного класса. Сперва добавим несколько новых констант:
STARTING_BLUE_BLOBS = 10 STARTING_RED_BLOBS = 3
Далее давайте рассмотрим сценарий, в котором мы хотим добавить кучу синих клякс нашего класса Blob
. Мы можем пойти в нашу главную функцию и сделать что-то вроде этого:
def main(): blue_blobs = [Blob(BLUE) for i in range(STARTING_BLUE_BLOBS)]
Затем мы могли бы изменить функцию draw_environment
следующим образом:
def draw_environment(blobs): game_display.fill(WHITE) for blob in blobs: pygame.draw.circle(game_display, blob.color, [blob.x, blob.y], blob.size) blob.move() pygame.display.update()
Теперь у нас много танцующих синих клякс! Это отлично, но нам, видимо, нужен какой-то способ для отслеживания каждого такого двоичного объекта. Иначе мы не сможем узнать, кто есть кто. А в будущем мы можем захотеть узнавать кляксы по какому-то идентификатору или имени. Если бы только мы знали хороший способ создавать своего рода идентификатор через счетчик, а затем, возможно, сделать из него словарь … о да! Мы ведь знаем функцию enumerate
!
Итак, вернемся к нашей главной функции:
def main(): blue_blobs = dict(enumerate([Blob(BLUE) for i in range(STARTING_BLUE_BLOBS)]))
Теперь у нас есть словарь, где ключ — это идентификатор, а значение — это объект класса blob
. Раз уж мы здесь, добавим еще и несколько красных клякс (в переменную red_blobs
):
def main(): blue_blobs = dict(enumerate([Blob(BLUE) for i in range(STARTING_BLUE_BLOBS)])) red_blobs = dict(enumerate([Blob(RED) for i in range(STARTING_RED_BLOBS)]))
Теперь мы можем передать список этих словарей в нашу функцию draw_environments
, сделав это также в главной функции:
def main(): blue_blobs = dict(enumerate([Blob(BLUE) for i in range(STARTING_BLUE_BLOBS)])) red_blobs = dict(enumerate([Blob(RED) for i in range(STARTING_RED_BLOBS)])) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() draw_environment([blue_blobs,red_blobs]) clock.tick(60)
Сейчас наша функция draw_environments
имеет следующий вид:
def draw_environment(blob_list): game_display.fill(WHITE) for blob_dict in blob_list: for blob_id in blob_dict: blob = blob_dict[blob_id] pygame.draw.circle(game_display, blob.color, [blob.x, blob.y], blob.size) blob.move() pygame.display.update()
Итак, мы берем список словарей blow_dict
, в которых ключами являются идентификаторы (id), а значениями — сами объекты, и перебираем эти словари по их идентификаторам, рисуя и перемещая кляксы так же, как раньше.
Полный код на данный момент имеет следующий вид:
import pygame import random STARTING_BLUE_BLOBS = 10 STARTING_RED_BLOBS = 3 WIDTH = 800 HEIGHT = 600 WHITE = (255, 255, 255) BLUE = (0, 0, 255) RED = (255, 0, 0) game_display = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Blob World") clock = pygame.time.Clock() class Blob: def __init__(self, color): self.x = random.randrange(0, WIDTH) self.y = random.randrange(0, HEIGHT) self.size = random.randrange(4,8) self.color = color def move(self): self.move_x = random.randrange(-1,2) self.move_y = random.randrange(-1,2) self.x += self.move_x self.y += self.move_y if self.x < 0: self.x = 0 elif self.x > WIDTH: self.x = WIDTH if self.y < 0: self.y = 0 elif self.y > HEIGHT: self.y = HEIGHT def draw_environment(blob_list): game_display.fill(WHITE) for blob_dict in blob_list: for blob_id in blob_dict: blob = blob_dict[blob_id] pygame.draw.circle(game_display, blob.color, [blob.x, blob.y], blob.size) blob.move() pygame.display.update() def main(): blue_blobs = dict(enumerate([Blob(BLUE) for i in range(STARTING_BLUE_BLOBS)])) red_blobs = dict(enumerate([Blob(RED) for i in range(STARTING_RED_BLOBS)])) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() draw_environment([blue_blobs,red_blobs]) clock.tick(60) if __name__ == '__main__': main()
Мы взяли хороший старт, но у нас уже есть некоторые фундаментальные проблемы с этим кодом, которые мы обсудим в следующей статье!
Следующая статья — Введение в объектно-ориентированное программирование: класс Blob и модульность.