def update(self, screen: pygame.Surface) -> None: """Get information from player, level and render.""" health: int = self._player.get_health() spheres: int = self._player.get_num_spheres() level: int = self._level.get_level() total_spheres: int = self._level.get_total_spheres() if pygame.font: level_surf: pygame.Surface = self._font.render( "Level " + str(level), True, (0, 0, 0)) health_surf: pygame.Surface = self._font.render( "Health " + str(health), True, (0, 0, 0)) spheres_surf: pygame.Surface = self._font.render( "Spheres " + str(spheres) + "/" + str(total_spheres), True, (0, 0, 0)) self.image = pygame.Surface( (screen.get_width(), self._font.get_height())) self.image.fill((200, 200, 200)) self.image.blit(level_surf, (0, 0)) self.image.blit(spheres_surf, (screen.get_width() - spheres_surf.get_width(), 0)) self.image.blit( health_surf, ((screen.get_width() - health_surf.get_width()) / 2, 0)) self.rect = self.image.get_rect() else: pygame.display.set_caption("Level " + str(level) + " Health " + str(health) + " Spheres " + str(spheres) + "/" + str(total_spheres))
def ingredient_count(self, items, money): # sides are at 650 and 675 # /1200 /900 # 13/24 27/36 ingredient_block = Surface((self.game_engine.width * 11/24, self.game_engine.height * 9/36)) ingredient_block.fill((255, 255, 255)) icon_size = int(ingredient_block.get_width() / (len(items) * 1.5)) icon_width = ingredient_block.get_width() / len(items) j = icon_size / 3 render_top = 15 + icon_size for name, count in items.items(): icon = image.load("images/icon-%s.gif" % name).convert() icon = transform.scale(icon, (icon_size, icon_size)) ingredient_block.blit(icon, (j, 10)) # Put an item count under the icon. ren = self.__font.render(str(count), True, (0, 0, 0)) fw, fh = ren.get_size() render_left = j + (icon_size / 2) - (fw / 2) ingredient_block.blit(ren, (render_left, render_top)) j += icon_width ren = self.__font.render("Funds: %s" % format_money(money), True, (0, 0, 0)) fw, fh = ren.get_size() render_left = ingredient_block.get_width() / 2 - fw / 2 render_top = (ingredient_block.get_height() - render_top) / 2 + render_top ingredient_block.blit(ren, (render_left, render_top)) return ingredient_block
def draw(self, surface: pygame.Surface) -> None: if self.__show: self.__rect.width = surface.get_width() pygame.draw.rect(surface, "white", self.__rect, border_bottom_left_radius=30, border_bottom_right_radius=30) pygame.draw.rect(surface, "black", self.__rect, width=2, border_bottom_left_radius=30, border_bottom_right_radius=30) for button in self.__buttons: button.draw(surface) else: pygame.draw.rect(surface, "white", (0, 0, surface.get_width(), 20), border_bottom_left_radius=30, border_bottom_right_radius=30) pygame.draw.rect(surface, "black", (0, 0, surface.get_width(), 20), width=2, border_bottom_left_radius=30, border_bottom_right_radius=30)
def draw_card(surface: pygame.Surface, card: SushiCardType, color_fore: Color, color_back: Color, num: int = 1, wasabi: bool = False): OFFSET = 0.03 BORDER_SIZE = 2 if wasabi: num = 2 offset = max(OFFSET * surface.get_width(), OFFSET * surface.get_height()) h = surface.get_height() - offset * (num - 1) w = surface.get_width() - offset * (num - 1) for i in range(num): x = int(offset * i) y = int(offset * i) pygame.draw.rect(surface, color_back, Rect(x, y, w, h)) pygame.draw.rect(surface, color_fore, Rect(x, y, w, h), BORDER_SIZE) App.draw_centered_text(surface, w / 2 + x, h / 2 + y, card, color_fore, 14) if wasabi: App.draw_centered_text(surface, w / 2 + x, h / 2 + y + 15, 'with WASABI', color_fore, 14) else: App.draw_centered_text(surface, w / 2 + x, h / 2 + y + 15, f'x{num}', color_fore, 14)
def move_x(self, screen: pygame.Surface, threshold: int, background: ScrollingBackground) -> int: """Attempt to move, return True if moved.""" moved: bool = False scroll_dir: int = NOT_MOVING # Adjust x according to dx. if self._dx < 0: can_scroll = background.can_scroll(screen, LEFT) if not (can_scroll and self.rect.left < threshold): self._x += self._dx if self._x < 0: self._x = 0 self.rect.left = self._x else: scroll_dir = LEFT elif self._dx > 0: can_scroll = background.can_scroll(screen, RIGHT) if not (can_scroll and self.rect.right > screen.get_width() - threshold): self._x += self._dx if self._x > screen.get_width() - self.rect.width: self._x = screen.get_width() - self.rect.width self.rect.left = self._x else: scroll_dir = RIGHT return scroll_dir
def finish_game(win: bool, screen: pygame.Surface): """ Is called when game is finished. """ if win: pygame.draw.rect(screen, pygame.Color('yellow'), screen.get_rect()) final_message = 'You win!' else: pygame.draw.rect(screen, pygame.Color('red'), screen.get_rect()) final_message = 'You lost...' # Set font. font = pygame.font.SysFont(name='Ani', size=100) # Place messages. screen.blit(font.render(final_message, True, pygame.Color('black')), (screen.get_width() // 3 + 80, screen.get_height() // 5)) screen.blit( font.render('To exit, press ESC.', True, pygame.Color('black')), (screen.get_width() // 6, screen.get_height() // 4 + 150)) screen.blit( font.render('To restart the game, press any other button.', True, pygame.Color('black')), (screen.get_width() // 4 + 30, screen.get_height() // 4 + 300)) # Display changes. pygame.display.update() _wait_for_command()
def update_percent(self, screen: pygame.Surface) -> None: self.add_percent() pygame.draw.rect(screen, (0, 0, 0), (0, screen.get_height() - 20, screen.get_width(), 10)) pygame.draw.rect(screen, (187, 11, 11), (0, screen.get_height() - 20, (screen.get_width() / 100) * self.percent, 10))
def move(self, screen: pygame.Surface, direction: int) -> None: """Move in direction.""" if direction == LEFT: self._angle = 180 self.image = pygame.transform.rotate(self._raw_image, 180) self.rect.left -= self._speed if self.rect.left < 0: self.rect.left = 0 elif direction == RIGHT: self._angle = 0 self.image = self._raw_image self.rect.left += self._speed if self.rect.right > screen.get_width(): self.rect.right = screen.get_width() elif direction == UP: self._angle = 270 self.image = pygame.transform.rotate(self._raw_image, 90) self.rect.top -= self._speed if self.rect.top < 0: self.rect.top = 0 elif direction == DOWN: self._angle = 90 self.image = pygame.transform.rotate(self._raw_image, -90) self.rect.top += self._speed if self.rect.bottom > screen.get_height(): self.rect.bottom = screen.get_height()
class Cell(): def __init__(self, x, y, width, height, block_image): self.x = x self.y = y self.activated = False self.small_block_image = scale_image(block_image, (20, 20)) self.image = Surface((width, height)) self.image.fill((139,69,19)) self.image.set_alpha(60) def update(self, event, cells): if event.type == MOUSEBUTTONDOWN: if event.button == 1: if event.pos[0] in range(self.x, self.x + self.image.get_width()) and event.pos[1] in range(self.y, self.y + self.image.get_height()): button_press_sound.play() self.activated = True for cell in cells: if cell != self: cell.activated = False def draw(self, window): window.blit(self.image, (self.x, self.y)) if self.activated: draw_rect(window, (0, 0, 0), (self.x, self.y, self.image.get_width(), self.image.get_height()), 2) else: draw_rect(window, (150, 150, 150), (self.x, self.y, self.image.get_width(), self.image.get_height()), 2) window.blit(self.small_block_image, ((self.x + self.image.get_width() // 2) - self.small_block_image.get_width() // 2, (self.y + self.image.get_height() // 2) - self.small_block_image.get_height() // 2))
def update(self, screen: pygame.Surface) -> None: """Move the goat.""" if self._timer % 60 == 0: self._timer += random.choice([0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) self._x += self._speed * math.cos(math.radians(self._angle)) self._y += self._speed * math.sin(math.radians(self._angle)) if self._x <= 0: self._x = 0 self._angle += 10 self._change_rotation() elif self._x + self.image.get_width() >= screen.get_width(): self._x = screen.get_width() - self.image.get_width() self._angle += 10 self._change_rotation() if self._y <= 0: self._y = 0 self._angle += 10 self._change_rotation() elif self._y + self.image.get_height() >= screen.get_height(): self._y = screen.get_height() - self.image.get_height() self._angle += 10 self._change_rotation() self.rect.top = self._y self.rect.left = self._x self._timer += 1 if self._timer == self._max_timer: self._randomize()
def update(self, screen: pygame.Surface) -> None: """Move the object by _dx and boundary check.""" self.rect.centerx += self._dx if self.rect.right > screen.get_width(): self.rect.right = screen.get_width() elif self.rect.left < 0: self.rect.left = 0
def _inner_pre_draw(self, surface: Surface): main_group_x = surface.get_width() / 2 main_group_y = surface.get_height() / 2 + 100 aux_group_x = surface.get_width() - 200 - 20 aux_group_y = surface.get_height() - 20 surface.blit(self._background_image, (0, 0)) self._start_button.set_position_centered(main_group_x, main_group_y - 80) self._how_to_play.set_position_centered(main_group_x, main_group_y) self._settings_button.set_position(aux_group_x, aux_group_y - 115) self._credits_button.set_position(aux_group_x, aux_group_y - 75) self._quit_button.set_position(aux_group_x, aux_group_y - 35) title_pos = (main_group_x - (self._title_surface.get_width() / 2), 50) surface.blit(self._title_surface, title_pos) surface.blit(self._espiria_image, (main_group_x - 110, 690)) surface.blit(self._insta_image, (10, 650)) surface.blit(self._discord_image, (10, 710)) surface.blit(self._insta_text, (70, 670)) surface.blit(self._discord_text, (70, 730))
def draw(self, screen: pygame.Surface) -> None: screen.blit(self.image, tuple(self.top_left_point)) scrrect = Rect(Color(0, 0, 0), Vector2D(0, 0), Vector2D(screen.get_width(), screen.get_height()), 0) radius = self.width / 2 if self.center.x - radius < 0 or self.center.x + radius > screen.get_width(): self.speed = Vector2D(-self.speed.x, self.speed.y) if self.center.y - radius < 0 or self.center.y + radius > screen.get_height(): self.speed = Vector2D(self.speed.x, -self.speed.y)
def double_tile_surface(surfaceIn: Surface): surfaceOut = Surface( (surfaceIn.get_width() * 2, surfaceIn.get_height() * 2), SRCALPHA) surfaceOut.blit(surfaceIn, (0, 0)) surfaceOut.blit(surfaceIn, (surfaceIn.get_width(), 0)) surfaceOut.blit(surfaceIn, (0, surfaceIn.get_height())) surfaceOut.blit(surfaceIn, (surfaceIn.get_width(), surfaceIn.get_height())) return surfaceOut
def draw_Player(surface: pygame.Surface, state: GameState, player_idx: int): CARD_SPACING = 5 CARD_W = int((surface.get_width() + CARD_SPACING) / 11) CARD_H = int(surface.get_height() / 3) FORE_C = Color('RED') BACK_C = Color('BLUE') LABEL_SIZE = 24 y = 10 App.draw_centered_text(surface, surface.get_width() / 2, y, f'Player {player_idx + 1}', FORE_C, LABEL_SIZE) y += 20 App.draw_centered_text(surface, surface.get_width() / 2, y, 'Hand', FORE_C, LABEL_SIZE) counts = count_card_types(state.hands[player_idx]) counts = {card: count for card, count in counts.items() if count > 0} y += 10 for k, card in enumerate(counts): count = counts[card] x = k * (CARD_W + CARD_SPACING) App.draw_card(surface.subsurface(Rect(x, y, CARD_W, CARD_H)), card, FORE_C, BACK_C, count) y += CARD_H + 10 App.draw_centered_text(surface, surface.get_width() / 2, y, 'Played', FORE_C, LABEL_SIZE) played_cards = list(state.played_cards[player_idx]) wasabi_combos = pair_wasabi(played_cards) for card in wasabi_combos: played_cards.remove(card) played_cards.remove(SushiCardType.WASABI) counts = count_card_types(played_cards) counts = {card: count for card, count in counts.items() if count > 0} y += 10 for k, card in enumerate(counts): count = counts[card] x = k * (CARD_W + CARD_SPACING) App.draw_card(surface.subsurface(Rect(x, y, CARD_W, CARD_H)), card, FORE_C, BACK_C, count) for k, card in enumerate(wasabi_combos): x = (k + len(counts)) * (CARD_W + CARD_SPACING) App.draw_card(surface.subsurface(Rect(x, y, CARD_W, CARD_H)), card, FORE_C, BACK_C, 1, True) y += CARD_H + 10 pudding = state.puddings[player_idx] score = state.scores[player_idx] App.draw_centered_text(surface, surface.get_width() / 2, y, f'Pudding: {pudding} Score: {score}', FORE_C, LABEL_SIZE)
def _drawbranch(self, indent, branch): result = [] truths = [] boxoffset = 0 for key, name, expanded, value in branch: space = self._font.render(' '*4*indent, False, (0,0,0)) title = self._font.render(name, True, (255,255,255)) if hasattr(value, '__iter__'): arrow = self._exp if expanded else self._col lines, suboffset, allsame = self._drawbranch(indent+1, value) selected = allsame boxoffset = max(boxoffset, suboffset) else: arrow = None lines = [] selected = value width = (space.get_width() + (arrow.get_width() if arrow else 0) + title.get_width()) height = title.get_height() image = Surface((width, height), flags=SRCALPHA) image.blit(space, (0,0)) if arrow: loc = space.get_width(), 0 image.blit(arrow, loc) buttons = [(Rect(loc, arrow.get_size()), 0, self._arrowhandler(branch, key, not expanded))] else: buttons = [] image.blit(title, (image.get_width()-title.get_width(), 0)) if selected: boxes = self._y, self._emp actions = None, False elif selected == False: boxes = self._emp, self._n actions = True, None else: boxes = self._emp, self._emp actions = True, False boxbuttons, boximage = self._drawboxes(branch, key, *(boxes + actions)) buttons.extend(boxbuttons) result.append((image, buttons, boximage)) if expanded: result.extend(lines) truths.append(selected) boxoffset = max(boxoffset, image.get_width()) allsame = (True if all(truths) else False if all([t == False for t in truths]) else None) return result, boxoffset, allsame
def update(self, screen: pygame.Surface) -> None: """Move left to right and back.""" self.rect.centerx += self._dx if self.rect.right > screen.get_width(): self.rect.right = screen.get_width() self._dx *= -1 elif self.rect.left < 0: self.rect.left = 0 self._dx *= -1
def image_action_upscale(self, image: pygame.Surface, parent) -> pygame.Surface: if parent.size != 0: scale_factor_x = parent.size[0] / image.get_width() scale_factor_y = parent.size[1] / image.get_height() scale_factor = min(scale_factor_x, scale_factor_y) new_width = int(image.get_width() * scale_factor) new_height = int(image.get_height() * scale_factor) image = pygame.transform.scale(image, (new_width, new_height)) return image
def image_action_scale_to_width( self, image: pygame.Surface, parent, ) -> pygame.Surface: scale_factor = parent.size[0] / image.get_width() new_width = int(image.get_width() * scale_factor) new_height = int(image.get_height() * scale_factor) image = pygame.transform.scale(image, (new_width, new_height)) return image
def update(self, screen: pygame.Surface) -> None: self.rect.top += self._dy self.rect.left += self._dx if self.rect.right > screen.get_width(): self.rect.right = screen.get_width() elif self.rect.left < 0: self.rect.left = 0 if self.rect.bottom > screen.get_height(): self.rect.bottom = screen.get_height() elif self.rect.top < 0: self.rect.top = 0
def _render_score(self, surface: pygame.Surface) -> None: text, _ = self.score_font.render(str(int(self.score)), fgcolor=self.scores_fg) pygame.draw.circle( surface, self.scores_bg, (int(surface.get_width() - text.get_width() / 2 - 20), int(20 + text.get_height() / 2)), int(max([text.get_width() / 2 + 10, text.get_height() / 2 + 10]))) surface.blit(text, (surface.get_width() - text.get_width() - 20, 20))
def update(self, screen: pygame.Surface) -> None: """Update sprite location.""" self.rect.left += self._dx self.rect.top += self._dy if self.rect.left < 0: self.rect.left = 0 elif self.rect.right > screen.get_width(): self.rect.right = screen.get_width() if self.rect.top < 0: self.rect.top = 0 elif self.rect.bottom > screen.get_height(): self.rect.bottom = screen.get_height()
def update(self, screen: pygame.Surface) -> None: """Move sprite by _dx, _dy.""" self.rect.top += self._dy self.rect.left += self._dx if self.rect.right < screen.get_width(): self.rect.right = screen.get_width() elif self.rect.left > 0: self.rect.left = 0 if self.rect.bottom < screen.get_height(): self.rect.bottom = screen.get_height() elif self.rect.top > 0: self.rect.top = 0
def update(self, screen: pygame.Surface) -> None: """Move sprite by _dx, _dy.""" self.rect.top += self._boost * self._dy self.rect.left += self._boost * self._dx if self.rect.right > screen.get_width(): self.rect.right = screen.get_width() - int(self.rect.width / 2) elif self.rect.left < 0: self.rect.left = int(self.rect.width / 2) if self.rect.bottom > screen.get_height(): self.rect.bottom = screen.get_height() - int(self.rect.height / 4) elif self.rect.top < 0: self.rect.top = int(self.rect.height / 4)
def pos_of_picture(picture: pygame.Surface, pos: int) -> Point: x = pic_size.w * (pos % COLUMNS) y = pic_size.h * int(pos / COLUMNS) if (picture.get_width() / picture.get_height()) > screen_ratio: h = int((pic_size.w - BORDER * 2) / (picture.get_width() / picture.get_height())) y += int((pic_size.h - h) / 2) elif (picture.get_width() / picture.get_height()) < screen_ratio: w = int((pic_size.h - BORDER * 2) * (picture.get_width() / picture.get_height())) x += int((pic_size.w - w) / 2) return Point(x, y)
def __init__(self, image: pygame.Surface, screen: pygame.Surface) -> None: """Initialize the sprite.""" super().__init__() self.image = image self.rect = self.image.get_rect() self.rect.left = random.randint( int(-image.get_width() / 2), screen.get_width() + int(image.get_width() / 2)) self.rect.top = random.randint( int(-image.get_height() / 2), screen.get_height() + int(image.get_height() / 2)) self._dy = random.randint(4, 10)
def _slam_position_calc(self, player: GameObject, surface: Surface) -> Vector2: x = player.center.x if self.level == 1: if player._last_direction == -1: x -= surface.get_width() if self.level >= 2: x -= surface.get_width() / 2 return Vector2( x, player.transform.y - surface.get_height() + player.height)
def draw(self, screen: pygame.Surface, camera: pygame.Vector3, rx: int, ry: int): vec3 = projection(self.points[0], camera, rx, ry) if (-screen.get_width() < vec3.x < screen.get_width() * 2 and -screen.get_height() * 1 < vec3.y < screen.get_height() * 1.5): c = [ min(max(0, vec3.z * 2) + self.color[0], 255), min(max(0, vec3.z * 2) + self.color[1], 255), min(max(0, vec3.z * 2) + self.color[2], 255) ] if vec3.z > 0: pygame.draw.circle(screen, c, vec3.xy, 30, 10)
def render(self, surface: pygame.Surface, size_factor: float): self.previous_state.render(surface, size_factor) s = pygame.Surface((surface.get_width(), surface.get_height())) s.set_alpha(150) s.fill((0, 0, 0)) surface.blit(s, (0, 0)) surface_width = surface.get_width() surface_height = surface.get_height() font = pygame.font.Font("res/arcade.ttf", surface_height // 10) entries = [(font.render(text, True, (255, 255, 255)), font.render(str(score), True, (255, 255, 255))) for text, score in self.high_score] height = max(x.get_height() for x, _ in entries) + 2 * GameMenu.PADDING left = int(surface_width * 0.25) right = int(surface_width * 0.75) top = surface_height // 2 - (height * (len(self.high_score) + 1.5) // 2) header = font.render("High score", True, (255, 255, 255)) header_left = surface_width // 2 - header.get_width() // 2 surface.blit(header, (header_left, top)) top += int(height * 1.5) index = 0 for text, score in entries: if self.index == index: s = pygame.Surface( (surface_width // 2 + GameMenu.PADDING * 2, height)) s.set_alpha(70) s.fill((255, 255, 255)) surface.blit(s, (left - GameMenu.PADDING, top + index * height)) surface.blit(text, (left, top + index * height + GameMenu.PADDING)) surface.blit(score, (right - score.get_width(), top + index * height + GameMenu.PADDING)) t = time.time() if self.index == index and self.score is not None and t - int( t) < 0.5: surface.fill( (255, 255, 255), pygame.Rect(left + text.get_width(), top + index * height, size_factor * Const.pixel_size, height)) index += 1
class InfoTab(): def __init__(self): self.surface_inside = Surface((295, 128)).convert() self.surface = Surface((300, 130)).convert() self.surface_inside.fill((255, 255, 255)) self.surface.fill((0, 0, 0)) self.font = font.Font(None, 15) self.l_font = font.Font(None, 25) def update(self, obj=None): self.surface_inside.fill((255, 255, 255)) self.surface.fill((0, 0, 0)) if obj is not None: self.surface_inside.blit(transform.scale(obj.image, (20, 20)), (5, 5)) self.surface_inside.blit( self.l_font.render(obj.name, 1, (0, 0, 0)), (30, 25 - self.l_font.get_height())) cost_str = "$" + str(obj.cost) self.surface_inside.blit( self.l_font.render(cost_str, 1, (0, 255, 0)), (self.surface_inside.get_width() - self.l_font.size(cost_str)[0] - 10, 5)) y_val = 30 for line in self.length_splitter( self.font, obj.description, self.surface_inside.get_width() - 10): self.surface_inside.blit(self.font.render(line, 1, (0, 0, 0)), (5, y_val)) y_val += self.font.size(line)[1] + 5 self.surface.blit(self.surface_inside, (1, 1)) # Word-wrap function @staticmethod def length_splitter(font, text, max_length): ret_list = [] explode = text.split() t_str = "" while len(explode) > 0: if font.size(t_str + explode[0])[0] > max_length: ret_list.append(t_str) t_str = "" else: t_str += explode.pop(0) + " " if len(explode) == 0: ret_list.append(t_str) return ret_list
def update(self, screen: pygame.Surface) -> None: """Get information from player, level and render.""" coins: int = self._player.get_coins() level: int = self._level.get_level() if pygame.font: level_surf: pygame.Surface = self._font.render("Level " + str(level), True, (0, 0, 0)) coins_surf: pygame.Surface = self._font.render("Coins " + str(coins), True, (0, 0, 0)) self.image = pygame.Surface((screen.get_width(), self._font.get_height())) self.image.fill((222, 237, 244)) self.image.blit(level_surf, (0, 0)) self.image.blit(coins_surf, (screen.get_width() - coins_surf.get_width(), 0)) self.rect = self.image.get_rect() else: pygame.display.set_caption("Level " + str(level) + " Coins " + str(coins))
def make_background(self,img_file,desktop_size): in_img = image.load(img_file) out_img = Surface(desktop_size) for x in range((out_img.get_width() // in_img.get_width()) + 1): for y in range((out_img.get_height() // in_img.get_height()) + 1): out_img.blit(in_img, (in_img.get_width() * x, in_img.get_height() * y)) return out_img
def create_dialog(self): f = font.Font(font.get_default_font(), 30) text = f.render(self.text, True, (255, 255, 255)) dialog = Surface((text.get_width() + 20, text.get_height() + 20)) self.stroke(dialog, (255, 0, 0)) dialog.blit(text, ((dialog.get_width() - text.get_width()) / 2, (dialog.get_height() - text.get_height()) / 2)) return dialog
def make_background(self, img_file, desktop_size): in_img = image.load(img_file) out_img = Surface(desktop_size) out_img.fill((0, 0, 0)) left = (out_img.get_width() - in_img.get_width()) / 2 top = (out_img.get_height() - in_img.get_height()) / 2 out_img.blit(in_img, (left, top)) return out_img
class InfoTab(): def __init__(self): self.surface_inside = Surface((295, 128)).convert() self.surface = Surface((300, 130)).convert() self.surface_inside.fill((255, 255, 255)) self.surface.fill((0, 0, 0)) self.font = font.Font(None, 15) self.l_font = font.Font(None, 25) def update(self, obj=None): self.surface_inside.fill((255, 255, 255)) self.surface.fill((0, 0, 0)) if obj is not None: self.surface_inside.blit(transform.scale(obj.image, (20, 20)), (5, 5)) self.surface_inside.blit(self.l_font.render(obj.name, 1, (0, 0, 0)), (30, 25-self.l_font.get_height())) cost_str = "$"+str(obj.cost) self.surface_inside.blit(self.l_font.render(cost_str, 1, (0, 255, 0)), (self.surface_inside.get_width() - self.l_font.size(cost_str)[0] - 10, 5)) y_val = 30 for line in self.length_splitter(self.font, obj.description, self.surface_inside.get_width()-10): self.surface_inside.blit(self.font.render(line, 1, (0, 0, 0)), (5, y_val)) y_val += self.font.size(line)[1]+5 self.surface.blit(self.surface_inside, (1, 1)) # Word-wrap function @staticmethod def length_splitter(font, text, max_length): ret_list = [] explode = text.split() t_str = "" while len(explode) > 0: if font.size(t_str + explode[0])[0] > max_length: ret_list.append(t_str) t_str = "" else: t_str += explode.pop(0) + " " if len(explode) == 0: ret_list.append(t_str) return ret_list
class IonField(Sprite): """Sprite that draws a bunch of random horizontal lines inside a rectangle.""" def __init__(self, left, top, width, height, noise_width, noise_height, delay): Sprite.__init__(self) self.top = top self.left = left self.width = width self.height = height self.image = Surface((self.width, self.height)) self.rect = Rect(left, top, self.width, self.height) self.rect = Rect(left, top, 0, 0) self.mask = Mask((self.width, self.height)) self.mask.fill() self.noise_width = noise_width self.noise_height = noise_height self.tick = 0 self.delay = delay def update(self): self.tick = self.tick + 1 if self.tick % self.delay == 0: self.generate_noise() def draw(self, screen): screen.blit(self.image, self.rect) def generate_noise(self): for col in range(0, self.image.get_width(), self.noise_width): for row in range(0, self.image.get_height(), self.noise_height): c = choice(COLORS) draw.rect(self.image, c, Rect(col, row, self.noise_width, self.noise_height))
def draw(self, time, settings, screen : Surface, scale, bottomypos : float, cursoroffset = 0, currentxscroll = 0, drawcursorindex = None, nodraw = False): # first draw wood if not nodraw: self.drawwood(time, settings, screen, scale, currentxscroll, bottomypos) xspace = screen.get_width()/50 currentx = xspace cursordrawpos = None for i in range(cursoroffset, len(self.plants)): currentpos = (currentx, bottomypos) if not nodraw: self.plants[i].draw(time, settings, screen, scale, currentpos) if drawcursorindex == i: potpos = self.plants[i].pot_pos(currentpos, scale) cursordrawpos = Rect(potpos[0]-xspace, potpos[1]-xspace, xspace, xspace) gfxdraw.box(screen, cursordrawpos, (211, 214, 64)) currentx += self.plants[i].plantwidth*scale + xspace return cursordrawpos
mdx = randint(-2048,2048) mdy = randint(-2048,2048) def spouses(x, y): global mdx global mdy m = noise.snoise2((x+mdx),(y+mdy),1,1) m = max(0, m) return int(4*m) + 1 shownoise = '-shownoise' in [a.lower() for a in argv] background = Surface(screen.get_size()) if shownoise: background.lock() for y in range(0, background.get_height()): for x in range(0, background.get_width()): background.set_at((x,y), grayvalue(noiseat(x,y))) background.unlock() else: background.fill((255,255,255)) screen.blit(background, (0,0)) sprites = Group() def personat(x,y): return noiseat(x*8,y*8) <= 0.95 for x in range(0, background.get_width(), 8): for y in range(0, background.get_height(), 8): present = personat(x/8, y/8)
from factions import * pygame.init() screen = display.set_mode((800,600),HWSURFACE) display.set_caption('Regime Change') background = Surface(screen.get_size()) background.fill((128,128,128)) text = font.SysFont('Courier', 10) plot = background.subsurface(Rect(0, 0, background.get_width(), background.get_height()/2)) chart = background.subsurface(Rect(0, plot.get_height(), background.get_width(), background.get_height()-plot.get_height())) values = 'militarism', 'moralism' society = Society([Faction('aristocracy', (0,0,255), random(), values), Faction('merchant class', (0,255,0), random(), values), Faction('populace', (255,0,0), random(), values)]) for f in society.factions: for v in f.values.keys(): f.values[v] = random() charts = [chart.subsurface(Rect(i * chart.get_width()/len(society.factions),
class Shop(): def __init__(self, name, inventory, price_mod, group_inventory, group_money, item_prices, position, blit_position, money, resource_path): self.yvalue = 40 self.group_inventory = group_inventory self.group_money = group_money self.price_mod = price_mod self.item_prices = item_prices self.inventory = inventory self.position = position self.blit_position = blit_position self.resource_path = resource_path self.buy_button_list = [] self.sell_button_list = [] # TODO: figure out what these magic numbers mean self.x_pos = (-self.position * 40) + 1280 # Gui stuff # # Main Window self.shop_surface = Surface((500, 300)).convert() # Separator Line self.sep_line = Surface((self.shop_surface.get_width(), 10)).convert() self.sep_line.fill((0, 0, 0)) # Inventory container box self.inv_container = Surface((self.shop_surface.get_width()-20, self.shop_surface.get_height()/2 - 35)).convert() self.inv_container.fill((255, 255, 255)) # Font creation self.title_font = font.Font(None, 30) self.text_font = font.Font(None, 20) # Random name generation if name == "": self.name = capitalize(choice(SHOP_NAME_PREFIX) + "'s " + choice(SHOP_NAME_SUFFIX)) else: self.name = name # Random inventory generation if self.inventory == {}: # TODO: The shop should have random items, not just what the group currently has inventory_random = copy(self.group_inventory) # Assign a random value between 1,10 to each inventory item for key in list(inventory_random.keys()): inventory_random[key] = randint(0, 10) # Inflate food count inventory_random["Food"] *= 20 self.inventory = inventory_random # Random money generation if money is None: self.money = randint(200, 500) else: self.name = name self.render() # Used to get the surface created in self.render() def get_surface(self): self.render() return self.shop_surface # Updates the group_inv and group_money to blit in self.render def update(self, group_inv, group_m): self.group_inventory = group_inv self.group_money = group_m self.render() def move(self, move_value): self.x_pos += (2 * move_value) self.render() def render(self): self.yvalue = 40 self.shop_surface.fill((133, 94, 66)) self.shop_surface.blit(self.title_font.render(self.name + " - $"+str(self.money), 1, (0, 0, 255)), (10, 5)) self.shop_surface.blit(self.inv_container, (10, 25)) self.shop_surface.blit(self.inv_container, (10, self.shop_surface.get_height()/2 + 30)) self.shop_surface.blit(self.text_font.render("Inventory", 1, (255, 0, 0)), (10, 25)) self.shop_surface.blit(self.text_font.render("Amount", 1, (255, 0, 0)), (130, 25)) self.shop_surface.blit(self.text_font.render("Price", 1, (255, 0, 0)), (200, 25)) #Blit the shop's inventory for key in list(self.inventory.keys()): self.shop_surface.blit(self.text_font.render(key+":", 1, (0, 0, 0)), (10, self.yvalue)) self.shop_surface.blit(self.text_font.render(str(self.inventory[key]), 1, (0, 0, 0)), (150, self.yvalue)) self.shop_surface.blit(self.text_font.render("$"+str(self.item_prices[key]*self.price_mod), 1, (0, 0, 0)), (200, self.yvalue)) if len(self.buy_button_list) < len(self.inventory.keys()): button_pos = tuple(map(sum, zip(self.blit_position, (250, self.yvalue)))) self.buy_button_list.append(TransactionButton(transaction="buy", item=key, image_position=(250, self.yvalue), rect_position=button_pos, resource_path=self.resource_path)) self.yvalue += 30 # Shows each button for button in self.buy_button_list: self.shop_surface.blit(button.image, button.image_position) self.shop_surface.blit(self.sep_line, (0, float(self.shop_surface.get_height())/2)) self.shop_surface.blit(self.title_font.render("You - $"+str(self.group_money), 1, (0, 0, 255)), (10, float(self.shop_surface.get_height()) / 2 + 10)) self.shop_surface.blit(self.text_font.render("Inventory", 1, (255, 0, 0)), (10, float(self.shop_surface.get_height()) / 2 + 30)) self.shop_surface.blit(self.text_font.render("Amount", 1, (255, 0, 0)), (130, float(self.shop_surface.get_height()) / 2 + 30)) self.shop_surface.blit(self.text_font.render("Price", 1, (255, 0, 0)), (200, float(self.shop_surface.get_height()) / 2 + 30)) self.yvalue = (float(self.shop_surface.get_height())/2) + 45 #Blit the player's inventory for key in list(self.group_inventory.keys()): self.shop_surface.blit(self.text_font.render(key+":", 1, (0, 0, 0)), (10, self.yvalue)) self.shop_surface.blit(self.text_font.render(str(self.group_inventory[key]), 1, (0, 0, 0)), (150, self.yvalue)) self.shop_surface.blit(self.text_font.render("$"+str(self.item_prices[key]*self.price_mod), 1, (0, 0, 0)), (200, self.yvalue)) if len(self.sell_button_list) < len(self.inventory.keys()): button_pos = tuple(map(sum, zip(self.blit_position, (250, self.yvalue)))) self.sell_button_list.append(TransactionButton(transaction="sell", item=key, image_position=(250, self.yvalue), rect_position=button_pos, resource_path=self.resource_path)) self.yvalue += 30 for button in self.sell_button_list: self.shop_surface.blit(button.image, button.image_position)
class TowerFrame(): """ Creates a frame full of information for the selected tower """ def __init__(self, tower, extra_attributes=None): self.tower = tower self.image = Surface((200, 300)).convert() self.image.fill((200, 115, 0)) self.s_width = self.image.get_width() self.s_height = self.image.get_height() # Can't divide by 0 if self.tower.fire_rate == 0: dps_calc = 0 else: dps_calc = self.tower.damage/self.tower.fire_rate tower_attributes = {"Name": self.tower.name, "Fire Rate": self.tower.fire_rate, "Damage": self.tower.damage, "DPS": dps_calc, "Damage Done": self.tower.damage_done} if extra_attributes is None: extra_attributes = dict() self.t_attributes = dict(tower_attributes.items() + extra_attributes.items()) # Upgrades self.font = font.Font(None, 18) self.upgrade_button = Surface((100, 50)).convert() self.upgrade_button.fill((0, 255, 0)) self.upgrade_button.blit(self.font.render("Upgrade", 1, (0, 0, 0)), (self.upgrade_button.get_width()/2 - self.font.size("Upgrade")[0]/2, self.upgrade_button.get_height()/2 - self.font.size("Upgrade")[1]/2)) self.image.blit(self.upgrade_button, (self.image.get_width() - self.upgrade_button.get_width(), self.image.get_height() - self.upgrade_button.get_height())) level_text = "Level: " + str(self.tower.level) self.image.blit(self.font.render(level_text, 1, (0, 0, 0)), (self.image.get_width() - self.upgrade_button.get_width(), self.image.get_height() - self.upgrade_button.get_height() - self.font.size(level_text)[1])) self.image.blit(self.tower.image, (self.s_width/2 - self.tower.image.get_width()/2, 2)) y_value = self.tower.image.get_width() + 7 # Blits the tower description for desc in self.length_splitter(self.font, self.tower.description, self.image.get_width() - 5): self.image.blit(self.font.render(desc, 1, (0, 0, 0)), (5, y_value)) y_value += self.font.get_height() + 1 y_value += 5 # Blits the tower's attributes in this order, tacking all extra stuff at the end for attr in ["Name", "Fire Rate", "Damage", "DPS", "Damage Done"]+extra_attributes.keys(): value = self.t_attributes[attr] self.image.blit(self.font.render(attr + ": " + str(value), 1, (0, 0, 0)), (5, y_value)) y_value += self.font.get_height() + 1 #self.image = OutlinedSurface(self.image, 5).surface @staticmethod # Used to split text up into lines that will fit the surface def length_splitter(font, text, maxlength): ret_list = [] explode = text.split() t_str = "" while len(explode) > 0: if font.size(t_str + explode[0])[0] > maxlength: ret_list.append(t_str) t_str = "" else: t_str += explode.pop(0) + " " if len(explode) == 0: ret_list.append(t_str) return ret_list
class Gameboard(object): ''' classdocs ''' def __init__(self, surface, width, height, song_filename): ''' Constructor ''' #progressively increase; must end with 1 self.PROB_HEALTH = 0.4 self.PROB_KI = 0.7 self.PROB_SHIELD = 0.9 self.PROB_SWORD = 1.0 self.windowSurface = surface self.width = width self.height = height self.song_filename = song_filename board_size = (width, height) self.gameSurface = Surface(board_size) # This will be drawn every frame to the window song_file = open(song_filename) self.song_name = song_file.readline().strip() self.song_length = float(song_file.readline()) self.pixels_per_second = float(song_file.readline()) self.level_filename = song_file.readline().strip() self.music_filename = song_file.readline().strip() self.background_filename = song_file.readline().strip() self.pixel_offset = 0 self.last_frame_time = -1 self.frac_scroll = 0 # print "{0}[{1}] : {2}".format(self.song_name, self.song_length, self.pixels_per_second) # self.background_width = (self.pixels_per_second * self.song_length) + width self.background_width = width + 96 # Jank scroll edition! background_size = (self.background_width, height) self.backgroundSurface = Surface(background_size) self.__render_background() self.backgroundSurface.set_colorkey((0,0,0),pygame.RLEACCEL) #self.backgroundSurface.set_colorkey((217,62,245),pygame.RLEACCEL) #self.backgroundSurface.set_alpha(100,pygame.RLEACCEL) self.mainScreenBackground,self.mainScreenBackgroundRect = load_image_from_folder('backgrounds', self.background_filename) #self.backgroundSurface.blit(mainScreenBackground, (0,0)) #self.__render_background() possible_samurai_positions = [] for i in range(0, 6): possible_samurai_positions.append(PATH_HEIGHT * i + 15) self.samurai = Samurai(possible_samurai_positions) self.samurai_sprite_group = Group(self.samurai) self.bridge_group = OrderedUpdates() self.mine_group = OrderedUpdates() self.enemy_group = OrderedUpdates() self.attack_group = OrderedUpdates() self.healthpack_group = OrderedUpdates() self.ki_potion_group = OrderedUpdates() self.shield_group = OrderedUpdates() self.sword_group = OrderedUpdates() self.explosion_group = OrderedUpdates() # tempSprite = self.samurai_sprite_group.sprites() # tempRect = tempSprite[0].get_rect() # self.testSword = VerticalSlash(tempRect.centerx,tempRect.centery, self.remove_attack) # self.attack_group.add(self.testSword) if sys.platform == "win32": # On Windows, the best timer is time.clock() self.default_timer = time.clock else: # On most other platforms, the best timer is time.time() self.default_timer = time.time def draw(self): self.gameSurface.fill((0,0,0)) #self.gameSurface.fill((217,62,245)) origin = (0, 0) # this_scroll = 0 self.scroll_amount = 0 if self.last_frame_time > 0: cur_time = self.default_timer() self.gap_time = cur_time - self.last_frame_time # print "Pixels per second: {0}\nGap Time: {1}\nScrollAmount: {2}".format(self.pixels_per_second, self.gap_time, this_scroll) self.last_frame_time = cur_time else: self.gap_time = 0 self.last_frame_time = self.default_timer() this_scroll = self.pixels_per_second * self.gap_time self.frac_scroll += this_scroll if self.frac_scroll >= 1: self.scroll_amount = math.floor(self.frac_scroll) self.pixel_offset += self.scroll_amount # print "Now scrolling {0} pixel(s)".format(whole_part) self.frac_scroll -= self.scroll_amount if self.pixel_offset > 96: self.pixel_offset = self.pixel_offset - 96 if self.pixel_offset < 0: self.pixel_offset = 0 self.gameSurface.blit(self.mainScreenBackground, origin) window_rect = Rect(self.pixel_offset, 0, self.gameSurface.get_width(), self.gameSurface.get_height()) # print window_rect self.gameSurface.blit(self.backgroundSurface, origin, window_rect) #All other drawing self.bridge_group.update(self.scroll_amount) self.bridge_group.draw(self.gameSurface) self.mine_group.update(self.scroll_amount) self.mine_group.draw(self.gameSurface) self.enemy_group.update(self.scroll_amount) self.enemy_group.draw(self.gameSurface) self.samurai_sprite_group.update() self.samurai_sprite_group.draw(self.gameSurface) self.healthpack_group.update(self.scroll_amount) self.healthpack_group.draw(self.gameSurface) self.ki_potion_group.update(self.scroll_amount) self.ki_potion_group.draw(self.gameSurface) self.shield_group.update(self.scroll_amount) self.shield_group.draw(self.gameSurface) self.sword_group.update(self.scroll_amount) self.sword_group.draw(self.gameSurface) #self.testSword = VerticalSlash(400,400) #self.attack_group.add(self.testSword) self.attack_group.update() self.attack_group.draw(self.gameSurface) self.explosion_group.update() self.explosion_group.draw(self.gameSurface) # self.testSword.draw(self.gameSurface) for bridge in self.bridge_group.sprites(): if bridge.rect.left < 0: self.bridge_group.remove(bridge) #Annnnd blast it back to the screen window_origin = (0, 60) self.windowSurface.blit(self.gameSurface, window_origin) def add_bridge(self, bridge_num): # print "FAKE BRIDGE" new_bridge = Bridge(1101, bridge_num * PATH_HEIGHT + 39) self.bridge_group.add(new_bridge) def add_mine(self, string_num): # print "CREATE ZE LANDMINE" new_mine = Mine(1101, PATH_HEIGHT * string_num + 42) self.mine_group.add(new_mine) def add_powerup(self, string_num): r = random.random() if r < self.PROB_HEALTH: self.add_healthpack(string_num) elif r < self.PROB_KI: self.add_kiboost(string_num) elif r < self.PROB_SHIELD: self.add_shield(string_num) elif r < self.PROB_SWORD: self.add_sword(string_num) def add_healthpack(self, string_num): # print "such a healthy young man!" new_healthpack = Healthpack(1101, PATH_HEIGHT * string_num + 42) self.healthpack_group.add(new_healthpack) def add_shield(self, string_num): new_shield = Shield(1101, PATH_HEIGHT * string_num + 42) self.shield_group.add(new_shield) def add_sword(self, string_num): new_sword = MegaSword(1101, PATH_HEIGHT * string_num + 42) self.sword_group.add(new_sword) def add_kiboost(self, string_num): new_ki_potion = KiPotion(1101, PATH_HEIGHT * string_num + 42) self.ki_potion_group.add(new_ki_potion) def add_enemy(self, string_num): new_enemy = Enemy(1111, PATH_HEIGHT * string_num + 42) self.enemy_group.add(new_enemy) def add_male_groupie(self, string_num): new_enemy = MaleGroupie(1111, PATH_HEIGHT * string_num + 15) self.enemy_group.add(new_enemy) def add_lawyer(self, string_num): new_lawyer = Lawyer(1111, PATH_HEIGHT * string_num + 15) self.enemy_group.add(new_lawyer) def add_bodyguard(self, string_num): new_bodyguard = Bodyguard(1111, PATH_HEIGHT * string_num + 15) self.enemy_group.add(new_bodyguard) def remove_attack(self, attack): self.attack_group.remove(attack) def add_attack(self, attack): self.attack_group.add(attack) def add_explosion(self, y_val): new_explosion = Explosion(20, y_val, self.explosion_group) def __render_background(self): # Jank implementation that just uses that one sprite over and over again! # Jay's jank dirtBlockThingy is 96x48 pixels num_blocks = int(math.ceil(self.background_width / 96.0)) cur_width = 0 for bI in range(0, num_blocks): for hI in range(0, 6): my_location = (cur_width, (PATH_HEIGHT * hI + 35)) dp = DirtPath(my_location) # print "DirtPath at {0}".format(my_location) self.backgroundSurface.blit(dp.image, my_location) cur_width += 96
def change_vaus_behavior(state, vaus): if state == 'C': pass elif state == 'L': ''' VAUS LASER ''' surfaces = [] laser_sheet_area = Surface((160, 8)) # 32 * 5 laser1_posx = 0 laser2_posx = 32 laser3_posx = 64 laser4_posx = 96 laser5_posx = 128 # En este caso el área 1 coincide con el área del recuadro para el estado inicial area1 = (0, 0, 32, 8) surfaces.append(area1) area2 = Surface((32, 8)) area2_borderlaser = (64, 8, 8, 8) area2_normalbody = (80, 0, 8, 7) area2_borderright = (112, 0, 8, 8) # borde izquierdo vaus láser area2.blit(vaus.animation_sheet.subsurface(area2_borderlaser), (0, 0)) area2.blit(vaus.animation_sheet.subsurface(area2_normalbody), (8, 0)) area2.blit(vaus.animation_sheet.subsurface(area2_normalbody), (16, 0)) area2.blit(vaus.animation_sheet.subsurface(area2_borderright), (24, 0)) surfaces.append((laser2_posx, 0, area2.get_width(), area2.get_height())) area3 = Surface((32, 8)) # Vamos reciclando piezas del vaus láser de áreas anteriores (por ejemplo, podemos reusar el borde del láser) area3_laserbody = (80, 8, 8, 7) area3.blit(vaus.animation_sheet.subsurface(area2_borderlaser), (0, 0)) area3.blit(vaus.animation_sheet.subsurface(area3_laserbody), (8, 0)) area3.blit(vaus.animation_sheet.subsurface(area2_normalbody), (16, 0)) area3.blit(vaus.animation_sheet.subsurface(area2_borderright), (24, 0)) surfaces.append((laser3_posx, 0, area3.get_width(), area3.get_height())) area4 = Surface((32, 8)) area4.blit(vaus.animation_sheet.subsurface(area2_borderlaser), (0, 0)) area4.blit(vaus.animation_sheet.subsurface(area3_laserbody), (8, 0)) area4.blit(vaus.animation_sheet.subsurface(area3_laserbody), (16, 0)) area4.blit(vaus.animation_sheet.subsurface(area2_borderright), (24, 0)) surfaces.append((laser4_posx, 0, area4.get_width(), area4.get_height())) area5 = (0, 16, 32, 8) surfaces.append((laser5_posx, 0, area5[2], area5[3])) laser_sheet_area.blit(vaus.animation_sheet.subsurface(area1), (laser1_posx, 0)) laser_sheet_area.blit(area2, (laser2_posx, 0)) laser_sheet_area.blit(area3, (laser3_posx, 0)) laser_sheet_area.blit(area4, (laser4_posx, 0)) laser_sheet_area.blit(vaus.animation_sheet.subsurface(area5), (laser5_posx, 0)) vaus.animation_sheet = laser_sheet_area vaus.frames = 5 vaus.current_frame = 0 vaus.animate = True vaus.shoot = True return surfaces elif state == 'E': ''' VAUS ELONGATED ''' # Creamos superficie uniendo subsuperficies de una misma sprite sheet # 4 fotogramas # Listado en blanco de áreas, sobre el que se iterará en play_animation() (sprite_factory.py) surfaces = [] elongated_sheet_area = Surface((120, 8)) elongated1_posx = 0 elongated2_posx = 32 # Ancho elongated1 elongated3_posx = 72 # Ancho elongated1 más ancho elongated2 (32 + 40 = 72) # areax = área calculada DE LA SPRITE SHEET ORIGINAL # Original: 32x8 # Esta primera área vale tanto para el sprite en la original como para el sprite en la nueva sprite sheet area1 = (0, 0, 32, 8) surfaces.append(area1) # Elongated 1: 40x8 area2 = Surface((40, 8)) area2_borderleft = (64, 0, 8, 8) area2_center = (80, 0, 8, 7) # x3 area2_borderright = (112, 0, 8, 8) area2.blit(vaus.animation_sheet.subsurface(area2_borderleft), (0, 0)) area2.blit(vaus.animation_sheet.subsurface(area2_center), (8, 0)) area2.blit(vaus.animation_sheet.subsurface(area2_center), (16, 0)) area2.blit(vaus.animation_sheet.subsurface(area2_center), (24, 0)) area2.blit(vaus.animation_sheet.subsurface(area2_borderright), (32, 0)) # Ubicación del segundo sprite en la nueva sprite sheet surfaces.append((elongated2_posx, 0, area2.get_width(), area2.get_height())) # Elongated final: 48x8 area3 = (0, 8, 48, 8) # Ubicación del tercer sprite en la nueva sprite sheet surfaces.append((elongated3_posx, 0, area3[2], area3[3])) # Pintamos las áreas en la superficie en blanco elongated_sheet_area.blit(vaus.animation_sheet.subsurface(area1), (elongated1_posx, 0)) elongated_sheet_area.blit(area2, (elongated2_posx, 0)) elongated_sheet_area.blit(vaus.animation_sheet.subsurface(area3), (elongated3_posx, 0)) vaus.animation_sheet = elongated_sheet_area vaus.frames = 3 vaus.current_frame = 0 vaus.animate = True return surfaces elif state == 'D': pass
class Shop(): def __init__(self, name, inventory, priceModifier, groupInventory, groupMoney, itemPrices, position, blitPosition, money, resourcePath): self.yValue = 40 self.groupInventory = groupInventory self.groupMoney = groupMoney self.priceModifier = priceModifier self.itemPrices = itemPrices self.inventory = inventory self.position = position self.blitPosition = blitPosition self.resourcePath = resourcePath self.buyButtonList = [] self.sellButtonList = [] self.xPos = (-self.position * 40) + 1280 self.shopSurface = Surface((500, 300)).convert() self.sepLine = Surface((self.shopSurface.get_width(), 10)).convert() self.sepLine.fill((0, 0, 0)) self.invContainer = Surface((self.shopSurface.get_width() - 20, self.shopSurface.get_height() / 2 - 35)).convert() self.invContainer.fill((255, 255, 255)) self.titleFont = font.Font("res/fonts/west.ttf", 17) self.textFont = font.Font("res/fonts/west.ttf", 15) if (name == ""): self.name = (choice(SHOP_PREFIX) + "'s " + choice(SHOP_SUFFIX)).capitalize() else: self.name = name if (self.inventory == {}): inventoryRandom = copy(self.groupInventory) for key in list(inventoryRandom.keys()): inventoryRandom[key] = randint(0, 10) inventoryRandom["Food"] *= 20 self.inventory = inventoryRandom if (money is None): self.money = randint(200, 500) else: self.name = name self.render() def get_surface(self): self.render() return self.shopSurface def update(self, groupInv, groupMoney): self.groupInventory = groupInv self.groupMoney = groupMoney self.render() def move(self, moveValue): self.xPos += (2 * moveValue) self.render() def render(self): self.yValue = 40 self.shopSurface.fill((133, 94, 66)) self.shopSurface.blit(self.titleFont.render(self.name + " - $" + str(self.money), 1, (0, 0, 255)), (10, 5)) self.shopSurface.blit(self.invContainer, (10, 25)) self.shopSurface.blit(self.invContainer, (10, self.shopSurface.get_height() / 2 + 30)) self.shopSurface.blit(self.textFont.render("Inventory", 1, (255, 0, 0)), (10, 25)) self.shopSurface.blit(self.textFont.render("Amount", 1, (255, 0, 0)), (130, 25)) self.shopSurface.blit(self.textFont.render("Price", 1, (255, 0, 0)), (200, 25)) for key in list(self.inventory.keys()): self.shopSurface.blit(self.textFont.render(key + ":", 1, (0, 0, 0)), (10, self.yValue)) self.shopSurface.blit(self.textFont.render(str(self.inventory[key]), 1, (0, 0, 0)), (150, self.yValue)) self.shopSurface.blit(self.textFont.render("$"+str(self.itemPrices[key] * self.priceModifier), 1, (0, 0, 0)), (200, self.yValue)) if (len(self.buyButtonList) < len(self.inventory.keys())): buttonPos = tuple(map(sum, zip(self.blitPosition, (250, self.yValue)))) self.buyButtonList.append(TransactionButton(transaction = "buy", item = key, imagePosition = (250, self.yValue), rectPosition = buttonPos, resourcePath = self.resourcePath)) self.yValue += 30 for button in self.buyButtonList: self.shopSurface.blit(button.image, button.imagePosition) self.shopSurface.blit(self.sepLine, (0, float(self.shopSurface.get_height()) / 2)) self.shopSurface.blit(self.titleFont.render("You - $" + str(self.groupMoney), 1, (0, 0, 255)), (10, float(self.shopSurface.get_height()) / 2 + 10)) self.shopSurface.blit(self.titleFont.render("Inventory", 1, (255, 0, 0)), (10, float(self.shopSurface.get_height()) / 2 + 30)) self.shopSurface.blit(self.titleFont.render("Amount", 1, (255, 0, 0)), (130, float(self.shopSurface.get_height()) / 2 + 30)) self.shopSurface.blit(self.titleFont.render("Price", 1, (255, 0, 0)), (200, float(self.shopSurface.get_height()) / 2 + 30)) self.yValue = (float(self.shopSurface.get_height()) / 2) + 45 for key in list(self.groupInventory.keys()): self.shopSurface.blit(self.textFont.render(key + ":", 1, (0, 0, 0)), (10, self.yValue)) self.shopSurface.blit(self.textFont.render(str(self.groupInventory[key]), 1, (0, 0, 0)), (150, self.yValue)) self.shopSurface.blit(self.textFont.render("$" + str(self.itemPrices[key] * self.priceModifier), 1, (0, 0, 0)), (200, self.yValue)) if (len(self.sellButtonList) < len(self.inventory.keys())): buttonPos = tuple(map(sum, zip(self.blitPosition, (250, self.yValue)))) self.sellButtonList.append(TransactionButton(transaction = "sell", item = key, imagePosition = (250, self.yValue), rectPosition = buttonPos, resourcePath = self.resourcePath)) self.yValue += 30 for button in self.sellButtonList: self.shopSurface.blit(button.image, button.imagePosition)
class SnakeUI: """Snake's game menu """ def __init__(self, main_ui, game=None): if game != None: self.snake_game = game else: level_manager = LevelManager(LEVELS_DIRECTORY) self.snake_game = Game(level_manager) self.last_move = GameMoves.PASS self.main_ui = main_ui level = self.snake_game.current_level self.maze_size = (level.maze_height, level.maze_width) self.game_surface = Surface(transform(self.maze_size, 2, 2)) #colors and images self.green_color = Color(151, 255, 148) self.white_color = Color(255, 255, 255) self.black_color = Color(0, 0, 0) self.apple = image.load('images/apple.png') self.block = image.load('images/block.png') self.brick = image.load('images/brick.jpg') #fonts self.info_font = font.Font(None, 23) self.is_running = True def draw(self): if self.is_running and self.main_ui.frame % GUI_GAME_SPEED == 0: self.snake_game.move(self.last_move) self.last_move = GameMoves.PASS level = self.snake_game.current_level if self.maze_size != (level.maze_width, level.maze_height): self.maze_size = (level.maze_height, level.maze_width) self.game_surface = Surface(transform(self.maze_size, 2, 2)) self.game_surface.fill(self.green_color) self.__draw_apple() self.__draw_snake() self.__draw_barrier() self.__draw_level_info() surface_width = self.main_ui.surface.get_width() surface_height = self.main_ui.surface.get_height() game_width = self.game_surface.get_width() game_height = self.game_surface.get_height() y_pos = surface_width / 2 - game_width / 2 x_pos = surface_height / 2 - game_height / 2 game_surface_pos = (y_pos, x_pos) self.main_ui.surface.blit(self.game_surface, game_surface_pos) def __draw_apple(self): apple_position = transform(self.snake_game.current_level.apple, 1, 1) self.game_surface.blit(self.apple, apple_position) def __draw_snake(self): level = self.snake_game.current_level for block in level.snake: self.game_surface.blit(self.block, transform(block, 1, 1)) def __draw_barrier(self): level = self.snake_game.current_level for brick in level.barrier: self.game_surface.blit(self.brick, transform(brick, 1, 1)) brick_height = self.brick.get_height() brick_width = self.brick.get_width() maze_height = self.game_surface.get_height() maze_width = self.game_surface.get_width() for x in range(0, maze_width, brick_width): self.game_surface.blit(self.brick, (x, 0)) for x in range(0, maze_width, brick_width): self.game_surface.blit(self.brick, (x, maze_height - brick_height)) for y in range(0, maze_height, brick_height): self.game_surface.blit(self.brick, (0, y)) for y in range(0, maze_height, brick_height): self.game_surface.blit(self.brick, (maze_width - brick_width, y)) def __draw_level_info(self): level = self.snake_game.current_level current_level = level.level snake_len = level.snake_length snake_max_len = level.snake_max_length info ='Level: {0} Snake Length: {1}/{2}'\ .format(current_level, snake_len, snake_max_len) info_surface = self.info_font.render(info, False, self.black_color) self.main_ui.surface.blit(info_surface, (10, 10)) def handle_events(self): for current_event in pygame.event.get(): if current_event.type == QUIT: pygame.quit() sys.exit() elif current_event.type == KEYDOWN: if current_event.key == K_LEFT: self.last_move = GameMoves.LEFT elif current_event.key == K_RIGHT: self.last_move = GameMoves.RIGHT elif current_event.key == K_UP: self.last_move = GameMoves.UP elif current_event.key == K_DOWN: self.last_move = GameMoves.DOWN elif current_event.key == K_ESCAPE: self.main_ui.state = GameMenuUI(self.main_ui, self)
def surface_with_node(surface, node, angle, offset_in, current_resize_offset, widthscalar, heightscalar): transformedlists = transformtopointlists(node.plantshapelist, node.shiftchance, angle, widthscalar, heightscalar) mainloffset = None mainltranslated = None def currentoffset(): return (offset_in[0] + current_resize_offset[0], offset_in[1] + current_resize_offset[1]) def surface_offset(pointlist_bounds): return Rect(currentoffset()[0]-node.anchor[0]+pointlist_bounds[0], currentoffset()[1]-node.anchor[1]+pointlist_bounds[1], pointlist_bounds.width, pointlist_bounds.height) # go through all the plantshapes and their corresponding transformed lists for i in range(len(transformedlists)): currentlist = transformedlists[i] bounds = getlistbounds(currentlist) # make the surface shape_surface = Surface((bounds.width, bounds.height), SRCALPHA) # translate points into this surface shiftedlist = offsetpointlist(currentlist, (-bounds[0], -bounds[1])) # draw the plant shape onto the new surface plantshape = node.plantshapelist[i] if plantshape.fillcolor != None: gfxdraw.filled_polygon(shape_surface, shiftedlist, plantshape.fillcolor) if plantshape.outlinecolor != None: gfxdraw.polygon(shape_surface, shiftedlist, plantshape.outlinecolor) # apply the texture if any for ptexture in plantshape.textures: addtexture(shape_surface, ptexture) # now check if resizing is needed newsurfacerect = surface.get_rect().union(surface_offset(bounds)) if not newsurfacerect == surface.get_rect(): new_surface = Surface((newsurfacerect.width, newsurfacerect.height), SRCALPHA) new_surface.blit(surface, (-newsurfacerect.x, -newsurfacerect.y)) current_resize_offset = (current_resize_offset[0]-newsurfacerect.x, current_resize_offset[1]-newsurfacerect.y) surface = new_surface devprint("Resized surface to " + str(new_surface.get_width()) + " by " + str(new_surface.get_height())) surface.blit(shape_surface, surface_offset(bounds)) # also save the first list for other nodes to go off of if i == 0: # save the offset of l without the resizing mainloffset = surface_offset(bounds) # also remove the current resize offset mainloffset = (mainloffset[0] - current_resize_offset[0], mainloffset[1]-current_resize_offset[1]) mainltranslated = shiftedlist return surface, mainltranslated, mainloffset, current_resize_offset
class Buffalo(): def __init__(self, posX, posY, picture, size, resourcePath): self.picture = picture self.size = size self.resourcePath = resourcePath self.maxHealth = 100 * self.size self.health = self.maxHealth self.preimage = image.load(self.resourcePath + "img/" + self.picture + "_buffalo.png") self.image = scale(self.preimage, (int(self.preimage.get_width() * self.size), int(self.preimage.get_height() * self.size))) self.healthFont = font.Font(None, 20) self.healthBarContainer = Surface((int(75 * self.size), int(12 * self.size))).convert() self.healthBarShader = Surface((self.healthBarContainer.get_width() + 6, self.healthBarContainer.get_height() + 6)).convert() self.healthNumber = self.healthFont.render(str(self.health), 1, (0, 0, 0)) self.healthBarShader.fill((175, 175, 175)) self.healthBar = Surface(self.healthBarContainer.get_size()).convert() self.healthColour = () if (self.health >= 50): self.healthColour = (float((self.maxHealth - self.health) * 2 / self.maxHealth * 255), 255, 0) else: self.healthColour = (255, float(self.health * 2 / self.maxHealth * 255), 0) try: self.healthBar.fill(self.healthColour) except TypeError: self.healthBar.fill((0, 0, 0)) self.healthBarContainer.blit(self.healthBar, (0, 0)) self.value = 20 * self.size self.rect = Rect((0, 0), self.image.get_size()) self.rect.x = posX self.rect.y = posY self.status = "alive" self.targetY = posY def update(self): self.preimage = image.load(self.resourcePath + "img/" + self.status + "_buffalo.png") self.image = scale(self.preimage, (int(self.preimage.get_width() * self.size), int(self.preimage.get_height() * self.size))) self.healthBarContainer = Surface((int(75 * self.size), int(12 * self.size))).convert() self.healthNumber = self.healthFont.render(str(int(self.health)), 1, (255, 255, 255)) self.healthBarShader = Surface((self.healthBarContainer.get_width() + 6, self.healthBarContainer.get_height() + 6)).convert() self.healthBarShader.fill((175, 175, 175)) if (self.health <= 0): self.healthBar = Surface((0, 0)).convert() else: self.healthBar = Surface((int(self.healthBarContainer.get_width() / self.maxHealth * self.health), self.healthBarContainer.get_height())).convert() if (self.health >= 50): self.healthColour = (float((self.maxHealth - self.health) * 2 / self.maxHealth * 255), 255, 0) else: self.healthColour = (255, float(self.health * 2 / self.maxHealth * 255), 0) try: self.healthBar.fill(self.healthColour) except TypeError: self.healthBar.fill((0, 0, 0)) self.healthBarContainer.blit(self.healthBar, (0, 0)) self.healthBarContainer.blit(self.healthNumber, (self.healthBarContainer.get_width() / 2 - self.healthNumber.get_width() / 2, self.healthBarContainer.get_height() / 2 - self.healthNumber.get_height() / 2)) self.healthBarShader.blit(self.healthBarContainer, (3, 3)) if (self.status == "alive"): self.rect.x += float(3 - self.size) if (self.rect.y != self.targetY): if (self.rect.y < self.targetY): self.rect.y += float(3 - self.size) elif (self.rect.y > self.targetY): self.rect.y -= float(3 - self.size) return self.rect.center
class Weapon(Item): def __init__(self, game, name): """ Slightly depreciated weapon class. Will need major rewriting. Used for loading and applying weapon characteristics to the player. """ self.game = game #setup base vars of all weapon(s) self.type = None self.shown = True self.range = 10 self.damage = 1 self.cooldown = 500 # in MS self.speed = 4 self.projectile = None self.loadWeapon(name) # attack based vars self.attacking = False def loadWeapon(self, name): """ Uses the weapon config file to load all weapon characteristics. """ config_file = open(os.path.join('rec', 'weapon', name, 'config.py')).read() exec(config_file) self.hold_image = img_load(os.path.join('rec', 'weapon', name, 'hold.png')).convert_alpha() if os.path.exists(os.path.join('rec', 'weapon', name, 'attack.png')): self.attack_image = img_load(os.path.join('rec', 'weapon', name, 'attack.png')).convert_alpha() else: self.attack_image = Surface([1, 1]) def getSurface(self, name): fi_name = name.lower().replace(' ', '_') + '.png' return img_load(os.path.join(self.game.main_path, 'rec', 'weapon', name, fi_name)) def preUpdate(self, ttime): """ Called before the update function, can be overriden for new functionality. """ pass def update(self, ttime): """ Main weapon update, should not be overriden. """ self.preUpdate(ttime) if self.type == 'short': self.shortUpdate() elif self.type == 'long': self.longUpdate() elif self.type == 'ranged': self.rangedUpdate() else: pass def shortAttack(self): self.attacking = True if self.game.Player.player_face == 'front': # I do not know why this vector needs to be 0 while the others are like, 1 self.directional_attack_image = rotate(self.attack_image, 180) self.sub_vector = [0, 0] elif self.game.Player.player_face == 'left': self.directional_attack_image = rotate(self.attack_image, 90) self.sub_vector = [-1, 0] elif self.game.Player.player_face == 'back': self.directional_attack_image = rotate(self.attack_image, 0) self.sub_vector = [0, -1] elif self.game.Player.player_face == 'right': self.directional_attack_image = rotate(self.attack_image, 270) self.sub_vector = [0.8, 0] # editing this seems to change the speed of the right dagger swing a bit self.game.Player.can_move = False self.receding = False self.potent = True self.weapon_rect = Rect(1, 1, 1, 1) p_coords = [self.game.Player.player_r.x, self.game.Player.player_r.y] a_coords = [p_coords[0] + self.game.Player.getRigging()[0], p_coords[1] + self.game.Player.getRigging()[1]] if self.game.Player.player_face == 'right' or self.game.Player.player_face == 'left': a_coords = [a_coords[0] - self.attack_image.get_height(), a_coords[1] - self.attack_image.get_width()] self.blit_pos = a_coords self.attack_ticks = self.range def shortUpdate(self): if self.attacking: for repeats in xrange(self.speed): self.game.Player.player_state = 3 self.blit_pos[0] += self.sub_vector[0] self.blit_pos[1] += self.sub_vector[1] if self.receding: self.attack_ticks += 1 elif not self.receding: self.attack_ticks -= 1 # check all monsters for touching weapon for index, monster in enumerate(self.game.EntityHandler.monsters): if monster.rect.colliderect(self.weapon_rect): if self.potent: monster.takeDamage(index, self.damage) self.potent = False if self.attacking and self.attack_ticks == self.range and self.receding: self.attacking = False self.game.Player.can_move = True elif self.attacking and self.attack_ticks <= 0 and not self.receding: self.receding = True self.sub_vector[0] *= -1 self.sub_vector[1] *= -1 def shortBlit(self): if self.attacking: if self.game.Player.player_face == 'front' or self.game.Player.player_face == 'back': height = self.directional_attack_image.get_rect().height d_rect = Rect([0, height - (self.range - self.attack_ticks)], [100, 100]) self.weapon_rect = self.game.screen.blit(self.directional_attack_image, self.game.off([self.blit_pos[0], self.blit_pos[1]]), d_rect) unoff_pos = self.game.unoff([self.weapon_rect.x, self.weapon_rect.y]) self.weapon_rect.x = unoff_pos[0] self.weapon_rect.y = unoff_pos[1] elif self.game.Player.player_face == 'right' or self.game.Player.player_face == 'left': pos = self.game.off([self.blit_pos[0] + self.rigging[1], self.blit_pos[1]]) if self.game.Player.player_face == 'left': #this prevents the "hover" look of the dagger off the default player body pos[0] += 7 width = self.directional_attack_image.get_rect().width d_rect = Rect([width - (self.range - self.attack_ticks), 0], [100, 100]) self.weapon_rect = self.game.screen.blit(self.directional_attack_image, pos, d_rect) unoff_pos = self.game.unoff([self.weapon_rect.x, self.weapon_rect.y]) self.weapon_rect.x = unoff_pos[0] self.weapon_rect.y = unoff_pos[1] def longAttack(self): self.attacking = True self.y_offset = 0 self.x_offset = 0 if self.game.Player.player_face == "front": self.init_angle = 180 elif self.game.Player.player_face == "back": self.init_angle = 0 self.y_offset = -self.game.Player.getSize()[1]*0.60 - self.attack_image.get_height() self.x_offset = -self.game.Player.getSize()[0]*0.60 elif self.game.Player.player_face == "left": self.init_angle = 90 self.x_offset = -self.game.Player.getSize()[0] - self.attack_image.get_height() elif self.game.Player.player_face == "right": self.init_angle = 270 self.directional_attack_image = rotate(self.attack_image, self.init_angle) self.attack_rect = self.directional_attack_image.get_rect() self.angle = 0 def longUpdate(self): if self.attacking: for x in xrange(5): attack_size = self.directional_attack_image.get_size() turn_point = [0, 0] if self.game.Player.isVertical(): turn_point = [attack_size[0]/2, 0] elif self.game.Player.isHorizontal(): turn_point = [0, attack_size[1]/2] self.mod_DAT = rotate(self.directional_attack_image, self.angle + 45) if self.angle < -90: self.attacking = False self.angle -= 1 def longBlit(self): if self.attacking: blit_pos = self.game.off(self.game.Player.getPos()) blit_pos = vector.add(blit_pos, self.game.Player.getRigging()) blit_pos = vector.sub(blit_pos, self.attack_image.get_size()) #offset for left/back blit_pos[0] += self.x_offset blit_pos[1] += self.y_offset self.new_rect = self.game.screen.blit(self.mod_DAT, blit_pos) self.new_rect.center = self.attack_rect.center self.attack_rect = self.new_rect def rangedAttack(self): pass def rangedUpdate(self): pass def rangedBlit(self): pass def blit(self): """ Called before the player is blitted """ if self.game.Player.player_face == 'back' and not self.attacking: self.drawInHand() if self.type == 'short': self.shortBlit() elif self.type == 'long': self.longBlit() elif self.type == 'ranged': self.rangedBlit() def blitAfter(self): if self.game.Player.player_face == 'front' and not self.attacking: self.drawInHand() def drawInHand(self): p_coords = [self.game.Player.player_r.x, self.game.Player.player_r.y] a_coords = [p_coords[0] + self.game.Player.getRigging()[0] - self.game.Player.equipment['weapon'].rigging[0], p_coords[1] + self.game.Player.getRigging()[1] - self.game.Player.equipment['weapon'].rigging[1]] self.game.screen.blit(self.hold_image, self.game.off(a_coords)) def onClick(self, game, vector): """ Called when the world is clicked. Activates the weapon. """ if self.projectile: game.Projectile(game, self.projectile, vector) if self.type == 'short': self.shortAttack() elif self.type == 'long': self.longAttack() elif self.type == 'ranged': self.rangedAttack()
def drawplant(head_node): devprint("drawing plant") surface = Surface((40, 43), SRCALPHA) rootpos = (surface.get_width()/2, surface.get_height()-3) # the stack has the node, the currentx, and the currenty for each node in it # currentx and currenty are without resizing of the surface stack = [] # keeps track of offset needed because of resizing the surface resizeoffset = (0, 0) for i in range(head_node.repeatnumseparate): stack.append(head_node) firstx = potwidth * random.random() * head_node.brancharea + rootpos[0] stack.append(firstx) stack.append(rootpos[1]) stack.append(math.pi/2) # base angle strait up to start with callcount = 0 while len(stack) != 0 and callcount < 1000: callcount += 1 base_angle = stack.pop() currenty = stack.pop() currentx = stack.pop() node = stack.pop() randomspacings = [0] spacingLength = 0 for i in range(node.repeatnumcircle-1): randomspacings.append(random.uniform(node.anglespace-node.anglevariance*node.anglespace, node.anglespace+node.anglevariance*node.anglespace)) spacingLength += randomspacings[i+1] startspacing = random.uniform(-node.anglevariance*node.anglespace, node.anglevariance*node.anglespace)/2 * random.choice((-1, 1)) # start angle so that it points up on average angle = base_angle + startspacing - (spacingLength/2) + node.angleoffset*random.choice((-1, 1)) # update the random spacing to be final angles for i in range(len(randomspacings)): angle = angle + randomspacings[i] randomspacings[i] = angle for i in range(node.repeatnumcircle): # draw all the plantshapes at this angle # pick a random angle out of the list angle = randomspacings.pop(random.randint(0, len(randomspacings)-1)) widthscalar = 1 + random.random()*node.widthvariance heightscalar = 1 + random.random()*node.heightvariance # now add the current node surface, mainltranslated, mainloffset, new_resize_offset = surface_with_node(surface, node, angle, (currentx, currenty), resizeoffset, widthscalar, heightscalar) resizeoffset = new_resize_offset # find the new currentx and currenty mainlistlen = len(mainltranslated) # add all the children at the current position for childnode in node.children: futureindexpositions = getfuturenodeindexpositions(childnode.repeatnumseparate, mainlistlen, childnode.brancharea) for i in range(childnode.repeatnumseparate): futurex = mainltranslated[futureindexpositions[i]][0]+mainloffset[0] futurey = mainltranslated[futureindexpositions[i]][1]+mainloffset[1] stack.append(childnode) stack.append(futurex) stack.append(futurey) futureangle = listangleatindex(mainltranslated, futureindexpositions[i]) stack.append(futureangle) finalsurfaceanchor = (rootpos[0] + resizeoffset[0], rootpos[1]+resizeoffset[1]) # draw dirt clumps at bottom clumpradius = 4 clumprange = 14 clumpnum = 4 for i in range(clumpnum): gfxdraw.filled_circle(surface, int(finalsurfaceanchor[0] + i * clumprange/clumpnum - clumprange/2)+1, int(finalsurfaceanchor[1]), int(random.uniform(clumpradius/3, clumpradius)), brighten(dirtcolor, -10)) return surface, finalsurfaceanchor
class Buffalo(): """ Buffalo object used in the Hunting minigame """ def __init__(self, pos_x, pos_y, picture, size, resource_path): self.picture = picture self.size = size self.resource_path = resource_path self.max_health = 100 * self.size self.health = self.max_health self.preimage = image.load(self.resource_path+"Images/"+self.picture+"_buffalo.png") self.image = scale(self.preimage, (int(self.preimage.get_width()*self.size), int(self.preimage.get_height()*self.size))) self.health_font = font.Font(None, 20) self.health_bar_container = Surface((int(75*self.size), int(12*self.size))).convert() self.health_bar_shader = Surface((self.health_bar_container.get_width() + 6, self.health_bar_container.get_height() + 6)).convert() self.health_number = self.health_font.render(str(self.health), 1, (0, 0, 0)) self.health_bar_shader.fill((175, 175, 175)) self.health_bar = Surface(self.health_bar_container.get_size()).convert() self.health_color = () if self.health >= 50: self.health_color = (float((self.max_health-self.health)*2/self.max_health*255), 255, 0) else: self.health_color = (255, float(self.health*2/self.max_health*255), 0) try: self.health_bar.fill(self.health_color) except TypeError: self.health_bar.fill((0, 0, 0)) self.health_bar_container.blit(self.health_bar, (0, 0)) self.value = 20 * self.size self.rect = Rect((0, 0), self.image.get_size()) self.rect.x = pos_x self.rect.y = pos_y self.status = "alive" self.target_y = pos_y def update(self): # Checks the health and updates the health bar self.preimage = image.load(self.resource_path+"Images/"+self.status+"_buffalo.png") self.image = scale(self.preimage, (int(self.preimage.get_width()*self.size), int(self.preimage.get_height()*self.size))) #Create health bar + shader + container self.health_bar_container = Surface((int(75*self.size), int(12*self.size))).convert() self.health_number = self.health_font.render(str(int(self.health)), 1, (255, 255, 255)) self.health_bar_shader = Surface((self.health_bar_container.get_width() + 6, self.health_bar_container.get_height() + 6)).convert() self.health_bar_shader.fill((175, 175, 175)) if self.health <= 0: self.health_bar = Surface((0, 0)).convert() else: self.health_bar = Surface((int(self.health_bar_container.get_width()/self.max_health*self.health), self.health_bar_container.get_height())).convert() # Set the color of the health_bar_container Red->Yellow->Red based on HP if self.health >= 50: self.health_color = (float((self.max_health-self.health)*2/self.max_health*255), 255, 0) else: self.health_color = (255, float(self.health*2/self.max_health*255), 0) # Band-aid solution # It tends to crash here when self.health_color isn't a valid RGB for some reason try: self.health_bar.fill(self.health_color) except TypeError: self.health_bar.fill((0, 0, 0)) self.health_bar_container.blit(self.health_bar, (0, 0)) self.health_bar_container.blit(self.health_number, (self.health_bar_container.get_width()/2 - self.health_number.get_width()/2, self.health_bar_container.get_height()/2 - self.health_number.get_height()/2)) self.health_bar_shader.blit(self.health_bar_container, (3, 3)) # Defines movement if self.status == "alive": # If buffalo is alive, move them until they reach their target X and Y positions # TODO: this logic should be reworked self.rect.x += float(3 - self.size) if self.rect.y != self.target_y: if self.rect.y < self.target_y: self.rect.y += float(3 - self.size) elif self.rect.y > self.target_y: self.rect.y -= float(3 - self.size) return self.rect.center