def _slice(surface: pygame.Surface, r): assert surface is not None sliced = surface.subsurface(r) if surface.get_colorkey() is not None: sliced.set_colorkey(surface.get_colorkey()) return sliced
def crop(source_image: pygame.Surface, rect): _, _, w, h = rect old_colorkey = source_image.get_colorkey() image = pygame.Surface((w, h)).convert() image.blit(source_image, (0, 0), rect) image.set_colorkey(old_colorkey) return image
class Collectible: def __init__(self, size, max_cells): self.started = False self.max_cells = max_cells self.cur_cell = (0, 0) self.surf = Surface(size) self.rect = self.surf.get_rect() colorkey = Color(0, 255, 0) fruit_colour = Color(217, 14, 24) self.surf.fill(colorkey) from pygame.draw import circle circle(self.surf, fruit_colour, self.rect.center, self.rect.width // 2 - 1) self.surf.set_colorkey(colorkey) self.reposition() def start(self): self.started = self.surf != None and self.surf.get_colorkey() != None return self.started def update(self, delta): pass def render(self, target): target.blit(self.surf, self.rect) def reposition(self): self.cur_cell = (randrange(0, self.max_cells), randrange(0, self.max_cells)) self.rect.left = self.cur_cell[0] * self.rect.width self.rect.top = self.cur_cell[1] * self.rect.height def get_current_cell(self): return self.cur_cell
def invertSurface(surface: pygame.Surface) -> pygame.Surface: """ 返回surface的反色图像 """ oriColorkey = surface.get_colorkey() result = pygame.surfarray.make_surface(255 - pygame.surfarray.array3d(surface)) result.set_colorkey(Color.invert(oriColorkey)) return result
class SimulationObject(Sprite): """ Abstraction of a simulated object with a pose and a sprite. """ def __init__(self, x, y, theta, width=0, height=0, color=(0, 0, 0), mask=MASK_RECT): """ Parameters ---------- x: float horizontal position in units y: float vertical position in units theta: heading in radians width: float width in units height: float height in units color: tuple (r, g, b) mask: int sprite mask (circle or rectangle) """ Sprite.__init__(self) # State self.pose = np.array([x, y, theta]) self.pose_velocity = np.array([0, 0, 0]) # Appearance self.mask = mask self.color = color self.image = Surface([width, height]) self.image.set_colorkey(simulation.SIMULATION_BG_COLOR) self.dims = [width, height] self.rect = self.image.get_rect() self.autoscale = True self.sprite_update() # Timekeeping self.timestamp_last = None self.timestamp_current = None def sprite_update(self): """ Updates the internal surface (usually called after forcibly updating the object's color, shape, etc.). Returns ------- None """ if self.mask == MASK_RECT: self.image.fill(self.color) elif self.mask == MASK_CIRCULAR: self.image.fill(self.image.get_colorkey()) pygame.draw.ellipse(self.image, self.color, self.image.get_rect()) def draw(self, display): """ Draws the object to a display surface. Parameters ---------- display: Surface target surface Returns ------- None """ # Scale to pixels sprite_transformed = self.image if self.autoscale: sprite_transformed = pygame.transform.scale( sprite_transformed, (int(self.image.get_width() * settings.PIXELS_PER_UNIT), int(self.image.get_height() * settings.PIXELS_PER_UNIT))) # Rotate to face heading sprite_transformed = pygame.transform.rotate( sprite_transformed, math.degrees(self.pose[2])) # Draw display.blit(sprite_transformed, [int(self.pose[0] * settings.PIXELS_PER_UNIT) -\ sprite_transformed.get_width() // 2, display.get_height() -\ int(self.pose[1] * settings.PIXELS_PER_UNIT) -\ sprite_transformed.get_height() // 2]) def get_corners(self): """ Gets the corner locations of this object. Returns ------- list [top left, top right, bottom left, bottom right] """ h_w = self.dims[0] / 2 h_h = self.dims[1] / 2 corners = [[self.pose[0] - h_w, self.pose[1] + h_h], [self.pose[0] + h_w, self.pose[1] + h_h], [self.pose[0] - h_w, self.pose[1] - h_h], [self.pose[0] + h_w, self.pose[1] - h_h]] return util.rotate_rect(corners, self.pose[2], self.pose[0], self.pose[1]) def collision(self, obj): """ Checks for a collision between this object and another. Parameters ---------- obj: SimulationObject object to check collision with Returns ------- bool whether or not I am colliding with obj """ self_corners = self.get_corners() obj_corners = obj.get_corners() # distance check, ignore if too far for corner in obj_corners: d = util.dist( self.pose[0], self.pose[1], corner[0], corner[1], ) if d > 10: return False # line intersection check based on corner points for i in range(0, 3): line_self = [self_corners[i], self_corners[(i + 1) % 4]] for j in range(0, 3): line_other = [obj_corners[j], obj_corners[(j + 1) % 4]] if util.intersects(line_self, line_other): return True return False