コード例 #1
0
ファイル: projectile.py プロジェクト: xchsp/Tower_Defense
class Projectile(sprite.Sprite):
    def __init__(self, pos, tower, target, image, speed, damage):
        sprite.Sprite.__init__(self)
        self.pos = pos
        self.tower = tower
        self.target = target
        self.image = image
        self.speed = speed
        self.damage = damage
        self.rect = Rect(self.pos, self.image.get_size())

        self.angle = atan2((self.target.rect.centery - self.rect.centery),
                           (self.target.rect.centerx - self.rect.centerx))
        self.x_speed = cos(self.angle) * self.speed
        self.y_speed = sin(self.angle) * self.speed

    def update(self, monsters, screen):

        # Kills the projectile if it doesn't get there before the target dies
        if self.target is None:
            self.kill()
            return

        # Calculates where the projectile needs to go
        self.angle = atan2((self.target.rect.centery - self.rect.centery),
                           (self.target.rect.centerx - self.rect.centerx))

        distance = hypot(self.target.rect.centerx - self.rect.centerx,
                         self.target.rect.centery - self.rect.centery)
        mod = self.target.speed + 1
        # Calculates the X and Y speed
        xspeed, yspeed = cos(self.angle) * mod, sin(self.angle) * mod
        self.x_speed = xspeed + xspeed / abs(xspeed) if xspeed != 0 else 0
        self.y_speed = yspeed + yspeed / abs(yspeed) if yspeed != 0 else 0

        # If the projectile is within range, it hit the target
        if abs(self.rect.centerx - self.target.rect.centerx) <= 20:
            if abs(self.rect.centery - self.target.rect.centery) <= 20:
                self.do_damage(monsters)
                self.kill()
            else:
                self.rect.move_ip((self.x_speed, self.y_speed))
        else:
            self.rect.move_ip((self.x_speed, self.y_speed))

        # Destroys the projectile if it goes off screen
        if not screen.contains(self.rect):
            self.kill()

    def do_damage(self, monsters):
        for monster in monsters:
            # Does damage to the target, and adds kills and money rewards if it dies, also adds damage_done to tower
            if monster == self.target:
                # dmg_result returns (None/Value of monster, Damage done by projectile)
                dmg_result = monster.damage(self.damage)
                if dmg_result[0] is not None:
                    self.tower.kills += 1
                    self.tower.turn_yield += dmg_result[0]
                self.tower.damage_done += dmg_result[1]
                break
コード例 #2
0
class Projectile(sprite.Sprite):
    def __init__(self, pos, tower, target, image, speed, damage):
        sprite.Sprite.__init__(self)
        self.pos = pos
        self.tower = tower
        self.target = target
        self.image = image
        self.speed = speed
        self.damage = damage
        self.rect = Rect(self.pos, self.image.get_size())

        self.angle = atan2((self.target.rect.centery-self.rect.centery),
                                (self.target.rect.centerx-self.rect.centerx))
        self.x_speed = cos(self.angle)*self.speed
        self.y_speed = sin(self.angle)*self.speed

    def update(self, monsters, screen):

        # Kills the projectile if it doesn't get there before the target dies
        if self.target is None:
            self.kill()
            return

        # Calculates where the projectile needs to go
        self.angle = atan2((self.target.rect.centery-self.rect.centery),
                                (self.target.rect.centerx-self.rect.centerx))

        distance = hypot(self.target.rect.centerx - self.rect.centerx,
                              self.target.rect.centery - self.rect.centery)
        mod = self.target.speed+1
        # Calculates the X and Y speed
        xspeed, yspeed = cos(self.angle)*mod, sin(self.angle)*mod
        self.x_speed = xspeed + xspeed/abs(xspeed) if xspeed != 0 else 0
        self.y_speed = yspeed + yspeed/abs(yspeed) if yspeed != 0 else 0

        # If the projectile is within range, it hit the target
        if abs(self.rect.centerx - self.target.rect.centerx) <= 20:
            if abs(self.rect.centery - self.target.rect.centery) <= 20:
                self.do_damage(monsters)
                self.kill()
            else:
                self.rect.move_ip((self.x_speed, self.y_speed))
        else:
            self.rect.move_ip((self.x_speed, self.y_speed))

        # Destroys the projectile if it goes off screen
        if not screen.contains(self.rect):
            self.kill()

    def do_damage(self, monsters):
        for monster in monsters:
            # Does damage to the target, and adds kills and money rewards if it dies, also adds damage_done to tower
            if monster == self.target:
                # dmg_result returns (None/Value of monster, Damage done by projectile)
                dmg_result = monster.damage(self.damage)
                if dmg_result[0] is not None:
                    self.tower.kills += 1
                    self.tower.turn_yield += dmg_result[0]
                self.tower.damage_done += dmg_result[1]
                break
コード例 #3
0
ファイル: colortest.py プロジェクト: Hug00/ninmonkey
class Thumbnail():
    """Thumbnail that has a surface, with a background color set"""
    def __init__(self, width=64):
        self.surface_thumb = Rect(0,0,width,width)
        self.rect_thumb = Rect(0,0,width,width)
                    
        # ex [1] the standard pygame.Color("white") , same as Color("#ffffff")
        self.color_bg = Color("white")                
        # ex [2] random color with a filter:
        self.color_bg = random_color('light')
        self.color_border = random_color('dark')
        
        # create empty surface;  fill it
        self.surface_thumb = pygame.Surface([width, width])
        self.surface_thumb.fill(self.color_bg)
    
    def fill(self):
        """clear thumb."""
        self.surface_thumb.fill(self.color_bg)

    def move(self, x, y):
        """move all rects/images together"""
        self.rect_thumb.move_ip(x,y)
  
    def draw(self, screen):        
        screen.blit(self.surface_thumb, self.rect_thumb)
                
    def __str__(self): return "<Thumbnail( bg={bg}, rect_thumb={rect_thumb} >".format(bg=self.color_bg, rect_thumb=self.rect_thumb)
コード例 #4
0
class Platform(Sprite):
    def __init__(self, init_pos, play_area_rect: Rect, *groups):
        super().__init__(*groups)

        self._play_area_rect = play_area_rect
        self._shift_speed = 5
        self._speed = [0, 0]
        self._init_pos = init_pos

        self.rect = Rect(init_pos[0], init_pos[1], 40, 5)
        self.image = self._create_surface()

    def _create_surface(self):
        surface = Surface((self.rect.width, self.rect.height))
        surface.fill((66, 226, 126)) # Green
        return surface

    @property
    def pos(self):
        return self.rect.topleft

    def reset(self):
        self.rect.topleft = self._init_pos

    def move(self, move_action: PlatformAction):
        if (move_action == PlatformAction.MOVE_LEFT and
            self.rect.left > self._play_area_rect.left):
            self._speed[0] = -self._shift_speed
        elif (move_action == PlatformAction.MOVE_RIGHT and
              self.rect.right < self._play_area_rect.right):
            self._speed[0] = self._shift_speed
        else:
            self._speed[0] = 0

        self.rect.move_ip(*self._speed)
コード例 #5
0
def drawStacks(stacks):
    __screen.fill(Color(50, 50, 150, 255))

    stackWidth = 15
    stack = Rect(0 - stackWidth / 2, 90, stackWidth, 310)
    disk = None

    for l in stacks:
        stack.move_ip(640 / 4, 0)
        draw.rect(__screen, BROWN, stack)

        for i, disk in enumerate(l, start=1):
            diskWidth = 640 / 5 * (float(disk) /
                                   float(__maxSize)) + stackWidth * 2
            disk = Rect((stack.left + stackWidth / 2) - diskWidth / 2,
                        400 - __diskHeight * (i), diskWidth, __diskHeight)

            draw.rect(__screen, RED, disk)
            draw.rect(__screen, BLACK, disk, 2)
            disk.width /= 10
            disk.height -= 6
            disk.move_ip(diskWidth / 6, 3)
            draw.rect(__screen, WHITE, disk)

    draw.rect(__screen, GREEN, Rect(0, 400, 640, 80))
    display.flip()
    handleEvents()
コード例 #6
0
ファイル: ball.py プロジェクト: OlexTym/tennis
class Ball():
    ball_diameter = 20
    ball_move_x = 4
    ball_move_y = 4

    def __init__(self, screen, color):
        self.screen = screen
        self.color = color
        self.pos_x = self.screen.get_height() / 2
        self.pos_y = self.screen.get_width() / 2
        self.rect = Rect(self.pos_x, self.pos_y, Ball.ball_diameter, Ball.ball_diameter)
        self.move_x = Ball.ball_move_x
        self.move_y = Ball.ball_move_y
        self.ball = draw_ellipse(self.screen, self.color, self.rect)

    def draw_ball(self):
        self.ball = draw_ellipse(self.screen, self.color, self.rect)

    def move_ball(self):

        if self.rect.top > (self.screen.get_height() - self.rect.height) or self.rect.top < 0:
            self.move_y *= -1

        if self.rect.left > (self.screen.get_width() - self.rect.width) or self.rect.left < 0:
            self.move_x = 0
            self.move_y = 0
            print("Game Over")

        self.rect.move_ip(0, self.move_y)
        self.rect.move_ip(self.move_x, 0)
  
    def racket_shoot(self):
        self.move_x *= -1
        self.rect.move_ip(self.move_x * 2, 0)
コード例 #7
0
 def __initPosition(self, windowSize: tuple, playerId: int) -> math.Vector2:
     rect = Rect(0, 0, windowSize[0] / 2, windowSize[1] / 2)
     if (0 == playerId):
         return math.Vector2(rect.center)
     else:
         rect.move_ip(windowSize[0] / 2, windowSize[1] / 2)
         return math.Vector2(rect.center)
コード例 #8
0
    def __updateTankSurface(self, surface: Surface, color: Color,
                            direction: math.Vector2):
        surface.fill((0, 0, 0, 0))

        # rect inside surface
        surfaceSize = surface.get_size()
        surfaceRect = Rect(0, 0, surfaceSize[0], surfaceSize[1])
        tankRect = Rect(0, 0, self.size[0], self.size[1])
        diff = math.Vector2(surfaceRect.center) - math.Vector2(tankRect.center)
        tankRect.move_ip(diff)

        temp = surface.copy()
        draw.rect(temp, color, tankRect)

        # apply tank direction to surface
        degree = -math.Vector2(0, 1).angle_to(direction)
        temp = transform.rotate(temp, degree)

        # temp was enlarged by rotate (wtf):
        # calculate diff so that temp surface is positioned outside
        # of the destination surface below
        tempRectSize = temp.get_size()
        diff = math.Vector2(tempRectSize) - math.Vector2(surfaceSize)

        # copy back wanted portion from rotation
        surface.blit(temp, -diff / 2)
コード例 #9
0
ファイル: colortest.py プロジェクト: Hug00/ninmonkey
class Thumbnail():
    """Thumbnail that has a surface, with a background color set"""
    def __init__(self, width=64):
        self.surface_thumb = Rect(0, 0, width, width)
        self.rect_thumb = Rect(0, 0, width, width)

        # ex [1] the standard pygame.Color("white") , same as Color("#ffffff")
        self.color_bg = Color("white")
        # ex [2] random color with a filter:
        self.color_bg = random_color('light')
        self.color_border = random_color('dark')

        # create empty surface;  fill it
        self.surface_thumb = pygame.Surface([width, width])
        self.surface_thumb.fill(self.color_bg)

    def fill(self):
        """clear thumb."""
        self.surface_thumb.fill(self.color_bg)

    def move(self, x, y):
        """move all rects/images together"""
        self.rect_thumb.move_ip(x, y)

    def draw(self, screen):
        screen.blit(self.surface_thumb, self.rect_thumb)

    def __str__(self):
        return "<Thumbnail( bg={bg}, rect_thumb={rect_thumb} >".format(
            bg=self.color_bg, rect_thumb=self.rect_thumb)
コード例 #10
0
ファイル: bbb_items.py プロジェクト: NatakuG/Pygame-Bebarball
class Ball(BeBarBallSprite):

    def __init__(self, screen, position=None):
        # 继承__init__
        BeBarBallSprite.__init__(self, screen)
        # 属性
        self.screen = screen

        self.init_speed = BALL_INIT_SPEED
        # 最大ball速度
        self.max_speed = BALL_MAX_SPEED
        # ball每次x速度增长
        self.speed_increase = BALL_INCREASE_SPEED
        self.init_position = BALL_INIT_POSITION
        self.rad = BALL_RAD

        # 当前方向
        self.direction = [random.choice((-1, 1)), random.choice((-1, 1))]
        # 当前速度
        self.speed = [self.init_speed[0], random.randrange(0, self.init_speed[1])]
        # 自身矩形
        self.rect = Rect(0, 0, self.rad, self.rad)

        if position is not None:
            self.rect.center = position
            self.init_position = position
        else:
            self.rect.center = self.init_position

    # 更新函数,每次主循环中更新
    def update(self):
        # 检测与上下边界碰撞,碰撞则y速度取反
        if self.rect.top < 0 and self.direction[1] < 0:
            self.direction[1] = -self.direction[1]
        elif self.rect.bottom > self.screen.get_height() and self.direction[1] > 0:
            self.direction[1] = -self.direction[1]
        # 保持移动
        self.rect.move_ip((self.speed[0] * self.direction[0], self.speed[1] * self.direction[1]))

        if self.speed[1] > self.max_speed[1]:
            self.speed[1] = self.max_speed[1]
        if self.speed[1] < 0:
            self.speed[1] = - self.speed[1]
            self.direction[1] = - self.direction[1]

    # 碰撞检测函数
    def hit(self, target):
        # 取自身的矩形大小
        return self.rect.colliderect(target.rect)

    # 重置速度与位置
    def reset(self):
        # 回到初始位置与速度
        self.speed = [self.init_speed[0], random.randrange(0, self.init_speed[1])]
        self.direction = [random.choice((-1, 1)), random.choice((-1, 1))]
        self.rect.center = self.init_position

    def blit(self):
        circle(self.screen, COLOR_BALL, self.rect.center, self.rad, 0)
