def _createSurfaceImage(self, surfaceHeight): """ Make the ground surface image. IDEA: Try changing the color of the ground, or maybe even add a texture to it. """ LunarSurface.image = pygame.Surface( [screen_width_pixels, surfaceHeight + self._groundElevation], pygame.SRCALPHA, 32 ).convert_alpha() initialY = y = ( Surface.get_height(LunarSurface.image) - self._pointsY[0] + self._drop_amount - self._groundElevation ) polyCoords = [(0, y)] for i in range(1, len(self._pointsX)): y -= self._pointsY[i] polyCoords.append((self._pointsX[i], y)) surfaceCoords = list(polyCoords) polyCoords.append([screen_width_pixels, Surface.get_height(LunarSurface.image)]) polyCoords.append([0, Surface.get_height(LunarSurface.image)]) polyCoords.append([0, initialY]) pygame.draw.polygon(LunarSurface.image, (64, 64, 64, 128), polyCoords, 0) for i in range(0, len(surfaceCoords) - 1): if self._flatCoordinates.count(i) or self._flatEasyCoordinates.count(i): # NAM change color: color = 0, 255, 255 color = 255, 0, 0 width = 3 else: color = 128, 128, 128 width = 1 pygame.draw.line(LunarSurface.image, color, surfaceCoords[i], surfaceCoords[i + 1], width) self._plotlandingScores(surfaceCoords)
def _createSurfaceImage(self, surfaceHeight): """ Make the ground surface image. IDEA: Try changing the color of the ground, or maybe even add a texture to it. """ LunarSurface.image = pygame.Surface([screen_width_pixels, surfaceHeight + self._groundElevation], pygame.SRCALPHA, 32).convert_alpha() initialY = y = Surface.get_height(LunarSurface.image) - self._pointsY[0] + self._drop_amount - self._groundElevation polyCoords = [(0, y)] for i in range(1, len(self._pointsX)): y -= self._pointsY[i] polyCoords.append((self._pointsX[i], y)) surfaceCoords = list(polyCoords) polyCoords.append([screen_width_pixels, Surface.get_height(LunarSurface.image)]) polyCoords.append([0, Surface.get_height(LunarSurface.image)]) polyCoords.append([0, initialY]) pygame.draw.polygon(LunarSurface.image, (64, 64, 64), polyCoords, 0) for i in range(0, len(surfaceCoords) - 1): if self._flatCoordinates.count(i) or self._flatEasyCoordinates.count(i): color = 0, 255, 255 width = 2 else: color = 128, 128, 128 width = 1 pygame.draw.line(LunarSurface.image, color, surfaceCoords[i], surfaceCoords[i + 1], width) self._plotlandingScores(surfaceCoords)
def draw_vector(vector: Vector, color: Color, surface: Surface, pixel_meter_ratio: float): """Draws a given Vector object on a given Surface. Args: vector (Vector): The vector object to be visualized. color (Color): The color the vector should be. surface (Surface): The surface the vector should be drawn on. pixel_meter_ratio (float): The amount of pixels corresponding to one meter. """ surface_x = vector.x * pixel_meter_ratio surface_y = surface.get_height() - vector.y * pixel_meter_ratio line(surface, color, (0.0, surface.get_height()), (surface_x, surface_y), 1)
class ResizeAlert(RootObject): def __init__(self, width, height, root_object_manager: RootObjectManager, timeout=1): self.width = width self.height = height self.root_object_manager = root_object_manager self.timeout = timeout self.start_time = time() self.background = Surface((300, 200)) self.background.fill(BACKGROUND_COLOR) self.background.set_alpha(127) self.background_x = center(self.width, self.background.get_width()) self.background_y = center(self.height, self.background.get_height()) self.surface = Font(NANUMSQUARE_BOLD_FONT, 36, TEXT_COLOR).render(f'{width}x{height}') self.x = center(self.width, self.surface.get_width()) self.y = center(self.height, self.surface.get_height()) self.root_object_manager.remove_by_class(ResizeAlert) def tick(self): if time() - self.timeout > self.start_time: self.destroy() def render(self, surface: Surface): surface.blit(self.background, (self.background_x, self.background_y)) surface.blit(self.surface, (self.x, self.y)) def destroy(self): self.root_object_manager.remove(self)
def __init__(self, initialFuel): self._tardisFrame = [] self._tardisFrame.append(pygame.image.load("Resources/tardis0.png").convert_alpha()) self._tardisFrame.append(pygame.image.load("Resources/tardis1.png").convert_alpha()) self._tardisFrame.append(pygame.image.load("Resources/tardis2.png").convert_alpha()) self._tardisFrame.append(pygame.image.load("Resources/tardisLand0.png").convert_alpha()) self._tardisFrame.append(pygame.image.load("Resources/tardisLand1.png").convert_alpha()) self._tardisFrame.append(pygame.image.load("Resources/tardisLand2.png").convert_alpha()) self.tardisHeight = Surface.get_height(self._tardisFrame[0]) * self._imageResample self.tardisWidth = Surface.get_width(self._tardisFrame[0]) * self._imageResample self.altitude = screen_height_pixels - self.tardisHeight * 1 # NAM: Adjust start height self._landingStickLength = max(self.tardisHeight, self.tardisWidth) self.x = 50 self.angle = 0 self.angleDelta = 0 self.velocityX = 0.1 self.velocityY = 0 self.thrusting = False self.image = pygame.transform.rotozoom(self._tardisFrame[0], 0, self._imageResample) self.rotate(45) self.thrustSound = pygame.mixer.Sound("Resources/tardisthrust.ogg") self.thrustSound.set_volume(0.5) self.fuel = initialFuel pygame.sprite.Sprite.__init__(self) self.rect = Rect(self.x, 0, self.tardisWidth, self.tardisWidth) self.maxHeight = math.sqrt(self.tardisHeight * self.tardisHeight + self.tardisWidth * self.tardisWidth) self.rotationsPerSec = 0.2 self.recalculateRect()
def __init__(self, initialFuel): self._pandaFrame = [] self._pandaFrame.append(pygame.image.load("Resources/panda0.png").convert_alpha()) self._pandaFrame.append(pygame.image.load("Resources/panda1.png").convert_alpha()) self._pandaFrame.append(pygame.image.load("Resources/panda2.png").convert_alpha()) self._pandaFrame.append(pygame.image.load("Resources/pandaLand0.png").convert_alpha()) self._pandaFrame.append(pygame.image.load("Resources/pandaLand1.png").convert_alpha()) self._pandaFrame.append(pygame.image.load("Resources/pandaLand2.png").convert_alpha()) self.pandaHeight = Surface.get_height(self._pandaFrame[0]) * self._imageResample self.pandaWidth = Surface.get_width(self._pandaFrame[0]) * self._imageResample self.altitude = screen_height_pixels - self.pandaHeight * 2 self._landingStickLength = max(self.pandaHeight, self.pandaWidth) self.x = 50 self.angle = 0 self.angleDelta = 0 self.velocityX = 0.1 self.velocityY = 0 self.thrusting = False self.image = pygame.transform.rotozoom(self._pandaFrame[0], 0, self._imageResample) self.rotate(45) self.thrustSound = pygame.mixer.Sound('Resources/thrust.ogg') self.thrustSound.set_volume(0.25) self.fuel = initialFuel pygame.sprite.Sprite.__init__(self) self.rect = Rect(self.x, 0, self.pandaWidth, self.pandaWidth) self.maxHeight = math.sqrt(self.pandaHeight * self.pandaHeight + self.pandaWidth * self.pandaWidth) self.rotationsPerSec = 0.2 self.recalculateRect()
class HelpText(Text): """ HelpText class extended from Text class. It creates the game help sprite """ def __init__(self, game_env): Text.__init__(self, game_env, size=20) self.__game_env = game_env seperator = self.font.render(' ', 1, self.color) header = self.font.render('=== HELP ===', 1, self.color) footer = self.font.render('=== GOOD LUCK ===', 1, self.color) all_surfaces = [] all_surfaces.append(seperator) all_surfaces.append(self.font.render('Your objective should you choose to accept is to navigate your jet without getting hit by', 1, self.color)) all_surfaces.append(self.font.render('the incoming missiles. For self-defence you can shoot down the enemy missiles. You are', 1, self.color)) all_surfaces.append(self.font.render('armed with 100 special missiles. Level-up awards you another 50 special missiles and a', 1, self.color)) all_surfaces.append(self.font.render('power-up star which will instantly deactivate all the enemy missiles.', 1, self.color)) all_surfaces.append(self.font.render('Your jet can carry maximum 999 special missiles.', 1, self.color)) all_surfaces.append(seperator) all_surfaces.append(self.font.render('With keyboard input, you should use your keyboard arrow keys to navigate and spacebar', 1, self.color)) all_surfaces.append(self.font.render('to shoot. With mouse as input, you should use your mouse to navigate your jet and', 1, self.color)) all_surfaces.append(self.font.render('mouse click to shoot', 1, self.color)) all_surfaces.append(self.font.render(' ', 1, self.color)) all_surfaces.append(self.font.render('POINTS: Destroy Missle -> 10 pts. Power-up Star -> 100 pts. Level-up -> 10 pts.', 1, self.color)) all_surfaces.append(seperator) self.surf = Surface((all_surfaces[1].get_width(), all_surfaces[0].get_height() * (len(all_surfaces) + 2)), self.__game_env.SRCALPHA) self.surf.blit(header, (self.surf.get_width()/2 - header.get_width()/2, 0)) for index, temp_surf in enumerate(all_surfaces): self.surf.blit(temp_surf, (0, header.get_height() + index * temp_surf.get_height())) self.surf.blit(footer, (self.surf.get_width()/2 - footer.get_width()/2, self.surf.get_height() - footer.get_height())) self.rect = self.surf.get_rect(center=(self.__game_env.static.screen_width/2, self.__game_env.static.screen_height/2))
class Label(): def __init__(self, width, height, color): self.surface = Surface((width, height)) self.color = color self.surface.fill(color) def caption(self, text, fontStyle): myfont = font.SysFont(fontStyle.font, fontStyle.size) self.size = myfont.size(text) offsetX = (self.surface.get_width() - self.size[0]) / 2 offsetY = (self.surface.get_height() - self.size[1]) / 2 self.surface.fill(self.color) label = myfont.render(text, True, fontStyle.color) self.surface.blit(label, (offsetX, offsetY)) return self.surface def width(self): return self.size[0] def height(self): return self.size[1]
def __init__(self, display: Surface): self.display = display self.score = Score(display) self.bullets = [Bullet(display) for _ in range(self.num_bullets)] self.block = Block(display, (display.get_width() // 2 - Block.WIDTH // 2, display.get_height() // 2 - Block.HEIGHT // 2), self.bullets)
class NameInputText(Text): """ NameInputText class extended from Text class. Class is responsible for creating the sprite for taking player name as input """ def __init__(self, game_env): Text.__init__( self, game_env, size=32) # initilizing parent class with default text color as red self.__game_env = game_env self.__header = Text(self.__game_env, "=== ENTER YOUR NAME ===", 36) self.__footer = Text(self.__game_env, "===============================", 36) self.__player_name = '' # default player name self.render(self.__player_name) def render(self, key): if key and re.match( r'[a-zA-Z0-9@. \b\r]', key): # basic input validation; user cannot enter rubbish if key == '\x08': # backspace self.__player_name = self.__player_name[:-1] elif key == '\r': # enter key if len(self.__player_name.strip() ) > 0: # to avoid spaces as name self.__game_env.dynamic.player_name = self.__player_name.strip( ) else: self.__player_name.strip() elif len( self.__player_name ) <= self.__game_env.static.name_length: # to avoid longer name self.__player_name += key self.__render() def __render(self): self.__input = self.font.render(self.__player_name, 1, self.color) self.surf = Surface( (self.__header.surf.get_width(), self.__header.surf.get_height() * 2 + self.__input.get_height()), self.__game_env.SRCALPHA) self.surf.blit(self.__header.surf, (self.surf.get_width() / 2 - self.__header.surf.get_width() / 2, 0)) self.surf.blit( self.__input, (self.surf.get_width() / 2 - self.__input.get_width() / 2, self.__header.surf.get_height())) self.surf.blit( self.__footer.surf, (self.surf.get_width() / 2 - self.__footer.surf.get_width() / 2, self.surf.get_height() - self.__footer.surf.get_height())) self.rect = self.surf.get_rect( center=(self.__game_env.static.screen_width / 2, self.__game_env.static.screen_height / 2))
def __init__(self, x=0, y=0, rotation=0, image: Surface = None, animation: Animation = None): self.current_image: Surface = image self.animation = animation width = 0 if not image else image.get_width() height = 0 if not image else image.get_height() self.transform = Transform(x, y, width, height, rotation) game.controllers.ObjectsController.add(self)
def draw_car(car: Car, image: Surface, vector_color: Color, surface: Surface, pixel_meter_ratio: float): """Draws a given Car object on a given Surface. Args: car (Car): The car object to be visualized. image (Surface): A surface containing an image visualizing a car vector_color (Color): The color the flocking vector should be surface (Surface): The surface the car should be drawn on. pixel_meter_ratio (float): The amount of pixels corresponding to one meter. """ resized_image = scale(image, (round(car.length * pixel_meter_ratio), round(car.width * pixel_meter_ratio))) rotated_image = rotate(resized_image, car.direction.get_degrees()) rect = rotated_image.get_rect() surface_x = car.x * pixel_meter_ratio - rect.width / 2.0 surface_y = surface.get_height() - car.y * pixel_meter_ratio - rect.height / 2.0 surface.blit(rotated_image, (surface_x, surface_y)) car_x = car.x * pixel_meter_ratio car_y = surface.get_height() - car.y * pixel_meter_ratio vector_x = (car.x + car.flocking_vector.x) * pixel_meter_ratio vector_y = surface.get_height() - (car.y + car.flocking_vector.y) * pixel_meter_ratio line(surface, vector_color, (car_x, car_y), (vector_x, vector_y), 1)
def draw_wall(wall: Wall, color: Color, surface: Surface, pixel_meter_ratio: float): """Draws a given Wall object on a given Surface. Args: wall (Wall): The wall object to be visualized. color (Color): The color the wall should be. surface (Surface): The surface the wall should be drawn on. pixel_meter_ratio (float): The amount of pixels corresponding to one meter. """ surface_height = surface.get_height() surface_x1 = wall.x1 * pixel_meter_ratio surface_y1 = surface_height - wall.y1 * pixel_meter_ratio surface_x2 = wall.x2 * pixel_meter_ratio surface_y2 = surface_height - wall.y2 * pixel_meter_ratio line(surface, color, (surface_x1, surface_y1), (surface_x2, surface_y2), 3)
def __init__(self, surface: Surface, rows, cols, frame_time=.1): self.surface = surface self.rows = rows self.cols = cols self.frame_width = surface.get_width() / rows self.frame_height = surface.get_height() / cols self.row = 0 self._col = 0 self.frame_time = frame_time self.time = 0 self.image = Surface((self.frame_width, self.frame_height)) self.image.set_colorkey(Animation.colorkey) self.valid = False
def __init__(self, sprite_sheet: Surface, frames_per_second: float): # Sheet assumed to be horizontal self.size_per_sprite = sprite_sheet.get_height() self.no_of_sprites = sprite_sheet.get_width() / self.size_per_sprite if int(self.no_of_sprites) != self.no_of_sprites: raise Exception("Invalid sprite sheet") self.no_of_sprites = int(self.no_of_sprites) sps = self.size_per_sprite # alias self.sprites = [] for i in range(self.no_of_sprites): self.sprites.append( sprite_sheet.subsurface(pg.Rect(i * sps, 0, sps, sps))) fpms = frames_per_second / 1000 # frames per ms self.mspf = 1 / fpms # ms per frame self.time = 0 self.sprite_index = 0
def __init__(self, row: int, col: int, width: int, height: int, grid: List[List[int]], solution_board: List[List[int]], screen: Surface) -> None: """ Initialize the Board with row, col, width, height, the grid which is the board being displayed, the solution board, and the screen that the board is displayed on. """ self.row = row self.col = col self.width = width self.height = height self.board = grid self.sol_board = solution_board self.gap_x = (screen.get_width() - self.width) // 2 self.gap_y = (screen.get_height() - self.height) // 2 self.x_max = self.row * 50 + self.gap_x self.y_max = self.col * 50 + self.gap_y self.squares = [[ Square(self.board[i][j], i, j, self.gap_x, self.gap_y) for i in range(row) ] for j in range(col)] self.selected = None
def __init__(self, image: Surface, position: Vector2, frame_count: int = 1) -> None: self.original_image = image self.image = None self._position = position frame_width = image.get_width() / frame_count frame_height = image.get_height() self.frames = [] for i in range(frame_count): self.frames.append( Rect(i * frame_width, 0, frame_width, frame_height)) self._current_frame = 0 self._rotate = 0 self.velocity = Vector2(0, 0) self.wrap = False self.radius = frame_width / 2 self.is_dead = False self.drotate = 0 self._scale = 1 self.create_image()
def __init__(self, display: Surface): self.display = display self.rect = Rect((70, display.get_height() - 100), (self.WIDTH, self.HEIGHT)) self.dy = 0
def get_center_position(surface_image: Surface): width = surface_image.get_width() height = surface_image.get_height() x = (GameConfig.screen.width - width) / 2 y = (GameConfig.screen.height - height) / 2 return x, y
def render_score_screen(board_render): should_show_screen = board_render.board_manager.round_should_end group = LayeredUpdates() if not should_show_screen: return group current_path = os.path.dirname(os.path.realpath(__file__)) font_path = os.path.join( current_path, "..", "..", "resources", "fonts", "SourceSans3-Semibold.ttf" ) font = Font(font_path, 40) font_small = Font(font_path, 24) match = board_render.match scores = match.scores delta_scores = match.delta_scores total_scores = list(map(lambda s: s[0] + s[1], zip(scores, delta_scores))) winner_indices = numpy.argwhere(numpy.array(delta_scores) > 0).flatten() winner_names = [] array = numpy.array(total_scores) temp = array.argsort()[::-1] ranks = numpy.empty_like(temp) ranks[temp] = numpy.arange(len(array)) icons = get_object('boticons')['bot'] screen_surface = Surface(board_render.surface.get_size(), pygame.SRCALPHA) screen_surface.fill((0, 0, 0)) ROUND_COMPLETE = "Round Complete" round_complete_surface = font.render(ROUND_COMPLETE, True, (255, 255, 255)) font_width, font_height = font.size(ROUND_COMPLETE) icon_size = (100, 100) player_list = match.ai_list x = screen_surface.get_width() // 5 y = font_height + 5 for seat in range(4): ai_name = player_list[seat] name = None icon = None for entry in icons: if entry['ai'] == ai_name: name = entry['name'] icon = entry['icon'] break if name is None: raise "BOT WAS NOT DEFINED." if seat in winner_indices: winner_names += [name] icon_surface = Surface(icon_size, pygame.SRCALPHA) load_image_resource(icon, icon_surface, size=icon_size) screen_surface.blit( icon_surface, (x, y) ) player_name = font.render(name, True, (255, 255, 255)) _, name_h = font.size(name) screen_surface.blit( player_name, (x + icon_size[0] + 10, y) ) score_string = "{} Points".format(scores[seat]) score_render = font_small.render(score_string, True, (255, 255, 255)) _, score_h = font_small.size(score_string) screen_surface.blit( score_render, (x + icon_size[0] + 10, y + name_h + 5) ) delta_string = "{}{}".format("+" if delta_scores[seat] >= 0 else "", delta_scores[seat]) delta_render = font_small.render(delta_string, True, (255, 255, 255)) _, delta_h = font_small.size(delta_string) screen_surface.blit( delta_render, (x + icon_size[0] + 10, y + name_h + 5 + score_h + 5) ) total_string = "Total: {} Points".format(total_scores[seat]) total_render = font_small.render(total_string, True, (255, 255, 255)) screen_surface.blit( total_render, (x + icon_size[0] + 10, y + name_h + 5 + score_h + 5 + delta_h + 5) ) place_string = "{}".format(ranks[seat] + 1) place_render = font.render(place_string, True, (255, 255, 255)) place_w, place_h = font.size(place_string) screen_surface.blit( place_render, (x - place_w - 5, y + ((icon_size[1] - place_h) // 2)) ) y += icon_size[1] + 70 LOADING_NEXT_ROUND = "Loading next Round..." loading_surface = font.render(LOADING_NEXT_ROUND, True, (255, 255, 255)) loading_width, loading_height = font.size(LOADING_NEXT_ROUND) screen_surface.blit( loading_surface, (screen_surface.get_width() - loading_width - 10, screen_surface.get_height() - loading_height - 10) ) screen_surface.blit( round_complete_surface, ((screen_surface.get_width() // 2) - (font_width // 2), 10), ) result_pos = (screen_surface.get_width() * 0.6, screen_surface.get_height() // 3) if board_render.board_manager.did_exhaustive_draw: EXHAUSTIVE = "Exhaustive Draw" exhaustive_surface = font.render(EXHAUSTIVE, True, (255, 255, 255)) screen_surface.blit( exhaustive_surface, result_pos ) else: WINNERS = "Winners:" winners = ", ".join(winner_names) winner_text = font_small.render(WINNERS, True, (255, 255, 255)) winner_name_text = font_small.render(winners, True, (255, 255, 255)) screen_surface.blit( winner_text, result_pos ) screen_surface.blit( winner_name_text, (result_pos[0], result_pos[1] + winner_text.get_rect().height + 5) ) background_sprite = Sprite() background_sprite.rect = screen_surface.get_rect() background_sprite.image = screen_surface background_sprite.layer = 0 group.add(background_sprite) return group
class TextShootObject(TextObject): def __init__(self, scene, location: Tuple[int, int], parent: GraphicalObject = None, short: bool = False): if not short and random.randint(0, 4) == 2: self.word = random.choice(Words.long).upper() else: self.word = random.choice(Words.single).upper() self.typed = 0 super().__init__(scene, location, self.word, font_path=FONT_PATH, font_size=FONT_SIZE, font_color=Colors.white) self.parent = parent self.half_width = self.surface.get_width() / 2 def key_input(self, key): key_name = pygame.key.name(key) if key_name == "space": key_name = " " if self.word[self.typed].lower() == key_name: if self.typed == len(self.word) - 1: return TextShootState.WORD_END self.typed += 1 return TextShootState.SUCCESS return TextShootState.WRONG_KEY def draw(self): if not self.typed: self.surface = FONT.render(self.word, True, Colors.white, Colors.blurple) elif self.typed >= len(self.word): self.surface = FONT.render(self.word, True, Colors.red, Colors.blurple) else: typed_text = self.word[:self.typed].replace(" ", "_") untyped_text = self.word[self.typed:] typed_surface: Surface = FONT.render(typed_text, True, Colors.red, Colors.blurple) untyped_surface: Surface = FONT.render(untyped_text, True, Colors.white, Colors.blurple) self.surface = Surface( (typed_surface.get_width() + untyped_surface.get_width(), max(typed_surface.get_height(), untyped_surface.get_height()))) self.surface.blits( ((typed_surface, (0, 0)), (untyped_surface, (typed_surface.get_width(), 0)))) surface = Surface( (self.surface.get_width() + 20, self.surface.get_height())) surface.set_colorkey((0, 0, 0)) pygame.draw.ellipse(surface, Colors.blurple, Rect(0, 0, 20, surface.get_height())) pygame.draw.ellipse( surface, Colors.blurple, Rect(surface.get_width() - 20, 0, 20, surface.get_height())) surface.blit(self.surface, (10, 0)) self.surface = surface if self.parent: self.location = (self.parent.location[0] - self.half_width + self.parent.surface.get_width() / 2, self.parent.location[1] - 40) # Out of bounds on left side if self.location[0] <= 0 and self.parent.y_direction < 0: self.parent.y_direction = abs(self.parent.y_direction) self.parent.move_absolute((self.half_width + self.parent.size[0], self.parent.location[1])) # Out of bounds on right side elif self.location[0] + self.surface.get_width() >= screen.get_width( ) and self.parent.y_direction > 0: self.parent.y_direction = -abs(self.parent.y_direction) new_x = Window.width - (self.half_width + self.parent.size[0]) self.parent.move_absolute((new_x, self.parent.location[1])) super(TextObject, self).draw() if self.parent: self.parent.draw()
def draw(self): if not self.typed: self.surface = FONT.render(self.word, True, Colors.white, Colors.blurple) elif self.typed >= len(self.word): self.surface = FONT.render(self.word, True, Colors.red, Colors.blurple) else: typed_text = self.word[:self.typed].replace(" ", "_") untyped_text = self.word[self.typed:] typed_surface: Surface = FONT.render(typed_text, True, Colors.red, Colors.blurple) untyped_surface: Surface = FONT.render(untyped_text, True, Colors.white, Colors.blurple) self.surface = Surface( (typed_surface.get_width() + untyped_surface.get_width(), max(typed_surface.get_height(), untyped_surface.get_height()))) self.surface.blits( ((typed_surface, (0, 0)), (untyped_surface, (typed_surface.get_width(), 0)))) surface = Surface( (self.surface.get_width() + 20, self.surface.get_height())) surface.set_colorkey((0, 0, 0)) pygame.draw.ellipse(surface, Colors.blurple, Rect(0, 0, 20, surface.get_height())) pygame.draw.ellipse( surface, Colors.blurple, Rect(surface.get_width() - 20, 0, 20, surface.get_height())) surface.blit(self.surface, (10, 0)) self.surface = surface if self.parent: self.location = (self.parent.location[0] - self.half_width + self.parent.surface.get_width() / 2, self.parent.location[1] - 40) # Out of bounds on left side if self.location[0] <= 0 and self.parent.y_direction < 0: self.parent.y_direction = abs(self.parent.y_direction) self.parent.move_absolute((self.half_width + self.parent.size[0], self.parent.location[1])) # Out of bounds on right side elif self.location[0] + self.surface.get_width() >= screen.get_width( ) and self.parent.y_direction > 0: self.parent.y_direction = -abs(self.parent.y_direction) new_x = Window.width - (self.half_width + self.parent.size[0]) self.parent.move_absolute((new_x, self.parent.location[1])) super(TextObject, self).draw() if self.parent: self.parent.draw()
class MenuImage(MenuObjectClickable): image: Surface = None # Картинка для отображения shadow_image: Surface = None active: bool = None # Нужно ли отрисовывать изображение alignment: int = ALIGNMENT_HIGH_LEFT # Тип выравнивания. def __init__(self, window_surface: Surface, pos: tuple, image: Surface, shadow: bool = False, alignment: int = ALIGNMENT_HIGH_LEFT, type: int = NORMAL, one_image_size: tuple = None, active: bool = True) -> None: self.window_surface = window_surface self.rect = Rect((pos[0], pos[1], pos[2], pos[3])) self.image = image self.active = active if type == NORMAL: # Поправка размеров if self.rect.w != 0 or self.rect.h != 0: # Если одна из координат == 0, значит не нужно изменять размеры картинки. if self.rect.w != self.image.get_width( ) or self.rect.h != self.image.get_height(): self.image = pygame.transform.scale( self.image, (self.rect.w, self.rect.h)) if shadow: self.shadow_image = self.image.copy() fill_color(self.shadow_image, BLACK, max_alpha=128) elif type == FILL: inserted_image = image if one_image_size is not None: # Если указан размер одного изображения... inserted_image = pygame.transform.scale( inserted_image, (one_image_size[0], one_image_size[1])) # Заполнить image картинками src_image_w, src_image_h = inserted_image.get_size( ) # Размеры исходного изобрежения self.image = Surface((self.rect.w, self.rect.h), SRCALPHA) w_times = self.rect.w // src_image_w + 1 # Что-то вроде округления в большую сторону h_times = self.rect.h // src_image_h + 1 # Заполняем self.image построчно, начиная с верхнего левого края done_h = 0 # Сколько высоты сделано for i in range(h_times): if done_h >= self.rect.h: # Из-за округления мы можем закончить раньше break incerted_h = min(src_image_h, self.rect.h - done_h) done_w = 0 # Сколько ширины сделано for j in range(w_times): if done_w >= self.rect.w: # Из-за округления мы можем закончить раньше break incerted_w = min( src_image_w, self.rect.w - done_w) # Вставляемая ширина на текущем шаге self.image.blit(inserted_image, (done_w, done_h), (0, 0, incerted_w, incerted_h)) done_w += incerted_w done_h += incerted_h self.alignment = alignment if self.alignment == ALIGNMENT_HIGH_LEFT: pass elif self.alignment == ALIGNMENT_CENTER: self.rect.x = self.rect.x - self.image.get_width() / 2 self.rect.y = self.rect.y - self.image.get_height() / 2 def draw(self) -> None: if self.active: if self.shadow_image: self.window_surface.blit(self.shadow_image, (self.rect.x + 2, self.rect.y + 2)) self.window_surface.blit(self.image, (self.rect.x, self.rect.y))
screen_width_pixels = 800 screen_height_pixels = 600 pygame.init() pygame.display.set_caption("Lunar Panda") screen=pygame.display.set_mode((screen_width_pixels, screen_height_pixels), pygame.FULLSCREEN, 32) pygame.mouse.set_visible(0) screen.fill((255, 255, 255)) pygame.display.update() background=pygame.image.load("Resources/background.png").convert() titleImage = pygame.image.load("Resources/titleimage.jpg").convert() uiFont = pygame.font.SysFont("monospace", 12) background_image_height = Surface.get_height(background) screenScroll = 0 def blitTextCentered(font, text, surface, color): """ Utility function for drawing text at the centre of a 'Surface'. """ label = font.render(text, True, color) textRect = label.get_rect() textRect.center = surface.get_rect().center surface.blit(label, textRect) def blitTextHorizontalCentered(font, text, y, leftX, width, surface, color): """ Utility function for drawing text at the horizontal centre of the screen. """ label = font.render(text, True, color) textRect = label.get_rect() textRect.top = y
def resize(image: Surface, new_height: int) -> Surface: old_width = image.get_width() old_height = image.get_height() new_width = int(old_width * (new_height / old_height)) return pygame.transform.scale(image, (new_width, new_height))
pygame.init() pygame.display.set_caption("Tardis Lander") # NAM: kill fullscreen screen=pygame.display.set_mode((screen_width_pixels, screen_height_pixels), pygame.FULLSCREEN, 32) screen = pygame.display.set_mode((screen_width_pixels, screen_height_pixels), 32) pygame.mouse.set_visible(0) screen.fill((255, 255, 255)) pygame.display.update() background = pygame.image.load("Resources/background.png").convert() background2 = pygame.image.load("Resources/background2.png").convert() titleImage = pygame.image.load("Resources/titleimage.jpg").convert() uiFont = pygame.font.SysFont("monospace", 12) uiFontBig = pygame.font.SysFont("monospace", 48) background_image_height = Surface.get_height(background) screenScroll = 0 def blitTextCentered(font, text, surface, color): """ Utility function for drawing text at the centre of a 'Surface'. """ label = font.render(text, True, color) textRect = label.get_rect() textRect.center = surface.get_rect().center surface.blit(label, textRect) def blitTextHorizontalCentered(font, text, y, leftX, width, surface, color): """ Utility function for drawing text at the horizontal centre of the screen. """ label = font.render(text, True, color) textRect = label.get_rect()
class ButtonWidget(Widget): """ clickable widget with text in it """ def __init__( self, evManager, text, rect=None, onDownClickEvent=None, onUpClickEvent=None, onMouseMoveOutEvent=None ): Widget.__init__(self, evManager) # Widget init sets dirty to true, hence the actual text rendering # will be done in ButtonWidget.update(), called by the view renderer. self._em.reg_cb(DownClickEvent, self.on_downclick) self._em.reg_cb(UpClickEvent, self.on_upclick) self._em.reg_cb(MoveMouseEvent, self.on_mousemove) # the events to be triggered when the button is clicked or mouse moved self.onDownClickEvent = onDownClickEvent self.onUpClickEvent = onUpClickEvent self.onMouseMoveOutEvent = onMouseMoveOutEvent self.text = text self.font = Font(None, config_get_fontsize()) # default font, 40 pixels high if rect: self.rect = rect self.image = Surface(self.rect.size) # container size from specified rect # if txtimg does not fit in rect, it'll get cut (good thing) else: txtimg = self.font.render(self.text, True, (0, 0, 0)) self.rect = txtimg.get_rect() self.image = Surface(self.rect.size) # container size from rendered text # if txt changes, the size of the button will stay the same def update(self, duration): if self.dirty == 0: return if self.focused: color = config_get_focusedbtn_txtcolor() bgcolor = config_get_focusedbtn_bgcolor() else: color = config_get_unfocusedbtn_txtcolor() bgcolor = config_get_unfocusedbtn_bgcolor() # TODO: is bliting on existing faster than creating a new surface? self.image = Surface(self.rect.size) # rectangle container for the text self.image.fill(bgcolor) txtimg = self.font.render(self.text, True, color) txtimg = txtimg.convert() textpos = txtimg.get_rect(centerx=self.image.get_width() / 2, centery=self.image.get_height() / 2) self.image.blit(txtimg, textpos) # self.dirty is set to 0 by LayeredDirty.update def on_downclick(self, event): """ button down focuses and triggers eventual behavior """ if self.rect.collidepoint(event.pos): self.dirty = 1 self.set_focus(True) if self.onDownClickEvent: self._em.post(self.onDownClickEvent) def on_upclick(self, event): """ button up loses focus and triggers eventual behavior """ if self.rect.collidepoint(event.pos): if self.focused: self.dirty = 1 self.set_focus(False) if self.onUpClickEvent: self.log.debug("Clicked on button widget " + self.text) self._em.post(self.onUpClickEvent) def on_mousemove(self, event): """ if focused, lose focus when the mouse moves out """ if self.rect.collidepoint(event.pos): # mouse moved in pass else: # mouse moved out if self.focused: if not self.onMouseMoveOutEvent: # default behavior self.set_focus(False)