Exemple #1
0
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
Exemple #2
0
    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
Exemple #4
0
 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
Exemple #8
0
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()
Exemple #9
0
 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
Exemple #10
0
    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
Exemple #11
0
    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
Exemple #13
0
    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
Exemple #14
0
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
Exemple #15
0
 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
Exemple #17
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
Exemple #18
0
 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)
Exemple #20
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))
Exemple #21
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))
Exemple #22
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
Exemple #23
0
 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
Exemple #24
0
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
Exemple #25
0
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
Exemple #26
0
	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
Exemple #27
0
    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
Exemple #29
0
 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
Exemple #30
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 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
Exemple #33
0
 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
Exemple #34
0
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
Exemple #35
0
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
Exemple #37
0
 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
Exemple #38
0
def cutCircle(fill, r):
    cutout = circleMask(r)
    a = sfa.pixels_alpha(fill)
    a[:] = cutout
    del a
Exemple #39
0
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
Exemple #40
0
                  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
Exemple #43
0
def fadeEdges(sf, r, startFade=0.9):
    alphas = sfa.array_alpha(circleFadedEdges(r, startFade))
    a = sfa.pixels_alpha(sf)
    a[:] = alphas
    del a
Exemple #44
0
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)))