def test_calculate_tile_coverage(self): v = Rect(0,0,11,11) m = map.MapBase(50,50) e = map.MapEntity(1) m.place_character(e,(25,25)) c = m.map_tile_coverage #Normal centered e.move_to((25,25)) v.center = (25,25) m.calculate_tile_coverage(v) self.assertEqual(16,c.width) self.assertEqual(16,c.height) self.assertEqual((25,25),c.center) #Not enough map on up and left e.move_to((1,1)) v.center = (6,6) m.calculate_tile_coverage(v) self.assertEqual(0,c.left) self.assertEqual(0,c.top) #Not enough map on down and right e.move_to((48,48)) v.right = 50 v.bottom = 50 m.calculate_tile_coverage(v) self.assertEqual(50,c.right) self.assertEqual(50,c.bottom) #Refresh while walking north e.move_to((25,21)) v.center = (25,25) m.calculate_tile_coverage(v) self.assertEqual(v.bottom + 1,c.bottom) self.assertEqual(25,c.centerx) #Refresh while walking south e.move_to((25,29)) v.center = (25,25) m.calculate_tile_coverage(v) self.assertEqual(v.top - 1,c.top) self.assertEqual(25,c.centerx) #Refresh while walking east e.move_to((29,25)) v.center = (25,25) m.calculate_tile_coverage(v) self.assertEqual(v.left - 1,c.left) self.assertEqual(25,c.centery) #Refresh while walking west e.move_to((21,25)) v.center = (25,25) m.calculate_tile_coverage(v) self.assertEqual(v.right + 1,c.right) self.assertEqual(25,c.centery)
def on_mouse_down(pos, button): global current_poly global current_point if button == mouse.RIGHT: p = Poly() polys.append(p) set_current_poly(p) return if current_poly is not None: r = Rect(0, 0, 6, 6) for i, handle in enumerate(current_poly.handles): r.center = handle.pos if r.collidepoint(pos): current_point = i return for p in polys: if len(p) > 2 and p.contains(pos): set_current_poly(p) current_point = None return else: if current_poly is not None: current_poly.add_point(pos) current_point = len(current_poly) - 1
def display_tryagain(textRectObj: pygame.Rect) -> bool: display_again = False x_display = textRectObj.bottomleft[0] + int(textRectObj.width / 4) y_display = textRectObj.bottomleft[1] + int( self.square_frame[1] / 2) width = height = int(textRectObj.width / 2) mouse = pygame.mouse.get_pos() if x_display + width > mouse[0] > x_display and \ y_display + height > mouse[1] > y_display: rectObj = pygame.draw.rect( self.surface_display, self.highlight_color, (x_display, y_display, width, height)) for event in pygame.event.get([MOUSEBUTTONDOWN]): display_again = True else: rectObj = pygame.draw.rect( self.surface_display, self.gameover_color, (x_display, y_display, width, height)) fontObj = pygame.font.SysFont('timesnewroman', 36) textSurfaceObj = fontObj.render('RESTART', True, self.fill_color) textRectObj = textSurfaceObj.get_rect() textRectObj.center = rectObj.center self.surface_display.blit(textSurfaceObj, textRectObj) return display_again
def _draw_animation(self, entity): height = entity.cliche.surface.get_height() dest = Rect(0, 0, height, height) dest.center = self._on_screen(entity.position) self.screen.blit(entity.cliche.surface, dest, entity.cliche.active_rect)
def draw_sprite(self, sprite, ratio=None): if ratio is None: ratio = self.ratio # calculate the size of the shadow w = sprite.rect.width * ratio + 1 h = w/2 rect = Rect(0,0,w,h) # shrink the shadow according to height if hasattr(sprite, "height"): height0 = sprite.__class__.height ratio = (height0 - sprite.height) / float(height0) rect.width = max(8, rect.width * ratio) rect.height = max(4, rect.height * ratio) # move the the midbottom of the sprite rect.center = sprite.rect.midbottom rect.x -= 1 rect.y -= 3 # if the sprite has a height property, use it to move the shadow if hasattr(sprite, "height"): rect.y += sprite.height # draw to the layer pygame.draw.ellipse(self._layer, self.color, rect)
def view_port(self): w, h = pygame.display.get_surface().get_size() width = 5000 / self.zoom_level height = width*(h/w) view_port = Rect(0, 0, 0, 0) view_port.size = (width+1, height+1) # +1 to prevent white bars at the bottom or right view_port.center = self.pos return view_port
def on_mouse_move(pos): cursor.pos = pos r = Rect(0, 0, 30, 30) r.center = pos possible_collisions = sh.query(r) for b in possible_collisions: sep = (b.pos - pos).scaled_to(2) b.velocity += sep
def get_object_global_rect(self, obj: BoardObject): """.""" if not hasattr(obj.original, "image"): return None rect = Rect((0, 0, 0, 0)) rect.size = math2d.v_mul(obj.original.image.get_size(), 1 / self.__scale) rect.center = self.to_global(obj.position) return rect
def __init__ (self, real, within, player, vel, dirn, pos): Entity.__init__(self, vel) self.size = conf.MINE['size'] r = Rect((0, 0), self.size) r.center = pos self.graphics.pos = r.clamp(within).topleft self.real = real self.player = player self.placed = None
def __init__(self, root: Panel): """Create a new MainMenuScene, creating the gui components to display. """ size = root.get_rect().size title_rect = Rect(0, 0, 500, 70) title_rect.center = (size[0] / 2, size[1] / 2 - 200) # A panel for all the options options_panel = VerticalPanel(rect=Rect(size[0] / 4, size[1] / 2, size[0] / 2, size[1] / 4), expand_height=False, parent=root) # Title label Label(text="BATTLE SHIP!", rect=title_rect, style=Style(background_color=None, border_width=0, font=pygame.font.Font('freesansbold.ttf', 64), primary_color=(255, 255, 255)), parent=root) # A style for all of the menu options button_style = Style(primary_color=(255, 255, 255), background_color=(128, 0, 0), border_width=1, border_color=(0, 0, 0), font=pygame.font.Font('freesansbold.ttf', 32)) # Player vs Computer button Button(rect=Rect(0, 0, 400, 40), on_click=self._pvc_clicked, text="Player vs Computer", style=button_style, parent=options_panel) # Player vs Player button Button(rect=Rect(0, 0, 400, 40), on_click=self._pvp_clicked, text="Player vs Player", style=button_style, parent=options_panel) # Settings button Button(rect=Rect(0, 0, 400, 40), on_click=self._settings_clicked, text="Settings", style=button_style, parent=options_panel) # Quit button Button(rect=Rect(0, 0, 400, 40), on_click=self._quit_clicked, text="Quit", style=button_style, parent=options_panel)
def render(self): rounded_rect(self.surface, self.rect, self.c_on if self.pressed else self.c_off, min(self.rect.width, self.rect.height) * .1) r = Rect(self.rect) r.center = self.rect.x + self.rect.width * 19 / 32, self.rect.y + self.rect.height * 19 / 32 draw_text(self.surface, self.label, Font(fonts.ANONYMOUS_PRO_REGULAR, 24), r, colour.ELECTROMAGNETIC)
def change_map(self): pos = list(next(self.hotspots)[:]) r = Rect((0,0), sd.get_size()).inflate((48, 48)) r.center = pos clip = Surface(r.size) clip.blit(self.overworld, (0,0), r) self.surfaceQueue.put(clip) self.thread = SubPixelThread(self.surfaceQueue, self.subpixelQueue) self.thread.start()
def change_map(self): pos = list(next(self.hotspots)[:]) r = Rect((0, 0), sd.get_size()).inflate((48, 48)) r.center = pos clip = Surface(r.size) clip.blit(self.overworld, (0, 0), r) self.surfaceQueue.put(clip) self.thread = SubPixelThread(self.surfaceQueue, self.subpixelQueue) self.thread.start()
def spawn_wave(self, number): """ a collection of beasts """ beasts = [] if 0 <= number < len(self.waves): wave = self.waves[number] for genus, west, south in wave: location = Rect(0,0,1,1) location.center = (west, south) beasts.append(getattr(bestiary, genus)(location)) return beasts
def get_collsion_locations(self, position, tilesize): size = min(self.rect.width, self.rect.height) rect = Rect(self.rect.topleft, (size, size)) rect.center = self.rect.center points = rect.topleft, rect.topright, rect.bottomleft, rect.bottomright for point in points: return set([ tuple(map(int, (point + position) / tilesize)) for point in points ])
def _update (self, col, row, tile_type_id, tile_rect=None): if self._cache_graphic: if tile_type_id in self._cache: g = self._cache[tile_type_id] else: g = self._type_to_graphic(tile_type_id) self._cache[tile_type_id] = g else: g = self._type_to_graphic(tile_type_id) dest = self._orig_sfc if tile_rect is None: tile_rect = self.grid.tile_rect(col, row) if isinstance(g, (Graphic, pg.Surface, basestring)): g = (g,) if (g is not None and isinstance(g[0], (Graphic, pg.Surface, basestring))): sfc = g[0] if isinstance(sfc, basestring): sfc = self._load_img(sfc) elif isinstance(sfc, Graphic): sfc = sfc.surface if len(g) == 1: alignment = rect = None else: if isinstance(g[1], int) or len(g[1]) == 2: alignment = g[1] rect = None else: alignment = None rect = g[1] if len(g) == 3: if rect is None: rect = g[2] else: alignment = g[2] if alignment is None: alignment = 0 if rect is None: rect = sfc.get_rect() # clip rect to fit in tile_rect dest_rect = Rect(rect) dest_rect.center = tile_rect.center fit = dest_rect.clip(tile_rect) rect = Rect(rect) rect.move_ip(fit.x - dest_rect.x, fit.y - dest_rect.y) rect.size = dest_rect.size # copy rect to tile_rect with alignment pos = gameutil.align_rect(rect, tile_rect, alignment) dest.blit(sfc, pos, rect) else: if g is None: g = (0, 0, 0, 0) # now we have a colour dest.fill(gameutil.normalise_colour(g), tile_rect) return tile_rect
def _compute_target_subsurface(self): screen = display.get_surface() screen.fill(self.bg_color) self_rect = self.get_rect() display_rect = screen.get_rect() if self._scale_type == 'pixelperfect': factor = min(float(display_rect.w) / self_rect.w, float(display_rect.h) / self_rect.h) if factor >= 1.0: factor = int(factor) w = int(factor * self_rect.w) h = int(factor * self_rect.h) r = Rect(0, 0, w, h) r.center = display_rect.center target = screen.subsurface(r) elif self._scale_type == 'scale2x': factor = min(display_rect.w // self_rect.w, display_rect.h // self_rect.h) pow2 = 0 while (2 << pow2) <= factor: # yes, 2<<pow2. pow2 += 1 factor = (1 << pow2) w = factor * self_rect.w h = factor * self_rect.h r = Rect(0, 0, w, h) r.center = display_rect.center if display_rect.contains(r): target = screen.subsurface(r) else: target = screen elif self._scale_type == 'proportional': target = screen.subsurface(self_rect.fit(display_rect)) elif self._scale_type == 'stretch': target = screen else: # elif self._scale_type == 'centered': self_rect.center = display_rect.center if display_rect.contains(self_rect): target = screen.subsurface(self_rect) else: target = screen.subsurface(self_rect.fit(display_rect)) return target
def set_parent(self, parent: Optional[Component]) -> None: """Set the component's parent. The default style is used if <parent> is None. """ Panel.set_parent(self, parent) if (self._parent is None): return self.set_rect(self._parent.get_rect()) size = self.get_rect().size title_rect = Rect(0, 0, 500, 70) title_rect.center = (size[0] / 2, size[1] / 2 - 200) self.clear_children() self.options_panel = VerticalPanel(rect=Rect(size[0] / 4, size[1] / 2, size[0] / 2, size[1] / 4), expand_height=False, parent=self) self.title_label = Label(text="BATTLE SHIP!", rect=title_rect, style=Style(background_color=None, border_width=0, font=pygame.font.Font( 'freesansbold.ttf', 64), primary_color=(255, 255, 255)), parent=self) button_style = Style(primary_color=(255, 255, 255), background_color=(128, 0, 0), border_width=1, border_color=(0, 0, 0), font=pygame.font.Font('freesansbold.ttf', 32)) self.cont_button = Button(rect=Rect(0, 0, 400, 40), on_click=self._cont_clicked, text="Continue", style=button_style, parent=self.options_panel) self.main_menu_button = Button(rect=Rect(0, 0, 400, 40), on_click=self._main_menu_clicked, text="Main menu", style=button_style, parent=self.options_panel) self.quit_button = Button(rect=Rect(0, 0, 400, 40), on_click=self._quit_clicked, text="Quit", style=button_style, parent=self.options_panel)
def __init__(self, hit_rect: pg.Rect, pos: Vector2, max_health: int) -> None: hit_rect = hit_rect.copy() hit_rect.center = pos self.motion: Motion = Motion(self, self.timer, self.groups.walls, hit_rect) self.status = Status(max_health) super().__init__(pos) self._base_rect = self.image.get_rect().copy() self.inventory = Inventory()
def render_center_info(board_render): center_info_surface = Surface((250, 250)) match = board_render.match group = LayeredUpdates() # Background info_rect = Rect(0, 0, 250, 250) info_rect.center = board_render.surface.get_rect().center pygame.draw.rect(center_info_surface, (0, 0, 0), info_rect) 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, 30) large_font = Font(font_path, 42) # Round Title round_text = "{} {}".format("East" if match.east_prevalent else "South", match.round_number) round_surface = font.render(round_text, True, (255, 255, 255)) round_sprite = Sprite() round_sprite.image = round_surface round_sprite.rect = round_surface.get_rect() round_sprite.rect.center = info_rect.center round_sprite.rect.y -= (round_surface.get_rect().height // 2) round_sprite.layer = 1 group.add(round_sprite) # Tiles Left in Wall tile_count_surface = large_font.render(str(len(match.current_board.wall)), True, (255, 255, 255)) wall_remaining_sprite = Sprite() wall_remaining_sprite.image = tile_count_surface wall_remaining_sprite.rect = tile_count_surface.get_rect() wall_remaining_sprite.rect.center = info_rect.center wall_remaining_sprite.rect.y += (tile_count_surface.get_rect().height // 3) wall_remaining_sprite.layer = 1 group.add(wall_remaining_sprite) # Wind Markers create_wind_markers(match, info_rect, group) # Turn Marker create_turn_marker(match, info_rect, group) # Riichi Markers create_riichi_markers(match, info_rect, group) background_sprite = Sprite() background_sprite.rect = info_rect background_sprite.image = center_info_surface background_sprite.layer = 0 group.add(background_sprite) return group
def test_center( self ): """Changing the center attribute moves the rect and does not change the rect's size """ r = Rect( 1, 2, 3, 4 ) new_center = (r.centerx+20,r.centery+30) expected_topleft = (r.left+20,r.top+30) old_size = r.size r.center = new_center self.assertEqual( new_center, r.center ) self.assertEqual( expected_topleft, r.topleft ) self.assertEqual( old_size, r.size )
def test_center(self): """Changing the center attribute moves the rect and does not change the rect's size """ r = Rect(1, 2, 3, 4) new_center = (r.centerx + 20, r.centery + 30) expected_topleft = (r.left + 20, r.top + 30) old_size = r.size r.center = new_center self.assertEqual(new_center, r.center) self.assertEqual(expected_topleft, r.topleft) self.assertEqual(old_size, r.size)
def rounded_rect(surface: Surface, rect: Rect, colour: Colour, corner_radius: int): ''' Draw a rectangle with rounded corners. Would prefer this: pygame.draw.rect(surface, colour, rect, border_radius=corner_radius) but this option is not yet supported in my version of pygame so do it ourselves. We use anti-aliased circles to make the corners smoother ''' if rect.width < 2 * corner_radius or rect.height < 2 * corner_radius: raise ValueError( f"Both height (rect.height) and width (rect.width) must be > 2 * corner radius ({corner_radius})" ) corner_radius = int(corner_radius) # need to use anti aliasing circle drawing routines to smooth the corners circle(surface, rect.left + corner_radius, rect.top + corner_radius, corner_radius, colour) circle(surface, rect.right - corner_radius - 1, rect.top + corner_radius, corner_radius, colour) circle(surface, rect.left + corner_radius, rect.bottom - corner_radius - 1, corner_radius, colour) circle(surface, rect.right - corner_radius - 1, rect.bottom - corner_radius - 1, corner_radius, colour) rect_tmp = Rect(rect) rect_tmp.width -= 2 * corner_radius rect_tmp.center = rect.center draw_rect(surface, colour, rect_tmp) rect_tmp.width = rect.width rect_tmp.height -= 2 * corner_radius rect_tmp.center = rect.center draw_rect(surface, colour, rect_tmp)
def render_vertical_discard_pile(board_render, player_id, seat): group = Group() match = board_render.match player = match.players[player_id] if player.discard_pile is None: return group rect = Rect(board_render.surface.get_rect()) rect.center = (0, 0) side_calculation = (SMALL_TILE_SIZE[1] + 10) * 4 if seat == 1: rect.right = side_calculation + 180 if seat == 3: rect.left = -side_calculation - 180 tile_offset = 10 tiles_per_row = 8 i = 0 row = 0 row_offset = SMALL_TILE_SIZE[1] + tile_offset full_width = tiles_per_row * (SMALL_TILE_SIZE[0] + tile_offset) - tile_offset beginning_of_across_line = rect.height - ((rect.height - full_width) / 2) beginning_of_across_line -= full_width if seat == 3 else 0 across = beginning_of_across_line for tile in player.discard_pile: tile_pos = (-rect.x + (row * row_offset), across) tile_sprite = TileRender( board_render.small_dictionary, tile, tile_pos, small_tile=True, rotation=seat, ) group.add(tile_sprite) across -= (SMALL_TILE_SIZE[0] + tile_offset if seat == 1 else -(SMALL_TILE_SIZE[0] + tile_offset)) i += 1 if i >= tiles_per_row: i = 0 row += 1 if seat == 1 else -1 across = beginning_of_across_line return group
def render_discard_pile(board_render, player_id, seat): group = Group() match = board_render.match player = match.players[player_id] if player.discard_pile is None: return group rect = Rect(board_render.surface.get_rect()) rect.center = (0, 0) side_calculation = (SMALL_TILE_SIZE[1] + 10) * 3 if seat == 0: rect.bottom = side_calculation + TILE_SIZE[1] + 20 if seat == 2: rect.top = -side_calculation tile_offset = 10 tiles_per_row = 12 i = 0 row = 0 row_offset = SMALL_TILE_SIZE[1] + tile_offset full_width = tiles_per_row * (SMALL_TILE_SIZE[0] + tile_offset) - tile_offset beginning_of_across_line = (rect.width - full_width) / 2 beginning_of_across_line += full_width if seat == 2 else 0 across = beginning_of_across_line for tile in player.discard_pile: tile_pos = (across, -rect.y + (row * row_offset)) tile_sprite = TileRender( board_render.small_dictionary, tile, tile_pos, small_tile=True, rotation=seat, ) group.add(tile_sprite) across += (SMALL_TILE_SIZE[0] + tile_offset if seat == 0 else -(SMALL_TILE_SIZE[0] + tile_offset)) i += 1 if i >= tiles_per_row: i = 0 row += 1 if seat == 0 else -1 across = beginning_of_across_line return group
def draw_tabs(self, surf): font = self.tab_font fg = self.tab_fg_color b = self.tab_border_width if b: surf.fill(fg, (0, self.tab_height - b, self.width, b)) for i, title, page, selected, rect in self.iter_tabs(): x0 = rect.left w = rect.width h = rect.height r = rect if not selected: r = Rect(r) r.bottom -= b self.draw_tab_bg(surf, page, selected, r) if b: surf.fill(fg, (x0, 0, b, h)) surf.fill(fg, (x0 + b, 0, w - 2 * b, b)) surf.fill(fg, (x0 + w - b, 0, b, h)) buf = font.render(title, True, page.fg_color or fg) r = buf.get_rect() r.center = (x0 + w // 2, h // 2) surf.blit(buf, r)
def rectangle(self): rect = Rect(0, 0, self.screen_height, self.screen_height) rect.center = (self.screen_width / 2, self.screen_height / 2) return rect
def get_view_rect(self): """Возвращает Rect видимой области на доске""" vs = self.__rect.w * self.__scale, self.__rect.h * self.__scale view_rect = Rect((0, 0), vs) view_rect.center = self.__pos return view_rect
def translate_rect(self, rect, pos): dest = Rect(0, 0, self.scale * rect.w, self.scale * rect.h) dest.center = self.translate_pos(pos) return dest
def rect(self, position): rect = Rect(0, 0, self.width, self.height) rect.center = (round(position.x), round(position.y)) return rect
def custom_update_actions(self, platforms, new_sprites_group, player): """ Some Player special actions. """ ###### # other stuff: shoot, actions, etc... ###### if self.use and self.col_down: self.use = False if self.match_position: #~ match_p = (self.match_position[0] + self.rect[0],self.match_position[1] + self.rect[1] - 1) match_rect = Rect(0,0,self.match_rect_size, self.match_rect_size) match_rect.center = (self.match_position[0] + self.rect[0],self.match_position[1] + self.rect[1] - 1) l = [spr for spr in self.groups()[0].sprites() if isinstance(spr,FireworkLauncher)] for f in l: if f.col_rect.colliderect(match_rect) and \ not f.lit and self.vx == 0: f.lit = True glo.score += f.SCORE_LIT size = 12 self.score_particle['x'] = self.rect.left self.score_particle['y'] = self.rect.top self.score_particle['text'] = f.SCORE_LIT self.properly_add_ontop(ScoreText(**self.score_particle)) f.ignite_sound.play() if abs(self.vx) >= self.max_speed: if self.running_timer.finished: self.multiplier += 0.015 if self.multiplier <= self.max_multiplier else 0.0 self.max_speed = self.base_max_speed * self.multiplier else: self.multiplier = 1. self.max_speed = self.base_max_speed self.running_timer.reset() # Draw the match fire particles if self.match_position: mp = self.match_particle mp['x'] = self.match_position[0] + self.rect[0] mp['y'] = self.match_position[1] + self.rect[1] - 1 if self.lit: for i in xrange(int(ceil(self.lit /200))): p=RandColorParticle(**mp) player.properly_add_below(p) too_fast = hypot(self.vx, self.vy) - self.speed_limit if too_fast > 0: self.lit -= too_fast * self.damage_factor # Falling stuff if self.falling: self.fallen_updates += 1 else: self.fallen_updates = 0 # Reduce 'lit' every 'updates_per_lit_unit' updates and # apply modifiers (pigeon attacks) if not self.winning: self.lit_counter += 1 if self.lit_counter % self.updates_per_lit_unit == 0: self.lit_counter = 0 self.lit -= 1 # Apply lit modifiers self.lit -= self.lit_taken self.lit_taken = 0 # Damage stuff # Look inside the mob classes to see how damage is applied if (self.half_platform_damage > 0 or self.inmunity_damage > 0) and not self.winning: self.damage_counter += 1 self.half_platform_damage -= 1 if self.half_platform_damage > 0 else self.half_platform_damage self.inmunity_damage -= 1 if self.inmunity_damage > 0 else self.inmunity_damage # Need to copy the image. Not copying the image permanently # modifies player animations. self.image = self.image.copy() self.image.set_alpha(int(255*(self.damage_counter % self.damage_period) / (self.damage_period -1))) ######### # Sounds if self.just_col_down: fall_sound.play() # Walking sounds if self.moving and self.col_down and \ self.moved_x: self.step_counter += 1 if self.step_counter % self.updates_per_step == 0: if self.step_counter == self.updates_per_step: step1_sound.play() else: step2_sound.play() self.step_counter = 0 # Braking sound # print "in custom update options:", self.braking if self.braking: if self.brake_counter % self.updates_per_brake == 0: brake_sounds[2].play() self.brake_counter += 1 else: self.brake_counter = 0 ##################################### # Amount of match and loosing things # if self.lit < 0.0 and not self.winning: self.loosing = True if self.player_controlled: ouch_sound.play() self.sound_delay = Timer(0.3) js = self.loosing_jump_speed if self.direction == LOOKING_LEFT: self.movement_mods.append((SPEED_ADD, (js[0], -1 * js[1]))) else: self.movement_mods.append((SPEED_ADD, (-1 * js[0], -1 * js[1]))) if self.sound_delay and self.sound_delay.finished: game_over_sound.play() self.sound_delay = None self.player_controlled = False if self.winning: self.player_controlled = False # Update the bonus value if not self.winning: glo.bonus = int(self.lit) * 10 * 3 ############ # Counters # # NOTE TO FUTURE SELF: # Counter must be at the start or at the end, but # never in the middle. if self.moving and self.col_down: self.walking_update_counter += 1 else: self.walking_update_counter = 0
def draw_vector_on(surface, color, pos, vec): vec = (pos[0] + vec[0], pos[1] + vec[1]) pygame.draw.line(surface, color, pos, vec) r = Rect(0, 0, 3, 3) r.center = vec pygame.draw.rect(surface, color, r)
def main(): pygame.init() screen = pygame.display.set_mode((1024, 768)) pygame.display.set_caption("Rect Test") #Create a Rectangle #Obs.: will be mouse-controlled #optional: create a tuple for the rectangle's colour player_rect = Rect(0, 0, 100, 100) player_colour = (0, 255, 0) #Create a list of rectangles rect_list = [Rect(550, 100, 200, 200), Rect(150, 150, 350, 350), Rect(800, 600, 150, 150)] #optional: create a list of colours (should match rect #list length) colours = [(255, 255, 0), (255, 0, 255), ( 0, 255, 255)] #Create an extra rectangle for overlap detection result = Rect(0, 0, 0, 0) is_running = True #Game loop while is_running: for evt in pygame.event.get(): if evt.type == pygame.QUIT: is_running = False #Controlling the player rectangle with the mouse #(uncomment code below) player_rect.center = pygame.mouse.get_pos() #clip result rectangle: #result = player_rect.clip(rect_list[0]) #advanced: clip against a list result = player_rect.clip(rect_list[player_rect.collidelist(rect_list)]) #Render part screen.fill((0, 0, 127)) #Render rectangles: #1: Render player rectangle pygame.draw.rect(screen, player_colour, player_rect) #2: Render list of rectangles #optional: use a for loop to render them with the #same or different colours. If using a for loop, the #example code below should be adjusted accordingly for i in range(len(rect_list)): pygame.draw.rect(screen, colours[i], rect_list[i]) #If there is a collision, render it here #Alternative if statements: #if player_rect.collidelist(rect_list) > -1: #if result.width > 0 and result.height > 0: if result.width > 0 < result.height: pygame.draw.rect(screen, (255, 0, 0), result, 5) #Render loop end pygame.display.flip() #cleanup pygame.quit() sys.exit()
def play(): screen_x = 1280 screen_y = 720 screen_center = (screen_x / 2, screen_y / 2) #enable framebuffer on Raspi. Might break on non-linux stuff. disp_no = os.getenv("DISPLAY") if disp_no: print("I'm running under X display = " + str(disp_no)) screen = pygame.display.set_mode((screen_x, screen_y)) else: drivers = ['fbcon', 'directfb', 'svgalib'] found = False for driver in drivers: # Make sure that SDL_VIDEODRIVER is set if not os.getenv('SDL_VIDEODRIVER'): os.putenv('SDL_VIDEODRIVER', driver) try: pygame.display.init() except pygame.error: print('Driver: ' + driver + ' failed') continue found = True break if not found: raise Exception('No suitable video driver found!') screen = pygame.display.set_mode((screen_x, screen_y), pygame.FULLSCREEN) screen.fill(BLACK) title_background = pygame.image.load( 'layouts/main_menu_background.png').convert() screen.blit(title_background, screen.get_rect()) pygame.display.flip() clock = pygame.time.Clock() de = DataEngine() de.newGame('easy', 'default') pygame.mixer.pre_init(44100, -16, 1, 512) pygame.mixer.init() pygame.font.init() k_up = k_down = k_left = k_right = 0 #load images #partytime images = {} print('Loading images...') #for image_file, image_path in de.gamepack['img'].items(): # print('\t'+image_file) # if image_file != 'path': # images[image_file] = pygame.image.load(str(image_path)).convert_alpha() #de.images = images #Just for Debugging. de shouldn't need this. #map_background = images['zone_1'] pygame.mouse.set_visible(False) #main menu images hangar_background = pygame.image.load( str(de.gamepack['img']['custom_main'])).convert() pointer_valid = pygame.image.load(str( de.gamepack['img']['pointerValid'])).convert_alpha() pointer_invalid = pygame.image.load( str(de.gamepack['img']['pointerInvalid'])).convert_alpha() #main menu buttons buttons = {} buttons_top = 285 counter = 0 button_suffixes = ['on', 'off', 'select2'] button_names = [ 'continue', 'start', 'tutorial', 'stats', 'options', 'credits', 'quit' ] for button_name in button_names: button = {} button['image'] = {} for button_suffix in button_suffixes: button_image_string = button_name + '_' + button_suffix button['image'][button_suffix] = pygame.image.load( str(de.gamepack['img'][button_image_string])).convert_alpha() button['image']['current'] = button['image']['on'] button['name'] = button_name button['rect'] = button['image']['on'].get_rect() button['rect'].right = 1190 button['rect'].top = buttons_top + (counter * 60) counter += 1 buttons[button_name] = button #set up main UI ui = {} ui['jump_button_charged'] = pygame.image.load( str(de.gamepack['img']['FTL_JUMP'])).convert_alpha() ui['map_backgrounds'] = [] ui['map_backgrounds'].append( pygame.image.load(str(de.gamepack['img']['zone_1']))) ui['map_backgrounds'].append( pygame.image.load(str(de.gamepack['img']['zone_2']))) ui['map_backgrounds'].append( pygame.image.load(str(de.gamepack['img']['zone_3']))) map_background_rect = ui['map_backgrounds'][0].get_rect() map_background_rect.center = screen_center ui['map_images'] = {} ui['map_images']['unvisited'] = pygame.image.load( str(de.gamepack['img']['map_icon_diamond_yellow'])).convert_alpha() beacon_rect = ui['map_images']['unvisited'].get_rect() ui['map_images']['visited'] = pygame.image.load( str(de.gamepack['img']['map_icon_diamond_blue'])).convert_alpha() ui['map_images']['warning'] = pygame.image.load( str(de.gamepack['img']['map_icon_warning'])).convert_alpha() ui['map_images']['danger'] = pygame.image.load( str(de.gamepack['img']['map_icon_triangle_red'])).convert_alpha() ui['map_images']['ship'] = pygame.image.load( str(de.gamepack['img']['map_icon_ship'])).convert_alpha() ui['map_images']['targetbox'] = pygame.image.load( str(de.gamepack['img']['map_targetbox'])).convert_alpha() #We don't need alpha for these. They are always the bottom layer backgrounds = { 'blueStarcluster': pygame.image.load(str( de.gamepack['img']['bg_blueStarcluster'])).convert(), 'darknebula': pygame.image.load(str(de.gamepack['img']['bg_darknebula'])).convert(), 'dullstars': pygame.image.load(str(de.gamepack['img']['bg_dullstars'])).convert(), 'dullstars2': pygame.image.load(str(de.gamepack['img']['bg_dullstars2'])).convert(), 'lonelyRedStar': pygame.image.load(str( de.gamepack['img']['bg_lonelyRedStar'])).convert(), 'lonelyStar': pygame.image.load(str(de.gamepack['img']['bg_lonelystar'])).convert() } background = backgrounds['lonelyStar'] planets = { 'bigblue': pygame.image.load(str( de.gamepack['img']['planet_bigblue'])).convert_alpha(), 'brown': pygame.image.load(str( de.gamepack['img']['planet_brown'])).convert_alpha(), 'gas_blue': pygame.image.load(str( de.gamepack['img']['planet_gas_blue'])).convert_alpha(), 'gas_yellow': pygame.image.load(str( de.gamepack['img']['planet_gas_yellow'])).convert_alpha(), 'peach': pygame.image.load(str( de.gamepack['img']['planet_peach'])).convert_alpha(), 'populated_brown': pygame.image.load(str( de.gamepack['img']['planet_populated_brown'])).convert_alpha(), 'populated_dark': pygame.image.load(str( de.gamepack['img']['planet_populated_dark'])).convert_alpha(), 'populated_orange': pygame.image.load(str( de.gamepack['img']['planet_populated_orange'])).convert_alpha(), 'red': pygame.image.load(str( de.gamepack['img']['planet_red'])).convert_alpha(), 'sun1': pygame.image.load(str( de.gamepack['img']['planet_sun1'])).convert_alpha() } populated = [] populated.append(planets['populated_brown']) populated.append(planets['populated_dark']) populated.append(planets['populated_orange']) #set up fonts pygame.font.init() font_10 = pygame.font.Font(str(de.gamepack['fonts']['JustinFont10']), 10) font_11 = pygame.font.Font(str(de.gamepack['fonts']['JustinFont11']), 11) font_11_bold = pygame.font.Font( str(de.gamepack['fonts']['JustinFont11Bold']), 11) font_12 = pygame.font.Font(str(de.gamepack['fonts']['JustinFont12']), 12) font_12_bold = pygame.font.Font( str(de.gamepack['fonts']['JustinFont12Bold']), 14) font_7 = pygame.font.Font(str(de.gamepack['fonts']['JustinFont7']), 7) font_8 = pygame.font.Font(str(de.gamepack['fonts']['JustinFont8']), 8) num_font = pygame.font.Font(str(de.gamepack['fonts']['num_font']), 10) cc_font = pygame.font.Font(str(de.gamepack['fonts']['c&c']), 14) cc_new_font = pygame.font.Font(str(de.gamepack['fonts']['c&cnew']), 14) choice_rects = [] #load sounds #Can't preload sounds and have it still work on pi. #print('Loading sounds ...') #sounds = {} #for sound_file, sound_path in de.gamepack['sounds'].items(): # print('\t'+sound_file) # if sound_file != 'path': # sounds[sound_file] = pygame.mixer.Sound(str(sound_path)) #print('Loading Music...') #loading all these sounds in advance chews up fucktons of RAM #music = {} #DO THIS SOMEWHERE ELSE! (Really, this is a job for the Clonebay_Importer): Sanitize stuff # Inconsistencies make this tough! mpre = 'bp_MUS_' track_map = { 'civilian': 'Civil', 'colonial': 'Colonial', 'cosmos': 'Cosmos', 'debris': 'Debris', 'deepspace': 'Deepspace', 'engi': 'Engi', 'hack': 'Hack', 'lostship': 'LostShip', 'mantis': 'Mantis', 'milkyway': 'MilkyWay', 'rockmen': 'Rockmen', 'shrike': 'Shrike', 'slug': 'Slug', 'void': 'Void', 'wasteland': 'Wasteland', 'zoltan': 'Zoltan' } print(track_map) for key, value in track_map.items(): track_map[key] = mpre + value #for music_file, music_path in de.gamepack['music'].items(): #print('\t'+music_file) #if music_file != 'path': #music[music_file] = pygame.mixer.Sound(str(music_path)) bleep = pygame.mixer.Sound(str(de.gamepack['sounds']['select_light1'])) music_vol = 0.05 game_vol = 1.0 current_vol = 0.000 #initialize the game state flippers = False countie = 0 indy = 0 paused = True in_combat = False jump_ready = True first_time = True can_continue = False mouse_image = pointer_invalid game_view = 'main_menu' bleeping = False pressing_key = False show_game_menu = False player_ships = [] player_ship_index = 0 for shipBlueprint in de.shipBlueprints: if 'PLAYER_SHIP' in shipBlueprint['@name']: player_ships.append(shipBlueprint) print(shipBlueprint['name']) player_ships_count = len(player_ships) - 1 de.player_ship = PlayerShip(player_ships[0], de) initPlayerShip(de.player_ship, de) # game subview = 'none' visited_beacons = [] #Main Game loop while 1: # USER INPUT clock.tick(60) screen.fill(BLACK) mousepos = pygame.mouse.get_pos() if game_view == 'main_menu': for event in pygame.event.get(): if not hasattr(event, 'key'): continue down = event.type == KEYDOWN pass #stuff to do first time: if first_time: #play music title_music = pygame.mixer.Sound( str(de.gamepack['music']['bp_MUS_TitleScreen'])) title_music.set_volume(music_vol) title_music.play(-1) first_time = False #blit the background screen.blit(title_background, screen.get_rect()) mousepos = pygame.mouse.get_pos() mouse_buttons = pygame.mouse.get_pressed() hovered = False for k, button in buttons.items(): if button['rect'].collidepoint(mousepos): button['image']['current'] = button['image']['select2'] mouse_image = pointer_valid hovered = True if mouse_buttons[0]: if button['name'] == 'quit': sys.exit(0) elif button['name'] == 'start': game_view = 'hangar' else: button['image']['current'] = button['image']['on'] mouse_image = pointer_invalid #button_images.append(button['image']['on']) #button_rects.append(button['rect']) screen.blit(button['image']['current'], button['rect']) if hovered: if not bleeping: bleep.play() bleeping = True else: bleeping = False #blit the planet #blit the ships #blit Game title #blit Menu items #set the music #handle inputs elif game_view == 'main_options': pass elif game_view == 'main_stats': pass elif game_view == 'hangar': #handle inputs for event in pygame.event.get(): if not hasattr(event, 'key'): continue down = event.type == KEYDOWN if not down: pressing_key = False #KEY DOWN OR UP? if event.key == K_ESCAPE: game_view = 'main_menu' elif event.key == K_RETURN: game_view = 'game' first_time = True screen.blit(title_background, screen.get_rect()) pygame.display.flip() elif event.key == K_UP and down: if not pressing_key: if player_ship_index == player_ships_count: player_ship_index = 0 else: player_ship_index += 1 de.player_ship = PlayerShip( player_ships[player_ship_index], de) initPlayerShip(de.player_ship, de) print("Ship selected: " + de.player_ship.id + " -- " + de.player_ship.name) pressing_key = True elif event.key == K_DOWN and down: if not pressing_key: if player_ship_index == 0: player_ship_index = player_ships_count else: player_ship_index -= 1 de.player_ship = PlayerShip( player_ships[player_ship_index], de) initPlayerShip(de.player_ship, de) print("Ship selected: " + de.player_ship.id + " -- " + de.player_ship.name) pressing_key = True screen.blit(hangar_background, screen.get_rect()) blitPlayerShip(de.player_ship, (640, 210), screen, de) if game_view == 'game': #This needs to happen early, or stuff won't work. #Store these for different handling based on context. if first_time: #get the starting event cur_sector = de.world_map[0] cur_beacon = cur_sector['beacons'][0] cur_beacon['background'] = background cur_event = cur_beacon['event'] visited_beacons.append(cur_beacon['id']) subview = 'show_event' first_time = False #set up the music title_music.stop() avl_tracks = cur_sector['description']['trackList']['track'] randomizer = randint(0, len(avl_tracks) - 1) trackset = avl_tracks[randomizer] randomizer = randint(0, len(ui['map_backgrounds']) - 1) map_background = ui['map_backgrounds'][randomizer] #Need to clean this stuff up in dataloader mus_explore = pygame.mixer.Sound( str(de.gamepack['music'][track_map[trackset] + 'EXPLORE'])) mus_battle = pygame.mixer.Sound( str(de.gamepack['music'][track_map[trackset] + 'BATTLE'])) mus_explore.set_volume(music_vol) mus_explore.set_volume(0) mus_explore.play(-1) mus_battle.play(-1) #map_background = pygame.image.load() randomizer = randint(0, len(planets) - 1) i = 0 for k, planet in planets.items(): if i == randomizer: cur_beacon['planet'] = planet cur_beacon['planet_rect'] = planet.get_rect() cur_beacon['planet_rect'].center = (randint( 0, screen_x), randint(0, screen_y)) break i += 1 frame_events = pygame.event.get() mouse_buttons = pygame.mouse.get_pressed() # do input handling that should happen consistently every frame, such as 'KEY_ESC'. #de.tick(paused) #BLITTING ORDER: (FROM BOTTOM TO TOP) # background # background image # background planets # # player ship (Location depends if in_combat) # # if in combat # enemy ship # # projectiles # # # Main UI Stuffs # # subviews: # 'esc' menu # 'beacon_map' # 'show_event' # 'upgrades' # 'crew' # 'equipment' # 'store' # # Menus #draw the background screen.fill(BLACK) screen.blit(cur_beacon['background'], screen.get_rect()) screen.blit(cur_beacon['planet'], cur_beacon['planet_rect']) try: if 'text' in cur_event.items(): if '@planet' in cur_event['text'].items(): pass except (KeyError): pass except (AttributeError): pass except (ValueError): pass except (TypeError): pass #do more here #Draw ships if not in_combat: position = screen_center blitPlayerShip(de.player_ship, position, screen, de) else: position = screen_center #just for now, figure out the offsets later. blitPlayerShip(de.player_ship, position, screen, de) #blitEnemyShip() #blitProjectiles() # #pass #blit systems and crew UI #just for testing if jump_ready: jump_ready_rect = ui['jump_button_charged'].get_rect() jump_ready_rect.x = 500 screen.blit(ui['jump_button_charged'], jump_ready_rect) if subview == 'none': if jump_ready_rect.collidepoint(mousepos): if mouse_buttons[0]: subview = 'beacon_map' #handle inputs for combat, or idling #everything should already be drawn. elif subview == 'show_event': choice_rects = [] paused = True event_rect = Rect(400, 300, 400, 300) event_rect.center = screen_center #blit the event window #blit the text #drawText(surface, text, color, rect, font, aa, bkg) screen.fill(BLACK, event_rect) event_rect.h -= 20 event_rect.w -= 20 event_rect.x += 10 event_rect.y += 10 try: full, offset = drawText(screen, cur_event['text'], WHITE, event_rect, font_12_bold, bkg=BLACK) except (TypeError): try: full, offset = drawText(screen, cur_event['text']['#text'], WHITE, event_rect, font_12_bold, bkg=BLACK) except (TypeError): print("D'oh!") except (KeyError): print("ERROR! THIS EVENT HAS NO 'text'") print(cur_event) cur_event['text'] = 'ERROR!' event_rect.h -= 20 event_rect.w -= 20 event_rect.x += 10 event_rect.y += 10 #blit the choices i = 0 if 'choices' in cur_event: choices = cur_event['choices'] for choice in choices: choice_rects.append(event_rect) choice_rects[i].top = offset + 10 if '#text' in choice['text']: choice_text = choice['text']['#text'] else: choice_text = choice['text'] full, offset = drawText( screen, str(i + 1) + '. ' + choice_text, WHITE, choice_rects[i], font_12_bold) choice_rects[i].h = offset - choice_rects[i].top if choice_rects[i].collidepoint(mousepos): full, choicebottom = drawText( screen, str(i + 1) + '. ' + choice_text, YELLOW, choice_rects[i], font_12_bold) if mouse_buttons[0]: try: tmp_event = choice['event'] for k, v in tmp_event.items(): if k == '@load': cur_event = de.find_event(v) break else: cur_event = tmp_event except (AttributeError): subview = 'none' offset += 10 i += 1 else: choice_rects.append(event_rect) choice_rects[i].top = offset + 10 full, choicebottom = drawText(screen, '1. Ok', WHITE, choice_rects[i], font_12_bold) choice_rects[i].h = choicebottom - choice_rects[i].top if choice_rects[i].collidepoint(mousepos): full, choicebottom = drawText( screen, '1. Ok', YELLOW, choice_rects[i], font_12_bold) if mouse_buttons[0]: subview = 'none' else: choice_rects.append(event_rect) choice_rects[i].top = offset + 10 full, choicebottom = drawText(screen, '1. Ok', WHITE, choice_rects[i], font_12_bold) choice_rects[i].h = choicebottom - choice_rects[i].top if choice_rects[i].collidepoint(mousepos): full, choicebottom = drawText(screen, '1. Ok', YELLOW, choice_rects[i], font_12_bold) if mouse_buttons[0]: subview = 'none' #for choice in event_cur['choices']: # pass #blit systems, crew UI #input handling #process the outcome elif subview == 'beacon_map': screen.blit(map_background, map_background_rect) for beacon in cur_sector['beacons']: beacon_x = beacon['x'] + 300 beacon_y = beacon['y'] + 165 if beacon['id'] == cur_beacon['id']: beacon_image = ui['map_images']['ship'] elif beacon['id'] in visited_beacons: beacon_image = ui['map_images']['visited'] else: beacon_image = ui['map_images']['unvisited'] if beacon['id'] in cur_beacon['connections']: #show connections pass beacon_location = (beacon_x, beacon_y) beacon_rect.center = beacon_location screen.blit(beacon_image, beacon_rect) if beacon_rect.collidepoint(mousepos): if beacon['id'] in cur_beacon['connections']: screen.blit(ui['map_images']['targetbox'], beacon_rect) #play bleeping sound if mouse_buttons[0]: #Jump! #animate the jump! cur_beacon = beacon cur_event = cur_beacon['event'] subview = 'show_event' i = 0 visited_beacons.append(cur_beacon['id']) for k, v in cur_beacon.items(): if k == 'background': break else: randomizer = randint( 0, len(backgrounds) - 1) for k, background in backgrounds.items(): if i == randomizer: cur_beacon[ 'background'] = background break i += 1 i = 0 for k, v in cur_beacon.items(): if k == 'planet': break else: i = 0 randomizer = randint(0, len(planets) - 1) for k, planet in planets.items(): if i == randomizer: cur_beacon['planet'] = planet cur_beacon[ 'planet_rect'] = planet.get_rect( ) cur_beacon[ 'planet_rect'].center = ( randint(0, screen_x), randint(0, screen_y)) break i += 1 else: #show beacon connections pass elif subview == 'sector_map': #handle inputs pass elif subview == 'upgrades': #handle inputs pass elif subview == 'equipment': #handle inputs pass elif subview == 'crew': #handle inputs pass elif subview == 'store': pass #blit ship stats ui (Shields, scrap, hull, etc...) #This stuff is not interactive if show_game_menu: #handle inputs pass #de.tickPost() screen.blit(mouse_image, mousepos) pygame.display.flip() #if not flippers: # sound_battle.set_volume(current_vol) # sound_explore.set_volume(1.000 - current_vol) # current_vol += .01 # if current_vol >= 1.0: # flippers = True # current_vol = 0.000 #else: # sound_explore.set_volume(current_vol) # sound_battle.set_volume(1.000 - current_vol) # current_vol += .01 # if current_vol >= 1.0: # flippers = False # current_vol = 0.000 return 0
def update(self, game, dt: float, events: list): # Step through 15 sprite frames each second self.steps += dt frame = int(self.steps // (1.0 / 15)) # Find our center, if we have a player to focus on our_center = (0, 0) for key, entity in game.entities.items(): # Are they a player? if PlayerControl in entity and IngameObject in entity: # Are they us? if game.net.is_me(entity[PlayerControl].player_id): our_center = entity[IngameObject].position break invMapX = {"min": 0, "max": 0} invMapY = {"min": 0, "max": 0} # Draw tilemap for key, entity in game.entities.items(): if Map in entity and SpriteSheet in entity: spritesheet = entity[SpriteSheet] map = entity[Map] # minimum and maximum tile indexes coordinates possible min_x = math.floor( (our_center[0] - game.framework.dimensions[0] / 2) / spritesheet.tile_size) min_y = math.floor( (our_center[1] - game.framework.dimensions[1] / 2) / spritesheet.tile_size) max_x = math.floor( (our_center[0] + game.framework.dimensions[0] / 2) / spritesheet.tile_size) max_y = math.floor( (our_center[1] + game.framework.dimensions[1] / 2) / spritesheet.tile_size) for y in range(min_y, max_y + 1): for x in range(min_x, max_x + 1): if 0 <= x < map.width and 0 <= y < map.height: tile = map.grid[y][x] else: tile = 20 img_indexes = spritesheet.tiles[str(tile - 1)] if spritesheet.moving: img_index = img_indexes[frame % len(img_indexes)] else: img_index = img_indexes[0] image = self.get_image(spritesheet, img_index) rel_pos = (x * spritesheet.tile_size - our_center[0], y * spritesheet.tile_size - our_center[1]) screen_pos = (rel_pos[0] + game.framework.dimensions[0] / 2, rel_pos[1] + game.framework.dimensions[1] / 2) image = image.convert() alpha = math.sin(self.ticks / 1000) * 100 alpha = 100 - alpha if alpha > 255: alpha = 255 image.set_alpha(alpha) self.screen.blit(image, screen_pos) self.draw_particles(game, "below", our_center) #pygame.draw.rect(self.screen,(255,0,0),Rect(0,0,self.screen.get_width(), self.screen.get_height())) previousCollidables = [] # Render everything we can for key, entity in game.entities.items(): r = False # Don't check for items being picked up if CanPickUp in entity: if entity[CanPickUp].pickedUp: continue if Wieldable in entity: wieldable = entity[Wieldable] if not wieldable.wielded: entity[GameAction].action = "delete" continue #Check collisions for entity against all previously checked entities if IngameObject in entity and Collidable in entity: if entity[Collidable].canCollide: game.collisionSystem.checkCollisions( game, key, entity[Collidable], previousCollidables) previousCollidables.append((key, entity[Collidable])) if IngameObject in entity and Wieldable not in entity: # Where are they relative to us? pos = entity[IngameObject].position rel_pos = (pos[0] - our_center[0], pos[1] - our_center[1]) screen_pos = (rel_pos[0] + game.framework.dimensions[0] / 2, rel_pos[1] + game.framework.dimensions[1] / 2) if screen_pos[0] < 0 or screen_pos[0] > self.screen.get_width( ) or screen_pos[1] < 0 or screen_pos[ 1] > self.screen.get_height(): continue if IngameObject in entity and ParticleEmitter in entity: if entity[ParticleEmitter].colour == (-1, -1, -1): r = True new_particles = entity[ParticleEmitter].getParticles(entity) for new_part in new_particles: game.particles.add_particle(new_part) # Is this an entity we should draw? if IngameObject in entity and SpriteSheet in entity: # Where are they relative to us? pos = entity[IngameObject].position rel_pos = (pos[0] - our_center[0], pos[1] - our_center[1]) screen_pos = (rel_pos[0] + game.framework.dimensions[0] / 2, rel_pos[1] + game.framework.dimensions[1] / 2) spritesheet = entity[SpriteSheet] if Wieldable in entity: wieldable = entity[Wieldable] wielding_player = game.entities[wieldable.player_id] if wieldable.wielded: io = wielding_player[IngameObject] entity[IngameObject].position = (io.position[0] + 25, io.position[1]) dire = wielding_player[Directioned].direction direction = Directioned(direction='default') if dire == 'left': entity[IngameObject].position = (io.position[0] - 25, io.position[1]) direction = Directioned(direction='left') elif dire == 'right': entity[IngameObject].position = (io.position[0] + 25, io.position[1]) direction = Directioned(direction='right') elif dire == 'up': entity[IngameObject].position = (io.position[0] + 25, io.position[1] - 10) direction = Directioned(direction='up') elif dire == 'down': entity[IngameObject].position = (io.position[0] - 25, io.position[1] + 25) direction = Directioned(direction='down') if Directioned in entity: entity[Directioned] = direction img_indexes = spritesheet.tiles["default"] # Will they be facing a certain direction? if Directioned in entity: alts = spritesheet.tiles[entity[Directioned].direction] if alts != None: img_indexes = alts # Get the image relevent to how far through the animation we are if spritesheet.moving: img_index = img_indexes[frame % len(img_indexes)] else: img_index = img_indexes[spritesheet.default_tile] img = self.get_image(spritesheet, img_index) #Scale the image if img.get_size() != entity[IngameObject].size: img = pygame.transform.scale(img, entity[IngameObject].size) rect = Rect(screen_pos, entity[IngameObject].size) rect.center = screen_pos # Add a rectangle behind the item because the quantity is seen outside of the item if CanPickUp in entity: pygame.draw.circle(self.screen, (0, 255, 0), (int(rect.x + rect.width / 2), int(rect.y + rect.height / 2)), int(rect.width / 2)) # Draw the image, but only if it's on screen if not (rect.right < 0 or rect.left >= game.framework.dimensions[0] or rect.bottom < 0 or rect.top >= game.framework.dimensions[1]): self.screen.blit(img, rect) # If it is an item show the amount of items there are if CanPickUp in entity: if entity[CanPickUp].quantity > 1: rendered_text_qitem = self.font.render( str(entity[CanPickUp].quantity), False, (0, 0, 0)) self.screen.blit(rendered_text_qitem, rect) # Center health bar and nametag rect.x -= 30 # Checks if entity has an energy component if Energy in entity: # Energy bar wrapper energyBarThickness = 2 pygame.draw.rect(self.screen, (255, 255, 255), (rect.x, rect.y - 45, 100 + energyBarThickness * 2, 10), energyBarThickness) # Yellow energy bar if entity[Energy].value > 0: currentEnergyPos = (rect.x + energyBarThickness, rect.y - 45 + energyBarThickness, entity[Energy].value, 10 - energyBarThickness * 2) pygame.draw.rect(self.screen, (255, 255, 0), currentEnergyPos) # Checks if entity has a health component if Health in entity: # Health bar wrapper healthBarThickness = 2 pygame.draw.rect(self.screen, (255, 255, 255), (rect.x, rect.y - 30, 100 + healthBarThickness * 2, 10), healthBarThickness) # Red health bar if entity[Health].value > 0: healthValue = int(entity[Health].value / entity[Health].maxValue * 100) currentHealthPos = (rect.x + healthBarThickness, rect.y - 30 + healthBarThickness, healthValue, 10 - healthBarThickness * 2) pygame.draw.rect(self.screen, (255, 0, 0), currentHealthPos) if WaterBar in entity: if not entity[WaterBar].disabled: # Water bar wrapper waterBarThickness = 2 pygame.draw.rect(self.screen, (255, 255, 255), (rect.x, rect.y - 60, 100 + waterBarThickness * 2, 10), waterBarThickness) # Blue water bar if entity[Health].value > 0: currentWaterPos = (rect.x + waterBarThickness, rect.y - 60 + waterBarThickness, entity[WaterBar].value, 10 - waterBarThickness * 2) pygame.draw.rect(self.screen, (0, 0, 255), currentWaterPos) rect.y -= 15 # Does the entity have a name we can draw if Profile in entity: name = entity[Profile].name # Draw our name with our font in white rendered_text_surface = self.font.render( name, False, entity[Profile].colour if not r else Particle.get_random_colour()) # Move the nametag above the player rect.y -= 100 # Draw this rendered text we've made to the screen self.screen.blit(rendered_text_surface, rect) # Checks if it is a player if PlayerControl in entity: # Draw the inventory bar for us only if game.net.is_me(entity[PlayerControl].player_id): # Debugging if statement if Inventory in entity: inv = entity[Inventory] # Store the map borders entity[Inventory].mapMinX = invMapX["min"] entity[Inventory].mapMinY = invMapY["min"] entity[Inventory].mapMaxX = invMapX["max"] entity[Inventory].mapMaxY = invMapY["max"] # Inventory bar colours inventoryBackgroundColour = (183, 92, 5) slotBackgroundColour = (255, 159, 67) # Draw inventory bar inventoryPos = (inv.x, inv.y, inv.width, inv.height) pygame.draw.rect(self.screen, inventoryBackgroundColour, inventoryPos) invX = game.screen.get_width() / 2 - inv.width / 2 invY = game.screen.get_height( ) - inv.height - inv.slotOffset entity[Inventory].x, entity[ Inventory].y = invX, invY distanceBetweenSlots = inv.slotOffset + inv.slotSize # Draw slots slotIndex = 0 for x in range(int(invX + inv.slotOffset), int(invX + inv.width), distanceBetweenSlots): # The active slot has a different colour if slotIndex == inv.activeSlot: colour = (241, 196, 15) elif slotIndex == inv.hoverSlot: colour = (243, 156, 18) else: colour = slotBackgroundColour pygame.draw.rect(self.screen, colour, (x, invY + inv.slotOffset, inv.slotSize, inv.slotSize)) slotIndex += 1 # Drawing items in slots for slotIndex, data in entity[ Inventory].items.items(): if data: itemImgIndexes = data['sprite'].tiles[ 'default'] itemImgIndex = itemImgIndexes[ frame % len(itemImgIndexes)] # If it does, get its image itemImg = self.get_image( data['sprite'], itemImgIndex) itemW, itemH = (inv.slotSize - inv.slotOffset, inv.slotSize - inv.itemSlotOffset * 2) itemImg = pygame.transform.scale( itemImg, (itemW, itemH)) # The item is placed in the slot with a 3px offset itemRect = ( invX + (distanceBetweenSlots * slotIndex) + inv.itemSlotOffset, invY + inv.slotOffset + inv.itemSlotOffset, itemW, itemH) self.screen.blit(itemImg, itemRect) # Drawing text that shows how many items of this kind there are lItemRect = list(itemRect) lItemRect[1] += inv.slotOffset itemRect = tuple(lItemRect) rendered_text_qslot = self.font.render( str(data['quantity']), False, (0, 0, 128)) self.screen.blit(rendered_text_qslot, itemRect) slotIndex += 1 if Clock in entity: time_names = ("Dusk", "Dawn", "Morning", "Noon", "Afternoon", "Evening") rendered_text_surface = self.font.render( time_names[entity[Clock].minute], False, (255, 255, 255)) rect = rendered_text_surface.get_rect() rect.topleft = (10, 5) self.screen.blit(rendered_text_surface, rect) cycle = entity[Clock].cycle rendered_text_surface = self.font.render( str("Day"), False, (255, 255, 255)) rect = rendered_text_surface.get_rect() rect.topleft = (150, 5) self.screen.blit(rendered_text_surface, rect) cycle = entity[Clock].cycle rendered_text_surface = self.font.render( str(cycle), False, (255, 255, 255)) rect = rendered_text_surface.get_rect() rect.topleft = (215, 5) self.screen.blit(rendered_text_surface, rect) year = entity[Clock].year rendered_text_surface = self.font.render( str("Year"), False, (255, 255, 255)) rect = rendered_text_surface.get_rect() rect.topleft = (270, 5) self.screen.blit(rendered_text_surface, rect) year = entity[Clock].year rendered_text_surface = self.font.render( str(year), False, (255, 255, 255)) rect = rendered_text_surface.get_rect() rect.topleft = (340, 5) self.screen.blit(rendered_text_surface, rect) self.ticks = entity[Timed].time + ( entity[Clock].minute * 3600) + (entity[Clock].cycle * 21600) + (entity[Clock].year * 7776000) self.draw_particles(game, "above", our_center)
DEBUG = False FPS = 30 SCREENSIZE = (1024, 768) CENTER = (SCREENSIZE[0] // 2, SCREENSIZE[1] // 2) ''' viewspace TBD ''' VIEWWIDTH = 500 VIEWHEIGHT = 600 VIEWPORT = Rect(0, 0, VIEWWIDTH, VIEWHEIGHT) VIEWPORT.center = CENTER ALIENSIZE = 24 #VIEWWIDTH // 20 ALIENSPEED = 300. DISTANCE_BETWEEN = 1.75 SHIPSIZE = int(ALIENSIZE * 1.2) SHIPY = VIEWHEIGHT - SHIPSIZE VIEWBOUNDS = (SHIPSIZE // 2, VIEWWIDTH - SHIPSIZE // 2) # the bounds within which the ship can move SHIPSPEED = 200. # in pixels per second, how fast the backdrop moves MOVESPEED = 500. # for the ship moving sideways BOLTLENGTH = SHIPSIZE // 2