diff --git a/ten_drops/__init__.py b/ten_drops/__init__.py index a5694c2..653e1a5 100644 --- a/ten_drops/__init__.py +++ b/ten_drops/__init__.py @@ -21,7 +21,7 @@ "TEXT_FONT_PATH", "BREAK_SOUND", "GROW_SOUND", - "HP_SOUND" + "HP_SOUND", ] pygame.init() @@ -70,18 +70,41 @@ def get_drop_images() -> List[Status]: drop_image_paths = [join(drop_image_path, f"{i}.png") for i in range(134)] drop_images = [image.load(i).convert_alpha() for i in drop_image_paths] - _ = [i.fill(pygame.Color("blue"), special_flags=pygame.BLEND_ADD) for i in drop_images] + _ = [ + i.fill(pygame.Color("blue"), special_flags=pygame.BLEND_ADD) + for i in drop_images + ] max_length = max(max(i.get_size()) for i in drop_images[:130]) radio = PLAYGROUND_LENGTH / GRID_SIZE / max_length - drop_images = [smoothscale(i, (i.get_width() * radio, - i.get_height() * radio)) for i in drop_images] - - return [Status(action=drop_images[0:20], change_action=drop_images[25:31], static=drop_images[19]), - Status(action=drop_images[48:66], change_action=drop_images[69:76], static=drop_images[60]), - Status(action=drop_images[76:90], change_action=drop_images[108:115], static=drop_images[85]), - Status(action=drop_images[115:130], change_action=drop_images[130:134], static=drop_images[126])] + drop_images = [ + smoothscale(i, (i.get_width() * radio, i.get_height() * radio)) + for i in drop_images + ] + + return [ + Status( + action=drop_images[0:20], + change_action=drop_images[25:31], + static=drop_images[19], + ), + Status( + action=drop_images[48:66], + change_action=drop_images[69:76], + static=drop_images[60], + ), + Status( + action=drop_images[76:90], + change_action=drop_images[108:115], + static=drop_images[85], + ), + Status( + action=drop_images[115:130], + change_action=drop_images[130:134], + static=drop_images[126], + ), + ] def get_droplet_images() -> List[Status]: @@ -89,16 +112,29 @@ def get_droplet_images() -> List[Status]: droplet_image_paths = [join(droplet_image_path, f"{i}.png") for i in range(7)] droplet_images = [image.load(i).convert_alpha() for i in droplet_image_paths] - _ = [i.fill(pygame.Color("blue"), special_flags=pygame.BLEND_ADD) for i in droplet_images] + _ = [ + i.fill(pygame.Color("blue"), special_flags=pygame.BLEND_ADD) + for i in droplet_images + ] max_length = max(max(i.get_size()) for i in droplet_images[:3]) - radio = PLAYGROUND_LENGTH / GRID_SIZE / max_length / 3 # droplet is 3 times smaller than a drop + radio = ( + PLAYGROUND_LENGTH / GRID_SIZE / max_length / 3 + ) # droplet is 3 times smaller than a drop - droplet_images = [smoothscale(i, (i.get_width() * radio, - i.get_height() * radio)) for i in droplet_images] + droplet_images = [ + smoothscale(i, (i.get_width() * radio, i.get_height() * radio)) + for i in droplet_images + ] - return [Status(action=droplet_images[:3], change_action=droplet_images[3:], static=droplet_images[1])] + return [ + Status( + action=droplet_images[:3], + change_action=droplet_images[3:], + static=droplet_images[1], + ) + ] SCREEN = pygame.display.set_mode((800, 600)) @@ -107,11 +143,15 @@ def get_droplet_images() -> List[Status]: FONT_PATH = join(Path, "asset", "font", "kust.ttf") TEXT_FONT_PATH = join(Path, "asset", "font", "FiraCode-Regular.ttf") -BACKGROUND = smoothscale(image.load(join(ImageFolderPath, "background.png")), - (SCREEN.get_width(), SCREEN.get_height())) +BACKGROUND = smoothscale( + image.load(join(ImageFolderPath, "background.png")), + (SCREEN.get_width(), SCREEN.get_height()), +) -NOTIFICATION = smoothscale(image.load(join(ImageFolderPath, "notification.png")), - (SCREEN.get_width() / 1.5, SCREEN.get_height() / 1.5)) +NOTIFICATION = smoothscale( + image.load(join(ImageFolderPath, "notification.png")), + (SCREEN.get_width() / 1.5, SCREEN.get_height() / 1.5), +) PLAYGROUND = BACKGROUND.copy() diff --git a/ten_drops/cover.py b/ten_drops/cover.py index 8608f88..492ef8d 100644 --- a/ten_drops/cover.py +++ b/ten_drops/cover.py @@ -18,11 +18,17 @@ def _update_image(self): cover_surface.fill((255, 255, 255, 30)) title_image = self.TitleFont.render("ten drops", True, (51, 255, 255)) - cover_surface.blit(title_image, ((width - title_image.get_width()) / 2, height / 10)) + cover_surface.blit( + title_image, ((width - title_image.get_width()) / 2, height / 10) + ) - text_image = self.TextFont.render("A ten drops game written in pygame.", True, (32, 32, 32)) + text_image = self.TextFont.render( + "A ten drops game written in pygame.", True, (32, 32, 32) + ) - cover_surface.blit(text_image, ((width - text_image.get_width()) / 2, height / 3)) + cover_surface.blit( + text_image, ((width - text_image.get_width()) / 2, height / 3) + ) self.image = cover_surface self.rect = self.image.get_rect() diff --git a/ten_drops/drop.py b/ten_drops/drop.py index a78ba8b..e0e1931 100644 --- a/ten_drops/drop.py +++ b/ten_drops/drop.py @@ -1,7 +1,13 @@ import pygame from pygame.sprite import Sprite -from ten_drops import DROP_IMAGES, GRID_SIZE, PLAYGROUND_OFFSET, PLAYGROUND_LENGTH, GROW_SOUND +from ten_drops import ( + DROP_IMAGES, + GRID_SIZE, + PLAYGROUND_OFFSET, + PLAYGROUND_LENGTH, + GROW_SOUND, +) class ActionType: @@ -24,10 +30,18 @@ def __init__(self, row, col, state=0, *groups): def _update_image(self, image): self.image = image rect = self.image.get_rect() - rect.x = self.col * (PLAYGROUND_LENGTH // GRID_SIZE) + ( - PLAYGROUND_LENGTH // GRID_SIZE // 2) - rect.width // 2 + PLAYGROUND_OFFSET - rect.y = self.row * (PLAYGROUND_LENGTH // GRID_SIZE) + ( - PLAYGROUND_LENGTH // GRID_SIZE // 2) - rect.height // 2 + PLAYGROUND_OFFSET + rect.x = ( + self.col * (PLAYGROUND_LENGTH // GRID_SIZE) + + (PLAYGROUND_LENGTH // GRID_SIZE // 2) + - rect.width // 2 + + PLAYGROUND_OFFSET + ) + rect.y = ( + self.row * (PLAYGROUND_LENGTH // GRID_SIZE) + + (PLAYGROUND_LENGTH // GRID_SIZE // 2) + - rect.height // 2 + + PLAYGROUND_OFFSET + ) self.rect = rect def click(self): @@ -74,7 +88,9 @@ def update(self): elif self.action_type == ActionType.change: all_count = len(DROP_IMAGES[self.state - 1].change_action) if self.action_count < all_count: - self._update_image(DROP_IMAGES[self.state - 1].change_action[self.action_count]) + self._update_image( + DROP_IMAGES[self.state - 1].change_action[self.action_count] + ) self.action_count += 1 else: self.action_count = 0 @@ -92,11 +108,24 @@ def __init__(self, row, col, *groups): super().__init__(*groups) self.row = row self.col = col - self.image = pygame.Surface(((PLAYGROUND_LENGTH // GRID_SIZE // 2), (PLAYGROUND_LENGTH // GRID_SIZE // 2)), - pygame.SRCALPHA) + self.image = pygame.Surface( + ( + (PLAYGROUND_LENGTH // GRID_SIZE // 2), + (PLAYGROUND_LENGTH // GRID_SIZE // 2), + ), + pygame.SRCALPHA, + ) rect = self.image.get_rect() - rect.x = self.col * (PLAYGROUND_LENGTH // GRID_SIZE) + ( - PLAYGROUND_LENGTH // GRID_SIZE // 2) - rect.width // 2 + PLAYGROUND_OFFSET - rect.y = self.row * (PLAYGROUND_LENGTH // GRID_SIZE) + ( - PLAYGROUND_LENGTH // GRID_SIZE // 2) - rect.height // 2 + PLAYGROUND_OFFSET + rect.x = ( + self.col * (PLAYGROUND_LENGTH // GRID_SIZE) + + (PLAYGROUND_LENGTH // GRID_SIZE // 2) + - rect.width // 2 + + PLAYGROUND_OFFSET + ) + rect.y = ( + self.row * (PLAYGROUND_LENGTH // GRID_SIZE) + + (PLAYGROUND_LENGTH // GRID_SIZE // 2) + - rect.height // 2 + + PLAYGROUND_OFFSET + ) self.rect = rect diff --git a/ten_drops/droplet.py b/ten_drops/droplet.py index 353fa2b..53c377a 100644 --- a/ten_drops/droplet.py +++ b/ten_drops/droplet.py @@ -34,20 +34,32 @@ def _update_image(self, image): rect = image.get_rect() - rect.x = self.col * (PLAYGROUND_LENGTH // GRID_SIZE) + ( - PLAYGROUND_LENGTH // GRID_SIZE // 2) - rect.width // 2 + PLAYGROUND_OFFSET - rect.y = self.row * (PLAYGROUND_LENGTH // GRID_SIZE) + ( - PLAYGROUND_LENGTH // GRID_SIZE // 2) - rect.height // 2 + PLAYGROUND_OFFSET + rect.x = ( + self.col * (PLAYGROUND_LENGTH // GRID_SIZE) + + (PLAYGROUND_LENGTH // GRID_SIZE // 2) + - rect.width // 2 + + PLAYGROUND_OFFSET + ) + rect.y = ( + self.row * (PLAYGROUND_LENGTH // GRID_SIZE) + + (PLAYGROUND_LENGTH // GRID_SIZE // 2) + - rect.height // 2 + + PLAYGROUND_OFFSET + ) self.rect = rect def update(self): self.row += self.direction[0] * self.speed self.col += self.direction[1] * self.speed - if any([self.row < -0.5, + if any( + [ + self.row < -0.5, self.col < -0.5, self.row > GRID_SIZE - 0.5, - self.col > GRID_SIZE - 0.5]): + self.col > GRID_SIZE - 0.5, + ] + ): # The actual animation is offset by half a grid cell self.kill() return @@ -58,6 +70,11 @@ def update(self): def diffusion(cls, row, col, *group) -> List["Droplet"]: BREAK_SOUND.play() droplets = [] - for direction in [Direction.Down, Direction.Up, Direction.Left, Direction.Right]: + for direction in [ + Direction.Down, + Direction.Up, + Direction.Left, + Direction.Right, + ]: droplets.append(Droplet(row, col, direction, *group)) return droplets diff --git a/ten_drops/game.py b/ten_drops/game.py index 1c3ceab..e334e80 100644 --- a/ten_drops/game.py +++ b/ten_drops/game.py @@ -1,12 +1,19 @@ import random -from collections import namedtuple - import pygame -from pygame import Rect + +from collections import namedtuple from pygame.sprite import Group, groupcollide, GroupSingle -from ten_drops import SCREEN, PLAYGROUND, BACKGROUND, GRID_SIZE, PLAYGROUND_OFFSET, PLAYGROUND_LENGTH, HP_SOUND, \ - GROW_SOUND +from ten_drops import ( + SCREEN, + PLAYGROUND, + BACKGROUND, + GRID_SIZE, + PLAYGROUND_OFFSET, + PLAYGROUND_LENGTH, + HP_SOUND, + GROW_SOUND, +) from ten_drops.button import StartButton, AboutButton, ExitButton from ten_drops.cover import Cover from ten_drops.drop import Drop, DummyDrop @@ -15,15 +22,17 @@ from ten_drops.panel import Level, Score, HP LevelDesign = namedtuple("LevelDesign", "state0, state1, state2, state3") -Levels = [LevelDesign(2, 5, 8, 9), - LevelDesign(2, 6, 7, 8), - LevelDesign(3, 7, 7, 7), - LevelDesign(3, 7, 6, 6), - LevelDesign(4, 7, 6, 5), - LevelDesign(4, 8, 6, 5), - LevelDesign(4, 8, 5, 5), - LevelDesign(5, 9, 3, 5), - LevelDesign(6, 9, 4, 5)] +Levels = [ + LevelDesign(2, 5, 8, 9), + LevelDesign(2, 6, 7, 8), + LevelDesign(3, 7, 7, 7), + LevelDesign(3, 7, 6, 6), + LevelDesign(4, 7, 6, 5), + LevelDesign(4, 8, 6, 5), + LevelDesign(4, 8, 5, 5), + LevelDesign(5, 9, 3, 5), + LevelDesign(6, 9, 4, 5), +] class Game: @@ -92,11 +101,13 @@ def notify(self, _type): elif _type == NoticeType.failed: text = f"You Lost\nYour Score: {self.score}" else: - text = ("The game and water drop assets are \n" - "from the Flash game \"Splash Back\".\n" - "\n\n\nAuthor: chyok\n" - "Email : chyok@hotmail.com\nGithub: https://github.com/chyok\n" - "\nImplemented using pygame-ce.") + text = ( + "The game and water drop assets are \n" + 'from the Flash game "Splash Back".\n' + "\n\n\nAuthor: chyok\n" + "Email : chyok@hotmail.com\nGithub: https://github.com/chyok\n" + "\nImplemented using pygame-ce." + ) Notice(_type, text, self.notifications) @@ -106,7 +117,7 @@ def start(self): self._init_panel() self._init_dummy_drops() - last_hover_rect = Rect(0, 0, 0, 0) + last_hover_rect = pygame.Rect(0, 0, 0, 0) while self.run: self.clock.tick(30) @@ -124,7 +135,10 @@ def start(self): continue for i in self.drops: - if i.rect.collidepoint(mouse_x, mouse_y) and len(self.droplets) == 0: + if ( + i.rect.collidepoint(mouse_x, mouse_y) + and len(self.droplets) == 0 + ): self.combo = 1 i.click() self.hp = self.hp - 1 @@ -135,7 +149,9 @@ def start(self): if len(self.droplets) == 0 and self.start_game: for j in self.dummy_drops: if j.rect.collidepoint(mouse_x, mouse_y): - if (j.row, j.col) not in ((i.row, i.col) for i in self.drops): + if (j.row, j.col) not in ( + (i.row, i.col) for i in self.drops + ): GROW_SOUND.play() Drop(j.row, j.col, 0, self.drops) self.hp -= 1 @@ -159,11 +175,12 @@ def start(self): mouse_x, mouse_y = pygame.mouse.get_pos() if not last_hover_rect.collidepoint(mouse_x, mouse_y): - last_hover_rect = Rect(0, 0, 0, 0) + last_hover_rect = pygame.Rect(0, 0, 0, 0) for i in self.drops: - if i.rect.collidepoint(mouse_x, mouse_y) and not last_hover_rect.collidepoint(mouse_x, - mouse_y): + if i.rect.collidepoint( + mouse_x, mouse_y + ) and not last_hover_rect.collidepoint(mouse_x, mouse_y): i.mouse_hover() last_hover_rect = i.rect break @@ -184,16 +201,32 @@ def start(self): pygame.display.update() continue - SCREEN.blit(PLAYGROUND, (PLAYGROUND_OFFSET, PLAYGROUND_OFFSET), - Rect(PLAYGROUND_OFFSET, PLAYGROUND_OFFSET, - PLAYGROUND_LENGTH, PLAYGROUND_LENGTH)) - - pygame.draw.lines(SCREEN, (255, 255, 255), True, [ + SCREEN.blit( + PLAYGROUND, (PLAYGROUND_OFFSET, PLAYGROUND_OFFSET), - (PLAYGROUND_OFFSET, PLAYGROUND_LENGTH + PLAYGROUND_OFFSET), - (PLAYGROUND_LENGTH + PLAYGROUND_OFFSET, PLAYGROUND_LENGTH + PLAYGROUND_OFFSET), - (PLAYGROUND_LENGTH + PLAYGROUND_OFFSET, PLAYGROUND_OFFSET), - ], 1) + pygame.Rect( + PLAYGROUND_OFFSET, + PLAYGROUND_OFFSET, + PLAYGROUND_LENGTH, + PLAYGROUND_LENGTH, + ), + ) + + pygame.draw.lines( + SCREEN, + (255, 255, 255), + True, + [ + (PLAYGROUND_OFFSET, PLAYGROUND_OFFSET), + (PLAYGROUND_OFFSET, PLAYGROUND_LENGTH + PLAYGROUND_OFFSET), + ( + PLAYGROUND_LENGTH + PLAYGROUND_OFFSET, + PLAYGROUND_LENGTH + PLAYGROUND_OFFSET, + ), + (PLAYGROUND_LENGTH + PLAYGROUND_OFFSET, PLAYGROUND_OFFSET), + ], + 1, + ) self.drops.update() self.droplets.update() @@ -205,7 +238,9 @@ def start(self): self.panel.draw(SCREEN) self.notifications.draw(SCREEN) - for drop, droplets in groupcollide(self.drops, self.droplets, dokilla=False, dokillb=False).items(): + for drop, droplets in groupcollide( + self.drops, self.droplets, dokilla=False, dokillb=False + ).items(): drop.hit() droplets[0].kill() # many droplets hit same drop, only delete one diff --git a/ten_drops/notification.py b/ten_drops/notification.py index d4f7d92..973f356 100644 --- a/ten_drops/notification.py +++ b/ten_drops/notification.py @@ -24,7 +24,7 @@ class NoticeType: TextDict: Dict[str, _NType] = { NoticeType.about: _NType("about", text_font, Color("white")), NoticeType.failed: _NType("failed", Font(FONT_PATH, size=45), Color("white")), - NoticeType.success: _NType("failed", Font(FONT_PATH, size=45), Color("white")) + NoticeType.success: _NType("failed", Font(FONT_PATH, size=45), Color("white")), } @@ -33,18 +33,26 @@ def __init__(self, _type, text, *groups): super().__init__(*groups) self._notification = TextDict[_type] - self.text_area = Surface((NOTIFICATION.get_width() * 0.8, NOTIFICATION.get_height() * 0.5), - pygame.SRCALPHA) + self.text_area = Surface( + (NOTIFICATION.get_width() * 0.8, NOTIFICATION.get_height() * 0.5), + pygame.SRCALPHA, + ) self.image = NOTIFICATION.copy() self.rect = self.image.get_rect() self.rect.y = -self.rect.height - text_surface = self._notification.font.render(text, True, self._notification.color) + text_surface = self._notification.font.render( + text, True, self._notification.color + ) self.text_area.blit(text_surface, (0, 0)) - self.image.blit(self.text_area, - ((self.image.get_width() - self.text_area.get_width()) / 1.8, - NOTIFICATION.get_height() * 0.4)) + self.image.blit( + self.text_area, + ( + (self.image.get_width() - self.text_area.get_width()) / 1.8, + NOTIFICATION.get_height() * 0.4, + ), + ) def update(self): if self.rect.y < 0: diff --git a/ten_drops/panel.py b/ten_drops/panel.py index 21f56e1..30043f1 100644 --- a/ten_drops/panel.py +++ b/ten_drops/panel.py @@ -33,7 +33,9 @@ def __init__(self, score, *groups): self._update_image() def _update_image(self): - self.image = self.ScoreFont.render(f"score \n{self.score}", True, Color("white")) + self.image = self.ScoreFont.render( + f"score \n{self.score}", True, Color("white") + ) self.rect = self.image.get_rect() self.rect.x = PLAYGROUND_LENGTH + PLAYGROUND_OFFSET * 2 self.rect.y = PLAYGROUND_OFFSET * 4 @@ -77,9 +79,13 @@ class About(Sprite): def __init__(self, *groups): super().__init__(*groups) - self.image = self.AboutFont.render("A ten drops game written in pygame.\n" - "author: chyok\n" - "email: chyok@hotmail.com", True, (32, 32, 32)) + self.image = self.AboutFont.render( + "A ten drops game written in pygame.\n" + "author: chyok\n" + "email: chyok@hotmail.com", + True, + (32, 32, 32), + ) self.rect = self.image.get_rect() self.rect.x = (SCREEN.get_width() - self.image.get_width()) / 2 self.rect.y = SCREEN.get_height() / 3