コード例 #11
0
ファイル: rect_test.py プロジェクト: CTPUG/pygame_cffi
 def test_move_ip( self ):    
     r = Rect( 1, 2, 3, 4 )
     r2 = Rect( r )
     move_x = 10
     move_y = 20
     r2.move_ip( move_x, move_y )
     expected_r2 = Rect(r.left+move_x,r.top+move_y,r.width,r.height)
     self.assertEqual( expected_r2, r2 )
コード例 #12
0
ファイル: rect_test.py プロジェクト: annie60/Xilarius
 def test_move_ip(self):
     r = Rect(1, 2, 3, 4)
     r2 = Rect(r)
     move_x = 10
     move_y = 20
     r2.move_ip(move_x, move_y)
     expected_r2 = Rect(r.left + move_x, r.top + move_y, r.width, r.height)
     self.assertEqual(expected_r2, r2)
コード例 #13
0
ファイル: camera.py プロジェクト: nyrocron/pathdemo
class Camera(object):
    """Manages current view rectangle and provides methods to convert
    coordinates from/to screen/map coordinate systems."""

    MOVE_SPEED = 0.25

    def __init__(self, view_size):
        self.view_rect = Rect((0, 0), view_size)
        self.move_event = EventManager.new_event_code()

        self._moving = False
        self._move_vector = [0, 0]

        self._last_update = 0

    def update(self, time_passed):
        """Update camera.

        Execute movement and such"""

        if self._moving:
            delta = util.vector_mul(util.vector_normalize(self._move_vector),
                                    Camera.MOVE_SPEED * time_passed)
            self.view_rect.move_ip(delta)
            self._post_move_event()

    def set_move(self, x=None, y=None):
        if x is not None:
            self._move_vector[0] = x
        if y is not None:
            self._move_vector[1] = y
        self._moving = True

    def stop_moving(self):
        self._move_vector = [0, 0]
        self._moving = False

    def move_to(self, x, y):
        self.view_rect.x = x
        self.view_rect.y = y
        self._post_move_event()

    def rect_to_screen(self, rect):
        return rect.move(-self.view_rect.x, -self.view_rect.y)

    def rect_to_map(self, rect):
        return rect.move(self.view_rect.x, self.view_rect.y)

    def point_to_screen(self, p):
        return p[0] - self.view_rect.x, p[1] - self.view_rect.y

    def point_to_map(self, p):
        return p[0] + self.view_rect.x, p[1] + self.view_rect.y

    def _post_move_event(self):
        EventManager.post(self.move_event, cam=self)
コード例 #14
0
ファイル: graphics.py プロジェクト: ikn/wearhouse
 def _update (self, col, row, tile_type_id, tile_rect=None):
     if self._cache_graphic:
         if tile_type_id in self._cache:
             g = self._cache[tile_type_id]
         else:
             g = self._type_to_graphic(tile_type_id)
             self._cache[tile_type_id] = g
     else:
         g = self._type_to_graphic(tile_type_id)
     dest = self._orig_sfc
     if tile_rect is None:
         tile_rect = self.grid.tile_rect(col, row)
     if isinstance(g, (Graphic, pg.Surface, basestring)):
         g = (g,)
     if (g is not None and
         isinstance(g[0], (Graphic, pg.Surface, basestring))):
         sfc = g[0]
         if isinstance(sfc, basestring):
             sfc = self._load_img(sfc)
         elif isinstance(sfc, Graphic):
             sfc = sfc.surface
         if len(g) == 1:
             alignment = rect = None
         else:
             if isinstance(g[1], int) or len(g[1]) == 2:
                 alignment = g[1]
                 rect = None
             else:
                 alignment = None
                 rect = g[1]
             if len(g) == 3:
                 if rect is None:
                     rect = g[2]
                 else:
                     alignment = g[2]
         if alignment is None:
             alignment = 0
         if rect is None:
             rect = sfc.get_rect()
         # clip rect to fit in tile_rect
         dest_rect = Rect(rect)
         dest_rect.center = tile_rect.center
         fit = dest_rect.clip(tile_rect)
         rect = Rect(rect)
         rect.move_ip(fit.x - dest_rect.x, fit.y - dest_rect.y)
         rect.size = dest_rect.size
         # copy rect to tile_rect with alignment
         pos = gameutil.align_rect(rect, tile_rect, alignment)
         dest.blit(sfc, pos, rect)
     else:
         if g is None:
             g = (0, 0, 0, 0)
         # now we have a colour
         dest.fill(gameutil.normalise_colour(g), tile_rect)
     return tile_rect
コード例 #15
0
class Marquee(BaseAnimation):
    """
    This class animates a surface like a marquee.

    Nothing fancy, just scrolls it back and forth, takes a pause
    when returning to ground zero. This is just intended as a demo
    for testing the rendering.
    """
    smoothfactor = 0.1
    image = None

    def __init__(self,
                 rectstyle,
                 surface,
                 step_x=1,
                 fps=25,
                 init_sleep=-1,
                 bg_update=True,
                 bg_wait=False,
                 bg_redraw=False):

        BaseAnimation.__init__(self, rectstyle, fps, bg_update, bg_wait,
                               bg_redraw)

        self.image = surface
        self.step_x = step_x

        self.w, self.h = surface.get_size()
        self.animrect = Rect((0, 0, self.rect.width, self.rect.height))

    def draw(self):
        if self.w < self.rect.width:
            self.surface.blit(self.image, (0, 0))
            return

        ### move and blit
        self.animrect.move_ip(int(self.step_x * self.smoothfactor), 0)
        self.surface.blit(self.image, (0, 0), self.animrect)

        ### recalculate for next pass
        if self.smoothfactor < float(1):
            self.smoothfactor *= 1.1
            if self.smoothfactor > float(1):
                self.smoothfactor = 1

        # at bounds, change direction
        if self.animrect.right > self.w or self.animrect.left < 0:
            self.smoothfactor = 0.08
            if self.step_x < 0:
                self.animrect.left = 0
                self.sleep = True
            else:
                self.animrect.right = self.w

            self.step_x = -self.step_x
コード例 #16
0
ファイル: item_screen.py プロジェクト: bpa/renegade
 def cache_inventory(self):
   '''Making the assumption that we won't really have that many items'''
   self.inventory_text = []
   add = self.inventory_text.append
   text = self.render_text
   loc = Rect(375,50,0,0)
   for i in self.inventory:
       add(text(i.get_name(),loc))
       loc.move_ip(0,25)
   if len(self.inventory_text) == 0:
       add(text("Your inventory is empty",loc.move(30,0)))
コード例 #17
0
ファイル: item_screen.py プロジェクト: bpa/renegade
 def cache_stats(self):
   self.stats_text = []
   add = self.stats_text.append
   text = self.render_text
   hero = core.game.save_data.hero.get
   label = Rect( 30,50,120,0)
   value = Rect(160,50,  0,0)
   for s in self.character_fields:
       add(text(s.capitalize(),label,align='right'))
       add(text(str(hero(s)),value))
       label.move_ip(0,25)
       value.move_ip(0,25)
コード例 #18
0
ファイル: marquee.py プロジェクト: freevo/freevo1
class Marquee(BaseAnimation):
    """
    This class animates a surface like a marquee.

    Nothing fancy, just scrolls it back and forth, takes a pause
    when returning to ground zero. This is just intended as a demo
    for testing the rendering.
    """

    smoothfactor = 0.1
    image = None

    def __init__(
        self, rectstyle, surface, step_x=1, fps=25, init_sleep=-1, bg_update=True, bg_wait=False, bg_redraw=False
    ):

        BaseAnimation.__init__(self, rectstyle, fps, bg_update, bg_wait, bg_redraw)

        self.image = surface
        self.step_x = step_x

        self.w, self.h = surface.get_size()
        self.animrect = Rect((0, 0, self.rect.width, self.rect.height))

    def draw(self):
        if self.w < self.rect.width:
            self.surface.blit(self.image, (0, 0))
            return

        ### move and blit
        self.animrect.move_ip(int(self.step_x * self.smoothfactor), 0)
        self.surface.blit(self.image, (0, 0), self.animrect)

        ### recalculate for next pass
        if self.smoothfactor < float(1):
            self.smoothfactor *= 1.1
            if self.smoothfactor > float(1):
                self.smoothfactor = 1

        # at bounds, change direction
        if self.animrect.right > self.w or self.animrect.left < 0:
            self.smoothfactor = 0.08
            if self.step_x < 0:
                self.animrect.left = 0
                self.sleep = True
            else:
                self.animrect.right = self.w

            self.step_x = -self.step_x
コード例 #19
0
class Ball(Sprite):
    def __init__(self, init_pos, play_area_rect: Rect, *groups):
        super().__init__(*groups)

        self._play_area_rect = play_area_rect
        self._speed = [7, 7]  # (x, y)
        self._init_pos = init_pos

        self.rect = Rect(init_pos[0], init_pos[1], 5, 5)
        self.image = self._create_surface()

    def _create_surface(self):
        surface = pygame.Surface((self.rect.width, self.rect.height))
        surface.fill((44, 185, 214))  # Blue
        return surface

    @property
    def pos(self):
        return self.rect.topleft

    def reset(self):
        self.rect.topleft = self._init_pos
        self._speed = [7, 7]

    def move(self):
        self.rect.move_ip(self._speed)

    def check_bouncing(self, platform: Platform):
        if physics.collide_or_tangent(self, platform):
            physics.bounce_off_ip(self.rect, self._speed, platform.rect,
                                  platform._speed)
        physics.bounce_in_box(self.rect, self._speed, self._play_area_rect)

    def check_hit_brick(self, group_brick: pygame.sprite.RenderPlain) -> int:
        hit_bricks = pygame.sprite.spritecollide(self, group_brick, 1, \
            physics.collide_or_tangent)

        if len(hit_bricks) > 0:
            # XXX: Bad multiple collision bouncing handling
            if len(hit_bricks) == 2 and \
                hit_bricks[0].rect.y == hit_bricks[1].rect.y:
                combined_rect = hit_bricks[0].rect.union(hit_bricks[1].rect)
                physics.bounce_off_ip(self.rect, self._speed, combined_rect,
                                      (0, 0))
            else:
                physics.bounce_off_ip(self.rect, self._speed,
                                      hit_bricks[0].rect, (0, 0))

        return len(hit_bricks)
コード例 #20
0
class RoadPiece(object):
    def __init__(self, _img, _x, _y):
        self.img = _img
        self.bounds = Rect(_x, _y, self.img.get_width(), self.img.get_height())
        self.alive = True
        self.road_speed = DIFFICULTY

    def render(self, _screen):
        _screen.blit(self.img, self.bounds)

    def update(self, _dt):
        self.bounds.move_ip(0, self.road_speed)

        if self.bounds.top > HEIGHT:
            self.alive = False
コード例 #21
0
class Enemy(object):
    def __init__(self, _x, _img, _type):
        self.img = _img
        self.bounds = Rect(_x, -_img.get_height(), self.img.get_width(),
                           self.img.get_height())
        self.alive = True
        self.speed = DIFFICULTY - 2
        self.vx = 0
        self.type = _type

    def update(self, _dt):
        self.bounds.move_ip(self.vx, self.speed)

    def render(self, _screen):
        _screen.blit(self.img, self.bounds)
コード例 #22
0
ファイル: sprites.py プロジェクト: zalt00/Platformer
class Player0(BaseSprite):
    def __init__(self, coords, image):
        super(Player, self).__init__(coords, image)
        self.isfalling = False
        self.bottom_rect = None
        self.place(self.rect.left, self.rect.top)
        self.vector = np.zeros(2, dtype=np.int)

    def place(self, left, top):
        self.rect = Rect(left, top, self.rect.width, self.rect.height)
        t = self.rect.width * 8 // 25
        self.bottom_rect = Rect(left + t, self.rect.bottom, self.rect.width - 2 * t, 5)

    def update(self, dx, dy):
        super(Player, self).update(dx, dy)
        self.bottom_rect.move_ip(dx, dy)
