class Ship(object): def __init__(self): self.lives = 3 self.state = MOVING # position self.pos = (VIEWWIDTH // 2, SHIPY) # shape -- placeholder self.colour = WHITE self.origShape = Surface((SHIPSIZE, SHIPSIZE)) self.origShape.fill(WHITE) self.shape = self.origShape.copy() self.rect = self.shape.get_rect() self.rect.center = self.pos # nr of bolts self.bolts = [] def move(self, movex): newx = self.pos[0] + movex if newx > VIEWBOUNDS[0] and newx < VIEWBOUNDS[1]: self.pos = (newx, self.pos[1]) def fireBolt(self): if len(self.bolts) >= 2: return self.bolts.append(Bolt(self.pos)) def removeBolt(self, bolt): self.bolts.remove(bolt) def hit(self): self.lives -= 1 self.state = DEAD self.frame = 1 def readyNewShip(self): self.pos = (VIEWWIDTH // 2, SHIPY) self.shape = self.origShape.copy() self.state = MOVING def update(self, ready=None): for bolt in self.bolts: if bolt.pos[1] - BOLTLENGTH < 0: self.bolts.remove(bolt) if self.state == DEAD: if self.frame < SHIPSIZE // 2: self.shape.fill(BLACK) pygame.draw.circle(self.shape, WHITE, (SHIPSIZE // 2, SHIPSIZE // 2), self.frame, 1) self.frame += 2 else: self.pos = None if not self.lives: self.state = GAMEOVER elif ready: self.readyNewShip()
def mult_color(surf: pygame.Surface, color: Tuple[int, int, int]) -> pygame.Surface: """ Multiply the color given on the provided surface. """ mult_surf = surf.copy() mult_surf.fill(color) new_surf = surf.copy() new_surf.blit(mult_surf, (0, 0), special_flags=BLEND_RGBA_MULT) return new_surf
def __init__(self, word, word_o, color, angle): Sprite.__init__(self) self.word = word self.angle = angle # Determine Word dimensions w_rect = word_o.get_bounding_rect() w_rect.x = -w_rect.x + WORD_PADDING w_rect.y = -w_rect.y + WORD_PADDING w_rect.width += WORD_PADDING * 2 w_rect.height += WORD_PADDING * 2 # Draw Word on a surface word_sf = Surface((w_rect.width, w_rect.height), SRCALPHA, 32) word_sf.blit(word_o, w_rect) self.rect = word_sf.get_rect() self.image = word_sf.copy() self.msf = word_sf.copy() # Create custom mask m1 = mask.from_surface(self.msf) cr, crw = [], [] for c in [x for x in range(w_rect.width) if x % PXL == 0]: for r in [y for y in range(w_rect.height) if y % PXL == 0]: if m1.get_at((c, r)) != 0: crw.append((c - PXL, r - PXL)) crw.append((c - PXL, r)) crw.append((c, r - PXL)) crw.append((c, r)) crw.append((c + PXL, r + PXL)) crw.append((c, r + PXL)) crw.append((c + PXL, r)) crw.append((c + PXL, r - PXL)) crw.append((c - PXL, r + PXL)) cr.append((c, r)) for c, r in crw: draw.rect(self.msf, color, Rect((c, r), (PXL, PXL))) for i in enumerate(cr): c, r = i[1] j = 1 if i[0] + 1 >= len(cr): break next_cr = cr[i[0] + 1] while next_cr[0] == c and next_cr[1] != r + PXL * j: draw.rect(self.msf, color, Rect((c, r + j * PXL), (PXL, PXL))) j += 1 self._rotate()
def make_bee_sprites(genome): """ Makes the bee sprites based on the provided genome :param genome: [(1-11), (1-5), (1-5)] Index 0 is the head gene, Index 2 is torso and Index 3,4 are the wings :return: wings up sprite, wings down sprite """ head_gene = genome[0] head = heads['head' + str(head_gene)] wing_u_gene = genome[1] wings_u = wings['wings_up' + str(wing_u_gene)] wing_d_gene = genome[2] wings_d = wings['wings_d' + str(wing_d_gene)] torso_gene = genome[3] torso = torsos['torso' + str(torso_gene)] sprite_surf = Surface((18, 18), SRCALPHA) sprite_surf.blit(head, (6, 0)) sprite_surf.blit(torso, (5, 11)) wings_u_sprite = sprite_surf.copy() wings_d_sprite = sprite_surf.copy() wings_u_sprite.blit(wings_u, (0, 2)) wings_d_sprite.blit(wings_d, (0, 6)) return wings_u_sprite, wings_d_sprite
def rotate_(image: pygame.Surface, angle: int): image_copy = image.copy() image_copy.fill((0, 0, 0, 0)) width, height = image.get_size() msin = [] mcos = [] for i in range(360): rad = math.radians(-i) msin.append(math.sin(rad)) mcos.append(math.cos(rad)) hwidth = width // 2 hheight = height // 2 for x in range(0, width): for y in range(0, height): xt = x - hwidth yt = y - hheight sinma = msin[angle] cosma = mcos[angle] xs = round((cosma * xt - sinma * yt) + hwidth) ys = round((sinma * xt + cosma * yt) + hheight) if 0 <= xs < width and 0 <= ys < height: image_copy.set_at((x, y), image.get_at((xs, ys))) return image_copy
def __updateTankSurface(self, surface: Surface, color: Color, direction: math.Vector2): surface.fill((0, 0, 0, 0)) # rect inside surface surfaceSize = surface.get_size() surfaceRect = Rect(0, 0, surfaceSize[0], surfaceSize[1]) tankRect = Rect(0, 0, self.size[0], self.size[1]) diff = math.Vector2(surfaceRect.center) - math.Vector2(tankRect.center) tankRect.move_ip(diff) temp = surface.copy() draw.rect(temp, color, tankRect) # apply tank direction to surface degree = -math.Vector2(0, 1).angle_to(direction) temp = transform.rotate(temp, degree) # temp was enlarged by rotate (wtf): # calculate diff so that temp surface is positioned outside # of the destination surface below tempRectSize = temp.get_size() diff = math.Vector2(tempRectSize) - math.Vector2(surfaceSize) # copy back wanted portion from rotation surface.blit(temp, -diff / 2)
def compileSVASheet(sheet, color): color = tuple([255-c for c in color]) width = sheet.get_width() height = sheet.get_height() / 3 colorSurf = Surface((width, height)) colorSurf.fill(color) colorSurf.blit(sheet, (0, 0), None, BLEND_MULT) # Now create a white surface so we can invert the Saturation map result = Surface((width, height), SRCALPHA) result.fill((255, 255, 255)) result.blit(colorSurf, (0, 0), None, BLEND_RGB_SUB) # Multiply this with the Value Map result.blit(sheet, (0, -height), None, BLEND_MULT) # copy the alpha mask from the spritesheet alpha = Surface((width, height)) alpha.blit(sheet, (0, -2 * height)) #convert the (nearly done) Surface to per pixel alpha result.convert_alpha() # Use Numpy here numWhite = surfarray.pixels_alpha( result ) numAlpha = surfarray.pixels3d( alpha ) numWhite[ :, : ] = numAlpha[ :, :, 0 ] return result.copy()
def makebackground(self, surface): surface.fill((0,0,0)) template = Surface(2*(min(self.zoom.width, self.zoom.height),)) template.fill((0,0,0,255)) width,height = template.get_size() ylim = surface.get_height()/height xlim = surface.get_width()/width data = self._data noise = [[pnoise2(self._selected[1][0]+x, self._selected[0][0]+y, 4, 0.85) * 50 for x in range(xlim)] for y in range(ylim)] hmin = hmax = 0 for y in range(ylim): for x in range(xlim): yd = len(data)*float(y)/ylim xd = len(data[0])*float(x)/xlim h = self._height(data, yd, xd) n = noise[y][x] if h < 0: h += -n if n > 0 else n else: h += n if n > 0 else -n if h < hmin: hmin = h if h > hmax: hmax = h self.rects = [] for y in range(ylim): for x in range(xlim): block = template.copy() yd = len(data)*float(y)/ylim xd = len(data[0])*float(x)/xlim h = self._height(data, yd, xd) n = noise[y][x] if h < 0: h += -n if n > 0 else n else: h += n if n > 0 else -n if h < 0: color = 0, 0, int(255 * (1 - h/hmin)) else: color = 0, int(255 * h/hmax), 0 block.fill(color) if self.selection: if self.selection[0][0] <= yd <= self.selection[0][1]: if self.selection[1][0] <= xd <= self.selection[1][1]: block.fill((255,0,0,32), special_flags = BLEND_ADD) rect = Rect(x*width, y*height, width, height) surface.blit(block, rect.topleft) self.rects.append((rect, (yd, xd)))
class AbstractTurretVisual(abc.ABC): def __init__(self,sizeX:int,sizeY:int,sourceTurret,alpha: bool = False): self.sizeX = sizeX self.sizeY = sizeY self.sourceTurret=sourceTurret if alpha: self.surface = Surface((sizeX, sizeY)) else: self.surface = Surface((sizeX, sizeY), SRCALPHA) self.cannonWidth=0 self.cannonhigh =0 self.canon = None def draw(self): surf2=transform.rotate(self.canon,self.sourceTurret.angle*180/pi) posBegin=self.sizeX//2-surf2.get_rect().width//2,self.sizeY//2-surf2.get_rect().height//2 copy=self.surface.copy() copy.blit(surf2,posBegin) return copy def recolorBase(self,value:float): edge = Color(int(min(255 * (2 - 2 * value), 255)), int(min(255 * value * 2, 255)), 0) self.surface.fill(edge) draw.rect(self.surface, Color(0, 0, 0), Rect(self.sizeX / 10, self.sizeY / 10, self.sizeX * 0.8, self.sizeY * 0.8)) draw.circle(self.surface, Color(0, 0, 80), (self.sizeX / 2, self.sizeX / 2), (self.sizeX * 0.4)) def drawCanon(self): pass
def palette_swap(surface: pygame.Surface, old_color, new_color): surf_copy = surface.copy() img_copy = pygame.Surface(surf_copy.get_size()) img_copy.fill(new_color) surf_copy.set_colorkey(old_color) img_copy.blit(surf_copy, (0, 0)) img_copy.set_colorkey((0, 0, 0)) return img_copy
def concatSurfaces(s1: pygame.Surface, s2: pygame.Surface, s2_coords: tuple, make_copy=True): if make_copy: s1 = s1.copy() s1.blit(s2, s2_coords) return s1
def __init__(self, surface: pygame.Surface, size: Tuple[int, int], alpha: int = 255, angle: float = 0): """Constructor method """ super(Image, self).__init__(alpha=alpha, angle=angle) self._orig_size = tuple(size) self.size = list(self._orig_size) self._orig_surface = surface.copy() self.make_surface()
def gerar_imagem(self, sprite: pg.Surface, gradientes: tp.pb[tp.grad]) -> tp.pb[pg.Surface]: """ Colore o sprite com os gradientes e os retorna :param sprite: sprite a ser colorido :param gradientes: gradientes para a peça preta e branca :return: sprites coloridos para a peça preta e para branca """ sprites = tp.pb(sprite.copy(), sprite.copy()) w, h = sprite.get_size() for i in range(w): for j in range(h): cor = sprite.get_at((i, j)) sprites.preto.set_at((i, j), gradientes.preto.gerar_cor(cor)) sprites.branco.set_at((i, j), gradientes.branco.gerar_cor(cor)) return sprites
def checkered_surface(screen: pygame.Surface) -> pygame.Surface: checkered = screen.copy().convert_alpha() checkered.fill(Color.GREY) for n, rect in enumerate(possible_rects(Screen.WIDTH, Screen.HEIGHT)): if n % 2 == 0: pygame.draw.rect(checkered, Color.LIGHT_GREY, rect) return checkered
def image(self, surface: pygame.Surface) -> None: if isinstance(surface, self.__class__): surface = surface.image elif not isinstance(surface, pygame.Surface): surface = create_surface((0, 0)) self.__default_surface = (surface if not surface.get_locked() else surface.copy()).convert_alpha() self.__surface_to_draw = self.__resized_surface = self.__rotated_surface = self.__default_surface self.__angle = 0
def add_surface_to_cache(self, surface: pygame.Surface, string_id: str): """ Adds a surface to the cache. There are two levels to the cache, the short term level just keeps hold of the surface until we have time to add it to the long term level. :param surface: The surface to add to the cache. :param string_id: An ID to store the surface under to make it easy to recall later. """ self.cache_short_term_lookup[string_id] = [surface.copy(), 1]
def __init__(self, game_instance, image: pygame.Surface, pos: (int, int), travel_vector: (float, float), travel_speed: int): super().__init__(game_instance) self.image = image.copy() self.rect = self.image.get_rect() self.rect.move_ip(pos[0] - self.rect.width / 2, pos[1]) self.travel_vector = travel_vector self.travel_speed = travel_speed self.scene_instance.game_objects["boss_projectiles"].append(self) self.player = self.scene_instance.game_objects["player"]
def convert_color(img: pygame.Surface, color_from: pygame.Color, color_to: pygame.Color) -> pygame.Surface: # FIXME: This is most likely not optimal. Change to some method that's better suited. if color_from == color_to: return img.copy() outp = pygame.Surface(img.get_size()) outp.blit(img, (0, 0)) for x in range(img.get_width()): for y in range(img.get_height()): if img.get_at((x, y)) == color_from: outp.set_at((x, y), color_to) return outp
def clear_line(self, screen: Surface, index: int) -> None: """ Collect all frozen sprites, draw them, remove line, create new frozen sprite. """ above_line = screen.subsurface( (0, 0, Config().width, index * Config.scale)).copy() screen.blit(above_line, (0, Config.scale)) self.frozen_tetrominos_layer.empty() self.frozen_tetrominos_layer.add(FrozenTetrominos(screen.copy())) return
class PyGameCameraOverlay(CameraOverlay): def __init__(self, viewer): CameraOverlay.__init__(self, viewer) self.overlay = Surface(self.dimensions.tupled()).convert_alpha() def captureOverlay(self): # Send out a copy of the overlay buffer. self.onOverlayCaptured(self.overlay.copy()) # Reset the overlay for the next capture. self.overlay.fill((0, 0, 0)) def displayRendering(self, rendering, position): self.overlay.blit(rendering, position.tupled())
def _draw_cooldown(self, cooldown_fraction: float, image: pg.Surface) -> pg.Surface: if cooldown_fraction >= 1: # No bar necessary return image image = image.copy() # Original image should be unchanged. col = settings.RED rect = image.get_rect() image_height = rect.height image_width = rect.width width = image_width * (1 - cooldown_fraction) if width > 0: cooldown_bar = pg.Rect(0, image_height - 7, width, 7) pg.draw.rect(image, col, cooldown_bar) return image
def __init__(self, game_instance, image: pygame.Surface, pos: (int, int), travel_speed: int, damage: int): super().__init__(game_instance) self.image = image.copy() self.rect = self.image.get_rect() self.rect.move_ip(pos[0] - self.rect.width / 2, pos[1]) self.player_instance = self.scene_instance.game_objects["player"] self.travel_speed = travel_speed self.damage = damage self.scene_instance.game_objects["player_projectiles"].append(self) # needed when player gets 'ghostBullets' powerup self.enemies_hit = list()
def create_color_image(image: pygame.Surface, target_color, src_color=WHITE, threshold=(10, 10, 10)): """ This function finds source color (color within threshold of src_color) in image and replaces it with target color and returns the new image """ new_image = image.copy() pygame.transform.threshold(dest_surf=new_image, surf=image, search_color=src_color, threshold=threshold, set_color=target_color, inverse_set=True) return new_image
def _main_menu(game_surface: pygame.Surface) -> int: background = pygame.image.load('assets/main_menu.png') game_surface.blit(background, (0, 0)) start_button = pygame.image.load('assets/start_button.png') game_surface.blit(start_button, (250, 320)) start_button_area = ((255, 250 + BUTTON_SIZE[0] - 5), (325, 320 + BUTTON_SIZE[1] - 5)) # start_button_rect = pygame.Rect(255, 325, BUTTON_SIZE[0] - 5, BUTTON_SIZE[1] - 5) quit_button = pygame.image.load('assets/quit_button.png') game_surface.blit(quit_button, (250, 380)) quit_button_area = ((255, 250 + BUTTON_SIZE[0] - 5), (385, 380 + BUTTON_SIZE[1] - 5)) # quit_button_rect = pygame.Rect(255, 385, BUTTON_SIZE[0] - 5, BUTTON_SIZE[1] - 5) original_surface = game_surface.copy() button_down = pygame.image.load('assets/button_down.png') pygame.display.flip() while True: event = pygame.event.wait() # The code in this if check has problems yet to be found. if event.type == pygame.MOUSEMOTION: mouse_pos = pygame.mouse.get_pos() if start_button_area[0][0] <= mouse_pos[0] <= start_button_area[0][1] and \ start_button_area[1][0] <= mouse_pos[1] <= start_button_area[1][1]: game_surface.blit(button_down, (250, 320)) pygame.display.flip() continue if quit_button_area[0][0] <= mouse_pos[0] <= quit_button_area[0][1] and \ quit_button_area[1][0] <= mouse_pos[1] <= quit_button_area[1][1]: game_surface.blit(button_down, (250, 380)) pygame.display.flip() continue else: game_surface = original_surface pygame.display.flip() continue if event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() if start_button_area[0][0] <= mouse_pos[0] <= start_button_area[0][1] and \ start_button_area[1][0] <= mouse_pos[1] <= start_button_area[1][1]: return 1 if quit_button_area[0][0] <= mouse_pos[0] <= quit_button_area[0][1] and \ quit_button_area[1][0] <= mouse_pos[1] <= quit_button_area[1][1]: pygame.quit() return -1 else: continue elif event.type == pygame.QUIT: return -1
def darken_and_blur(surface: pygame.Surface, amt: float = 30, opacity=200): if amt < 1.0: raise ValueError( "Arg 'amt' must be greater than 1.0, passed in value is %s" % amt) surf = surface.copy() darken = pygame.Surface(surf.get_size()) darken.fill((0, 0, 0)) darken.set_alpha(opacity) surf.blit(darken, (0, 0)) scale = 1.0 / float(amt) surf_size = surf.get_size() scale_size = (int(surf_size[0] * scale), int(surf_size[1] * scale)) surf = pygame.transform.smoothscale(surf, scale_size) surf = pygame.transform.smoothscale(surf, surf_size) return surf
class VideoMeter(object): def __init__(self, video_icon_, indicator_, volume_, scale_=1, color_=Color(28, 40, 32, 20)): self.video_icon = video_icon_ self.indicator = indicator_ self.volume = volume_ self.scale = scale_ self.width = 350 * scale_ self.height = 72 * scale_ self.canvas = Surface( (self.width, self.height)).convert(32, RLEACCEL) self.canvas.fill(color_) if scale_ != 1.0: vw, vh = self.video_icon.get_size() self.video_icon = smoothscale( self.video_icon, (int(vw * scale_), int(vh * scale_))) iw, ih = self.indicator.get_size() self.indicator = smoothscale( self.indicator, (int(iw * scale_), int(ih * scale_))) vw, vh = self.video_icon.get_size() self.canvas.blit(self.video_icon, (int(2.85 * self.width / 100.0), (self.height - vh) // 2)) self.w, self.h = self.indicator.get_size() self.value = 255 self.image = None self.update_meter(volume_) def update_meter(self, vol_): canvas = self.canvas.copy() canvas_blit = canvas.blit c1 = int(22.85 * self.width / 100.0) c2 = float(25.0 * self.scale) c3 = (self.height - self.h) // 2 for level in range(int(vol_ * 10)): canvas_blit(self.indicator, (c1 + int(level * c2), c3)) self.value = 255 canvas.set_alpha(self.value) self.image = canvas
class PyGameCameraSensorArray(CameraSensorArray): def __init__(self, columns, rows): CameraSensorArray.__init__(self, columns, rows) self.sensorArray = Surface(self.dimensions.tupled()) def collect(self, column, row, intensities): self.sensorArray.set_at((int(column), int(row)), intensities) def capture(self): # Copy the sensor array data as a frame. frame = self.sensorArray.copy() # Clear the sensor array for the next frame. self.sensorArray.fill((0, 0, 0)) return frame
def init(): global debugFont global debugSurf global buffSurf debugFont = font.SysFont('Arial', 16) debugSurf = Surface( (Render.display.get_width(), Render.display.get_height()), pygame.HWSURFACE) debugSurf.fill(transparentColor) debugSurf.set_colorkey(transparentColor) buffSurf = debugSurf.copy() pass
def func(size): if size == func.last_size: return func.last_surf.copy() surf = Surface(size, SRCALPHA) surf.fill(edge) if size[0] > 2 * thickness and size[1] > 2 * thickness: if fill[3] == 255: surf1 = Surface([a - (2 * thickness) for a in size], SRCALPHA) surf1.fill(fill) surf.blit(surf1, (thickness, thickness)) else: for y in range(thickness, size[1] - thickness): for x in range(thickness, size[0] - thickness): surf.set_at((x, y), fill) func.last_size = size func.last_surf = surf.copy() return surf
def __init__(self, game_instance, image: pygame.Surface, powerup_type: PowerupType): super().__init__(game_instance) self.image = image.copy() self.rect = self.image.get_rect() self.player = None self.type = powerup_type self.is_picked_up = False if powerup_type == PowerupType.POWER: self.start_duration = 300 elif powerup_type == PowerupType.SPEED: self.start_duration = 1000 elif powerup_type == PowerupType.GHOST_BULLETS: self.start_duration = 500 elif powerup_type == PowerupType.INVINCIBILITY: self.start_duration = 500 self.duration = self.start_duration
def __init__(self, game_instance, image: pygame.Surface, pos: (int, int), health_points: int = 1, powerup: Powerup = None, score_value: int = 100): super().__init__(game_instance) self.image = image.copy() self.rect = self.image.get_rect() self.rect.move_ip(pos[0], pos[1]) self.speed = (2, 0) self.width = self.rect.width self.height = self.rect.width self.y_jump = 50 self.health_points = health_points self.powerup = powerup self.score_value = score_value
def image_action_coloring(self, image: pygame.Surface, parent) -> pygame.Surface: """ Create a "colorized" copy of a surface (replaces RGB values with the given color, preserving the per-pixel alphas of original). :param image: Surface to create a colorized copy of :param newColor: RGB color to use (original alpha values are preserved) :return: New colorized Surface instance """ image = image.copy() # zero out RGB values image.fill((0, 0, 0, 255), None, pygame.BLEND_RGBA_MULT) # Fill black # add in new RGB values new_color = self.color[0:3] + (0, ) image.fill(new_color, None, pygame.BLEND_RGBA_ADD) # Add color new_color = (255, 255, 255) + (self.color[3], ) image.fill(new_color, None, pygame.BLEND_RGBA_MULT) # Multiply transparency return image
def makebackground(self, surface): surface.fill((0,0,0)) template = Surface(2*(min(self.zoom.width, self.zoom.height),), flags=SRCALPHA) template.fill((0,0,0,255)) width,height = template.get_size() o = min(surface.get_width()/width, surface.get_height()/height)/2 self.rects = [] for y in range(2*o): lat = asin(float(y-o)/o) * 180/pi r = int(sqrt(o**2-(o-y)**2)) for x in range(o-r, o+r): block = template.copy() v = [float(x-r)/o, float(y-o)/o] if x >= o: lon = self.rotate - acos(float((x-(o-r)-r))/r) * 180/pi else: lon = self.rotate + 180 + acos(float(r-(x-(o-r)))/r) * 180/pi if lon > 180: lon -= 360 h = self.planet.sample(lat, lon) color = ((0,int(255 * (h/9000.0)),0) if h > 0 else (0,0,int(255 * (1 + h/11000.0)))) block.fill(color) if self.selection: if self.selection[0][0] <= lat <= self.selection[0][1]: if self.selection[1][0] <= lon <= self.selection[1][1]: block.fill((255,0,0,32), special_flags = BLEND_ADD) rect = Rect(x * width, y * height, width, height) surface.blit(block, rect.topleft) self.rects.append((rect, (lat, lon)))
def __init__(self, radius, attitude=0): self.radius = radius self.attitude = attitude self.__sides_dict = dict() r1 = self.radius / cos(pi / 6) if self.attitude == 0: lines = [(round(cos(i / 6 * pi2) * self.radius / cos(pi / 6) + r1 + 1), round(sin(i / 6 * pi2) * self.radius / cos(pi / 6) + self.radius) + 1) for i in range(0, 6)] image = Surface((round(2 * r1) + 3, round(2 * self.radius) + 3)) else: lines = [(sin(i / 6 * pi2) * self.radius / cos(pi / 6) + self.radius, cos(i / 6 * pi2) * self.radius / cos(pi / 6) + r1) for i in range(0, 6)] image = Surface((round(2 * self.radius), round(2 * r1))) for side in _STONE_ENTITY_3: self.__sides_dict[side] = image.copy() self.__sides_dict[side].set_colorkey((0, 0, 0)) draw.aalines(self.__sides_dict[side], _STONE_ENTITY_3[side], True, lines)
class Display: screen = None size = None background = None minimap_surface = None minimap_scale = 10 texture_size = 64 main_wall_texture = None wall_textures = None textures_count = None texture_types_count = None main_sprite_texture = None sprites_count = None sprites = None raycast = None default_font = None def __init__(self): self.screen = None self.size = None self.background = None self.minimap_surface = None def loadTextures(self): self.main_wall_texture = image.load(os.path.join('data', 'walls.png')).convert() main_texture_size = self.main_wall_texture.get_size() self.textures_count = round(main_texture_size[1]/self.texture_size) self.texture_types_count = round(main_texture_size[0]/self.texture_size) self.wall_textures = [] for i in range(self.textures_count): texture_types = [] for t in range(self.texture_types_count-1): texture_type = [] x = t * self.texture_size y = i * self.texture_size for strip in range(self.texture_size): texture_type.append( self.main_wall_texture.subsurface((x, y, 1, self.texture_size)).convert() ) x = x + 1 texture_types.append(texture_type) self.wall_textures.append(texture_types) pass self.main_sprite_texture = image.load(os.path.join('data', 'sprites.png')).convert() self.sprites_count = self.main_sprite_texture.get_size()[0]//self.texture_size self.sprites = [] for i in range(self.sprites_count): sprite = [] x = i * self.texture_size y = 0 for strip in range(self.texture_size): sprite.append( self.main_sprite_texture.subsurface((x, y, 1, self.texture_size)).convert() ) x = x + 1 self.sprites.append(sprite) pass def initWindow(self, size = None): if (size == None): self.size = Config.screen_size display.init() font.init() self.screen = display.set_mode( self.size, flags.FULLSCREEN if Config.fullscreen else flags.RESIZABLE ) display.set_caption(Config.screen_caption) #Initializing bachground surface self.background = Surface(self.size).convert() self.background.fill(Config.background_color) #Initializing raycast engine self.raycast = Raycast(self.size) self.loadTextures() self.default_font = font.SysFont('Arial', 15) def close(self): display.quit() #TODO:use def drawRaycastedView(self,rays): default_texture = 1 default_type = 0 strip_no = 0 strip_width = self.raycast.strip_width x = 0 last_slice_meta = (None, None, None, None) last_slice = None for ray in rays: this_slice_meta = (default_texture, default_type, ray['texture_x'], ray['distance']) if (this_slice_meta != last_slice_meta): last_slice_meta = this_slice_meta strip_height = round(self.raycast.distance_to_plane / ray['distance']) y = round((self.size[1]-strip_height)/2) required_slice = round((self.texture_size/strip_width)*ray['texture_x']) - 1 try: last_slice = transform.scale(self.wall_textures[default_texture][default_type][required_slice], (strip_width, strip_height)) except Exception as e: pass try: self.screen.blit(last_slice,(x,y)) except Exception as e: pass x += strip_width strip_no = strip_no + 1 def draw(self,game): self.clearScreen() rays = self.raycast.castRays(game.player, game.world) self.drawRaycastedView(rays) self.drawUpdatedMinimap(game.world, game.player, rays, (0,0)) self.drawFPS(game.fps) self.finishDrawing() def clearScreen(self): self.screen.blit(self.background, (0, 0)) def initMinimap(self, world): size = ((world.width+2) * self.minimap_scale,(world.height+2) * self.minimap_scale) self.minimap_surface = Surface(size).convert() self.prenderMinimap(world) def prenderMinimap(self, world): self.minimap_surface.fill((0, 0, 0)) scale = self.minimap_scale y = scale # margin for row in world.world: x = scale for item in row: draw.rect( self.minimap_surface, item.map_color, (x,y,scale,scale) ) x = x + scale y = y + scale def drawUpdatedMinimap(self, world, player, rays, coords): scale = self.minimap_scale player_coords = ((player.coords+1) * scale).rounded().toInt().toTuple() player_direction = player.direction * scale player_direction = (player_direction + player_coords).rounded().toInt().toTuple() minimap = self.minimap_surface.copy() draw.circle( minimap, player.map_color, player_coords, round(player.size*scale) ) for ray in rays: draw.line( minimap, (0,255,0), player_coords, ((ray['coords'][0]+1)*scale, (ray['coords'][1]+1)*scale) ) draw.line( minimap, player.map_color, player_coords, player_direction ) self.screen.blit(minimap, coords) def finishDrawing(self): display.flip() def drawFPS(self, fps): fps = round(fps) if (fps >= 40): fps_color = (0,102,0) elif(fps >= 20): fps_color = (255, 153, 0) else: fps_color = (204, 0, 0) self.screen.blit( self.default_font.render('FPS: '+str(fps), False, fps_color), (self.size[0]-70, 5) )
def makebackground(self, surface): surface.fill((0,0,0)) template = Surface(2*(min(self.zoom.width, self.zoom.height),)) template.fill((0,0,0,255)) width,height = template.get_size() ylim = surface.get_height()/height dlat = float(self.selected[0][1] - self.selected[0][0])/ylim xmax = 0 for y in range(ylim): lat = self.selected[0][0] + y * dlat scale = cos(lat * pi/180) w = int(surface.get_width() * scale/width) if w > xmax: xmax = w hmin = hmax = 0 for y in range(ylim): lat = self.selected[0][0] + y * dlat scale = cos(lat * pi/180) xlim = int(surface.get_width() * scale/width) for x in range(xlim): dx = float(xmax - xlim)/2 lon = self.selected[1][0] + (x + dx) * scale * dlat h = self.planet.sample(lat, lon) if h < hmin: hmin = h if h > hmax: hmax = h self.rects = [] for y in range(ylim): lat = self.selected[0][0] + y * dlat scale = cos(lat * pi/180) xlim = int(surface.get_width() * scale/width) for x in range(xlim): dx = float(xmax - xlim)/2 lon = self.selected[1][0] + (x + dx) * scale * dlat block = template.copy() h = self.planet.sample(lat, lon) if h < 0: color = 0, 0, int(255 * (1 - h/hmin)) else: color = 0, int(255 * h/hmax), 0 block.fill(color) if self.selection: if self.selection[0][0] <= lat <= self.selection[0][1]: if self.selection[1][0] <= lon <= self.selection[1][1]: block.fill((255,0,0,32), special_flags = BLEND_ADD) rect = Rect(int(x+dx)*width, y*height, width, height) surface.blit(block, rect.topleft) self.rects.append((rect, (lat, lon)))
class LayeredRenderer(Renderer): """ A renderer that uses all the layers in a tiled map. """ def __init__(self, level, screen_size_in_tiles, display_size): # the next few variables are used to initialize the parent # the size of the screen in tiles self.screen_size_in_tiles = screen_size_in_tiles # small name for the big variable intiles = screen_size_in_tiles # this is the size of the surface holding what is # visible right now in the screen screen_size = (intiles[0]*level.tiledmap.tilewidth, intiles[1]*level.tiledmap.tileheight ) self.screen_size = screen_size self.ratio = float(screen_size[0]) / float(screen_size[1]) # Size of the pygame window, the screen being rendered # will be scaled to this size self.display_size = display_size # init the parent Renderer.__init__(self, level, screen_size) # the size of the whole map in pixels self.map_size_in_pixels = (self.tiledmap.width*self.tw, self.tiledmap.height*self.th) # Everything will be drawn in here, used to clear when dirty. self.map_background = Surface(self.map_size_in_pixels) # This will hold the whole map with sprites included. # From here we take the subsurface showed in screen. self.full_map = None # Keep aspect ratio? self.keep_aspect_ratio = True self.ratio_display_size = (1,1) self.temp_surface = Surface((1,1)) self.ratio_dest = (0,0) self.new_size = self.display_size self.debug_images = False self.debugging = False def coords_from_screen_to_map(self, screen_coords): ratio_x = float(self.screen_size[0]) / float(self.display_size[0]) ratio_y = float(self.screen_size[1]) / float(self.display_size[1]) new_coord_x = screen_coords[0] * ratio_x + self.current_camera.screen_rect[0] new_coord_y = screen_coords[1] * ratio_y + self.current_camera.screen_rect[1] return new_coord_x,new_coord_y def coords_from_map_to_screen(self, coords): pass def render_map_background(self, surface=None): """ Render the whole static part of a map in the given surface. I a surface is not given uses self.map_background. Copy it to self.full_map if it doesn't exist. Only needs to be called once, after init. Can be used to clean sprites that haven't been cleaned properly. """ if surface == None: surface = self.map_background for i in range(len(self.level.layers)): layer = self.level.layers[i] if layer.visible: if isinstance(layer, ImageLayer): layer.draw(surface) elif isinstance(layer, TileLayer): # TODO # animated tiles need som special treatment too layer.static.draw(surface) elif isinstance(layer, ObjectLayer): pass if self.full_map == None: self.full_map = self.map_background.copy() def get_dirty_rects(self): """ Get all the rects that need to be repainted. DEPRECATED Because of alpha compositing this have to be called before updating the mobs and after updating the mobs. """ union_add = self.union_add last_dirty_rects = self.last_dirty_rects layers = self.level.layers for i in range(len(layers)): layer = layers[i] if not layer.visible: continue # ImageLayer and TileLayer have no moving parts (yet) if isinstance(layer, ImageLayer): pass elif isinstance(layer, TileLayer): # animated tiles need som special treatment too TODO TODO pass elif isinstance(layer, ObjectLayer): some_rects = copy_visible_rects_from_sprites(layer) some_rects.extend(copy_visible_rects_from_sprites(layer.actionsprites.sprites())) #~ if debug_images: #~ for spr in layer.sprites(): #~ if hasattr(spr, 'debug_image'): #~ some_rects.append(spr.debug_image, spr.col_rect) # Add all the sprite and make sure there are no # overlapping rects for r in some_rects: union_add(last_dirty_rects, r) # TODO ! this is debugging stuff and should be deleted # at the end #~ if self.check_overlapping(last_dirty_rects): #~ print "*******************************************************************" #~ print "*******There are overlapping dirty rects! this should not happen!**" #~ print "*******************************************************************" def check_overlapping(self, rect_list): """ Return True if two or more rects overlap in a list of rects. This is not used at the moment, is a debugging stuff. """ overlap = False for i in range(len(rect_list)): r = rect_list[i] for j in range(i+1, len(rect_list)): if r.colliderect(rect_list[j]): overlap = True break if overlap: break return overlap def union_add(self, rect_list, rect): """ Add rect to rect_list joining them if they overlap. """ rect_col = rect.collidelistall rect_list_append = rect_list.append rect_list_pop = rect_list.pop rect_union = rect.union_ip indices = rect_col(rect_list) while indices: for index in reversed(indices): rect_union(rect_list_pop(index)) indices = rect_col(rect_list) else: rect_list_append(rect) def interpolate_draw(self, surface = None, interpolate = 0.): """ Clear and draw the moving part of the map. First clear the surface using self.last_dirty_rects, then draw all these zones and all the sprites. """ self.dprint("## In LayeredRederer.draw") if surface == None: surface = self.full_map # Speed-ups surface_blit = surface.blit draw_rects = self.draw_rects union_add = self.union_add debug_rects = s.debug_mode > 1 surface_fill = surface.fill BACK_COLOR = Color(0,0,0,0) # Store debug rects by color violet_rects = [] red_rects = [] green_rects = [] blue_rects = [] # Clear all the dirty rects # We are using layers with opacity, steps to make this look nice: # - Clear all the dirty rects with the new and the old position of the # sprites, these dirty rects are contained in every TrySprite and are # updated when change_sprite_position and move_sprite are called. # - Draw all the layers in correct order. # First collect dirty rects dirty_rects = [] tmp_dirty_rects = [] for i in xrange(len(self.level.layers)): layer = self.level.layers[i] if isinstance(layer, ObjectLayer): for spr in layer.sprites(): try: vx = spr.vx vy = spr.vy except AttributeError: vx = vy = 0. spr.i_rect = spr.rect.move(vx*interpolate, vy*interpolate) # TODO: need to get the interpolated rect, no the original one tmp_dirty_rects.extend([spr.i_rect.copy() for spr in layer.sprites()]) # Next two also need to copy rectangles, if not bad things happen with # not moving sprites tmp_dirty_rects.extend([i.copy() for i in layer.spritedict.values() if i != 0]) tmp_dirty_rects.extend([i.copy() for i in layer.actionsprites.spritedict.values() if i != 0]) #~ tmp_dirty_rects.extend([spr.dirty_rect for spr in layer.actionsprites.sprites() if spr.visible == 1]) # don't forget killed sprites! (bad things happen if you forget them) tmp_dirty_rects.extend(layer.lostsprites) tmp_dirty_rects.extend(layer.actionsprites.lostsprites) # Because of opacity we can't have any overlapping rect, if that # would happen layers with opacity will look wierd. Join using union # all the overlapping rects for r in tmp_dirty_rects: union_add(dirty_rects, r) # Clear them in the map for r in dirty_rects: surface_fill(BACK_COLOR, r) #~ pygame.draw.rect(surface, RED, r, 3) # Iterate layers and redraw dirty rects for i in xrange(len(self.level.layers)): layer = self.level.layers[i] if not layer.visible: continue self.dprint("\t layer.name = {0}; layer.visible = {1}".format(layer.name, layer.visible)) if isinstance(layer, ImageLayer): spr = layer.sprites()[0] img = spr.image for r in dirty_rects: #~ if img_rect.colliderect(r): # TODO: is this good or bad idea? surface_blit(img, r, r) if debug_rects: red_rects.extend(rects_from_sprites([spr])) elif isinstance(layer, TileLayer): # Animated tiles need som special treatment TODO TODO. img = layer.static_img for r in dirty_rects: surface_blit(img, r, r) elif isinstance(layer, ObjectLayer): # All sprites are redrawn always #~ layer.actionsprites.simple_draw(surface) #~ layer.simple_draw(surface) layer.actionsprites.interpolate_draw(surface, interpolate) layer.interpolate_draw(surface, interpolate) if debug_rects: violet_rects.extend(col_rects_from_sprites(layer.sprites())) violet_rects.extend([spr.feet_rect for spr in layer.sprites()]) blue_rects.extend(rects_from_sprites(layer.actionsprites.sprites())) # draw on top all the debug rects collected if debug_rects: # First collect all the collision rects from the # collision_group used by engine. red_rects.extend(col_rects_from_sprites(self.level.collision_group)) offset = (0, 0) size = 1 iterator = zip( (green_rects, blue_rects, red_rects, violet_rects), (GREEN, BLUE, RED, VIOLET)) for rect_list, color in iterator: draw_rects(surface, rect_list, offset, size, color) draw_rects(surface, red_rects, offset, size, RED) # get the camera and the screen rect cm = self.current_camera #~ print cm.screen_rect self.current_screen = self.full_map.subsurface(cm.screen_rect) # Get events and update stuff self.get_events() def get_events(self): l = event.get(RENDERER) for e in l: if e.code == FADE: self.toggle_fade() elif e.code == NEXT_CAMERA: self.next_camera() elif e.code == CAMERA_LEFT: self.current_camera.accel_left() elif e.code == CAMERA_RIGHT: self.current_camera.accel_right() elif e.code == CAMERA_UP: self.current_camera.accel_up() elif e.code == CAMERA_DOWN: self.current_camera.accel_down() elif e.code == CAMERA_SHAKE: self.current_camera.shake(30, 5) else: print "WARNING: Unhandled event code in renderer: {0}".format(e) def blit_scaled_map(self, surface): """ Scale the subsurface representing the screen and return it. Note that this is the only method to obtain the render screen, you can if you want get the self.current_screen directly BUT it won't have any fading effects. """ # Update the display size self.display_size = surface.get_size() if self.keep_aspect_ratio: size = surface.get_size() # If the display size has changed make calculations if self.ratio_display_size != size: self.ratio_display_size = size ratio = float(size[0]) / float(size[1]) if ratio >= self.ratio: self.new_size = (int(size[1] * self.ratio), size[1]) self.ratio_dest = ((size[0] - self.new_size[0]) / 2, 0) self.temp_surface = Surface(self.new_size, pygame.HWSURFACE) elif ratio < self.ratio: self.new_size = (size[0], int(size[0] / self.ratio)) self.ratio_dest = (0, (size[1] - self.new_size[1]) / 2) self.temp_surface = Surface(self.new_size, pygame.HWSURFACE) # Scale the image and blit in the correct place # leaving balck bands if needed #~ print self.temp_surface.get_flags(), pygame.HWSURFACE pygame.transform.scale(self.current_screen, self.new_size, self.temp_surface) surface.blit(self.temp_surface, self.ratio_dest) else: # Just scale the camera to the display surface pygame.transform.scale(self.current_screen, surface.get_size(), surface) # If the display size has changed update the fading # image if self.display_size != surface.get_size(): self.generate_fade_image(surface.get_size()) # Do fading self.update_fading() if self.fade_image.get_alpha() != 0: surface.blit(self.fade_image, [0, 0]) def toggle_collision_rects(self): if self.debug_images: self.debug_images = False self.full_map = self.map_background.copy() else: self.debug_images = True def redraw_background(self): self.full_map = self.map_background.copy()