# coding=utf-8 import pygame import pygame.locals class Board(object): """ Plansza do gry. Odpowiada za rysowanie okna gry. """ def __init__(self, width, height): """ Konstruktor planszy do gry. Przygotowuje okienko gry. :param width: szerokoÅÄ w pikselach :param height: wysokoÅÄ w pikselach """ self.surface = pygame.display.set_mode((width, height), 0, 32) pygame.display.set_caption('Game of life') def draw(self, *args): """ Rysuje okno gry :param args: lista obiektów do narysowania """ background = (0, 0, 0) self.surface.fill(background) for drawable in args: drawable.draw_on(self.surface) # dopiero w tym miejscu nastÄpuje fatyczne rysowanie # w oknie gry, wczeÅniej tylko ustalaliÅmy co i jak ma zostaÄ narysowane pygame.display.update() class GameOfLife(object): """ ÅÄ czy wszystkie elementy gry w caÅoÅÄ. """ def __init__(self, width, height, cell_size=10): """ Przygotowanie ustawieÅ gry :param width: szerokoÅÄ planszy mierzona liczbÄ komórek :param height: wysokoÅÄ planszy mierzona liczbÄ komórek :param cell_size: bok komórki w pikselach """ pygame.init() self.board = Board(width * cell_size, height * cell_size) # zegar którego użyjemy do kontrolowania szybkoÅci rysowania # kolejnych klatek gry self.fps_clock = pygame.time.Clock() self.population = Population(width, height, cell_size) def run(self): """ GÅówna pÄtla gry """ while not self.handle_events(): # dziaÅaj w pÄtli do momentu otrzymania sygnaÅu do wyjÅcia self.board.draw( self.population, ) self.fps_clock.tick(15) def handle_events(self): """ ObsÅuga zdarzeÅ systemowych, tutaj zinterpretujemy np. ruchy myszkÄ :return True jeżeli pygame przekazaÅ zdarzenie wyjÅcia z gry """ for event in pygame.event.get(): if event.type == pygame.locals.QUIT: pygame.quit() return True from pygame.locals import MOUSEMOTION, MOUSEBUTTONDOWN if event.type == MOUSEMOTION or event.type == MOUSEBUTTONDOWN: self.population.handle_mouse() # magiczne liczby używane do okreÅlenia czy komórka jest żywa DEAD = 0 ALIVE = 1 class Population(object): """ Populacja komórek """ def __init__(self, width, height, cell_size=10): """ Przygotowuje ustawienia populacji :param width: szerokoÅÄ planszy mierzona liczbÄ komórek :param height: wysokoÅÄ planszy mierzona liczbÄ komórek :param cell_size: bok komórki w pikselach """ self.box_size = cell_size self.height = height self.width = width self.generation = self.reset_generation() def reset_generation(self): """ Tworzy i zwraca macierz pustej populacji """ # w pÄtli wypeÅnij listÄ kolumnami # które także w pÄtli zostajÄ wypeÅnione wartoÅciÄ 0 (DEAD) return [[DEAD for y in xrange(self.height)] for x in xrange(self.width)] def handle_mouse(self): # pobierz stan guzików myszki z wykorzystaniem funcji pygame buttons = pygame.mouse.get_pressed() if not any(buttons): # ignoruj zdarzenie jeÅli żaden z guzików nie jest wciÅniÄty return # dodaj żywÄ komórkÄ jeÅli wciÅniÄty jest pierwszy guzik myszki # bÄdziemy mogli nie tylko dodawaÄ Å¼ywe komórki ale także je usuwaÄ alive = True if buttons[0] else False # pobierz pozycjÄ kursora na planszy mierzonÄ w pikselach x, y = pygame.mouse.get_pos() # przeliczamy wspóÅrzÄdne komórki z pikseli na wspóÅrzÄdne komórki w macierz # gracz może kliknÄ Ä w kwadracie o szerokoÅci box_size by wybraÄ komórkÄ x /= self.box_size y /= self.box_size # ustaw stan komórki na macierzy self.generation[x][y] = ALIVE if alive else DEAD def draw_on(self, surface): """ Rysuje komórki na planszy """ for x, y in self.alive_cells(): size = (self.box_size, self.box_size) position = (x * self.box_size, y * self.box_size) color = (255, 255, 255) thickness = 1 pygame.draw.rect(surface, color, pygame.locals.Rect(position, size), thickness) def alive_cells(self): """ Generator zwracajÄ cy wspóÅrzÄdne żywych komórek. """ for x in range(len(self.generation)): column = self.generation[x] for y in range(len(column)): if column[y] == ALIVE: # jeÅli komórka jest żywa zwrócimy jej wspóÅrzÄdne yield x, y # Ta czÄÅÄ powinna byÄ zawsze na koÅcu moduÅu (ten plik jest moduÅem) # chcemy uruchomiÄ naszÄ grÄ dopiero po tym jak wszystkie klasy zostanÄ zadeklarowane if __name__ == "__main__": game = GameOfLife(80, 40) game.run()