def load_images(sprites_path): base_image = load(sprites_path + 'base.png').convert_alpha() background_image = load(sprites_path + 'background-black.png').convert() pipe_images = [ rotate(load(sprites_path + 'pipe-green.png').convert_alpha(), 180), load(sprites_path + 'pipe-green.png').convert_alpha() ] bird_images = [ load(sprites_path + 'redbird-upflap.png').convert_alpha(), load(sprites_path + 'redbird-midflap.png').convert_alpha(), load(sprites_path + 'redbird-downflap.png').convert_alpha() ] bird_hitmask = [pixels_alpha(image).astype(bool) for image in bird_images] pipe_hitmask = [pixels_alpha(image).astype(bool) for image in pipe_images] return base_image, background_image, pipe_images, bird_images, bird_hitmask, pipe_hitmask
def get_night_mask(self): width, height = self.real_size max_alpha = 255 day_of_year = self.compute_day_of_year() if day_of_year != self.night_mask_day_of_year: self.night_mask = None elif self.night_mask_dim != (width, height): self.night_mask = None if self.night_mask is None: self.night_mask_day_of_year = day_of_year self.night_mask_dim = (width, height) self.night_mask = pygame.Surface((width, height), 0, gg.ALPHA) sun_declination = -23.45 / 360.0 * 2 * math.pi * math.cos(2 * math.pi / 365.0 * (day_of_year + 10)) sun_diameter = 0.5 * pi / 180 lat = linspace(-pi / 2, pi / 2, height)[newaxis, :] long = linspace(0, 2 * pi, width)[:, newaxis] sin_sun_altitude = cos(long) * (cos(lat) * cos(sun_declination)) + sin(lat) * sin(sun_declination) # use tanh to convert values to the range [0,1] light = 0.5 * (tanh(sin_sun_altitude / (sun_diameter / 2)) + 1) night_alphas = pixels_alpha(self.night_mask) night_alphas[...] = round(max_alpha * light).astype(uint8) del night_alphas return self.night_mask
def from_function_alpha(surface): if not HAS_NUMPY: raise Exception("Could not use surfarray module from PyGame.\ NumPy is probably missing.") size = surface.size newsurf = pygame.Surface(size, SRCALPHA, depth=surface.get_bitsize()).convert_alpha() newsurf.blit(surface, (0, 0)) if subrect: rect = subrect arrayrgb = surfarray.pixels3d(newsurf) arraya = surfarray.pixels_alpha(newsurf) points = [] max_d = hypot(rect.w, rect.h) for x in range(rect.left, rect.right): for y in range(rect.top, rect.bottom): if tuple(arrayrgb[x][y]) != color_except: points.append((x, y)) if points: for x in range(rect.left, rect.right): for y in range(rect.top, rect.bottom): if not (x, y) in points: d = 1. - illuminate_dist(points, rect, x, y) / max_d d = 255 * factor * d**fadout arraya[x][y] = d arrayrgb[x][y] = color_target else: if color_bulk: arrayrgb[x][y] = color_bulk if bulk_alpha: arraya[x][y] = bulk_alpha
def get_round(self, radius, background): w, h = self.c.get_size() surface = self.s.copy().convert_alpha() newsurf = pygame.Surface((w, h), pygame.SRCALPHA, depth=self.c.get_bitsize()).convert_alpha() newsurf.fill((0, 0, 0, 0)) inner = self.c.get_rect().inflate((-4 * radius, -4 * radius)) n_a = surfarray.pixels_alpha(newsurf) n_rgb = surfarray.pixels3d(newsurf) b_b_c_rgb = surfarray.pixels3d(self.c) rngs = [(inner.x, inner.y, 0, inner.x, 0, inner.y), (inner.right, inner.y, inner.right, w, 0, inner.y), (inner.x, inner.bottom, 0, inner.x, inner.bottom, h), (inner.right, inner.bottom, inner.right, w, inner.bottom, h)] for i, ranges in enumerate(rngs): x0, y0, xi, xf, yi, yf = ranges for x in range(xi, xf): for y in range(yi, yf): d = math.hypot(x - x0, y - y0) n_a[x][y] = 255 - get_y(d, 0, 2 * radius) n_rgb[x][y] = b_b_c_rgb[x][y] del n_a del n_rgb surface.unlock() newsurf.unlock() surface.blit(newsurf, (0, 0)) return surface
def set_alpha_from_intensity(surface, alpha_factor, decay_mode, color): if not HAS_PIL: raise Exception("PIL was not found on this machine.") if not HAS_NUMPY: raise Exception("NumPy was not found on this machine.") rect = surface.get_rect() newsurf = Surface(rect.size, SRCALPHA, depth=surface.get_bitsize()) newsurf = newsurf.convert_alpha() newsurf.blit(surface, (0, 0)) arrayrgb = surfarray.pixels3d(newsurf) arraya = surfarray.pixels_alpha(newsurf) bulk_color = tuple(color) for x in range(rect.left, rect.right): for y in range(rect.top, rect.bottom): color = tuple(arrayrgb[x][y]) light = square_color_norm(color) alpha = float(light) / MAX_NORM * 255 arrayrgb[x][y][0] = bulk_color[0] arrayrgb[x][y][1] = bulk_color[1] arrayrgb[x][y][2] = bulk_color[2] if decay_mode == "linear": actual_alpha = int(255 - alpha) elif decay_mode == "exponential": tuning_factor = 1.03 actual_alpha = int(255 * tuning_factor**-alpha) ## elif decay_mode == "quadratic": ## pass else: raise Exception("decay_mode not recognized: " + decay_mode) actual_alpha *= alpha_factor arraya[x][y] = actual_alpha return newsurf
def render(self): bulletlayer.blit(self.img,(int(self.x),int(self.y))) self.x += self.dx self.y += self.dy-1 self.s -= 1 array = surfarray.pixels_alpha(self.img) array[array>0] = array[array>0]-1
def _is_collided(self): # out-of-screen if self.bird_rect.top < -self.bird.get_height( ) * 0.1 or self.bird_rect.bottom >= self.floory: return True # mask = self.bird_hitmask[self.bird_index] mask = pixels_alpha(self.rotate_bird()).astype(bool) rows, columns = mask.shape # pipe collison for pipe in self.pipes: lx, rx = pipe.x, pipe.x + self.pipe_surface.get_width() ty, by = pipe.y, pipe.y + self.pipe_surface.get_height() for i in range(rows): for j in range(columns): # posx, posy = self.bird_rect.x + j, self.bird_rect.y + i posx, posy = self.bird_rect.x + i, self.bird_rect.y + j if mask[i, j] and lx < posx < rx and ty < posy < by: return True ''' if self.bird_rect.colliderect(pipe): return True ''' return False
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 get_antiround(self, radius, background): w, h = self.c.get_size() surface = self.s.copy().convert_alpha() newsurf = pygame.Surface((w, h), pygame.SRCALPHA, depth=self.c.get_bitsize()).convert_alpha() newsurf.fill((0, 0, 0, 0)) outer = self.c.get_rect().inflate((-2 * radius, -2 * radius)) n_a = surfarray.pixels_alpha(newsurf) n_rgb = surfarray.pixels3d(newsurf) b_b_c_rgb = surfarray.pixels3d(self.c) rngs = [(0, 0, 0, 2 * radius, 0, 2 * radius), (w, 0, w - 2 * radius, w, 0, 2 * radius), (0, h, 0, 2 * radius, h - 2 * radius, h), (w, h, w - 2 * radius, w, h - 2 * radius, h)] for i, ranges in enumerate(rngs): x0, y0, xi, xf, yi, yf = ranges for x in range(xi, xf): for y in range(yi, yf): d = math.hypot(x - x0, y - y0) n_a[x][y] = get_y(d, 0, 2 * radius) n_rgb[x][y] = b_b_c_rgb[x][y] #grass del n_a del n_rgb surface.unlock() newsurf.unlock() surface.blit(newsurf, (0, 0)) return surface
def highlight(self): if not self.highlighted: (x, y) = self.pos() (w, h) = self.rect.size (lw, lh) = (round(w * 1.5), round(h * 1.5)) img = Surface((lw, lh), pygame.SRCALPHA) img.fill(COLOR_WHITE) a = surfa.pixels_alpha(img) d = max(lw, lh) / 2 (cx, cy) = (lw // 2, lh // 2) for i in range(len(a)): for j in range(len(a[i])): k = math.sqrt(sqr(100.0 * (i - cx) / cx) + sqr(100.0 * (j - cy) / cy)) if k > 100: a[i][j] = 0 else: a[i][j] = 255 - round(k / 100.0 * 255.0) a = None img.blit(self.image, ((lw - w) // 2, (lh - h) // 2)) self.image = img self.set_pos(x - (lw - w) // 2, y - (lh - h) // 2) self.highlighted = True
def _compute_night_mask_step(self, width, height, next_day_of_year): if self.next_night_mask_ready: return if self.next_night_mask_step == 0: self.next_night_mask = pygame.Surface((width, height), 0, gg.ALPHA) self.step_sun_declination = (-23.45 / 360. * 2 * math.pi * math.cos(2 * math.pi / 365. * (next_day_of_year + 10))) elif self.next_night_mask_step == 1: self.step_sin_sun_altitude = ( self._cos_longitude_x_cos_latitiude * cos(self.step_sun_declination) + self._sin_latitude * sin(self.step_sun_declination)) elif self.next_night_mask_step == 2: self.step_light = 0.5 * ( tanh(self.step_sin_sun_altitude / self.sun_radius) + 1) elif self.next_night_mask_step == 3: max_alpha = 255 self.step_night_alphas = pixels_alpha(self.next_night_mask) self.step_round_light = round(max_alpha * self.step_light).astype(uint8) elif self.next_night_mask_step == 4: self.step_night_alphas[...] = self.step_round_light self.next_night_mask_ready = True self.next_night_mask_step = (self.next_night_mask_step + 1) % 5
def set_alpha_from_intensity(surface, alpha_factor, decay_mode, color): if not HAS_PIL: raise Exception("PIL was not found on this machine.") if not HAS_NUMPY: raise Exception("NumPy was not found on this machine.") rect = surface.get_rect() newsurf = Surface(rect.size, SRCALPHA, depth=surface.get_bitsize()) newsurf = newsurf.convert_alpha() newsurf.blit(surface, (0, 0)) arrayrgb = surfarray.pixels3d(newsurf) arraya = surfarray.pixels_alpha(newsurf) bulk_color = tuple(color) for x in range(rect.left, rect.right): for y in range(rect.top, rect.bottom): color = tuple(arrayrgb[x][y]) light = square_color_norm(color) alpha = float(light)/MAX_NORM * 255 arrayrgb[x][y][0] = bulk_color[0] arrayrgb[x][y][1] = bulk_color[1] arrayrgb[x][y][2] = bulk_color[2] if decay_mode == "linear": actual_alpha = int(255 - alpha) elif decay_mode == "exponential": tuning_factor = 1.03 actual_alpha = int(255*tuning_factor**-alpha) ## elif decay_mode == "quadratic": ## pass else: raise Exception("decay_mode not recognized: " + decay_mode) actual_alpha *= alpha_factor arraya[x][y] = actual_alpha return newsurf
def get_night_mask(self): width, height = self.real_size max_alpha = 255 day_of_year = self.compute_day_of_year() if day_of_year != self.night_mask_day_of_year: self.night_mask = None elif self.night_mask_dim != (width, height): self.night_mask = None if self.night_mask is None: self.night_mask_day_of_year = day_of_year self.night_mask_dim = (width, height) self.night_mask = pygame.Surface((width, height), 0, gg.ALPHA) sun_declination = (-23.45/360.*2*math.pi * math.cos(2*math.pi/365.*(day_of_year + 10))) sun_diameter = 0.5*pi/180 lat = linspace(-pi/2,pi/2,height)[newaxis,:] long = linspace(0,2*pi,width)[:,newaxis] sin_sun_altitude = (cos(long)*(cos(lat)*cos(sun_declination)) +sin(lat)*sin(sun_declination)) # use tanh to convert values to the range [0,1] light = 0.5*(tanh(sin_sun_altitude/(sun_diameter/2))+1) night_alphas = pixels_alpha(self.night_mask) night_alphas[...] = round(max_alpha*light).astype(uint8) del night_alphas return self.night_mask
def render(self): bulletlayer.blit(self.img, (int(self.x), int(self.y))) self.x += self.dx self.y += self.dy - 1 self.s -= 1 array = surfarray.pixels_alpha(self.img) array[array > 0] = array[array > 0] - 1
def _transformerPartie(self, surface): """Applique une transformation individuellement à chaque <surface> (mobile, tile...) lors de sa pose.""" for nomTransformation in self._transformationsParties: p = self._parametresTransformations[nomTransformation] if nomTransformation == "AlphaFixe": pixels = surfarray.pixels_alpha(surface) positionsNulles = numpy.where(pixels == 0) pixels[:,:] = p["alpha"] pixels[positionsNulles] = 0
def apply(self, img, n): if n >= 1: return img srf = self.srfSize(img) sa = pixels_alpha(srf) h = len(sa[0]) for c in sa: for r in range(h): if random() > n: c[r] = 0 return srf
def adjust_alpha(surface, alpha): if alpha > 255: alpha = 255 if alpha < 0: alpha = 0 factor = float(alpha) / 255.0 alphas = surfarray.pixels_alpha(surface) alphas = (alphas * factor) alphas = numpy.clip(alphas, 0, 255) alphas[:] = alphas.astype("uint8") del alphas
def _transformerPartie(self, surface, nomPnj, positionCarte, **p): """Applique une transformation individuellement à chaque <surface> (mobile) lors de sa pose.""" for nomTransformation in self._transformationsParties: p = self._parametresTransformations[nomTransformation] if nomTransformation == "AlphaFixe": pixels = surfarray.pixels_alpha(surface) positionsNulles = numpy.where(pixels == 0) pixels[:,:] = p["alpha"] pixels[positionsNulles] = 0 elif nomTransformation == "Action Joueur" and nomPnj == "Joueur": centre = positionCarte.move(-self._scrollingX, -self._scrollingY).center pygame.draw.circle(self._fenetre, (255,255,255), centre, p["rayon"], 1)
def redraw(self): width = self.real_size[0] self.night_start = self.compute_night_start() super(EarthImage, self).redraw() if not g.daynight: return # Turn half of the map to night, with blended borders. night_mask = self.get_night_mask() mask_alphas = pixels_alpha(night_mask) night_alphas = pixels_alpha(self.night_image) right_width = width - self.night_start night_alphas[self.night_start:] = mask_alphas[:right_width] if self.night_start != 0: night_alphas[:self.night_start] = mask_alphas[right_width:] del night_alphas, mask_alphas self.surface.blit(self.night_image, (0,0))
def redraw(self): width = self.real_size[0] self.night_start = self.compute_night_start() super(EarthImage, self).redraw() if not g.daynight: return # Turn half of the map to night, with blended borders. night_mask = self.get_night_mask() mask_alphas = pixels_alpha(night_mask) night_alphas = pixels_alpha(self.night_image) right_width = width - self.night_start night_alphas[self.night_start :] = mask_alphas[:right_width] if self.night_start != 0: night_alphas[: self.night_start] = mask_alphas[right_width:] del night_alphas, mask_alphas self.surface.blit(self.night_image, (0, 0))
def update(self): delta = self.pow/80. self.radius += self.step self.pow -= 1 r = (int(self.radius),)*2 self.img = transform.smoothscale(Torpedo0.Blast.img,r) array = surfarray.pixels_alpha(self.img) array[:] = array[:]*delta self.size = r self.center = self.pos for f in enemi: x,y = f.center h2 = (self.centerx-x)**2+(self.centery-y)**2 if h2 < (self.radius/2.)**2: f.shield -= 1
def update(self): delta = self.pow / 80.0 self.radius += self.step self.pow -= 1 r = (int(self.radius),) * 2 self.img = transform.smoothscale(Torpedo0.Blast.img, r) array = surfarray.pixels_alpha(self.img) array[:] = array[:] * delta self.size = r self.center = self.pos for f in enemi: x, y = f.center h2 = (self.centerx - x) ** 2 + (self.centery - y) ** 2 if h2 < (self.radius / 2.0) ** 2: f.shield -= 1
def illuminate_alphacolor_except(surface, color_except, color_target, color_bulk=None, subrect=None, factor=1., fadout=2, bulk_alpha=255): """ mode : "except" means all the pixels that are not color_source. "exact" means all the pixels that are exacly color_source. Set fadout to 0 and bulk_alpha to 255 if you do not want alpha fade out. """ if not HAS_NUMPY: raise Exception("Could not use surfarray module from PyGame.\ NumPy is probably missing.") rect = surface.get_rect() newsurf = pygame.Surface(rect.size, SRCALPHA, depth=surface.get_bitsize()).convert_alpha() newsurf.blit(surface, (0, 0)) if subrect: rect = subrect arrayrgb = surfarray.pixels3d(newsurf) arraya = surfarray.pixels_alpha(newsurf) points = [] max_d = hypot(rect.w, rect.h) for x in range(rect.left, rect.right): for y in range(rect.top, rect.bottom): if tuple(arrayrgb[x][y]) != color_except: points.append((x, y)) if points: for x in range(rect.left, rect.right): for y in range(rect.top, rect.bottom): if not (x, y) in points: d = 1. - illuminate_dist(points, rect, x, y) / max_d d = 255 * factor * d**fadout arraya[x][y] = d arrayrgb[x][y] = color_target else: if color_bulk: arrayrgb[x][y] = color_bulk if bulk_alpha: arraya[x][y] = bulk_alpha else: functions.debug_msg("No points for illuminate alpha except") return newsurf
def get_round_river(radius_divider, corner, front): if corner is None: return front w, h = front.get_size() background = pygame.Surface((w, h)) surface = front.copy().convert_alpha() newsurf = pygame.Surface((w, h), pygame.SRCALPHA, depth=background.get_bitsize()).convert_alpha() newsurf.fill((0, 0, 0, 0)) radius = w // radius_divider inner = background.get_rect().inflate((-2 * radius, -2 * radius)) n_a = surfarray.pixels_alpha(newsurf) n_rgb = surfarray.pixels3d(newsurf) b_b_c_rgb = surfarray.pixels3d(background) #Define ranges. topleft = (inner.left, inner.top, 0, inner.left, 0, inner.top) topright = (inner.right, inner.top, inner.right, h, 0, inner.top) bottomleft = (inner.left, inner.bottom, 0, inner.left, inner.bottom, h) bottomright = (inner.right - 1, inner.bottom - 1, inner.right, h, inner.bottom, h) ranges = { "topleft": topleft, "topright": topright, "bottomleft": bottomleft, "bottomright": bottomright } r2 = radius**2 centerx, centery, xi, xf, yi, yf = ranges[corner] for x in range(xi, xf): rx2 = (x - centerx)**2 for y in range(yi, yf): if rx2 + (y - centery)**2 > r2: n_a[x][y] = 255 #alpha background = 255 n_rgb[x][y] = b_b_c_rgb[x][y] ## else: ## n_rgb[x][y] = (b_b_c_rgb[x][y]+n_rgb[x][y])//2 del n_a del n_rgb surface.unlock() newsurf.unlock() surface.blit(newsurf, (0, 0)) surface = surface.convert() surface.set_colorkey((0, 0, 0)) return surface
def CreateShadow(self): if self._shadows: return self._shadows = [InterpolateToScale(surface, 1.025) for surface in self._surfaces] for shadow in self._shadows: # Make the shadow black. pixels = surfarray.pixels3d(shadow) pixels[:] = 0 # Make the shadow semi-transparent. alpha = surfarray.pixels_alpha(shadow) alpha[alpha > 0] = 150
def set_alpha(self, alpha=255): """F.set_alpha (...) -> None Sets the alpha transparency value. Raises a TypeError, if the passed argument is not an integer. Raises a ValueError, if the passed argument is not in the range 0 <= alpha <= 255 """ if type(alpha) != int: raise TypeError("alpha must be a positive integer") if (alpha < 0) or (alpha > 255): raise ValueError("alpha must be in the range 0 <= alpha <= 255") self._alpha = alpha # Apply the alpha. array = surfarray.pixels_alpha(self) array[:] = alpha del array
def set_alpha (self, alpha=255): """F.set_alpha (...) -> None Sets the alpha transparency value. Raises a TypeError, if the passed argument is not an integer. Raises a ValueError, if the passed argument is not in the range 0 <= alpha <= 255 """ if type (alpha) != int: raise TypeError ("alpha must be a positive integer") if (alpha < 0) or (alpha > 255): raise ValueError ("alpha must be in the range 0 <= alpha <= 255") self._alpha = alpha # Apply the alpha. array = surfarray.pixels_alpha (self) array[:] = alpha del array
def update(self): sx,sy = ship.center deltax, deltay = -self.centerx+sx, -self.centery+sy if deltax**2+deltay**2 <= ship.magnetradius**2: tau = atan2(deltay,deltax) self.deltaX = cos(tau)*3 self.deltaY = sin(tau)*3 self.X += self.deltaX self.Y += self.deltaY self.x = int(self.X) self.y = int(self.Y) self.ttl -= 1 alpha = 1.275*self.ttl Alpha = int(alpha) array = surfarray.pixels_alpha(self.img) array[array>alpha] = Alpha if self.colliderect(ship): self.set() self.ttl = 0
def update(self): """F.update () -> bool Updates the alpha channel of the surface. Updates the alpha channel of the surface and returns True, if the alpha channel was modified or False, if not. """ val = self._alpha + self._step if val < 0: val = 0 if val > 255: val = 255 array = surfarray.pixels_alpha(self) array[:] = val del array self._alpha = val return not (val == 0) and not (val == 255)
def update (self): """F.update () -> bool Updates the alpha channel of the surface. Updates the alpha channel of the surface and returns True, if the alpha channel was modified or False, if not. """ val = self._alpha + self._step if val < 0: val = 0 if val > 255: val = 255 array = surfarray.pixels_alpha (self) array[:] = val del array self._alpha = val return not (val == 0) and not (val == 255)
def cut_side(self, side, radius, background): w, h = self.c.get_size() b_c_surf = self.c.copy().convert_alpha() #beach newsurf = pygame.Surface((w, h), pygame.SRCALPHA, depth=self.c.get_bitsize()).convert_alpha() newsurf.fill((0, 0, 0, 0)) n_a = surfarray.pixels_alpha(newsurf) n_rgb = surfarray.pixels3d(newsurf) s_rgb = surfarray.pixels3d(self.s) b_c_rgb = surfarray.pixels3d(b_c_surf) if "top" in side: for x in range(w): for y in range(0, 2 * radius): n_a[x][y] = 255 - get_y(y, 0, 2 * radius) n_rgb[x][y] = s_rgb[x][y] if "bottom" in side: for x in range(w): for y in range(h - 2 * radius, h): n_a[x][y] = get_y(y, h - 2 * radius, h) n_rgb[x][y] = s_rgb[x][y] if "left" in side: for y in range(h): for x in range(0, 2 * radius): n_a[x][y] = 255 - get_y(x, 0, 2 * radius) n_rgb[x][y] = s_rgb[x][y] if "right" in side: for y in range(h): for x in range(w - 2 * radius, w): n_a[x][y] = get_y(x, w - 2 * radius, w) n_rgb[x][y] = s_rgb[x][y] del n_a del n_rgb del b_c_rgb b_c_surf.unlock() newsurf.unlock() b_c_surf.blit(newsurf, (0, 0)) return b_c_surf
def make_bg_gradient(surface): from pygame.surfarray import pixels_alpha from numpy import full, linspace, concatenate, flip # manipulate alpha values with numpy grad_width = surface.get_width() // 3 grad_height = surface.get_height() alpha_array = pixels_alpha(surface) all_fill = full( grad_height, # single dimension 255) all_empty = full(grad_height, 0) left_half = linspace(all_empty, all_fill, num=grad_width, dtype='uint8') right_half = flip(left_half, axis=0) # mirrored center = full( (surface.get_width() - 2 * grad_width, grad_height), 255, # fill value dtype='uint8') # operates in place, since we used pixels_alpha and not array_alpha alpha_array -= concatenate([left_half, center, right_half], axis=0) return
def cropCircle(fill, r): alphas = circleMask(r) // 255 a = sfa.pixels_alpha(fill) a *= alphas del a
class NS_SHAFT(object): init() fps_clock = time.Clock() screen_width = 288 screen_height = 512 screen = display.set_mode((screen_width, screen_height)) display.set_caption('Deep Q-Network NS-SH') base_image = load('assets/sprites/base.png').convert_alpha() background_image = load('assets/sprites/background-black.png').convert() floor_images = [load('assets/sprites/floors.PNG').convert_alpha()] man_images = [load('assets/sprites/man.PNG').convert_alpha()] # number_images = [load('assets/sprites/{}.png'.format(i)).convert_alpha() for i in range(10)] man_hitmask = [pixels_alpha(image).astype(bool) for image in man_images] floor_hitmask = [pixels_alpha(image).astype(bool) for image in floor_images] fps = 30 #pipe_gap_size = 100 floor_velocity_y = 4 # parameters for man min_velocity_y = -4 max_velocity_y = 10 downward_speed = 1 upward_speed = -9 man_index_generator = cycle([0, 1, 2, 1]) state = 0 # 0 falling, 1 stand on floor state2_counter = 0 def __init__(self): self.iter = self.man_index = self.score = 0 self.man_width = self.man_images[0].get_width() self.man_height = self.man_images[0].get_height() self.floor_width = self.floor_images[0].get_width() self.floor_height = self.floor_images[0].get_height() self.man_x = int((self.screen_width- self.man_width)/2) #self.man_y = int((self.screen_height - self.man_height) / 2) self.man_y = int(self.screen_height*0.25)-50 #self.base_x = 0 #self.base_y = self.screen_height * 0.79 #self.base_shift = self.base_image.get_width() - self.background_image.get_width() floors = [{'x':self.man_x,'y':self.man_y+self.man_height+3},{'x':30,'y':250},{'x':100,'y':400}] #floors[0]["x_upper"] = pipes[0]["x_lower"] = self.screen_width #floors[1]["x_upper"] = pipes[1]["x_lower"] = self.screen_width * 1.5 self.floors = floors self.current_velocity_y = 0 self.is_flapped = False def generate_floor(self): y = self.screen_height f = [randint(10,210),randint(0,75),randint(150,220)] x = f[randint(0,2)] #gap_y = randint(2, 10) * 10 + int(self.base_y / 5) return {'x' : x,'y' : y} def is_collided(self): man_bbox = Rect(self.man_x, self.man_y, self.man_width, self.man_height) collided_floor = {'x': 0,'y':0} is_collided = False for floor in self.floors: floor_box = Rect(floor["x"], floor["y"], self.floor_width, self.floor_height) if Rect.colliderect(man_bbox, floor_box): collided_floor['x'] = floor['x'] collided_floor['y'] = floor['y'] is_collided = True return is_collided, collided_floor def next_frame(self, action): pump() reward = 0.01 terminal = False # Check input action self.current_velocity_x = action if self.is_flapped: self.is_flapped = False if self.state == 1: self.current_velocity_y = self.floor_velocity_y elif self.state == 2: self.current_velocity_y = -4 else: self.current_velocity_y = max(min(-1,self.current_velocity_y-1),self.min_velocity_y) #print(self.state,self.current_velocity_y) self.man_y -= self.current_velocity_y self.man_x = min(max(0,self.man_x+self.current_velocity_x),self.screen_width-self.man_width) if(self.man_x == 0 or self.man_x == self.screen_width-self.man_width): reward -=1 # Update pipes' position for floor in self.floors: #print(floor["y"],self.floor_velocity_y) floor["y"] -= self.floor_velocity_y # Update pipes if self.floors[0]["y"] < 0: self.floors.append(self.generate_floor()) del self.floors[0] is_collided, floor = self.is_collided() if (self.state2_counter==0): if self.man_y >=self.screen_height: self.state = 3 terminal = True reward = -1 self.__init__() elif self.man_y <=0: self.state = 2 self.state2_counter = 10 reward = -0.2 elif is_collided: self.man_y = floor['y']-28 self.state = 1 reward = 0.4 else: self.state = 0 #reward = -1 else: self.state2_counter = max(0,self.state2_counter-1) # Draw everything self.screen.blit(self.background_image, (0, 0)) #self.screen.blit(self.base_image, (self.base_x, self.base_y)) self.screen.blit(self.man_images[0], (self.man_x, self.man_y)) for floor in self.floors: self.screen.blit(self.floor_images[0], (floor["x"], floor["y"])) #self.screen.blit(self.pipe_images[1], (pipe["x_lower"], pipe["y_lower"])) image = array3d(display.get_surface()) display.update() self.fps_clock.tick(self.fps) return image, reward, terminal
def _appliquerTransformationGlobale(self, nomTransformation, **p): """Applique la transformation globale <nomTransformation> avec le dico de paramètres <p>.""" if nomTransformation == "Alpha": surface = self._fenetre.copy() self._fenetre.fill((0,0,0)) surface.set_alpha(None) surface.set_alpha(0) surface.set_alpha(p["alpha"]) self._fenetre.blit(surface, (0,0)) if nomTransformation == "Rouge": pixels = surfarray.pixels3d(self._fenetre)[:FENETRE["longueurFenetre"], :FENETRE["largeurFenetre"]] #On exclut la zone de pensée pixels[:,:,1:] = 0 elif nomTransformation == "Noir" or nomTransformation == "NoirTransition": pixels = surfarray.pixels3d(self._fenetre)[:FENETRE["longueurFenetre"],:FENETRE["largeurFenetre"]] pixels /= p["coef"] if p["coef"] >= 12: pixels[:] = (0,0,0) elif nomTransformation == "NoirTotal": pixels = surfarray.pixels3d(self._fenetre)[:FENETRE["longueurFenetre"],:FENETRE["largeurFenetre"]] pixels[:] = (0,0,0) elif nomTransformation == "Glow": nomPNJ, c = p["nomPNJ"], p["couche"] if nomPNJ in self._pnj[c].keys(): x, y = self._pnj[c][nomPNJ].positionCarte.left - self._scrollingX, self._pnj[c][nomPNJ].positionCarte.top - self._scrollingY x1, y1, x2, y2 = x-32 if x-32 >= 0 else 0, y-32 if y-32 >= 0 else 0, x+64 if x+64 <= FENETRE["longueurFenetre"] else FENETRE["longueurFenetre"], y+64 if y+64 <= FENETRE["largeurFenetre"] else FENETRE["largeurFenetre"] #On limite les coordonnées du carré autour du cercle aux limites de la fenêtre cerclePossible = False if x1 < x2 and y1 < y2: #On évite les problèmes quand le cercle est en dehors de l'écran à l'arrière... xCentre, yCentre, (xPixels, yPixels), pixels, cerclePossible = x+16, y+16, numpy.mgrid[x1:x2, y1:y2], surfarray.pixels3d(self._fenetre)[x1:x2,y1:y2], True if cerclePossible and 0 not in pixels.shape: #...comme à l'avant distancesCarrees = (xPixels - xCentre) ** 2 + (yPixels - yCentre) ** 2 pixels[distancesCarrees <= 32 ** 2] *= 5 elif nomTransformation == "Fog": idParam = id(self._parametresTransformations[nomTransformation]) fogAlpha = p.get("alpha", 150) if self._idParametres.get(nomTransformation, False) == idParam or (self._idParametres.get(nomTransformation, False) != idParam and p.get("minorChange", False) is True): fog, tempsPrecedent = self._donneesParametres[nomTransformation]["fog"], self._donneesParametres[nomTransformation]["tempsPrecedent"] fogScrollX = self._donneesParametres[nomTransformation]["fogScrollX"] else: fog = pygame.image.load(os.path.join(DOSSIER_RESSOURCES, "fog.png")) surfarray.pixels_alpha(fog)[:] = fogAlpha self._donneesParametres[nomTransformation] = {"fog":fog, "tempsPrecedent":pygame.time.get_ticks(), "fogScrollX":0} self._idParametres[nomTransformation], tempsPrecedent = idParam, self._donneesParametres[nomTransformation]["tempsPrecedent"] fogScrollX = self._donneesParametres[nomTransformation]["fogScrollX"] if p.get("minorChange", False) is True: surfarray.pixels_alpha(fog)[:] = fogAlpha tempsActuel = pygame.time.get_ticks() avancee = ((tempsActuel - tempsPrecedent) / 1000) * VITESSE_DEFILEMENT_FOG if avancee >= 1.0: self._donneesParametres[nomTransformation]["tempsPrecedent"] = tempsActuel fogScrollX += avancee self._donneesParametres[nomTransformation]["fogScrollX"] = fogScrollX #We calculate where the junction between two scroll images will be on screen xScrollRelatif = (((self._scrollingX+fogScrollX) / FENETRE["longueurFenetre"]) - int((self._scrollingX+fogScrollX) / FENETRE["longueurFenetre"])) * FENETRE["longueurFenetre"] yScrollRelatif = ((self._scrollingY / FENETRE["largeurFenetre"]) - int(self._scrollingY / FENETRE["largeurFenetre"])) * FENETRE["largeurFenetre"] fogPositions = dict() #Four images on screen if xScrollRelatif > 0 and yScrollRelatif > 0: fogPositions[0] = Rect(xScrollRelatif, yScrollRelatif, FENETRE["longueurFenetre"]-xScrollRelatif, FENETRE["largeurFenetre"]-yScrollRelatif) fogPositions[1] = Rect(0, yScrollRelatif, xScrollRelatif, FENETRE["largeurFenetre"]-yScrollRelatif) fogPositions[2] = Rect(xScrollRelatif, 0, FENETRE["longueurFenetre"]-xScrollRelatif, yScrollRelatif) fogPositions[3] = Rect(0, 0, xScrollRelatif, yScrollRelatif) elif xScrollRelatif > 0: fogPositions[0] = Rect(xScrollRelatif, 0, FENETRE["longueurFenetre"]-xScrollRelatif, FENETRE["largeurFenetre"]) fogPositions[1] = Rect(0, 0, xScrollRelatif, FENETRE["largeurFenetre"]) elif yScrollRelatif > 0: fogPositions[0] = Rect(0, yScrollRelatif, FENETRE["longueurFenetre"], FENETRE["largeurFenetre"]-yScrollRelatif) fogPositions[2] = Rect(0, 0, FENETRE["longueurFenetre"], yScrollRelatif) else: fogPositions[0] = Rect(0,0, FENETRE["longueurFenetre"], FENETRE["largeurFenetre"]) i = 0 while i < 4: coord = (0,0) if i == 0 else (FENETRE["longueurFenetre"]-xScrollRelatif,0) if i == 1 else (0, FENETRE["largeurFenetre"]-yScrollRelatif) if i == 2 else (FENETRE["longueurFenetre"]-xScrollRelatif, FENETRE["largeurFenetre"]-yScrollRelatif) self._fenetre.blit(fog.subsurface(fogPositions[i]), coord) i += 1 while i not in fogPositions.keys() and i < 4: i += 1 elif nomTransformation == "RemplirNoir": self._fenetre.fill((0,0,0), rect=(0,0,FENETRE["longueurFenetre"],FENETRE["largeurFenetre"])) elif "SplashText" in nomTransformation: idParam = id(p) if self._idParametres.get(nomTransformation, False) == idParam: surfaceTexte = self._donneesParametres[nomTransformation] else: self._idParametres[nomTransformation] = id(p) couleurFond, police, taille = p.get("couleurFond", None), p.get("police", NOM_FICHIER_POLICE_PAR_DEFAUT), p.get("taille", TAILLE_POLICE_SPLASH_SCREEN) self._ajouterPolice(police, taille) surfaceTexte = self._polices[police][taille].render(p["texte"], p["antialias"], p["couleurTexte"], couleurFond) self._donneesParametres[nomTransformation] = surfaceTexte if p.get("position", False) is not False: position = p["position"] self._fenetre.blit(surfaceTexte, position) elif self._ecranVisible.colliderect(self._pnj[p["couche"]][p["nomPNJ"]].positionCarte) or self._jeu.carteActuelle._ecranVisible.contains(self._pnj[p["couche"]][p["nomPNJ"]].positionCarte): position = self._pnj[p["couche"]][p["nomPNJ"]].positionCarte.move(-16, -surfaceTexte.get_height()) position.move_ip(-self._scrollingX, -self._scrollingY) self._fenetre.blit(surfaceTexte, position) elif nomTransformation == "Nuit": self._fenetre.fill((0,0,0), rect=(0,0,FENETRE["longueurFenetre"],FENETRE["largeurFenetre"])) c = 0 while c < self._nombreCouches: for nomPnj in self._pnj[c]: self._afficherBlocPnj(c, nomPnj) c += 1
def cutCircle(fill, r): cutout = circleMask(r) a = sfa.pixels_alpha(fill) a[:] = cutout del a
class Flappyplayer(): global SCREEN, FPSCLOCK pygame.init() FPSCLOCK = pygame.time.Clock() SCREEN = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT)) pygame.display.set_caption('Flappy player') # numbers sprites for score display IMAGES['numbers'] = ( pygame.image.load('assets/sprites/0.png').convert_alpha(), pygame.image.load('assets/sprites/1.png').convert_alpha(), pygame.image.load('assets/sprites/2.png').convert_alpha(), pygame.image.load('assets/sprites/3.png').convert_alpha(), pygame.image.load('assets/sprites/4.png').convert_alpha(), pygame.image.load('assets/sprites/5.png').convert_alpha(), pygame.image.load('assets/sprites/6.png').convert_alpha(), pygame.image.load('assets/sprites/7.png').convert_alpha(), pygame.image.load('assets/sprites/8.png').convert_alpha(), pygame.image.load('assets/sprites/9.png').convert_alpha()) # game over sprite IMAGES['gameover'] = pygame.image.load( 'assets/sprites/gameover.png').convert_alpha() # message sprite for welcome screen IMAGES['message'] = pygame.image.load( 'assets/sprites/message.png').convert_alpha() # base (ground) sprite IMAGES['base'] = pygame.image.load( 'assets/sprites/base.png').convert_alpha() # sounds if 'win' in sys.platform: soundExt = '.wav' else: soundExt = '.ogg' SOUNDS['die'] = pygame.mixer.Sound('assets/audio/die' + soundExt) SOUNDS['hit'] = pygame.mixer.Sound('assets/audio/hit' + soundExt) SOUNDS['point'] = pygame.mixer.Sound('assets/audio/point' + soundExt) SOUNDS['swoosh'] = pygame.mixer.Sound('assets/audio/swoosh' + soundExt) SOUNDS['wing'] = pygame.mixer.Sound('assets/audio/wing' + soundExt) randBg = random.randint(0, len(BACKGROUNDS_LIST) - 1) IMAGES['background'] = pygame.image.load( BACKGROUNDS_LIST[randBg]).convert() # select random player sprites randPlayer = random.randint(0, len(PLAYERS_LIST) - 1) IMAGES['player'] = ( pygame.image.load(PLAYERS_LIST[randPlayer][0]).convert_alpha(), pygame.image.load(PLAYERS_LIST[randPlayer][1]).convert_alpha(), pygame.image.load(PLAYERS_LIST[randPlayer][2]).convert_alpha(), ) # select random pipe sprites pipeindex = random.randint(0, len(PIPES_LIST) - 1) IMAGES['pipe'] = ( pygame.transform.flip( pygame.image.load(PIPES_LIST[pipeindex]).convert_alpha(), False, True), pygame.image.load(PIPES_LIST[pipeindex]).convert_alpha(), ) # hismask for pipes HITMASKS['pipe'] = ( getHitmask(IMAGES['pipe'][0]), getHitmask(IMAGES['pipe'][1]), ) # hitmask for player HITMASKS['player'] = ( getHitmask(IMAGES['player'][0]), getHitmask(IMAGES['player'][1]), getHitmask(IMAGES['player'][2]), ) pipeVelX = -4 # player velocity, max velocity, downward accleration, accleration on flap playerVelY = 0 # player's velocity along Y, default same as playerFlapped playerMaxVelY = 10 # max vel along Y, max descend speed playerMinVelY = -8 # min vel along Y, max ascend speed playerAccY = 1 # players downward accleration playerRot = 45 # player's rotation playerVelRot = 3 # angular speed playerRotThr = 20 # rotation threshold playerFlapAcc = -9 # players speed on flapping playerFlapped = False # True when player flaps playerIndexGen = cycle([0, 1, 2, 1]) baseShift = IMAGES['base'].get_width() - IMAGES['background'].get_width() player_hitmask = [ pixels_alpha(image).astype(bool) for image in IMAGES['player'] ] pipe_hitmask = [ pixels_alpha(image).astype(bool) for image in IMAGES['pipe'] ] def __init__(self): self.iter = self.player_index = self.score = 0 self.player_width = IMAGES['player'][0].get_width() self.player_height = IMAGES['player'][0].get_height() self.pipe_width = IMAGES['pipe'][0].get_width() self.pipe_height = IMAGES['pipe'][0].get_height() self.player_x = int(SCREENWIDTH * 0.2) self.player_y = int((SCREENHEIGHT - self.player_height) / 2) self.base_x = 0 self.base_y = SCREENHEIGHT * 0.79 self.SCREENW = 288 self.SCREENH = 512 self.BASEY = SCREENHEIGHT * 0.79 self.current_velocity_y = 0 newPipe1 = self.getRandomPipe() newPipe2 = self.getRandomPipe() # list of upper pipes self.upperPipes = [ { 'x': SCREENWIDTH, 'y': newPipe1[0]['y'] }, { 'x': SCREENWIDTH + (SCREENWIDTH / 2), 'y': newPipe2[0]['y'] }, ] # list of lowerpipe self.lowerPipes = [ { 'x': SCREENWIDTH, 'y': newPipe1[1]['y'] }, { 'x': SCREENWIDTH + (SCREENWIDTH / 2), 'y': newPipe2[1]['y'] }, ] # self.current_velocity_y = 0 self.is_flapped = False def getRandomPipe(self): """returns a randomly generated pipe""" # y of gap between upper and lower pipe gapY = random.randrange(0, int(BASEY * 0.6 - PIPEGAPSIZE)) gapY += int(BASEY * 0.2) pipeHeight = IMAGES['pipe'][0].get_height() pipeX = SCREENWIDTH + 10 return [ { 'x': pipeX, 'y': gapY - pipeHeight }, # upper pipe { 'x': pipeX, 'y': gapY + PIPEGAPSIZE }, # lower pipe ] def checkCrash(self): """returns True if player collders with base or pipes.""" if self.player_height + self.player_y + 1 >= self.base_y: return True playerRect = pygame.Rect(self.player_x, self.player_y, self.player_width, self.player_height) pipeW = IMAGES['pipe'][0].get_width() pipeH = IMAGES['pipe'][0].get_height() pipeBoxes = [] for uPipe, lPipe in zip(self.upperPipes, self.lowerPipes): uPipeRect = pipeBoxes.append( pygame.Rect(uPipe['x'], uPipe['y'], pipeW, pipeH)) lPipeRect = pipeBoxes.append( pygame.Rect(lPipe['x'], lPipe['y'], pipeW, pipeH)) if playerRect.collidelist(pipeBoxes) == -1: return False for i in range(2): croppedPlayerRect = playerRect.clip(pipeBoxes[i]) minX1 = croppedPlayerRect.x - playerRect.x minY1 = croppedPlayerRect.y - playerRect.y minX2 = croppedPlayerRect.x - pipeBoxes[i].x minY2 = croppedPlayerRect.y - pipeBoxes[i].y if np.any(self.player_hitmask[self.player_index] [minX1:minX1 + croppedPlayerRect.width, minY1:minY1 + croppedPlayerRect.height] * self.pipe_hitmask[i][minX2:minX2 + croppedPlayerRect.width, minY2:minY2 + croppedPlayerRect.height]): return True return False def showScore(self, score): scoreDigits = [int(x) for x in list(str(score))] totalWidth = 0 for digit in scoreDigits: totalWidth += IMAGES['numbers'][digit].get_width() Xoffset = (SCREENWIDTH - totalWidth) / 2 for digit in scoreDigits: SCREEN.blit(IMAGES['numbers'][digit], (Xoffset, SCREENHEIGHT * 0.1)) Xoffset += IMAGES['numbers'][digit].get_width() def pixelCollision(self, rect1, rect2, hitmask1, hitmask2): """Checks if two objects collide and not just their rects""" rect = rect1.clip(rect2) if rect.width == 0 or rect.height == 0: return False x1, y1 = rect.x - rect1.x, rect.y - rect1.y x2, y2 = rect.x - rect2.x, rect.y - rect2.y for x in xrange(rect.width): for y in xrange(rect.height): if hitmask1[x1 + x][y1 + y] and hitmask2[x2 + x][y2 + y]: return True return False def next_frame(self, action): pump() reward = 0.1 terminal = False if action == 1: self.current_velocity_y = self.playerFlapAcc self.is_flapped = True # SOUNDS['wing'].play() playerMidPos = self.player_x + IMAGES['player'][0].get_width() / 2 for pipe in self.upperPipes: pipeMidPos = pipe['x'] + IMAGES['pipe'][0].get_width() / 2 if pipeMidPos <= playerMidPos < pipeMidPos + 4: self.score += 1 SOUNDS['point'].play() reward = 1 if (self.iter + 1) % 3 == 0: self.player_index = next(self.playerIndexGen) self.iter = 0 # self.iter = (self.iter + 1) % 30 self.base_x = -((-self.base_x + 100) % self.baseShift) # if self.playerRot > -90: # self.playerRot -= self.playerVelRot if self.current_velocity_y < 10 and not self.is_flapped: self.current_velocity_y += 1 if self.is_flapped: self.is_flapped = False # self.playerRot = 45 self.player_y += min( self.current_velocity_y, self.player_y - self.current_velocity_y - self.player_height) if self.player_y < 0: self.player_y = 0 # self.player_height = IMAGES['player'][self.player_index].get_height() for uPipe, lPipe in zip(self.upperPipes, self.lowerPipes): uPipe['x'] += self.pipeVelX lPipe['x'] += self.pipeVelX # add new pipe when first pipe is about to touch left of screen if len(self.upperPipes) > 0 and 0 < self.upperPipes[0]['x'] < 5: newPipe = self.getRandomPipe() self.upperPipes.append(newPipe[0]) self.lowerPipes.append(newPipe[1]) # remove first pipe if its out of the screen if len( self.upperPipes ) > 0 and self.upperPipes[0]['x'] < -IMAGES['pipe'][0].get_width(): self.upperPipes.pop(0) self.lowerPipes.pop(0) if self.checkCrash(): terminal = True reward = -1 self.__init__() SCREEN.blit(IMAGES['background'], (0, 0)) SCREEN.blit(IMAGES['base'], (self.base_x, self.base_y)) # visibleRot = self.playerRotThr # if self.playerRot <= self.playerRotThr: # visibleRot = self.playerRot # playerSurface = pygame.transform.rotate(IMAGES['player'][self.player_index], visibleRot) self.showScore(self.score) SCREEN.blit(IMAGES['player'][self.player_index], (self.player_x, self.player_y)) for uPipe, lPipe in zip(self.upperPipes, self.lowerPipes): SCREEN.blit(IMAGES['pipe'][0], (uPipe['x'], uPipe['y'])) SCREEN.blit(IMAGES['pipe'][1], (lPipe['x'], lPipe['y'])) image = array3d(pygame.display.get_surface()) pygame.display.update() FPSCLOCK.tick(FPS) return image, reward, terminal
number=N) print( "\nPerformance testing blur5x5_array24 per call %s overall time %s for %s" % (round(float(t) / float(N), 10), round(float(t), 5), N)) alpha_array = array_alpha(background) rgb_array = array3d(background) rgba_array = numpy.dstack((rgb_array, alpha_array)).transpose(1, 0, 2) t = timeit.timeit("blur5x5_array32(rgb_array)", "from __main__ import blur5x5_array32, rgb_array", number=N) print( "\nPerformance testing blur5x5_array32 per call %s overall time %s for %s" % (round(float(t) / float(N), 10), round(float(t), 5), N)) alpha_array = pixels_alpha(background) rgb_array = pixels3d(background) rgba_array = numpy.dstack((rgb_array, alpha_array)).transpose(1, 0, 2) t = timeit.timeit("blur5x5_array32_inplace(rgba_array)", "from __main__ import blur5x5_array32_inplace, rgba_array", number=N) print( "\nPerformance testing blur5x5_array32_inplace per call %s overall time %s for %s" % (round(float(t) / float(N), 10), round(float(t), 5), N)) t = timeit.timeit("blur5x5_array24_inplace(rgba_array)", "from __main__ import blur5x5_array24_inplace, rgba_array", number=N) print( "\nPerformance testing blur5x5_array24_inplace per call %s overall time %s for %s"
class Environment(): pygame.init() width, height = (288, 512) screen = pygame.display.set_mode((width, height)) clock = pygame.time.Clock() fps = 30 # Backgroun background = pygame.image.load("assets/sprites/background-day.png").convert() # Floor floor = pygame.image.load("assets/sprites/base.png").convert() floor_limit = background.get_width() - floor.get_width() # Bird bird_downflap = pygame.image.load("assets/sprites/bluebird-downflap.png").convert_alpha() bird_midflap = pygame.image.load("assets/sprites/bluebird-midflap.png").convert_alpha() bird_upflap = pygame.image.load("assets/sprites/bluebird-upflap.png").convert_alpha() bird_index = 0 bird_frames = [bird_downflap, bird_midflap, bird_upflap] bird = bird_frames[bird_index] bird_hitmask = [pixels_alpha(image).astype(bool) for image in bird_frames] # print(bird_hitmask[bird_index]) init_pos = ( int(width * 0.2), int(height / 2) ) # Pipe pipe_surface = pygame.image.load("assets/sprites/pipe-green.png").convert_alpha() pipes = [] pipe_gap = 100 pipe_min = int(pipe_gap / 4) pipe_max = int(height * 0.79 * 0.6 - pipe_gap / 2) def __init__(self): self.floorx, self.floory = (0, self.background.get_height() - self.floor.get_height()) self.bird_rect = self.bird.get_rect(center=self.init_pos) # Game variables self.GRAVITY = 1 self.FLAP_POWER = 9 self.MAX_DROP_SPEED = 10 # Velocity on y and x self.vel = 0 self.speed = 4 # Score self.score = 0 self.tick = 0 self.pipes.extend(self._generate_pipes(self.width)) self.pipes.extend(self._generate_pipes(offset=int(self.pipe_surface.get_width()/2 + 1.5 * self.width))) self.pipes.extend(self._generate_pipes(offset=int(self.pipe_surface.get_width() + 2 * self.width))) self.next_pipe = 0 def _generate_pipes(self, offset=0): gap_start = random.randint(self.pipe_min, self.pipe_max) top_bottom = gap_start - self.pipe_surface.get_height() bottom_top = gap_start + self.pipe_gap top_pipe = self.pipe_surface.get_rect(topleft=(self.width + offset, top_bottom)) bottom_pipe = self.pipe_surface.get_rect(topleft=(self.width + offset, bottom_top)) return top_pipe, bottom_pipe def _is_collided(self): # out-of-screen if self.bird_rect.top < - self.bird.get_height() * 0.1 or self.bird_rect.bottom >= self.floory: return True mask = self.bird_hitmask[self.bird_index] rows, columns = mask.shape # pipe collison for pipe in self.pipes: lx, rx = pipe.x, pipe.x + self.pipe_surface.get_width() ty, by = pipe.y, pipe.y + self.pipe_surface.get_height() for i in range(rows): for j in range(columns): posx, posy = self.bird_rect.x + j, self.bird_rect.y + i if mask[i, j] and lx < posx < rx and ty < posy < by: return True ''' if self.bird_rect.colliderect(pipe): return True ''' return False def rotate_bird(self): return pygame.transform.rotozoom(self.bird, -self.vel * 3, 1) def bird_animation(self): new_bird = self.bird_frames[self.bird_index] new_bird_rect = new_bird.get_rect(center=(100, self.bird_rect.centery)) return new_bird, new_bird_rect def step(self, action): pygame.event.pump() # reward to stay alive reward = 0.1 # terminal terminal = False # update tick self.tick += 1 # Velocity updating if self.vel < self.MAX_DROP_SPEED: self.vel += self.GRAVITY if action == 1: self.vel = 0 self.vel -= self.FLAP_POWER # bird movement self.bird_rect.centery += self.vel # floor movement self.floorx -= 1 if self.floorx < self.floor_limit: self.floorx = 0 # pipes' movement for pipe in self.pipes: pipe.centerx -= self.speed # Check whether bird passes the pipe or not for pipe in self.pipes: if pipe.centerx < self.bird_rect.centerx <= pipe.centerx + self.speed: reward = 1 self.score += 1 self.next_pipe += 2 break # Update pipes if self.pipes[0].x <= -self.pipe_surface.get_width(): self.pipes.extend(self._generate_pipes(offset=int(0.5 * self.pipe_surface.get_width() + 0.5 * self.width))) # delete top and bottom pipes if self.pipes[0].x <= -self.pipe_surface.get_width(): del self.pipes[0] del self.pipes[0] self.next_pipe -= 2 # collision control if self._is_collided(): reward = -1 terminal = True if (self.tick + 1) % 15 == 0: self.bird_index = (self.bird_index + 1) % 3 self.bird, self.bird_rect = self.bird_animation() # TODO: Check functions # draw self.screen.blit(self.background, (0, 0)) for i, pipe in enumerate(self.pipes): if i % 2 == 0: flip_pipe = pygame.transform.flip(self.pipe_surface, False, True) self.screen.blit(flip_pipe, pipe) else: self.screen.blit(self.pipe_surface, pipe) self.screen.blit(self.floor, (self.floorx, self.floory)) rotated_bird = self.rotate_bird() self.screen.blit(rotated_bird, self.bird_rect) # self.screen.blit(self.bird, self.bird_rect) pygame.display.update() # screen = pygame.surfarray.array3d(pygame.display.get_surface()) screen = [ self.bird_rect.centery, self.vel, self.pipes[self.next_pipe].centerx - self.bird_rect.centerx, self.pipes[self.next_pipe].y, self.pipes[self.next_pipe + 1].y, self.pipes[self.next_pipe + 2].centerx - self.bird_rect.centerx, self.pipes[self.next_pipe + 2].y, self.pipes[self.next_pipe + 3].y ] """ Gets a non-visual state representation of the game. Returns ------- dict * player y position. * players velocity. * next pipe distance to player * next pipe top y position * next pipe bottom y position * next next pipe distance to player * next next pipe top y position * next next pipe bottom y position See code for structure. """ self.clock.tick(self.fps) return screen, reward, terminal # TODO : State of the game should be returned def get_screen(self): return array3d(pygame.display.get_surface()) def reset(self): self.pipes.clear() self.__init__() def quit(self): pygame.quit()
def render(self): scr.blit(self.surface,self) array = surfarray.pixels_alpha(self.surface) array[(self.alpha<array)&(array<self.alpha+self.delta)] = self.alpha array[array>self.alpha] = array[array>self.alpha]-self.delta
def fadeEdges(sf, r, startFade=0.9): alphas = sfa.array_alpha(circleFadedEdges(r, startFade)) a = sfa.pixels_alpha(sf) a[:] = alphas del a
class FlappyBird(object): init() fps_clock = time.Clock() screen_width = 288 screen_height = 512 screen = display.set_mode((screen_width, screen_height)) display.set_caption('Deep Q-Network Flappy Bird') base_image = load('assets/sprites/base.png').convert_alpha() background_image = load('assets/sprites/background-black.png').convert() pipe_images = [ rotate(load('assets/sprites/pipe-green.png').convert_alpha(), 180), load('assets/sprites/pipe-green.png').convert_alpha() ] bird_images = [ load('assets/sprites/redbird-upflap.png').convert_alpha(), load('assets/sprites/redbird-midflap.png').convert_alpha(), load('assets/sprites/redbird-downflap.png').convert_alpha() ] # number_images = [load('assets/sprites/{}.png'.format(i)).convert_alpha() for i in range(10)] bird_hitmask = [pixels_alpha(image).astype(bool) for image in bird_images] pipe_hitmask = [pixels_alpha(image).astype(bool) for image in pipe_images] fps = 30 pipe_gap_size = 100 pipe_velocity_x = -4 # parameters for bird min_velocity_y = -8 max_velocity_y = 10 downward_speed = 1 upward_speed = -9 bird_index_generator = cycle([0, 1, 2, 1]) def __init__(self): self.iter = self.bird_index = self.score = 0 self.bird_width = self.bird_images[0].get_width() self.bird_height = self.bird_images[0].get_height() self.pipe_width = self.pipe_images[0].get_width() self.pipe_height = self.pipe_images[0].get_height() self.bird_x = int(self.screen_width / 5) self.bird_y = int((self.screen_height - self.bird_height) / 2) self.base_x = 0 self.base_y = self.screen_height * 0.79 self.base_shift = self.base_image.get_width( ) - self.background_image.get_width() pipes = [self.generate_pipe(), self.generate_pipe()] pipes[0]["x_upper"] = pipes[0]["x_lower"] = self.screen_width pipes[1]["x_upper"] = pipes[1]["x_lower"] = self.screen_width * 1.5 self.pipes = pipes self.current_velocity_y = 0 self.is_flapped = False def generate_pipe(self): x = self.screen_width + 10 gap_y = randint(2, 10) * 10 + int(self.base_y / 5) #gap_y = 6 * 10 + int(self.base_y / 5) return { "x_upper": x, "y_upper": gap_y - self.pipe_height, "x_lower": x, "y_lower": gap_y + self.pipe_gap_size } def diff_distance(self): bird_center_x = self.bird_x + self.bird_width / 2 bird_center_y = self.bird_y + self.bird_height / 2 min_dist = np.Inf pipe_x_temp = pipe_y_temp = bird_x_temp = bird_y_temp = p_id = 0 for p_idx, pipe in enumerate(self.pipes): pipe_x = pipe["x_upper"] + self.pipe_width #print(pipe["y_upper"], pipe["y_lower"]) pipe_y_mid = (pipe["y_lower"] - self.pipe_gap_size / 2) if pipe_x < bird_center_x: continue current_dist = ((pipe_x - bird_center_x)**2 + (pipe_y_mid - bird_center_y)**2) / 10000 if min_dist > current_dist: min_dist = current_dist pipe_x_temp = pipe_x pipe_y_temp = pipe_y_mid bird_x_temp = bird_center_x bird_y_temp = bird_center_y p_id = p_idx #print(min_dist, p_id ,pipe_x_temp, pipe_y_temp, bird_x_temp, bird_y_temp) return min_dist def is_collided(self): # Check if the bird touch ground if self.bird_height + self.bird_y + 1 >= self.base_y: self.distance_reward = 0 return True bird_bbox = Rect(self.bird_x, self.bird_y, self.bird_width, self.bird_height) pipe_boxes = [] for pipe in self.pipes: pipe_boxes.append( Rect(pipe["x_upper"], pipe["y_upper"], self.pipe_width, self.pipe_height)) pipe_boxes.append( Rect(pipe["x_lower"], pipe["y_lower"], self.pipe_width, self.pipe_height)) # Check if the bird's bounding box overlaps to the bounding box of any pipe if bird_bbox.collidelist(pipe_boxes) == -1: return False for i in range(2): cropped_bbox = bird_bbox.clip(pipe_boxes[i]) min_x1 = cropped_bbox.x - bird_bbox.x min_y1 = cropped_bbox.y - bird_bbox.y min_x2 = cropped_bbox.x - pipe_boxes[i].x min_y2 = cropped_bbox.y - pipe_boxes[i].y if np.any(self.bird_hitmask[ self.bird_index][min_x1:min_x1 + cropped_bbox.width, min_y1:min_y1 + cropped_bbox.height] * self.pipe_hitmask[i][min_x2:min_x2 + cropped_bbox.width, min_y2:min_y2 + cropped_bbox.height]): self.distance_reward = 0.9 / (self.diff_distance() + 1) return True return False def next_frame(self, action): pump() reward = 0.1 terminal = False # Check input action if action == 1: self.current_velocity_y = self.upward_speed self.is_flapped = True # Update score bird_center_x = self.bird_x + self.bird_width / 2 for pipe in self.pipes: pipe_center_x = pipe["x_upper"] + self.pipe_width / 2 if pipe_center_x < bird_center_x < pipe_center_x + 5: self.score += 1 reward = 1 break # Update index and iteration if (self.iter + 1) % 3 == 0: self.bird_index = next(self.bird_index_generator) self.iter = 0 self.base_x = -((-self.base_x + 100) % self.base_shift) # Update bird's position if self.current_velocity_y < self.max_velocity_y and not self.is_flapped: self.current_velocity_y += self.downward_speed if self.is_flapped: self.is_flapped = False self.bird_y += min( self.current_velocity_y, self.bird_y - self.current_velocity_y - self.bird_height) if self.bird_y < 0: self.bird_y = 0 # Update pipes' position for pipe in self.pipes: pipe["x_upper"] += self.pipe_velocity_x pipe["x_lower"] += self.pipe_velocity_x # Update pipes if 0 < self.pipes[0]["x_lower"] < 5: self.pipes.append(self.generate_pipe()) if self.pipes[0]["x_lower"] < -self.pipe_width: del self.pipes[0] if self.is_collided(): terminal = True #if self.distance_reward < 0.2: # reward = -1 #else: if terminal == True: while 1 == 1: print("1") reward = -1 + self.distance_reward #print(reward) self.__init__() # Draw everything self.screen.blit(self.background_image, (0, 0)) self.screen.blit(self.base_image, (self.base_x, self.base_y)) self.screen.blit(self.bird_images[self.bird_index], (self.bird_x, self.bird_y)) for pipe in self.pipes: self.screen.blit(self.pipe_images[0], (pipe["x_upper"], pipe["y_upper"])) self.screen.blit(self.pipe_images[1], (pipe["x_lower"], pipe["y_lower"])) image = array3d(display.get_surface()) display.update() self.fps_clock.tick(self.fps) return image, reward, terminal, self.score
class FlappyBird(object): init() fps_clock = time.Clock() screen_width = 288 screen_height = 512 screen = display.set_mode((screen_width, screen_height)) display.set_caption('Flappy Bird') base_image = load(os.path.join(base_path, 'assets/base.png')).convert_alpha() background_image = load( os.path.join(base_path, 'assets/background-black.png')).convert() pipe_images = [ rotate( load(os.path.join(base_path, 'assets/pipe-green.png')).convert_alpha(), 180), load(os.path.join(base_path, 'assets/pipe-green.png')).convert_alpha() ] bird_images = [ load(os.path.join(base_path, 'assets/redbird-upflap.png')).convert_alpha(), load(os.path.join(base_path, 'assets/redbird-midflap.png')).convert_alpha(), load(os.path.join(base_path, 'assets/redbird-downflap.png')).convert_alpha() ] bird_hitmask = [pixels_alpha(image).astype(bool) for image in bird_images] pipe_hitmask = [pixels_alpha(image).astype(bool) for image in pipe_images] fps = 100 pipe_gap_size = 100 pipe_velocity_x = -4 # parameters for bird min_velocity_y = -8 max_velocity_y = 10 downward_speed = 2 upward_speed = -9 bird_index_generator = cycle([0, 1, 2, 1]) def __init__(self): self.iter = self.bird_index = self.score = 0 self.bird_width = self.bird_images[0].get_width() self.bird_height = self.bird_images[0].get_height() self.pipe_width = self.pipe_images[0].get_width() self.pipe_height = self.pipe_images[0].get_height() self.bird_x = int(self.screen_width / 5) self.bird_y = int((self.screen_height - self.bird_height) / 2) self.base_x = 0 self.base_y = self.screen_height * 0.79 self.base_shift = self.base_image.get_width( ) - self.background_image.get_width() pipes = [self.generate_pipe(), self.generate_pipe()] pipes[0]["x_upper"] = pipes[0]["x_lower"] = self.screen_width pipes[1]["x_upper"] = pipes[1]["x_lower"] = self.screen_width * 1.5 self.pipes = pipes self.current_velocity_y = 0 self.is_flapped = False def generate_pipe(self): x = self.screen_width + 10 gap_y = randint(2, 10) * 10 + int(self.base_y / 5) return { "x_upper": x, "y_upper": gap_y - self.pipe_height, "x_lower": x, "y_lower": gap_y + self.pipe_gap_size } def is_collided(self): # Check if the bird touch ground if self.bird_height + self.bird_y + 1 >= self.base_y: return True bird_bbox = Rect(self.bird_x, self.bird_y, self.bird_width, self.bird_height) pipe_boxes = [] for pipe in self.pipes: pipe_boxes.append( Rect(pipe["x_upper"], pipe["y_upper"], self.pipe_width, self.pipe_height)) pipe_boxes.append( Rect(pipe["x_lower"], pipe["y_lower"], self.pipe_width, self.pipe_height)) # Check if the bird's bounding box overlaps to the bounding box of any pipe if bird_bbox.collidelist(pipe_boxes) == -1: return False for i in range(2): cropped_bbox = bird_bbox.clip(pipe_boxes[i]) min_x1 = cropped_bbox.x - bird_bbox.x min_y1 = cropped_bbox.y - bird_bbox.y min_x2 = cropped_bbox.x - pipe_boxes[i].x min_y2 = cropped_bbox.y - pipe_boxes[i].y if np.any(self.bird_hitmask[ self.bird_index][min_x1:min_x1 + cropped_bbox.width, min_y1:min_y1 + cropped_bbox.height] * self.pipe_hitmask[i][min_x2:min_x2 + cropped_bbox.width, min_y2:min_y2 + cropped_bbox.height]): return True return False def next_frame(self, action, text=''): pump() reward = 1 terminal = False # Check input action if action == 0: # 0 means flap self.current_velocity_y = self.upward_speed self.is_flapped = True # Update score bird_center_x = self.bird_x + self.bird_width / 2 for pipe in self.pipes: pipe_center_x = pipe["x_upper"] + self.pipe_width / 2 if pipe_center_x < bird_center_x < pipe_center_x + 5: self.score += 1 break # get detal_x, detal_y for pipe in self.pipes: if self.bird_x < pipe["x_lower"] + self.pipe_width: detal_x = pipe['x_lower'] + self.pipe_width - self.bird_x detal_y = pipe['y_lower'] - self.bird_y + self.bird_height # a triangle points = ((self.bird_x, self.bird_y + self.bird_height), (pipe['x_lower'] + self.pipe_width, pipe['y_lower']), (self.bird_x, pipe['y_lower'])) break # Update index and iteration if (self.iter + 1) % 3 == 0: self.bird_index = next(self.bird_index_generator) self.iter = 0 self.base_x = -((-self.base_x + 100) % self.base_shift) # Update bird's position if self.current_velocity_y < self.max_velocity_y and not self.is_flapped: self.current_velocity_y += self.downward_speed if self.is_flapped: self.is_flapped = False self.bird_y += min( self.current_velocity_y, self.bird_y - self.current_velocity_y - self.bird_height) if self.bird_y < 0: self.bird_y = 0 # Update pipes' position for pipe in self.pipes: pipe["x_upper"] += self.pipe_velocity_x pipe["x_lower"] += self.pipe_velocity_x # Update pipes if 0 < self.pipes[0]["x_lower"] < 5: self.pipes.append(self.generate_pipe()) if self.pipes[0]["x_lower"] < -self.pipe_width: del self.pipes[0] if self.is_collided(): terminal = True reward = -1000 self.__init__() # show info font = pygame.font.Font('freesansbold.ttf', 20) info = font.render(text, False, (255, 200, 10)) # Draw everything self.screen.blit(self.background_image, (0, 0)) self.screen.blit(self.base_image, (self.base_x, self.base_y)) self.screen.blit(self.bird_images[self.bird_index], (self.bird_x, self.bird_y)) for pipe in self.pipes: self.screen.blit(self.pipe_images[0], (pipe["x_upper"], pipe["y_upper"])) self.screen.blit(self.pipe_images[1], (pipe["x_lower"], pipe["y_lower"])) self.screen.blit(info, (0, 100)) pygame.draw.polygon(display.get_surface(), (255, 0, 0), points, width=1) image = array3d(display.get_surface()) display.update() self.fps_clock.tick(self.fps) return image, reward, terminal, self.score, str( (int(detal_x / 4), int(detal_y / 4)))