コード例 #23
0
ファイル: Paddle.py プロジェクト: IsaacSpeed/neuralnetpong
class Paddle:
    background_color = (0, 0, 0)
    foreground_color = (255, 255, 255)

    def __init__(self, x, y, width, height, surface):
        self.rect = Rect(x, y, width, height)
        self.surface = surface

    def move(self, dx):
        self.undraw()
        self.rect.move_ip(dx, 0)
        self.draw()

    def draw(self):
        pygame.draw.rect(self.surface, Paddle.foreground_color, self.rect, 0)

    def undraw(self):
        pygame.draw.rect(self.surface, Paddle.background_color, self.rect, 0)
コード例 #24
0
ファイル: Player.py プロジェクト: HTMLProgrammer2001/pyGame
class Player:
    def __init__(self, x, y, speed=5):
        self.x = x
        self.y = y

        self.color = PLAYER_COLOR

        self.speed = 5
        self.dir = 0

        self.score = 0

        self.size = {'width': 3, 'height': 80}

        self.rect = Rect((x, y, self.size['width'], self.size['height']))

    def update(self):
        self.rect.move_ip(0, self.speed * self.dir)

        if (self.rect.y < 0):
            self.rect.y = 0

        if (self.rect.y > H - self.size['height']):
            self.rect.y = H - self.size['height']

    def stop(self):
        self.dir = 0

    def changeDir(self, up=False):
        if (up):
            self.dir = -1
        else:
            self.dir = 1

    def goal(self):
        self.score += 1

    def move(self, x, y):
        self.rect.x = x
        self.rect.y = y

    def draw(self, sc):
        draw.rect(sc, self.color, self.rect)
コード例 #25
0
ファイル: Ball.py プロジェクト: janwilamowski/pong
class Ball():

    def __init__(self, screen, x, y, speed = 4, angle = 45):
        self.screen = screen
        self.rect = Rect(x, y, 20, 20)
        self.moving = False
        self.moving_right = True
        self.moving_up = angle > 0
        self.speed = speed
        self.angle = math.pi * abs(angle)/180

    def is_offscreen(self):
        return not self.screen.get_rect().colliderect(self.rect)

    def step(self):
        if not self.moving: return

        dx = int(round(math.cos(self.angle) * self.speed))
        dy = int(round(math.sin(self.angle) * self.speed))

        if not self.moving_right:
            dx *= -1
        if self.moving_up:
            dy *= -1

        self.rect.move_ip(dx, dy)

        if self.rect.y < 0 or self.rect.y > 460:
            self.bounce_y()
            return True

        return False

    def bounce_x(self):
            self.moving_right = not self.moving_right

    def bounce_y(self):
            self.moving_up = not self.moving_up

    def display(self):
        pygame.draw.rect(self.screen, WHITE, self.rect)
コード例 #26
0
    def move(self, step, carrect: pygame.Rect, PictureArr, sc):
        """Изменение координат машинки"""
        if self.isLive:
            dx = self.v * math.cos(self.angle)*step
            dy = -self.v * math.sin(self.angle)*step
            self.dx_error += dx - int(dx)
            self.dy_error += dy - int(dy)
            self.x += dx
            self.y += dy
            if abs(self.dx_error)>=1:
                dx+=int(self.dx_error)
                self.dx_error-=int(self.dx_error)
            if abs(self.dy_error)>=1:
                dy+=int(self.dy_error)
                self.dy_error-=int(self.dy_error)

            carrect.move_ip(dx, dy)
            distance = []
            for laser in self.arr_laser:
                distance.append(laser.move(PictureArr, self, sc))
        return distance
コード例 #27
0
class Zombie:
    def __init__(self, size, position, _range):
        self.size = size
        self.position = position
        self.xposition = (position[0] + size[0] // 2), (position[1] +
                                                        size[1] // 2)
        self._range = _range
        self.rect = Rect(self.position, self.size)

    def findAngle(self, oposition, _range):
        angles = [tan(2 * pi / 12 * i) for i in range(12)]
        tangle = aprox(self.xposition[1] - oposition[1]) / aprox(
            self.xposition[0] -
            oposition[0]) if self.xposition[0] != oposition[0] else False

        if tangle == False and type(tangle) == bool: return False
        return (min(angles, key=lambda i: (tangle - i)**2))

    def move(self, oposition):
        ang = self.findAngle(oposition, self._range)
        #if ang == 0: print("ta indo")

        if type(ang) == bool:

            if oposition[1] - self.xposition[1] > 0:
                self.position[1] += self._range
                self.rect.move_ip(0, self._range)
            elif oposition[1] - self.xposition[1] < 0:
                self.position[1] -= self._range
                self.rect.move_ip(0, -self._range)
            self.xposition = (self.position[0] +
                              self.size[0] // 2), (self.position[1] +
                                                   self.size[1] // 2)
        else:
            #print(ang)
            if oposition[0] - self.xposition[0] > 0:
                self.position = [
                    self.position[0] + self._range,
                    (round(ang * (self._range)) + self.position[1])
                ]
                self.rect.move_ip(self._range, round(ang * (self._range)))
            elif oposition[0] - self.xposition[0] < 0:
                self.position = [
                    self.position[0] - self._range,
                    (round(ang * (-self._range)) + self.position[1])
                ]
                self.rect.move_ip(-self._range, round(ang * (-self._range)))
            self.xposition = (self.position[0] +
                              self.size[0] // 2), (self.position[1] +
                                                   self.size[1] // 2)
コード例 #28
0
class PowerUp(object):
    def __init__(self, _x, _y, _nombre):
        self.bounds = Rect(_x, _y, 0, 0)
        self.animaciones = GestorAnimaciones()

        self.bounds.width, self.bounds.height = self.animaciones.añadir_animacion(
            _nombre, self.animaciones.cargar_frames("powerups/" + _nombre, 6),
            200, 0)
        self.temporizador_movimiento = Timer(10)
        self.tipo = _nombre

    def dibujar(self, _pantalla):
        self.animaciones.render(_pantalla, self.bounds)

    def actualizar(self, _dt):
        self.animaciones.update(_dt)
        self.temporizador_movimiento.update(_dt)
        self.mover()

    def mover(self):
        if self.temporizador_movimiento.tick:
            self.bounds.move_ip(0, 1)
コード例 #29
0
ファイル: Ball.py プロジェクト: HTMLProgrammer2001/pyGame
class Ball:
    def __init__(self, x, y, speed=3):
        self.color = BALL_COLOR

        self.isMove = True
        self.speed = speed

        self.size = 10
        self.rect = Rect((x, y, self.size, self.size))

        self.dx = 1 if random.random() < 0.5 else -1
        self.dy = 1 if random.random() < 0.5 else -1

    def update(self):
        self.rect.move_ip(self.speed * self.dx, self.speed * self.dy)

        if (self.rect.y < 0):
            self.rect.y = 0
            self.dy = 1

        if (self.rect.y + self.size > H):
            self.rect.y = H - self.size
            self.dy = -1

        self.speed += 0.001

    def stop(self):
        self.isMove = False

    def move(self):
        self.isMove = True

    def changeDir(self, dx=None, dy=None):
        self.dx = dx if dx is not None else self.dx
        self.dy = dy if dy is not None else self.dy

    def draw(self, sc):
        draw.circle(sc, self.color, self.rect.center, self.size)
コード例 #30
0
    def callback(event_object):
        rotation_center = grid_centroid(well_offset, grid_spacing,
                                        tile.sprites())
        for brick in iter(tile):
            rotated_vertices = []
            for vertexname in [
                    'topleft', 'topright', 'bottomleft', 'bottomright'
            ]:
                vertex = getattr(brick.rect, vertexname)
                rvertex = rotator(rotation_center, vertex)
                rotated_vertices.append(rvertex)

            coord1, coord2 = zip(*rotated_vertices)
            left, top = min(coord1), min(coord2)
            rotated_rect = Rect((left, top), (grid_spacing, grid_spacing))

            # prevent tile from creeping upwards with repeated rotations
            rotated_rect.move_ip((0, grid_spacing))
            brick.rect = rotated_rect

        if heap.did_collide(
            (0, 0))(tile):  # ensure that tiles don't rotate into a heap
            for brick in iter(tile):
                brick.rect.move_ip((0, -grid_spacing))
コード例 #31
0
class Player(Rect):
    size_x = 20
    size_y = 100
    move_step = 6

    def __init__(self, screen, color, pos_x, pos_y):
        self.screen = screen
        self.color = color
        self.rect = Rect(pos_x, pos_y, self.size_x, self.size_y)
        self.move_step = self.move_step
        self.racket = draw_rect(self.screen, self.color, self.rect)

    def draw_racket(self):
        self.racket = draw_rect(self.screen, self.color, self.rect)

    def move_down(self):
        ic()
        if (self.rect.top < self.screen.get_height() - self.rect.height):
            self.rect.move_ip(0, self.move_step)

    def move_up(self):
        ic()
        if (self.rect.top > 0):
            self.rect.move_ip(0, -self.move_step)
コード例 #32
0
ファイル: map.py プロジェクト: ceronman/twsitemall
class Map:
	TILE_SIZE = (30, 30)
	def __init__(self, view_size):
		self.view_rect = Rect((0,0), view_size)
		self.update_rects = []
		self.previous_rects = []
		self.actual_rects = []
		self.group = MapGroup(self)
		self.special_block_group = Group()
		self.bullet_group = Group()
		self.enemies_group = Group()
		self.items_group = Group()
		self.enemy_bullet_group = Group()
		self.special_items_group = Group()
		self.main_character = TMan(self, self.group)
		
		self.got_key = False
		self.won = False
		self.finish = False
		
	def try_won(self):
		if self.got_key:
			self.won = True
		
	def load(self, map_name):
		tile1 = data.load_image('tile-solid-1.png')
		tile2 = data.load_image('tile-solid-2.png')
		tilenull = data.load_image('tile-null.png')
		
		mapfile = open(data.filepath('maps', map_name))
		
		self.name = mapfile.readline().strip()
		
		self.time = float(mapfile.readline().strip())
		
		bg = mapfile.readline().strip()
		self.background = data.load_image('background-%s.png' % bg)

		def append_tile(code, tilex, tiley):
			def add(c, tile,*args):
				obj = c(self, *args)
				x, y = self.tile_center(tilex, tiley)
				obj.put(x, y)
				self.tiles.append(tile)

			if code == '1':
				self.tiles.append(tile1)
			elif code == '2':
				self.tiles.append(tile2)
			elif code == 'S':
				add(SpecialTile, 0, len(self.tiles))
			elif code == 'a':
				add(Fly, None, EllipsePath(20, 20, 10), random.randint(25, 75))
			elif code == 'b':
				add(SpikeSpawn, None, 4, 50)
			elif code == 'c':
				add(Defender, None, HorizontalLinePath(100, 'bounce'), random.randint(50, 100))
			elif code == 't':
				add(TwisterUpItem, None)
			elif code == 'L':
				add(LifeButterflyItem, None)
			elif code == 'l':
				add(LifeTankItem, None)
			elif code == 'z':
				add(KeyItem, None)
			elif code == 'Z':
				add(LockItem, None)
			elif code == 'X':
				self.tiles.append(None)
				x, y = self.tile_center(tilex, tiley)
				self.main_character.put(x, y)
			else:
				self.tiles.append(None)
	
		
		height = 0
		width = 0
		self.tiles = []
		for line in mapfile:
			line = line.strip()
			width = len(line)
			for char, i in zip(line, range(len(line))):
				append_tile(char, i, height)
			height += 1

		self.width = width
		self.height = height
		
		tw, th = self.TILE_SIZE
		right, bottom = tw*width, th*height
		
		self.rect = Rect((0, 0), (right, bottom))
		
	def get_time(self):
		return '%d:%d' % (int(self.time/60), int(self.time%60))
		
	def get_tile(self, x, y): 
		if x<0 or y<0 or x>=self.width or y>=self.height:
			return None
		return self.tiles[y*self.width+x]
		
	def pixel_to_tile(self, x, y):
		tw, th = self.TILE_SIZE
		tile_x = x / tw
		tile_y = y / th
		return (tile_x, tile_y)
		
	def tile_to_pixel(self, tilex, tiley):
		tw, th = self.TILE_SIZE
		return tilex * tw, tiley * th
		
	def tile_center(self, tilex, tiley):
		tw, th = self.TILE_SIZE
		x, y = self.tile_to_pixel(tilex, tiley)
		return (x+tw/2, y+th/2)
		
	def tile_rect(self, tilex, tiley):
		x, y = self.tile_to_pixel(tilex, tiley)
		return Rect((x, y), self.TILE_SIZE)
		
	def tile_at(self, x, y):
		tile_x, tile_y = self.pixel_to_tile(x, y)
		return self.get_tile(tile_x, tile_y), self.tile_rect(tile_x, tile_y)
	
	def scroll(self):
		spritex = self.main_character.rect.centerx
		spritey = self.main_character.rect.centery
		width_space = self.view_rect.width * 1 / 3
		height_space = self.view_rect.height * 1 / 3
		
		scroll_right_point = self.view_rect.right - width_space
		if spritex > scroll_right_point:
			self.move_view(spritex - scroll_right_point, 0)
			
		scroll_left_point = self.view_rect.left + width_space
		if spritex < scroll_left_point:
			self.move_view(spritex - scroll_left_point, 0)
			
		scroll_top_point = self.view_rect.top + height_space
		if spritey < scroll_top_point:
			self.move_view(0, spritey - scroll_top_point)
			
		scroll_bottom_point = self.view_rect.bottom - height_space
		if spritey > scroll_bottom_point:
			self.move_view(0, spritey - scroll_bottom_point)

	def update(self, *args):
		self.group.update(*args)
		self.scroll()
		self.check_collisions()
		self.time = self.time - (1.0/FPS)
		self.check_status()
		
	def check_status(self):
		self.finish = self.main_character.death() or self.won or self.time <= 0

	def check_collisions(self):
		tman = self.main_character
		pygame.sprite.groupcollide(self.bullet_group, self.enemies_group, True, True)
		pygame.sprite.groupcollide(self.special_block_group, self.bullet_group, True, True)
		pygame.sprite.groupcollide(self.special_block_group, self.enemy_bullet_group, False, True)
		pygame.sprite.groupcollide(self.enemy_bullet_group, self.bullet_group, True, True)
		enemies = pygame.sprite.spritecollide(tman, self.enemies_group, not tman.blinking)
		bullets = pygame.sprite.spritecollide(tman, self.enemy_bullet_group, not tman.blinking)
		items = pygame.sprite.spritecollide(tman, self.items_group, True)
		special_items = pygame.sprite.spritecollide(tman, self.special_items_group, True)
		
		for enemy in enemies:
			tman.enemy_touched(enemy)
		
		for bullet in bullets:
			tman.bullet_touched()
			
		for item in items:
			tman.item_touched(item)
			
		for item in special_items:
			item.use()
	
	
	def draw(self, surface, draw_position):
		tw, th = self.TILE_SIZE
		tile_x1, tile_y1 = self.pixel_to_tile(self.view_rect.left, self.view_rect.top)
		tile_x2, tile_y2 = self.pixel_to_tile(self.view_rect.right, self.view_rect.bottom)
		
		dx, dy = draw_position
		
		clip_rect = Rect(draw_position, (self.view_rect.width, self.view_rect.height))
		surface.set_clip(clip_rect)
				
		self.actual_rects = []
		self.update_rects = self.previous_rects
		
		if len(self.previous_rects) == 0:
			self.previous_rects.append(clip_rect)
		
		for rect in self.previous_rects:
			area = rect.move(-dx, -dy)
			surface.blit(self.background, rect, area)

		for x in range(tile_x1, tile_x2 + 1):
			for y in range(tile_y1, tile_y2 + 1):
				
				pos_x = dx + x * tw - self.view_rect.left
				pos_y = dy + y * th - self.view_rect.top
				image = self.get_tile(x, y)
				if image is not None and image != 0:
					surface.blit(image, (pos_x, pos_y))
					self.actual_rects.append(image.get_rect().move(pos_x, pos_y))
					
		self.actual_rects += self.group.draw(surface, draw_position)
					
		surface.set_clip(None)
		
		self.update_rects += self.actual_rects
		self.previous_rects = self.actual_rects
		
	def move_view(self, x, y):
		self.view_rect.move_ip(x, y)
		
		self.view_rect.top = max(self.rect.top, self.view_rect.top)
		self.view_rect.left = max(self.rect.left, self.view_rect.left)
		self.view_rect.right = min(self.rect.right, self.view_rect.right)
		self.view_rect.bottom = min(self.rect.bottom, self.view_rect.bottom)
		
	def goto_bottom(self):
		self.view_rect.bottom = self.rect.bottom
		
	def goto_left(self):
		self.view_rect.left = self.rect.left
		
	def goto_right(self):
		self.view_rect.right = self.rect.right

	def goto_top(self):
		self.view_rect.right = self.rect.right
		
	def set_main_character(self, sprite):
		self.main_character = sprite
コード例 #33
0
class IsometricBufferedRenderer(BufferedRenderer):
    """ TEST ISOMETRIC

    here be dragons.  lots of odd, untested, and unoptimised stuff.

    - coalescing of surfaces is not supported
    - drawing may have depth sorting issues
    """
    def _draw_surfaces(self, surface, rect, surfaces):
        if surfaces is not None:
            [(surface.blit(i[0], i[1]), i[2]) for i in surfaces]

    def _initialize_buffers(self, view_size):
        """ Create the buffers to cache tile drawing

        :param view_size: (int, int): size of the draw area
        :return: None
        """
        import math
        from pygame import Rect

        tw, th = self.data.tile_size
        mw, mh = self.data.map_size
        buffer_tile_width = int(math.ceil(view_size[0] / tw) + 2) * 2
        buffer_tile_height = int(math.ceil(view_size[1] / th) + 2) * 2
        buffer_pixel_size = buffer_tile_width * tw, buffer_tile_height * th

        self.map_rect = Rect(0, 0, mw * tw, mh * th)
        self.view_rect.size = view_size
        self._tile_view = Rect(0, 0, buffer_tile_width, buffer_tile_height)
        self._redraw_cutoff = 1  # TODO: optimize this value
        self._create_buffers(view_size, buffer_pixel_size)
        self._half_width = view_size[0] // 2
        self._half_height = view_size[1] // 2
        self._x_offset = 0
        self._y_offset = 0

        self.redraw_tiles()

    def _flush_tile_queue(self):
        """ Blits (x, y, layer) tuples to buffer from iterator
        """
        iterator = self._tile_queue
        surface_blit = self._buffer.blit
        map_get = self._animation_map.get

        bw, bh = self._buffer.get_size()
        bw /= 2

        tw, th = self.data.tile_size
        twh = tw // 2
        thh = th // 2

        for x, y, l, tile, gid in iterator:
            tile = map_get(gid, tile)
            x -= self._tile_view.left
            y -= self._tile_view.top

            # iso => cart
            iso_x = ((x - y) * twh) + bw
            iso_y = ((x + y) * thh)
            surface_blit(tile, (iso_x, iso_y))

    def center(self, coords):
        """ center the map on a "map pixel"
        """
        x, y = [round(i, 0) for i in coords]
        self.view_rect.center = x, y

        tw, th = self.data.tile_size

        left, ox = divmod(x, tw)
        top, oy = divmod(y, th)

        vec = int(ox / 2), int(oy)

        iso = vector2_to_iso(vec)
        self._x_offset = iso[0]
        self._y_offset = iso[1]

        print(self._tile_view.size)
        print(self._buffer.get_size())

        # center the buffer on the screen
        self._x_offset += (self._buffer.get_width() - self.view_rect.width) // 2
        self._y_offset += (self._buffer.get_height() - self.view_rect.height) // 4

        # adjust the view if the view has changed without a redraw
        dx = int(left - self._tile_view.left)
        dy = int(top - self._tile_view.top)
        view_change = max(abs(dx), abs(dy))

        # force redraw every time: edge queuing not supported yet
        self._redraw_cutoff = 0

        if view_change and (view_change <= self._redraw_cutoff):
            self._buffer.scroll(-dx * tw, -dy * th)
            self._tile_view.move_ip(dx, dy)
            self._queue_edge_tiles(dx, dy)
            self._flush_tile_queue()

        elif view_change > self._redraw_cutoff:
            # logger.info('scrolling too quickly.  redraw forced')
            self._tile_view.move_ip(dx, dy)
            self.redraw_tiles()
コード例 #34
0
class Ball(Sprite):
    def __init__(self, init_pos, play_area_rect: Rect, enable_slide_ball: bool, *groups):
        super().__init__(*groups)

        self._play_area_rect = play_area_rect
        self._do_slide_ball = enable_slide_ball
        self._init_pos = init_pos
        self._speed = [0, 0]

        self.hit_platform_times = 0

        self.rect = Rect(*self._init_pos, 5, 5)
        self.image = self._create_surface()

        # For additional collision checking
        self._last_pos = self.rect.copy()

    def _create_surface(self):
        surface = pygame.Surface((self.rect.width, self.rect.height))
        surface.fill((44, 185, 214)) # Blue
        return surface

    @property
    def pos(self):
        return self.rect.topleft

    def reset(self):
        self.hit_platform_times = 0
        self.rect.topleft = self._init_pos
        self._speed = [0, 0]

    def stick_on_platform(self, platform_centerx):
        self.rect.centerx = platform_centerx

    def serve(self, platform_action: PlatformAction):
        if platform_action == PlatformAction.SERVE_TO_LEFT:
            self._speed = [-7, -7]
        elif platform_action == PlatformAction.SERVE_TO_RIGHT:
            self._speed = [7, -7]

    def move(self):
        self._last_pos.topleft = self.rect.topleft
        self.rect.move_ip(self._speed)

    def check_bouncing(self, platform: Platform):
        if (physics.collide_or_contact(self, platform) or
            self._platform_additional_check(platform)):
            self.hit_platform_times += 1

            rect_after_bounce, speed_after_bounce = physics.bounce_off(
                self.rect, self._speed, platform.rect, platform._speed)
            # Check slicing ball when the ball goes up after bouncing (not game over)
            if self._do_slide_ball and speed_after_bounce[1] < 0:
                speed_after_bounce[0] = self._slice_ball(self._speed[0], platform._speed[0])

            self.rect = rect_after_bounce
            self._speed = speed_after_bounce

        if physics.rect_break_or_contact_box(self.rect, self._play_area_rect):
            physics.bounce_in_box_ip(self.rect, self._speed, self._play_area_rect)

    def _platform_additional_check(self, platform: Platform):
        """
        The additional checking for the condition that the ball passes the corner of the platform
        """
        if self.rect.bottom > platform.rect.top:
            routine_a = (Vector2(self._last_pos.bottomleft), Vector2(self.rect.bottomleft))
            routine_b = (Vector2(self._last_pos.bottomright), Vector2(self.rect.bottomright))

            return (physics.rect_collideline(platform.rect, routine_a) or
                    physics.rect_collideline(platform.rect, routine_b))

        return False

    def _slice_ball(self, ball_speed_x, platform_speed_x):
        """
        Check if the platform slices the ball, and modify the ball speed.

        @return The new x speed of the ball after slicing
        """
        # If the platform doesn't move, bounce normally.
        if platform_speed_x == 0:
            return 7 if ball_speed_x > 0 else -7
        # If the platform moves at the same direction as the ball moving,
        # speed up the ball.
        elif ball_speed_x * platform_speed_x > 0:
            return 10 if ball_speed_x > 0 else -10
        # If the platform moves at the opposite direction against the ball moving,
        # hit the ball back.
        else:
            return -7 if ball_speed_x > 0 else 7

    def check_hit_brick(self, group_brick: pygame.sprite.RenderPlain) -> int:
        """
        Check if the ball hits bricks in the `group_brick`.
        The hit bricks will be removed from `group_brick`, but the alive hard brick will not.
        However, if the ball speed is high, the hard brick will be removed with only one hit.

        @param group_brick The sprite group containing bricks
        @return The number of destroyed bricks
        """
        hit_bricks = pygame.sprite.spritecollide(self, group_brick, 1,
            physics.collide_or_contact)
        num_of_destroyed_brick = len(hit_bricks)

        if num_of_destroyed_brick > 0:
            # XXX: Bad multiple collision bouncing handling
            if (num_of_destroyed_brick == 2 and
                (hit_bricks[0].rect.y == hit_bricks[1].rect.y or
                 hit_bricks[0].rect.x == hit_bricks[1].rect.x)):
                combined_rect = hit_bricks[0].rect.union(hit_bricks[1].rect)
                physics.bounce_off_ip(self.rect, self._speed, combined_rect, (0, 0))
            else:
                physics.bounce_off_ip(self.rect, self._speed, hit_bricks[0].rect, (0, 0))

            if abs(self._speed[0]) == 7:
                for brick in hit_bricks:
                    if isinstance(brick, HardBrick) and brick.hit():
                        group_brick.add((brick,))
                        num_of_destroyed_brick -= 1

        return num_of_destroyed_brick
コード例 #35
0
ファイル: cMsg.py プロジェクト: kxtells/Maze
class cMsg():
	HOLD_TIME = 2
	
	def __init__(self,string,window):
		font.init()
		self.text = string
        	self.myfont = font.SysFont("Arial", 20)
        	self.render_font = self.myfont.render(string, 1, C.black)
		w = self.render_font.get_width()
		h = self.render_font.get_height()
		self.winh = window.get_height()
		self.rect = Rect(0,self.winh,w,h)
		
		self.movein = False
		self.moveout = False
		self.hold = False
		self.hold_start = 0
	
	def draw(self,window):
		"""
			Draw the current message
		"""
		draw.rect(window, C.white, self.rect)
        	window.blit(self.render_font, (self.rect.x, self.rect.y))

	def update_logic(self,window):
		"""
			Movein and Moveout logic movement
		"""
		if self.movein:
			fh = self.render_font.get_height()
			self.rect.move_ip(0,-1)
			if self.rect.y <= window.get_height()-fh:
				self.move_hold()

		elif self.moveout:
			self.rect.move_ip(0,1)
			if self.rect.y > window.get_height():
				self.move_stop()
		elif self.hold:
			self.update_hold()

	def update_hold(self):
		"""
			Controls how much time the message must stay
			between movein state and moveout state
		"""
		ctime = time.time()
		if (ctime - self.hold_start) > self.HOLD_TIME:
			self.move_out()

	#
	# Flag control for movement
	#
	def move_in(self):
		self.movein = True
		self.moveout = False
		self.hold = False

	def move_out(self):
		self.movein = False
		self.moveout = True
		self.hold = False
	
	def move_hold(self):
		self.movein = False
		self.moveout = False
		self.hold = True
		self.hold_start = time.time()

	def move_stop(self):
		self.movein = False
		self.moveout = False
		self.hold = False

	def set_text(self,string,movein=True):
		"""
			Set a new text for the message.
			Additionally it shows the message. the flag movein controls that True=>Move in, False=> simply set text
		"""
		self.text = string
        	self.render_font = self.myfont.render(string, 1, C.black) 
		w = self.render_font.get_width()
		h = self.render_font.get_height()
		self.rect = Rect(0,self.winh,w,h)

		if movein: self.move_in()
コード例 #36
0
ファイル: cPlayer.py プロジェクト: kxtells/Maze
class cPlayer():
	mx = 0
	my = 0
	speed = 4
	sounds = True

	def __init__(self,left,top,width,height):
		self.startx = left
		self.starty = top
		self.width = width
		self.height = height
		self.rect = Rect(left, top, width, height)

		self.path = [self.rect.center]
		self.pathlist = []

	def update_logic(self):
		self.rect.move_ip(self.mx,self.my)

        def move_down(self):
		self.my = self.speed
		self.mx = 0
		self.add_point_to_path(self.rect.center)
		if self.sounds: SOUNDS.play_fx(11)
 
        def move_up(self):
 		self.my = -self.speed
		self.mx = 0               
		self.add_point_to_path(self.rect.center)
		if self.sounds: SOUNDS.play_fx(11)
	
	def move_left(self):
 		self.my = 0
		self.mx = -self.speed               
		self.add_point_to_path(self.rect.center)
		if self.sounds: SOUNDS.play_fx(11)

	def move_right(self):
 		self.my = 0
		self.mx = self.speed 
		self.add_point_to_path(self.rect.center)
		if self.sounds: SOUNDS.play_fx(11)

	def stop_moving(self):
		self.my = 0
		self.mx = 0
	
	def set_to_start(self):
		self.stop_moving()
		
		self.path.append(self.rect.center)
		
		self.rect = Rect(self.startx,self.starty,self.width,self.height)

		self.move_path_to_pathlist()

	def add_point_to_path(self,point):
		self.path.append(point)

	def move_path_to_pathlist(self):
		self.pathlist.append(self.path)
		self.path = [self.rect.center]

	def clear_pathlist(self):
		self.pathlist = []

	def random_speed(self):
		self.speed = random.uniform(2,5)

	def set_speed(self,speed):
		self.speed = speed

	def toggle_sounds(self):
		if self.sounds: self.sounds = False
		else: self.sounds = True
		return self.sounds
コード例 #37
0
class Player():
    def __init__(self, screen, x, y):
        self.screen = screen
        self.rect = Rect(x, y, 20, 80)

    def move_up(self):
        if self.rect.y > 0:
            self.rect.move_ip(0, -4)

    def move_down(self):
        if self.rect.y < 400:
            self.rect.move_ip(0, 4)

    def display(self):
        pygame.draw.rect(self.screen, WHITE, self.rect)

    def check_contact(self, ball):
        """
        Checks whether this player has contact with the given ball. If so, will bounce the ball
        in the appropriate direction.

        Uses PyGame's overlap functionality which is convenient but somewhat imprecise.

        @return bool whether there's a contact between player and ball
        """
        if not self.overlaps(ball):
            return False

        if ball.moving_right:
            x_diff = abs(ball.rect.right - self.rect.left)
        else:
            x_diff = abs(ball.rect.left - self.rect.right)

        if ball.moving_up:
            y_diff = abs(ball.rect.top - self.rect.bottom)
        else:
            y_diff = abs(ball.rect.bottom - self.rect.top)

        if x_diff < y_diff and ball.rect.x:
            ball.bounce_x()
        elif x_diff > y_diff:
            ball.bounce_y()
        else:
            # corner bounce
            ball.bounce_x()
            ball.bounce_y()

        return True

    def overlaps(self, other):
        return self.rect.colliderect(other.rect)

    def ai_move(self, ball):
        if not ball.moving: return

        if ball.moving_right:
            # go back to center
            target_y = 200
        else:
            # follow ball
            target_y = ball.rect.y - 30

        if self.rect.y < target_y:
            self.move_down()
        elif self.rect.y > target_y:
            self.move_up()
コード例 #38
0
ファイル: gui_elements.py プロジェクト: tborisova/hackfmi4
class InputBox(Rect):

    PADDING = 3
    HANDLED_KEYS = set(
        [
            pygame.K_DELETE,
            pygame.K_BACKSPACE,
            pygame.K_LEFT,
            pygame.K_RIGHT]).union(
        range(
            pygame.K_a,
            pygame.K_z +
            1)).union(
        range(
            pygame.K_0,
            pygame.K_9 +
            1))

    def __init__(self, dimensions, pos, text="", text_colour=(0, 0, 0),
                 text_font=(None, 50), bg_colour=(255, 255, 255),
                 frame_colour=(0, 0, 0), frame_size=1):
        Rect.__init__(self, (pos[0] - dimensions[0] / 2,
                             pos[1] - dimensions[1] / 2), dimensions)
        self.text = text
        self.text_colour = text_colour
        self.text_font = text_font
        self.create_char_avatars()
        self.bg_colour = bg_colour
        self.frame_colour = frame_colour
        self.frame_size = frame_size
        self.input_cursor = Rect((self.left, self.top + InputBox.PADDING),
                                 (2, (self.height - 2 * InputBox.PADDING)))
        self.put_cursor(self.right)
        self.clicked = False
        self.state = "normal"
        self.char_limit = None
        self.handled_chars = InputBox.HANDLED_KEYS

    def draw(self, surface):
        if self.bg_colour is not None:
            pygame.draw.rect(surface, self.bg_colour, self, 0)
        if self.frame_colour is not None:
            pygame.draw.rect(surface, self.frame_colour, self, self.frame_size)
        shift = 0
        for char in self.char_avatars:
            surface.blit(char, (
                self.left + InputBox.PADDING + shift,
                self.centery - char.get_height() / 2))
            shift += char.get_width()
        if self.state == "active":
            pygame.draw.rect(surface, self.text_colour, self.input_cursor)

    def create_char_avatars(self):
        self.char_avatars = []
        for char in self.text:
            char_avatar = pygame.font.Font(*self.text_font).render(
                char, 20, self.text_colour)
            if char_avatar.get_height() > self.y:
                char_avatar = pygame.transform.scale(
                    char_avatar, (char_avatar.get_width(), self.height))
            self.char_avatars.append(char_avatar)

    def put_cursor(self, cursor_x):
        error = cursor_x - (self.left + InputBox.PADDING)
        self.cursor_index = len(self.char_avatars)
        for index, char in enumerate(self.char_avatars):
            if error < char.get_width() / 2:
                self.cursor_index = index
                break
            error -= char.get_width()
        cursor_x -= error
        self.input_cursor.move_ip(cursor_x - self.input_cursor.left, 0)

    def update_state(self, cursor_pos, event):
        cursor_on_inputbox = self.collidepoint(cursor_pos)
        if self.state is "active":
            if not cursor_on_inputbox:
                if event:
                    self.state = "normal"
                CURSORS["arrow"]()
            if cursor_on_inputbox:
                if event:
                    self.put_cursor(cursor_pos[0])
                CURSORS["textmarker"]()
        elif self.state is "hover":
            if event and cursor_on_inputbox:
                self.state = "active"
                self.put_cursor(cursor_pos[0])
            elif not cursor_on_inputbox:
                self.state = "normal"
                CURSORS["arrow"]()
        else:
            if event and cursor_on_inputbox:
                self.state = "active"
                CURSORS["textmarker"]()
                self.put_cursor(cursor_pos[0])
            elif cursor_on_inputbox:
                self.state = "hover"
                CURSORS["textmarker"]()

    def shift_cursor(self, positions):
        direction = int(abs(positions) / positions)
        side = 1
        if direction == 1:
            side = 0
        for index in range(0, abs(positions)):
            self.input_cursor.move_ip((direction * self.char_avatars[
                self.cursor_index - side].get_width()), 0)
            self.cursor_index += direction

    def handle_key_event(self, key):
        if self.state != "active":
            pass
        elif key == pygame.K_BACKSPACE and self.cursor_index:
            self.shift_cursor(-1)
            self.text = self.text[:self.cursor_index] + \
                self.text[1 + self.cursor_index:]
            self.create_char_avatars()
        elif key == pygame.K_DELETE and self.cursor_index < len(
                self.char_avatars):
            self.text = self.text[:self.cursor_index] + \
                self.text[self.cursor_index + 1:]
            self.create_char_avatars()
        elif key in self.handled_chars:
            if self.char_limit is None or self.char_limit > len(self.text):
                self.text = self.text[:self.cursor_index] + chr(key) +\
                    self.text[self.cursor_index:]
                self.create_char_avatars()
                self.shift_cursor(1)
        elif key == pygame.K_LEFT and self.cursor_index:
            self.shift_cursor(-1)

        elif key == pygame.K_RIGHT and self.cursor_index < len(
                self.char_avatars):
            self.shift_cursor(1)
コード例 #39
0
ファイル: isometric.py プロジェクト: TBPanther/LKQ
class IsometricBufferedRenderer(BufferedRenderer):
    """ TEST ISOMETRIC

    here be dragons.  lots of odd, untested, and unoptimised stuff.

    - coalescing of surfaces is not supported
    - drawing may have depth sorting issues
    """
    def _draw_surfaces(self, surface, rect, surfaces):
        if surfaces is not None:
            [(surface.blit(i[0], i[1]), i[2]) for i in surfaces]

    def _initialize_buffers(self, view_size):
        """ Create the buffers to cache tile drawing

        :param view_size: (int, int): size of the draw area
        :return: None
        """
        import math
        from pygame import Rect

        tw, th = self.data.tile_size
        mw, mh = self.data.map_size
        buffer_tile_width = int(math.ceil(view_size[0] / tw) + 2) * 2
        buffer_tile_height = int(math.ceil(view_size[1] / th) + 2) * 2
        buffer_pixel_size = buffer_tile_width * tw, buffer_tile_height * th

        self.map_rect = Rect(0, 0, mw * tw, mh * th)
        self.view_rect.size = view_size
        self._tile_view = Rect(0, 0, buffer_tile_width, buffer_tile_height)
        self._redraw_cutoff = 1  # TODO: optimize this value
        self._create_buffers(view_size, buffer_pixel_size)
        self._half_width = view_size[0] // 2
        self._half_height = view_size[1] // 2
        self._x_offset = 0
        self._y_offset = 0

        self.redraw_tiles()

    def _flush_tile_queue(self):
        """ Blits (x, y, layer) tuples to buffer from iterator
        """
        iterator = self._tile_queue
        surface_blit = self._buffer.blit
        map_get = self._animation_map.get

        bw, bh = self._buffer.get_size()
        bw /= 2

        tw, th = self.data.tile_size
        twh = tw // 2
        thh = th // 2

        for x, y, l, tile, gid in iterator:
            tile = map_get(gid, tile)
            x -= self._tile_view.left
            y -= self._tile_view.top

            # iso => cart
            iso_x = ((x - y) * twh) + bw
            iso_y = ((x + y) * thh)
            surface_blit(tile, (iso_x, iso_y))

    def center(self, coords):
        """ center the map on a "map pixel"
        """
        x, y = [round(i, 0) for i in coords]
        self.view_rect.center = x, y

        tw, th = self.data.tile_size

        left, ox = divmod(x, tw)
        top, oy = divmod(y, th)

        vec = int(ox / 2), int(oy)

        iso = vector2_to_iso(vec)
        self._x_offset = iso[0]
        self._y_offset = iso[1]

        print(self._tile_view.size)
        print(self._buffer.get_size())

        # center the buffer on the screen
        self._x_offset += (self._buffer.get_width() -
                           self.view_rect.width) // 2
        self._y_offset += (self._buffer.get_height() -
                           self.view_rect.height) // 4

        # adjust the view if the view has changed without a redraw
        dx = int(left - self._tile_view.left)
        dy = int(top - self._tile_view.top)
        view_change = max(abs(dx), abs(dy))

        # force redraw every time: edge queuing not supported yet
        self._redraw_cutoff = 0

        if view_change and (view_change <= self._redraw_cutoff):
            self._buffer.scroll(-dx * tw, -dy * th)
            self._tile_view.move_ip(dx, dy)
            self._queue_edge_tiles(dx, dy)
            self._flush_tile_queue()

        elif view_change > self._redraw_cutoff:
            # logger.info('scrolling too quickly.  redraw forced')
            self._tile_view.move_ip(dx, dy)
            self.redraw_tiles()
コード例 #40
0
ファイル: SpeciesInfoBox.py プロジェクト: beniamin666/py-evo
class SpeciesInfoBox(object):

    def __init__(self, ui, surface, font, x, y, species):
        self.ui = ui
        self.surface = surface
        self.species = species
        self.font = font
        self.x = x
        self.y = y
        self.padding = (10, 10, 10, 10)
        self.line_height = 20
        self.width = info_panel_config.width - 1
        self.height = 300
        self.color = (255, 255, 255)
        self.mutated_param_color = (100, 255, 100)
        self.labels = None
        self.border_rect = Rect(self.x, self.y, self.width, self.height)
        self.border_width = 1
        self.border_color = (255, 255, 255)
        self.bg_rect = Rect(self.x + self.border_width, self.y + self.border_width,
                            self.width - self.border_width * 2, self.height - self.border_width * 2)
        self.bg_color = (30, 30, 30)
        self.y_offset = 0
        self._generate_labels()

    def _generate_labels(self):
        self.labels = []
        self.y_offset = self.y + self.padding[0]
        self._add_label('Type: %s' % str(self.species.life_obj.type))
        self._add_label('Size: %.2f' % float(self.species.life_obj.inheritable_size),
                        'size' in self.species.life_obj.mutated_params)
        self._add_label('Nutritional value: %.2f' % float(self.species.life_obj.inheritable_nutritional_value),
                        'nutritional_value' in self.species.life_obj.mutated_params)
        self._add_label('Defence: %.2f' % float(self.species.life_obj.inheritable_defence),
                        'defence' in self.species.life_obj.mutated_params)
        self._add_label('Attack: %.2f' % float(self.species.life_obj.inheritable_attack),
                        'attack' in self.species.life_obj.mutated_params)
        self._add_label('Speed: %.2f' % float(self.species.life_obj.inheritable_speed *
                                              self.species.life_obj.environment.calculate_speed_factor(
                                                  self.species.life_obj.humidity_likeness,
                                                  self.species.life_obj.temperature_likeness)),
                        'speed' in self.species.life_obj.mutated_params)
        self._add_label('Reproducing interval: %.2f' % float(self.species.life_obj.reproducing_interval),
                        'reproducing_interval' in self.species.life_obj.mutated_params)
        self._add_label('Reproducing probability: %.2f' % float(self.species.life_obj.reproducing_probability),
                        'reproducing_probability' in self.species.life_obj.mutated_params)
        self._add_label('Energy needed to reproduce: %.2f' % float(self.species.life_obj.energy_needed_to_reproduce),
                        'energy_needed_to_reproduce' in self.species.life_obj.mutated_params)
        self._add_label('Energy move cost: %.2f' % float(self.species.life_obj.energy_move_cost),
                        'energy_move_cost' in self.species.life_obj.mutated_params)
        self._add_label('Energy live cost: %.2f' % float(self.species.life_obj.energy_live_cost),
                        'energy_live_cost' in self.species.life_obj.mutated_params)

    def _add_label(self, text, param_has_mutated=False):
        self.labels.append(Label(self.ui, self.surface, text,
                                 self.x + self.padding[3], self.y_offset, self.font,
                                 self.color if not param_has_mutated else self.mutated_param_color))
        self.y_offset += self.line_height

    def draw(self, y):
        if y is not None and y + self.line_height != self.y:
            y += self.line_height
            self.border_rect.move_ip(0, y - self.y)
            self.bg_rect.move_ip(0, y - self.y)
            self.y = y
            self._generate_labels()
        pygame.draw.rect(self.surface, self.border_color, self.border_rect, self.border_width)
        pygame.draw.rect(self.surface, self.bg_color, self.bg_rect, 0)
        for label in self.labels:
            label.draw()
コード例 #41
0
ファイル: renderer.py プロジェクト: bitcraft/polerunner
    def draw(self, surface, rect):
        onScreen = []

        if self.blank:
            self.blank = False
            self.maprender.blank = True

        visible_shapes = self.area.space.bb_query(toBB(self.extent))

        for child in [ child for child in self.area if child.avatar]:
            shape = child.shapes[0]
            if shape not in visible_shapes:
                continue

            bb = child.bb
            x = bb.left - self.extent.left - child.avatar.axis.x
            y = bb.top - self.extent.top

            if hasattr(shape, "radius"):
                w, h = child.avatar.image.get_size()
                angle = -(math.degrees(shape.body.angle)) % 360
                image = rotozoom(child.avatar.image.convert_alpha(), angle, 1.0)
                ww, hh = image.get_size()
                rrect = Rect(x, y-h, ww, hh)
                rrect.move_ip((w-ww)/2, (h-hh)/2)
            else:
                w, h = child.avatar.image.get_size()
                rrect = Rect(x, y - h, w, h)
                image = child.avatar.image
            onScreen.append((image, rrect, 1))

        if parallax:
            self.parallaxrender.draw(surface, rect, [])

        dirty = self.maprender.draw(surface, rect, onScreen)

        if DEBUG:
            def translate((x, y)):
                return x - self.extent.left, y - self.extent.top

            for shape in self.area.space.shapes:
                try:
                    points = [ translate(i) for i in shape.get_points() ]
                except AttributeError:
                    pass
                else:
                    draw.aalines(surface, (255,100,100), 1, points)
                    continue

                try:
                    radius = shape.radius
                    pos = shape.body.position
                    pos = translate(pos)
                    pos += shape.offset
                except AttributeError:
                    pass
                else:
                    pos = map(int, pos)
                    draw.circle(surface, (255,100,100), pos, int(radius), 1)
                    continue

        return dirty
コード例 #42
0
class Monster(sprite.Sprite):
    def __init__(self, move_time, nodes):
        sprite.Sprite.__init__(self)
        self.nodes = nodes
        self.orig_nodes = nodes
        self.move_time = move_time
        self.spawn_time = time.time()
        self.image = Surface((40, 40)).convert()
        self.image_inside = Surface((38, 38)).convert()
        self.image_inside.fill((0, 255, 0))
        self.image.blit(self.image_inside, (1, 1))
        self.pos = (80, 40)
        self.real_pos = (80, 40)
        self.rect = Rect(self.pos, self.image.get_size())
        self.speed = 2
        self.speed_mod = 1
        self.diag_speed = 2
        self.target_pos = (880, 560)
        self.value = 1
        self.cost = 0
        self.health = 100
        self.damage_mod = 1
        self.counter = 0
        self.cur_node = self.nodes[0]
        self.the_dir = (0, 0)
        self.can_move = False

        self.name = "Monster"
        self.description = "A basic monster with slow movement speed and moderate health."

    def update(self, window):

        if time.time() - self.spawn_time >= self.move_time:
            self.can_move = True
            # If it's hit the last block
            if len(self.nodes) < 1:
                self.kill()
                return self.value
            else:

                # Figuring direction
                if self.nodes[0].rect.x > self.cur_node.rect.x:
                    self.the_dir = (1, 0)
                elif self.nodes[0].rect.x < self.cur_node.rect.x:
                    self.the_dir = (-1, 0)
                elif self.nodes[0].rect.y > self.cur_node.rect.y:
                    self.the_dir = (0, 1)
                elif self.nodes[0].rect.y < self.cur_node.rect.y:
                    self.the_dir = (0, -1)

                # Check to see the most the monster can move
                for speed in range(0, self.speed+1):
                    t_dir = tuple([x * speed * self.speed_mod for x in self.the_dir])

                    # Monster can only move this much
                    if self.rect.move(t_dir) == self.nodes[0].rect:
                        self.rect.move_ip(t_dir)
                        self.real_pos = tuple(map(sum, zip(self.real_pos, t_dir)))
                        self.cur_node = self.nodes.pop(0)
                        break
                else:
                    # The monster can move by self.speed
                    a = tuple([x * self.speed * self.speed_mod for x in self.the_dir])
                    self.real_pos = tuple(map(sum, zip(self.real_pos, a)))
                    self.pos = tuple(map(round, self.real_pos))
                    self.rect.x, self.rect.y = self.pos

                # Conditions for the monster to die
                die_conditions = [self.rect.top >= window.get_height(),
                                  self.rect.left >= window.get_width(),
                                  self.rect.bottom <= 0]
                if any(die_conditions):
                    self.kill()
                    return self.value

                # Resetting the modifiers, they'll be changed if the monster is under an effect
                self.speed_mod = 1
                self.damage_mod = 1
        return 0

    # Does damage to the monster and checks if it dies
    def damage(self, damage):
        self.health -= damage*self.damage_mod

        # Returns the amount of money to grant the player if the monster dies and also how much damage was done
        if self.health <= 0:
            self.kill()
            return self.value, damage*self.damage_mod
        else:
            return None, damage*self.damage_mod
コード例 #43
0
class MovingSprite(Entity):
        """
        Sprite base class that implements movement on a gameboard.
        """
        # Sprite state
        speed = 5

        def __init__(self, x, y, width, height):
            super(MovingSprite, self).__init__(x, y, width, height)
            # Center the sprite to initial coords
            center_coords = (self.rect.centerx - self.rect.width, self.rect.centery - self.rect.height)
            self.rect = Rect(center_coords, self.rect.size)
            # Set current movement target equal to initial position
            self.target = vec2(self.rect.centerx, self.rect.centery)
            self.targets = deque()  # Target queue
            self.facing_direction = Direction.DOWN
            self.state = State.STATIONARY

        def move_to_target(self, x, y):
            """
            Add new target for the sprite to move towards. Starts movement towards target if stationary, otherwise
            appends the target to a queue.
            """
            # Set new direction
            new_target = vec2(x, y)

            if self.state == State.STATIONARY and new_target != self.target and not self.need_to_move():
                self.facing_direction = self.get_facing(x, y)
                self.state = State.MOVING
                self.target = vec2(x, y)
            else:
                self.targets.append(vec2(x, y))

        def get_facing(self, x, y):
            # TODO: If target diagonally away, do something
            if x > self.target.x:
                return Direction.RIGHT
            elif x < self.target.x:
                return Direction.LEFT
            elif y > self.target.y:
                return Direction.DOWN
            elif y < self.target.y:
                return Direction.UP
            else:
                return Direction.STATIONARY

        def need_to_move(self):
            current_position = self.rect.center
            return current_position[0] != self.target.x or current_position[1] != self.target.y

        def calculate_movement(self):
            if self.state != State.STATIONARY:
                current_position = vec2(self.rect.centerx, self.rect.centery)
                velocity = DIRECTIONS[self.facing_direction] * self.speed
                new_position = current_position + velocity
                target_position = self.target

                # Calculate velocity to just reach the target, not go over
                if (current_position.x < target_position.x < new_position.x or
                   new_position.x < target_position.x < current_position.x):
                    velocity.x = target_position.x - current_position.x

                elif (current_position.y < target_position.y < new_position.y or
                      new_position.y < target_position.y < current_position.y):
                    velocity.y = target_position.y - current_position.y

                return velocity
            else:
                return vec2(0, 0)

        def move(self):
            """
            Move the sprite towards next target. Switches to a new target if targets queue is not empty, otherwise
            stays still.
            """
            # Check if already at current target
            if not self.need_to_move():
                # Get new target
                if len(self.targets) != 0:
                    next_target = self.targets.popleft()
                    facing = self.get_facing(*next_target)

                    # If new target is equal to previous
                    if facing == Direction.STATIONARY:
                        self.state = State.STATIONARY
                        return

                    self.facing_direction = facing
                    self.target = next_target
                # No target, stay still
                else:
                    if self.state != State.STATIONARY:
                        self.state = State.STATIONARY
                    return
            else:
                self.state = State.MOVING

                velocity = self.calculate_movement()
                self.rect.move_ip(*velocity)
コード例 #44
0
 def get_cell_rect(self, i, j):
     """Get rectangle from index (i, j)."""
     rect = Rect(*self.pos, self.case_length, self.case_length)
     rect.move_ip(j * self.case_length, i * self.case_length)
     return rect
コード例 #45
0
ファイル: orthographic.py プロジェクト: ri0t/pyscroll
class BufferedRenderer(object):
    """ Renderer that support scrolling, zooming, layers, and animated tiles

    The buffered renderer must be used with a data class to get tile, shape,
    and animation information.  See the data class api in pyscroll.data, or
    use the built-in pytmx support for loading maps created with Tiled.
    """
    def __init__(self, data, size, clamp_camera=True, colorkey=None, alpha=False,
                 time_source=time.time, scaling_function=pygame.transform.scale):

        # default options
        self.map_rect = None                       # pygame rect of entire map
        self.data = data                           # reference to data source
        self.clamp_camera = clamp_camera           # if clamped, cannot scroll past map edge
        self.time_source = time_source             # determines how tile animations are processed
        self.scaling_function = scaling_function   # what function to use when zooming
        self.default_shape_texture_gid = 1         # [experimental] texture to draw shapes with
        self.default_shape_color = 0, 255, 0       # [experimental] color to fill polygons with

        # internal private defaults
        self._alpha = False
        if colorkey and alpha:
            print('cannot select both colorkey and alpha.  choose one.')
            raise ValueError
        elif colorkey:
            self._clear_color = colorkey
        else:
            self._clear_color = None

        # private attributes
        self._size = None             # size that the camera/viewport is on screen, kinda
        self._redraw_cutoff = None    # size of dirty tile edge that will trigger full redraw
        self._x_offset = None         # offsets are used to scroll map in sub-tile increments
        self._y_offset = None
        self._buffer = None           # complete rendering of tilemap
        self._tile_view = None        # this rect represents each tile on the buffer
        self._half_width = None       # 'half x' attributes are used to reduce division ops.
        self._half_height = None
        self._tile_queue = None       # tiles queued to be draw onto buffer
        self._animation_queue = None  # heap queue of animation token.  schedules tile changes
        self._animation_map = None    # map of GID to other GIDs in an animation
        self._last_time = None        # used for scheduling animations
        self._layer_quadtree = None   # used to draw tiles that overlap optional surfaces
        self._zoom_buffer = None      # used to speed up zoom operations
        self._zoom_level = 1.0        # negative numbers make map smaller, positive: bigger

        # this represents the viewable pixels, aka 'camera'
        self.view_rect = Rect(0, 0, 0, 0)

        self.reload_animations()
        self.set_size(size)

    def _update_time(self):
        self._last_time = time.time() * 1000

    def reload_animations(self):
        """ Reload animation information
        """
        self._update_time()
        self._animation_map = dict()
        self._animation_queue = list()

        for gid, frame_data in self.data.get_animations():
            frames = list()
            for frame_gid, frame_duration in frame_data:
                image = self.data.get_tile_image_by_gid(frame_gid)
                frames.append(AnimationFrame(image, frame_duration))

            ani = AnimationToken(gid, frames)
            ani.next += self._last_time
            self._animation_map[ani.gid] = ani.frames[ani.index].image
            heappush(self._animation_queue, ani)

    def _process_animation_queue(self):
        self._update_time()
        requires_redraw = False

        # test if the next scheduled tile change is ready
        while self._animation_queue[0].next <= self._last_time:
            requires_redraw = True
            token = heappop(self._animation_queue)

            # advance the animation index, looping by default
            if token.index == len(token.frames) - 1:
                token.index = 0
            else:
                token.index += 1

            next_frame = token.frames[token.index]
            token.next = next_frame.duration + self._last_time
            self._animation_map[token.gid] = next_frame.image
            heappush(self._animation_queue, token)

        if requires_redraw:
            # TODO: record the tiles that changed and update only affected tiles
            self.redraw_tiles()
            pass

    def _calculate_zoom_buffer_size(self, value):
        if value <= 0:
            print('zoom level cannot be zero or less')
            raise ValueError
        value = 1.0 / value
        return [int(round(i * value)) for i in self._size]

    @property
    def zoom(self):
        """ Zoom the map in or out.

        Increase this number to make map appear to come closer to camera.
        Decrease this number to make map appear to move away from camera.

        Default value is 1.0
        This value cannot be negative or 0.0

        :return: float
        """
        return self._zoom_level

    @zoom.setter
    def zoom(self, value):
        self._zoom_level = value
        buffer_size = self._calculate_zoom_buffer_size(value)
        self._initialize_buffers(buffer_size)

    def set_size(self, size):
        """ Set the size of the map in pixels

        This is an expensive operation, do only when absolutely needed.

        :param size: (width, height) pixel size of camera/view of the group
        """
        self._size = size
        buffer_size = self._calculate_zoom_buffer_size(self._zoom_level)
        self._initialize_buffers(buffer_size)

    def _create_buffers(self, view_size, buffer_size):
        """ Create the buffers, taking in account pixel alpha or colorkey

        :param view_size: pixel size of the view
        :param buffer_size: pixel size of the buffer
        """
        requires_zoom_buffer = not view_size == buffer_size
        self._zoom_buffer = None

        if self._clear_color:
            if requires_zoom_buffer:
                self._zoom_buffer = Surface(view_size, flags=pygame.RLEACCEL)
                self._zoom_buffer.set_colorkey(self._clear_color)
            self._buffer = Surface(buffer_size, flags=pygame.RLEACCEL)
            self._buffer.set_colorkey(self._clear_color)
            self._buffer.fill(self._clear_color)
        elif self._alpha:
            if requires_zoom_buffer:
                self._zoom_buffer = Surface(view_size, flags=pygame.SRCALPHA)
            self._buffer = Surface(buffer_size, flags=pygame.SRCALPHA)
        else:
            if requires_zoom_buffer:
                self._zoom_buffer = Surface(view_size)
            self._buffer = Surface(buffer_size)

    def _initialize_buffers(self, size):
        """ Create the buffers to cache tile drawing

        :param size: (int, int): size of the draw area
        :return: None
        """
        tw, th = self.data.tile_size
        mw, mh = self.data.map_size
        buffer_tile_width = int(math.ceil(size[0] / tw) + 2)
        buffer_tile_height = int(math.ceil(size[1] / th) + 2)
        buffer_pixel_size = buffer_tile_width * tw, buffer_tile_height * th

        self.map_rect = Rect(0, 0, mw * tw, mh * th)
        self.view_rect.size = size
        self._tile_view = Rect(0, 0, buffer_tile_width, buffer_tile_height)
        self._redraw_cutoff = min(buffer_tile_width, buffer_tile_height)
        self._create_buffers(size, buffer_pixel_size)
        self._half_width = size[0] // 2
        self._half_height = size[1] // 2
        self._x_offset = 0
        self._y_offset = 0

        def make_rect(x, y):
            return Rect((x * tw, y * th), (tw, th))

        rects = [make_rect(*i) for i in product(range(buffer_tile_width),
                                                range(buffer_tile_height))]

        # TODO: figure out what depth -actually- does
        self._layer_quadtree = quadtree.FastQuadTree(rects, 4)

        self.redraw_tiles()

    def scroll(self, vector):
        """ scroll the background in pixels

        :param vector: (int, int)
        """
        self.center((vector[0] + self.view_rect.centerx,
                     vector[1] + self.view_rect.centery))

    def center(self, coords):
        """ center the map on a pixel

        float numbers will be rounded.

        :param coords: (number, number)
        """
        x, y = [round(i, 0) for i in coords]
        self.view_rect.center = x, y

        if self.clamp_camera:
            self.view_rect.clamp_ip(self.map_rect)
            x, y = self.view_rect.center

        # calc the new position in tiles and offset
        tw, th = self.data.tile_size
        left, self._x_offset = divmod(x - self._half_width, tw)
        top, self._y_offset = divmod(y - self._half_height, th)

        # adjust the view if the view has changed without a redraw
        dx = int(left - self._tile_view.left)
        dy = int(top - self._tile_view.top)
        view_change = max(abs(dx), abs(dy))

        if view_change <= self._redraw_cutoff:
            self._buffer.scroll(-dx * tw, -dy * th)
            self._tile_view.move_ip((dx, dy))
            self._queue_edge_tiles(dx, dy)
            self._flush_tile_queue()

        elif view_change > self._redraw_cutoff:
            logger.info('scrolling too quickly.  redraw forced')
            self._tile_view.move_ip((dx, dy))
            self.redraw_tiles()

    def _queue_edge_tiles(self, dx, dy):
        """ Queue edge tiles and clear edge areas on buffer if needed

        :param dx: Edge along X axis to enqueue
        :param dy: Edge along Y axis to enqueue
        :return: None
        """
        v = self._tile_view
        fill = partial(self._buffer.fill, self._clear_color)
        tw, th = self.data.tile_size
        self._tile_queue = iter([])

        def append(rect):
            self._tile_queue = chain(self._tile_queue, self.data.get_tile_images_by_rect(rect))
            if self._clear_color:
                fill(((rect[0] - self._tile_view.left) * tw,
                      (rect[1] - self._tile_view.top) * th,
                      rect[2] * tw, rect[3] * th))

        if dx > 0:    # right side
            append((v.right - dx, v.top, dx, v.height))

        elif dx < 0:  # left side
            append((v.left, v.top, -dx, v.height))

        if dy > 0:    # bottom side
            append((v.left, v.bottom - dy, v.width, dy))

        elif dy < 0:  # top side
            append((v.left, v.top, v.width, -dy))

    def draw(self, surface, rect, surfaces=None):
        """ Draw the map onto a surface

        pass a rect that defines the draw area for:
            drawing to an area smaller that the whole window/screen

        surfaces may optionally be passed that will be blitted onto the surface.
        this must be a list of tuples containing a layer number, image, and
        rect in screen coordinates.  surfaces will be drawn in order passed,
        and will be correctly drawn with tiles from a higher layer overlapping
        the surface.

        surfaces list should be in the following format:
        [ (layer, surface, rect), ... ]

        :param surface: pygame surface to draw to
        :param rect: area to draw to
        :param surfaces: optional sequence of surfaces to interlace into tiles
        """
        if self._zoom_level == 1.0:
            self._render_map(surface, rect, surfaces)
        else:
            self._render_map(self._zoom_buffer, self._zoom_buffer.get_rect(), surfaces)
            self.scaling_function(self._zoom_buffer, rect.size, surface)

    def _render_map(self, surface, rect, surfaces):
        """ Render the map and optional surfaces to destination surface

        :param surface: pygame surface to draw to
        :param rect: area to draw to
        :param surfaces: optional sequence of surfaces to interlace into tiles
        """
        if self._animation_queue:
            self._process_animation_queue()

        if rect.width > self.map_rect.width:
            x = (rect.width - self.map_rect.width) // 4
            print(x)
            self._x_offset += x

        if rect.height > self.map_rect.height:
            pass

        # need to set clipping otherwise the map will draw outside its area
        with surface_clipping_context(surface, rect):
            # draw the entire map to the surface taking in account the scrolling offset
            surface.blit(self._buffer, (-self._x_offset - rect.left,
                                        -self._y_offset - rect.top))
            if surfaces:
                self._draw_surfaces(surface, rect, surfaces)

    def _draw_surfaces(self, surface, rect, surfaces):
        """ Draw surfaces onto map, then redraw tiles that cover them

        :param surface: destination
        :param rect: clipping area
        :param surfaces: sequence of surfaces to blit
        """
        surface_blit = surface.blit
        left, top = self._tile_view.topleft
        ox = self._x_offset - rect.left
        oy = self._y_offset - rect.top
        hit = self._layer_quadtree.hit
        get_tile = self.data.get_tile_image
        tile_layers = tuple(self.data.visible_tile_layers)
        dirty = [(surface_blit(i[0], i[1]), i[2]) for i in surfaces]

        for dirty_rect, layer in dirty:
            for r in hit(dirty_rect.move(ox, oy)):
                x, y, tw, th = r
                for l in [i for i in tile_layers if gt(i, layer)]:
                    tile = get_tile((x // tw + left, y // th + top, l))
                    if tile:
                        surface_blit(tile, (x - ox, y - oy))

    def _draw_objects(self):
        """ Totally unoptimized drawing of objects to the map [probably broken]
        """
        tw, th = self.data.tile_size
        buff = self._buffer
        blit = buff.blit
        map_gid = self.data.tmx.map_gid
        default_color = self.default_shape_color
        get_image_by_gid = self.data.get_tile_image_by_gid
        _draw_textured_poly = pygame.gfxdraw.textured_polygon
        _draw_poly = pygame.draw.polygon
        _draw_lines = pygame.draw.lines

        ox = self._tile_view.left * tw
        oy = self._tile_view.top * th

        def draw_textured_poly(texture, points):
            try:
                _draw_textured_poly(buff, points, texture, tw, th)
            except pygame.error:
                pass

        def draw_poly(color, points, width=0):
            _draw_poly(buff, color, points, width)

        def draw_lines(color, points, width=2):
            _draw_lines(buff, color, False, points, width)

        def to_buffer(pt):
            return pt[0] - ox, pt[1] - oy

        for layer in self.data.visible_object_layers:
            for o in (o for o in layer if o.visible):
                texture_gid = getattr(o, "texture", None)
                color = getattr(o, "color", default_color)

                # BUG: this is not going to be completely accurate, because it
                # does not take into account times where texture is flipped.
                if texture_gid:
                    texture_gid = map_gid(texture_gid)[0][0]
                    texture = get_image_by_gid(int(texture_gid))

                if hasattr(o, 'points'):
                    points = [to_buffer(i) for i in o.points]
                    if o.closed:
                        if texture_gid:
                            draw_textured_poly(texture, points)
                        else:
                            draw_poly(color, points)
                    else:
                        draw_lines(color, points)

                elif o.gid:
                    tile = get_image_by_gid(o.gid)
                    if tile:
                        pt = to_buffer((o.x, o.y))
                        blit(tile, pt)

                else:
                    x, y = to_buffer((o.x, o.y))
                    points = ((x, y), (x + o.width, y),
                              (x + o.width, y + o.height), (x, y + o.height))
                    if texture_gid:
                        draw_textured_poly(texture, points)
                    else:
                        draw_poly(color, points)

    def _flush_tile_queue(self):
        """ Blit the queued tiles and block until the tile queue is empty
        """
        tw, th = self.data.tile_size
        ltw = self._tile_view.left * tw
        tth = self._tile_view.top * th
        blit = self._buffer.blit
        map_get = self._animation_map.get

        for x, y, l, tile, gid in self._tile_queue:
            blit(map_get(gid, tile), (x * tw - ltw, y * th - tth))

    def redraw_tiles(self):
        """ redraw the visible portion of the buffer -- it is slow.
        """
        if self._clear_color:
            self._buffer.fill(self._clear_color)
        elif self._alpha:
            self._buffer.fill(0)

        self._tile_queue = self.data.get_tile_images_by_rect(self._tile_view)
        self._flush_tile_queue()

    def get_center_offset(self):
        """ Return x, y pair that will change world coords to screen coords
        :return: int, int
        """
        return (-self.view_rect.centerx + self._half_width,
                -self.view_rect.centery + self._half_height)
コード例 #46
0
ファイル: player.py プロジェクト: SeoulSKY/PingPong
class Player:
    def __init__(self, window: pygame.Surface, x_pos: float, y_pos: float,
                 color: Tuple[int, int, int]):
        """
        Create a player
        :param window: The pygame window that player will be displayed
        :param x_pos: Player's initial x position
        :param y_pos: Player's initial y position
        :param color: The color of the player
        """
        self._window: pygame.Surface = window
        self._DEFAULT_X_POS: float = x_pos
        self._DEFAULT_Y_POS: float = y_pos
        self._rect = Rect(self._DEFAULT_X_POS, self._DEFAULT_Y_POS,
                          PLAYER_WIDTH, PLAYER_HEIGHT)
        self._color: Tuple[int, int, int] = color
        self._y_speed: float = 0

    def x_pos(self) -> int:
        """
        Return the x position of the player
        :return: x position of the player
        """
        return self._rect.x

    def y_pos(self) -> int:
        """
        Return the y position of the player
        :return: y position of the player
        """
        return self._rect.y

    def y_speed(self) -> float:
        """
        Returns the y speed of the player
        :return: The y speed of the player
        """
        return self._y_speed

    def is_moving_up(self) -> bool:
        """
        Check if the player is moving up
        :return: True if the player is, False otherwise
        """
        return self._y_speed < 0

    def is_moving_down(self) -> bool:
        """
        Check if the player is moving down
        :return: True if the player is, False otherwise
        """
        return self._y_speed > 0

    def move_up(self) -> None:
        """
        Move the player upward based on the current speed
        """
        # check if the player is moving down
        if self.is_moving_down():
            self.stop()

        self._move()

        # accelerate upward
        if self._y_speed > -PLAYER_MAX_Y_SPEED:
            self._y_speed -= 0.7

            # make sure the current speed doesn't exceed the maximum speed
            if self._y_speed < -PLAYER_MAX_Y_SPEED:
                self._y_speed = -PLAYER_MAX_Y_SPEED

    def move_down(self) -> None:
        """
        Move the player downward based on the current speed
        """
        # check if the player is moving up
        if self.is_moving_up():
            self.stop()

        self._move()

        # accelerate downward
        if self._y_speed < PLAYER_MAX_Y_SPEED:
            self._y_speed += 0.7

            # make sure the current speed doesn't exceed the maximum speed
            if self._y_speed > PLAYER_MAX_Y_SPEED:
                self._y_speed = PLAYER_MAX_Y_SPEED

    def _move(self) -> None:
        """
        Move the player based on the current speed
        """
        self._rect.move_ip(0, self._y_speed)

    def stop(self) -> None:
        """
        Stop the player's movement
        """
        self._y_speed = 0

    def is_collided(self, x_pos: float, y_pos: float) -> bool:
        """
        Check if the given positions are within the player's area
        :param x_pos: The x position to check
        :param y_pos: The y position to check
        :return: True if the given positions are within the player's area, False otherwise
        """
        return self.x_pos(
        ) <= x_pos <= self.x_pos() + PLAYER_WIDTH and self.y_pos(
        ) <= y_pos <= self.y_pos() + PLAYER_HEIGHT

    def reset(self) -> None:
        """
        Reset the player to the initial state
        """
        self._rect.x = self._DEFAULT_X_POS
        self._rect.y = self._DEFAULT_Y_POS
        self.stop()

    def draw(self) -> None:
        """
        Draw the player
        """
        draw.rect(self._window, self._color, self._rect)
コード例 #47
0
class Chromossome:
    def __init__(self, position, size, _range, cic=3, angl=[]):
        self.size = size
        self.initialp = position
        self.position = position
        self.xposition = (self.position[0] +
                          self.size[0] // 2), (self.position[1] +
                                               self.size[1] // 2)
        self.rect = Rect(position, size)
        self.angles = [angles[randint(0, 7)]
                       for i in range(cic)] if angl == [] else angl
        self._range = _range
        self.cic = cic
        self.cicles = -1

    def crossover(self, other):
        i1 = randint(0, self.cic - 1)
        newchromo1 = Chromossome(self.initialp, self.size, self._range,
                                 self.cic,
                                 self.angles[:i1] + other.angles[i1:])
        newchromo2 = Chromossome(self.initialp, self.size, self._range,
                                 self.cic,
                                 other.angles[:i1] + self.angles[i1:])
        return newchromo1, newchromo2

    def move(self, ang):
        if ang >= pi:
            if (type(tan(ang)) == float):
                self.rect.move_ip(-self._range,
                                  round(tan(ang) * (-self._range)))
                self.position = (self.position[0] - self._range,
                                 self.position[1] +
                                 round(tan(ang) * (-self._range)))
            else:
                self.rect.move_ip(0, -self._range)
                self.position = (self.position[0],
                                 self.position[1] - self._range)
        else:
            if type(tan(ang)) == float:
                self.rect.move_ip(self._range, round(tan(ang) * (self._range)))
                self.position = (self.position[0] + self._range,
                                 self.position[1] +
                                 round(tan(ang) * (self._range)))
            else:
                self.rect.move_ip(0, self._range)
                self.position = (self.position[0],
                                 self.position[1] + self._range)
        self.xposition = (self.position[0] +
                          self.size[0] // 2), (self.position[1] +
                                               self.size[1] // 2)

    def mutate(self, p=0.03):
        if random() <= p:
            self.angles[randint(0, self.cic - 1)] = angles[randint(0, 7)]

    def getCicl(self, nzombies, zombieargs, dist):
        if self.cicles > -1: return
        initialp = self.position, self.xposition
        zs = [
            Zombie(zombieargs[0],
                   [zombieargs[1][0] + i, zombieargs[1][1] + dist * i],
                   zombieargs[2]) for i in range(nzombies)
        ]
        k = 0
        while True:
            for z in zs:
                z.move(self.xposition)
            self.move(self.angles[k])
            k += 1
            if ((self.rect.collidelist([z.rect for z in zs])) > -1) or (
                    self.xposition[0] >= 100 or self.xposition[1] >= 100) or (
                        self.xposition[0] <= 0 or self.xposition[1] <= 0):
                ##print(k)
                self.cicles = k
                break
        self.position, self.xposition = initialp
コード例 #48
0
ファイル: map.py プロジェクト: bpa/renegade
class MapEntity(Sprite):
    """MapEntity is a sprite that knows how to interact with a map.
       It contains code that can be run periodically, the default
       is to do nothing.  There are also methods for each type of 
       map event.  To do anything useful, subclass this"""

    def __init__(self, image_map=None):
        self.name = self.__class__.__name__
        if image_map is not None:
            self.init(image_map)
           
    def __getstate__(self):
        dict = self.__dict__.copy()
        dict.pop('map')
        dict.pop('_Sprite__g')
        dict.pop('image')
        return dict

    def __setstate__(self, dict):
        self.__dict__ = dict
        Sprite.__init__(self)
        self.image = util.load_image(CHARACTERS_DIR, *self.image_args)
        self.animation_speed = 6

    def init(self,image_map,tile_x=0,tile_y=0,color_key=None):
        """MapEntity(Surface, tile_x, tile_y, direction)
       
           Surface should be obtained from util.load_image

           tile_x & tile_y specify what image map to use if you join
           multiple images into one map (Characters, Entities, etc)
           legal values are positive integers representing zero based index

           direction is what direction the entity should face,
           can also be set later with MapEntity.face(direction)
           legal values are map.NORTH, map.EAST, map.SOUTH, & map.WEST"""

        image = util.load_image(CHARACTERS_DIR, image_map, True, color_key)
        Sprite.__init__(self)
        self.image_args = (image_map, True, color_key)
        self.pos = (0,0)
        self.map = None
        self.image = image
        self.image_base_x = tile_x * 3 * TILE_SIZE
        self.image_base_y = tile_y * 4 * TILE_SIZE
        self.frame = 0
        self.image_tile = Rect( self.image_base_x, self.image_base_y,
                                TILE_SIZE, TILE_SIZE )
        self.rect = Rect(0,0,TILE_SIZE,TILE_SIZE)
        self.face(NORTH)
        self.next_frame()
        self.velocity = (0,0)
        self.speed = 4
        self.moving = False # For tile based motion
        self.always_animate = False
        self.animation_count = 1
        self.animation_speed = 6
        self.entered_tile = False
        self.can_trigger_actions = 0

    def speed(self, pixels_per_update):
        """speed(int) Set the movement speed, currently in pixels per update"""
        self.speed = pixels_per_update

    def face(self,direction):
        self.facing = direction
        self.image_tile.top = self.image_base_y + (self.facing * TILE_SIZE)

    def next_frame(self):
        self.frame = self.frame + 1
        if self.frame > 3: self.frame = 0
        if self.frame == 3:
          self.image_tile.left = self.image_base_x + (1 * TILE_SIZE)
        else:
          self.image_tile.left = self.image_base_x + (self.frame * TILE_SIZE)

    def move_to(self, pos):
        """Moves the entity to a location without running triggers
           or changing the direction its facing"""
        x, y = pos
        self.pos = pos
        self.rect.top  = TILE_SIZE * (y - self.map.viewport.top)
        self.rect.left = TILE_SIZE * (x - self.map.viewport.left)

    def move(self, direction, face_dir=True):
        """move(direction, face_direction=True)
           Start moving if not already"""
        if not self.moving:
            target = add(self.pos, MOVE_VECTORS[direction])
            if face_dir: self.face(direction)
            if self.map.move_ok(target, self):
                self.direction = MOVE_VECTORS[direction]
                self.pos = target
                self.moving = True
                self.pixels_left_to_move = TILE_SIZE
                self.velocity = (MOVE_VECTORS[direction][0] * self.speed, \
                        MOVE_VECTORS[direction][1] * self.speed)

    def update(self):
        if self.moving:
            self.pixels_left_to_move = self.pixels_left_to_move - self.speed
            self.animation_count = self.animation_count + 1
            if self.animation_count % self.animation_speed == 0:
                self.animation_count = 1
                self.next_frame()
            self.rect.move_ip(self.velocity)
            if self.pixels_left_to_move < self.speed:
                # Move the remaining pixels
                self.velocity = (self.direction[0] * self.pixels_left_to_move, \
                                 self.direction[1] * self.pixels_left_to_move)
                self.rect.move_ip(self.velocity)
                self.entered_tile = True
                self.moving = False
        else:
            if self.always_animate:
                self.animation_count = self.animation_count + 1
                if self.animation_count % self.animation_speed == 0:
                    self.animation_count = 1
                    self.next_frame()

################## The following are all action methods ########################
############ These are the ones you will override most commonly ################

#TODO Decide if these methods should have a prefix like action_
    def activate(self):
        """Called when the character hits the action key while facing entity"""
        pass

    def touch(self):
        """Called when the character makes contact with the entity
           This can be one of the following conditions:
              The character attempts to move into the entity
              The entity attempts to move into the character
           This will not be triggered if the sprites overlap temporarily.
           If it should, add an enhancement request and I'll fix it"""
        pass

    def enter_map(self):
        pass

    def leave_map(self):
        pass
コード例 #49
0
screen.blit(original_background, background_dimensions)

pygame.display.update()
scale = 1
prev_scale = 1
running = True
while running:
    redraw = False
    normalize = False
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            redraw = True
            if event.key == pygame.K_UP:
                background_dimensions.move_ip(0, 100)
            elif event.key == pygame.K_DOWN:
                background_dimensions.move_ip(0, -100)
            elif event.key == pygame.K_LEFT:
                background_dimensions.move_ip(100, 0)
            elif event.key == pygame.K_RIGHT:
                background_dimensions.move_ip(-100, 0)
            elif event.key == pygame.K_SPACE:
                normalize = True
            else:
                redraw = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            redraw = True
            if event.button == 4:
                scale *= 1.1
            elif event.button == 5: