コード例 #1
0
ファイル: rect_test.py プロジェクト: stephenh67/pygame
    def test_collidedict__zero_sized_rects(self):
        """Ensures collidedict works correctly with zero sized rects.

        There should be no collisions with zero sized rects.
        """
        zero_rect1 = Rect(1, 1, 0, 0)
        zero_rect2 = Rect(1, 1, 1, 0)
        zero_rect3 = Rect(1, 1, 0, 1)
        zero_rect4 = Rect(1, 1, -1, 0)
        zero_rect5 = Rect(1, 1, 0, -1)

        no_collide_item1 = ('no collide 1', zero_rect1.copy())
        no_collide_item2 = ('no collide 2', zero_rect2.copy())
        no_collide_item3 = ('no collide 3', zero_rect3.copy())
        no_collide_item4 = ('no collide 4', zero_rect4.copy())
        no_collide_item5 = ('no collide 5', zero_rect5.copy())
        no_collide_item6 = ('no collide 6', Rect(0, 0, 10, 10))
        no_collide_item7 = ('no collide 7', Rect(0, 0, 2, 2))

        # Dict to check collisions with values.
        rect_values = dict((no_collide_item1, no_collide_item2,
            no_collide_item3, no_collide_item4, no_collide_item5,
            no_collide_item6, no_collide_item7))

        # Dict to check collisions with keys.
        rect_keys = {tuple(v) : k for k, v in rect_values.items()}

        for use_values in (True, False):
            d = rect_values if use_values else rect_keys

            for zero_rect in (zero_rect1, zero_rect2, zero_rect3, zero_rect4,
                              zero_rect5):
                collide_item = zero_rect.collidedict(d, use_values)

                self.assertIsNone(collide_item)
コード例 #2
0
ファイル: rect_test.py プロジェクト: stephenh67/pygame
    def test_collidedict(self):
        """Ensures collidedict detects collisions."""
        rect = Rect(1, 1, 10, 10)

        collide_item1 = ('collide 1', rect.copy())
        collide_item2 = ('collide 2', Rect(5, 5, 10, 10))
        no_collide_item1 = ('no collide 1', Rect(60, 60, 10, 10))
        no_collide_item2 = ('no collide 2', Rect(70, 70, 10, 10))

        # Dict to check collisions with values.
        rect_values = dict((collide_item1, collide_item2, no_collide_item1,
                           no_collide_item2))
        value_collide_items = (collide_item1, collide_item2)

        # Dict to check collisions with keys.
        rect_keys = {tuple(v) : k for k, v in rect_values.items()}
        key_collide_items = tuple(
            (tuple(v), k) for k, v in value_collide_items)

        for use_values in (True, False):
            if use_values:
                expected_items = value_collide_items
                d = rect_values
            else:
                expected_items = key_collide_items
                d = rect_keys

            collide_item = rect.collidedict(d, use_values)

            # The detected collision could be any of the possible items.
            self.assertIn(collide_item, expected_items)
コード例 #3
0
ファイル: ui_window.py プロジェクト: yangtau/feed-the-dragon
    def __init__(self, rect: pygame.Rect,
                 manager: 'ui_manager.UIManager',
                 element_ids: List[str],
                 object_ids: Union[List[Union[str, None]], None] = None):

        new_element_ids = element_ids.copy()
        if object_ids is not None:
            new_object_ids = object_ids.copy()
        else:
            new_object_ids = [None]

        self.window_container = None
        # need to create the container that holds the elements first if this is the root window
        # so we can bootstrap everything and effectively add the root window to it's own container.
        # It's a little bit weird.
        if len(element_ids) == 1 and element_ids[0] == 'root_window':
            self._layer = 0
            self.window_container = UIContainer(rect.copy(), manager, None, None, None)
            self.window_stack = manager.get_window_stack()
            self.window_stack.add_new_window(self)

        super().__init__(rect, manager, container=None,
                         starting_height=1,
                         layer_thickness=1,
                         object_ids=new_object_ids,
                         element_ids=new_element_ids)

        if self.window_container is None:
            self.window_container = UIContainer(self.rect.copy(), manager, None, self, None)
            self.window_stack = self.ui_manager.get_window_stack()
            self.window_stack.add_new_window(self)

        self.image = self.image = pygame.Surface((0, 0))
コード例 #4
0
ファイル: rect_test.py プロジェクト: stephenh67/pygame
    def test_collidedict__invalid_dict_key_format(self):
        """Ensures collidedict correctly handles dicts with invalid keys."""
        rect = Rect(0, 0, 10, 10)
        rect_values = {'collide' : rect.copy()}

        with self.assertRaises(TypeError):
            collide_item = rect.collidedict(rect_values)
コード例 #5
0
class ExplosionAnimation(Sprite):
    image = pygame.image.load("images/explosion.png")

    def __init__(self, screen, position):
        super().__init__()
        self.screen = screen
        self.position = position
        self.full_rect = self.__class__.image.get_rect()
        self.width = self.full_rect.width/3
        self.height = self.full_rect.height/3
        self.rect = Rect(0, 0, self.width, self.height)
        self.rect.center = self.position
        self.frame_index = 0
        self.clock = Clock()
        self.time = 0

    def update(self):
        self.time += self.clock.tick()
        if self.time > Settings.explosion_duration/9:
            self.frame_index += 1
            self.time = 0

    def draw(self):
        subrect = self.rect.copy()
        subrect.left = self.full_rect.left + (self.frame_index % 3) * self.width
        subrect.top = self.full_rect.top + (self.frame_index // 3) * self.height
        self.screen.blit(self.__class__.image, self.rect, subrect)
コード例 #6
0
ファイル: main.py プロジェクト: i3Cheese/Hello-Sans
    def draw_on(self, screen: pg.Surface, rect: pg.Rect) -> None:
        """Рисует все свои спрайты на себе, затем блитает на screen часть себя.
        Фокусируется на игроке, но не выходя за границы. (У краёв игрок будет не в центре)"""
        self.fill(pg.Color("black"))

        # Рисуем спрайты в определёной последовательности
        self.tiles_group.draw(self)
        self.objects_group.draw(self)
        self.enemies_group.draw(self)
        self.player_group.draw(self)
        self.participles_group.draw(self)

        # вычисляем координаты прямоугольника, который будем рисовать
        target = self.player.rect  # фокус на игроке
        self.visible_area = rect.copy()
        self.visible_area.x = max(
            0,
            min(self.width - rect.width,
                target.x + target.width // 2 - rect.width // 2))
        self.visible_area.y = max(
            0,
            min(self.height - rect.height,
                target.y + target.height // 2 - rect.height // 2))

        screen.blit(self, rect, self.visible_area)
        screen.blit(self.player.draw_inventory(), rect)
コード例 #7
0
 def delta(self, rect: pg.Rect) -> pg.Rect:
     rect = rect.copy()
     rect.x = ceil(rect.x * self.dz + self.dx)
     rect.y = ceil(rect.y * self.dz + self.dy)
     rect.w = ceil(rect.w * self.dz)
     rect.h = ceil(rect.h * self.dz)
     return rect
コード例 #8
0
ファイル: textsprites.py プロジェクト: Fenixin/yogom
class NewTextSprite(TryMovingSprite):
    def __init__(self, font_render, text, size,
                 bg_color, layers, x=0, y=0, 
                 bg_transparent=True):
        """ Background is transparent by defualt. """
        
        # Render the image
        self.font = font_render
        self._text = text
        self.size = size
        self.background = bg_color
        self.bg_transparent = bg_transparent
        self.layers = layers
        
        img = self._render(text)
        
        TryMovingSprite.__init__(self, img, x, y, img.get_rect())
    
    @property
    def text(self):
        return self._text
    
    @text.setter
    def text(self, value):
        self._text = value
        self.image = self._render(value)
        self.rect = Rect((self.rect[0], self.rect[1]), self.image.get_rect()[2:])
        self.col_rect = self.rect.copy()
        self.mask = mask.from_surface(self.image)
        self.create_feet()
        
    def _render(self, text):
        """ Renders text using stored options """
        img = self.font.render(self.text, self.size, self.background, self.bg_transparent, self.layers)
        return img
コード例 #9
0
ファイル: rect_test.py プロジェクト: stephenh67/pygame
    def test_collidedictall(self):
        """Ensures collidedictall detects collisions."""
        rect = Rect(1, 1, 10, 10)

        collide_item1 = ('collide 1', rect.copy())
        collide_item2 = ('collide 2', Rect(5, 5, 10, 10))
        no_collide_item1 = ('no collide 1', Rect(60, 60, 20, 20))
        no_collide_item2 = ('no collide 2', Rect(70, 70, 20, 20))

        # Dict to check collisions with values.
        rect_values = dict((collide_item1, collide_item2, no_collide_item1,
                           no_collide_item2))
        value_collide_items = [collide_item1, collide_item2]

        # Dict to check collisions with keys.
        rect_keys = {tuple(v) : k for k, v in rect_values.items()}
        key_collide_items = [(tuple(v), k) for k, v in value_collide_items]

        for use_values in (True, False):
            if use_values:
                expected_items = value_collide_items
                d = rect_values
            else:
                expected_items = key_collide_items
                d = rect_keys

            collide_items = rect.collidedictall(d, use_values)

            self._assertCountEqual(collide_items, expected_items)
コード例 #10
0
ファイル: textsprites.py プロジェクト: Fenixin/yogom
class TextSprite(TryMovingSprite):
    def __init__(self, font_render, text, color, background=(0,0,0), antialias = False, x = 0, y = 0, bg_transparent = True ):
        """ Background is transparent by defualt. """
        
        # Render the image
        self.font = font_render
        self._text = text
        self.antialias = antialias
        self.background = background
        self.color = color
        self.bg_transparent = bg_transparent
        img = self.render(text)
        if bg_transparent:
            img.set_colorkey(background)
        
        TryMovingSprite.__init__(self, img, x, y, img.get_rect())
    
    @property
    def text(self):
        return self._text
    
    @text.setter
    def text(self, value):
        self._text = value
        self.image = self.render(value)
        self.rect = Rect((self.rect[0], self.rect[1]), self.image.get_rect()[2:])
        self.col_rect = self.rect.copy()
        self.mask = mask.from_surface(self.image)
        self.create_feet()
        
    def render(self, text):
        """ Renders the text using the options first used. """
        img = self.font.render(text, self.antialias, self.color, self.background)
        return img
コード例 #11
0
ファイル: rect_test.py プロジェクト: stephenh67/pygame
    def test_collidedictall__negative_sized_rects(self):
        """Ensures collidedictall works correctly with negative sized rects."""
        neg_rect = Rect(2, 2, -2, -2)

        collide_item1 = ('collide 1', neg_rect.copy())
        collide_item2 = ('collide 2', Rect(0, 0, 20, 20))
        no_collide_item1 = ('no collide 1', Rect(1, 1, 20, 20))

        # Dict to check collisions with values.
        rect_values = dict((collide_item1, collide_item2, no_collide_item1))
        value_collide_items = [collide_item1, collide_item2]

        # Dict to check collisions with keys.
        rect_keys = {tuple(v) : k for k, v in rect_values.items()}
        key_collide_items = [(tuple(v), k) for k, v in value_collide_items]

        for use_values in (True, False):
            if use_values:
                expected_items = value_collide_items
                d = rect_values
            else:
                expected_items = key_collide_items
                d = rect_keys

            collide_items = neg_rect.collidedictall(d, use_values)

            self._assertCountEqual(collide_items, expected_items)
コード例 #12
0
    def build(self):
        # calculate the max dimensions
        max_w, max_h = 0, 0
        for item in self.items:
            width, height = self.font.size(item.text)
            max_w = max(width, max_w)
            max_h = max(height, max_h)

        rect = Rect(0, 0, max_w, max_h).inflate(self.padding, self.padding)

        # place and initialize each menu item
        bounds = Rect(0, 0, 0, 0)
        top = 0
        for item in self.items:
            item.image = Surface(rect.size, SRCALPHA)
            item.rect = rect.copy()
            item.rect.top = top

            top = item.rect.bottom + self.margin

            bounds.union_ip(item.rect)

        # tmp, render each sprite initially
        for item in self.items:
            item.draw_normal()
コード例 #13
0
ファイル: rect_test.py プロジェクト: stephenh67/pygame
    def test_collidedict__negative_sized_rects(self):
        """Ensures collidedict works correctly with negative sized rects."""
        neg_rect = Rect(1, 1, -1, -1)

        collide_item1 = ('collide 1', neg_rect.copy())
        collide_item2 = ('collide 2', Rect(0, 0, 10, 10))
        no_collide_item1 = ('no collide 1', Rect(1, 1, 10, 10))

        # Dict to check collisions with values.
        rect_values = dict((collide_item1, collide_item2, no_collide_item1))
        value_collide_items = (collide_item1, collide_item2)

        # Dict to check collisions with keys.
        rect_keys = {tuple(v) : k for k, v in rect_values.items()}
        key_collide_items = tuple(
            (tuple(v), k) for k, v in value_collide_items)

        for use_values in (True, False):
            if use_values:
                collide_items = value_collide_items
                d = rect_values
            else:
                collide_items = key_collide_items
                d = rect_keys

            collide_item = neg_rect.collidedict(d, use_values)

            # The detected collision could be any of the possible items.
            self.assertIn(collide_item, collide_items)
コード例 #14
0
 def __init__(self, rect: Rect, **kwargs):
     self._rect = rect.copy()
     self._pos = Vector2(self._rect.centerx, self._rect.centery)
     self._alive = True
     self._dir = kwargs.get('direction', Vector2(
         1, 0))  # defaults to a rightward movement vector
     self._speed = kwargs.get('speed', 250)
コード例 #15
0
ファイル: menu.py プロジェクト: HampshireCS/cs143-Spring2012
    def build(self):
        # calculate the max dimensions
        max_w, max_h = 0, 0
        for item in self.items:
            width, height = self.font.size(item.text)
            max_w = max(width, max_w)
            max_h = max(height, max_h)

        rect = Rect(0,0,max_w,max_h).inflate(self.padding, self.padding)

        # place and initialize each menu item
        bounds = Rect(0, 0, 0, 0)
        top = 0
        for item in self.items:
            item.image = Surface(rect.size, SRCALPHA)
            item.rect = rect.copy()
            item.rect.top = top

            top = item.rect.bottom + self.margin
            
            bounds.union_ip(item.rect)

        # tmp, render each sprite initially
        for item in self.items:
            item.draw_normal()
コード例 #16
0
def stretched_circle(surface: Surface, rect: Rect, colour: Colour):
    rounded_rect(surface, rect, colour, min(rect.width, rect.height) * .5)
    r = rect.copy()
    r.width -= r.height
    r.x += r.height / 2
    r.height += 2
    r.y -= 1
    draw_rect(surface, colour, r)
コード例 #17
0
class Slider(Object):
    def __init__(self, topleft, size, color):
        super().__init__([
            "mouse_down", "mouse_up", "mouse_motion", "value_changed",
            "value_stabilized"
        ])

        self.connect("mouse_down", lambda event: self.clicked_handler(event))
        self.connect("mouse_motion", lambda event: self.motion_handler(event))
        self.connect("mouse_up", lambda _: self.mouse_up_handler())

        self.volume = 0
        self.color = color
        self.border_rect = Rect(topleft, size)

        self.moving = False

        self.ppv = self.border_rect.width // 100

    def set_moving(self, state):
        self.moving = state

    def motion_handler(self, event):
        if self.moving:
            self.change_volume_by_pos(event.pos)

    def mouse_up_handler(self):
        if self.moving:
            self.set_moving(False)
            self.signal("value_stabilized", self.volume)

    def change_volume_by_pos(self, pos):
        self.set_volume((pos[0] - self.border_rect.x) // self.ppv)

    def clicked_handler(self, event):
        position = event.pos
        if self.border_rect.collidepoint(position):
            self.moving = True
            self.change_volume_by_pos(position)

    def set_volume(self, volume):
        self.volume = min(volume if volume >= 0 else 0, 100)
        self.signal("value_changed", self.volume)

    def add_volume(self, volume):
        self.set_volume(self.volume + volume)

    def draw(self, screen):
        volume_rect = self.border_rect.copy()
        volume_rect.width = self.ppv * self.volume
        pygame.draw.rect(
            screen,
            self.color,
            volume_rect,
        )

        pygame.draw.rect(screen, (0, 0, 0), self.border_rect, 1)
コード例 #18
0
class ThrowedGrenade(Bullet):
    def __init__(self, creator, x, y, speedX, speedY, throwDistance):
        Bullet.__init__(self, creator, x, y, speedX, speedY,
                        "items-1small.png", None, Rect(110, 120, 9, 11))
        self.rect = Rect(x, y, 0, 0)
        self.speedX = speedX
        self.speedY = speedY

        # Important if you want pinpoint accuracy
        self.floatX = float(self.rect.x)
        self.floatY = float(self.rect.y)

        if throwDistance > MAX_THROW_DISTANCE:
            throwDistance = MAX_THROW_DISTANCE

        self.timeToStop = throwDistance / GRENADE_SPEED
        self.timeToBoom = TIME_TO_BOOM
        self.atk = 70

    def update(self, time, scene):
        self.floatX += self.speedX * time * GRENADE_SPEED
        self.floatY += self.speedY * time * GRENADE_SPEED
        self.rect.x = roundToInt(self.floatX)
        self.rect.y = roundToInt(self.floatY)

        self.timeToBoom -= time

        if self.timeToBoom <= 0:
            scene.bulletGroup.remove(self)
            scene.bulletGroup.add(Explosion(self.rect.x, self.rect.y))

            # Kill people!
            originalRect = self.rect.copy()
            self.rect.inflate_ip(80, 80)  # 80x80 area damage

            enemies_hit = sprite.spritecollide(self, scene.enemyGroup, False)

            for enemy in enemies_hit:
                # Friendly fire
                if self.creator.__class__.__name__ == enemy.__class__.__name__:
                    continue
                enemy.receive_attack(self.atk)

            if sprite.collide_rect(self, scene.player):
                scene.player.receive_attack(self.atk)

            self.rect = originalRect  # Restore the real rect

        self.timeToStop -= time

        if self.timeToStop <= 0:
            self.speedX = 0
            self.speedY = 0
コード例 #19
0
    def __init__(self, hit_rect: pg.Rect, pos: Vector2,
                 max_health: int) -> None:
        hit_rect = hit_rect.copy()
        hit_rect.center = pos
        self.motion: Motion = Motion(self, self.timer, self.groups.walls,
                                     hit_rect)

        self.status = Status(max_health)
        super().__init__(pos)
        self._base_rect = self.image.get_rect().copy()

        self.inventory = Inventory()
コード例 #20
0
ファイル: rect_test.py プロジェクト: stephenh67/pygame
    def test_collidedict__invalid_dict_format(self):
        """Ensures collidedict correctly handles invalid dict parameters."""
        rect = Rect(0, 0, 10, 10)

        invalid_value_dict = ('collide', rect.copy())
        invalid_key_dict = tuple(invalid_value_dict[1]), invalid_value_dict[0]

        for use_values in (True, False):
            d = invalid_value_dict if use_values else invalid_key_dict

            with self.assertRaises(TypeError):
                collide_item = rect.collidedict(d, use_values)
コード例 #21
0
ファイル: ThrowedGrenade.py プロジェクト: dgalaktionov/Aleph
class ThrowedGrenade(Bullet):
	def __init__(self,creator, x, y, speedX, speedY, throwDistance):
		Bullet.__init__(self, creator, x, y, speedX, speedY, "items-1small.png", None, Rect(110, 120, 9, 11))
		self.rect = Rect(x, y, 0, 0)
		self.speedX = speedX
		self.speedY = speedY

		# Important if you want pinpoint accuracy
		self.floatX = float(self.rect.x)
		self.floatY = float(self.rect.y)


		if throwDistance > MAX_THROW_DISTANCE:
			throwDistance = MAX_THROW_DISTANCE

		self.timeToStop = throwDistance / GRENADE_SPEED
		self.timeToBoom = TIME_TO_BOOM
		self.atk = 70

	def update(self, time, scene):
		self.floatX += self.speedX * time * GRENADE_SPEED
		self.floatY += self.speedY * time * GRENADE_SPEED
		self.rect.x = roundToInt(self.floatX)
		self.rect.y = roundToInt(self.floatY)

		self.timeToBoom -= time

		if self.timeToBoom <= 0:
			scene.bulletGroup.remove(self)
			scene.bulletGroup.add(Explosion(self.rect.x, self.rect.y))

			# Kill people!
			originalRect = self.rect.copy()
			self.rect.inflate_ip(80, 80)  # 80x80 area damage
			
			enemies_hit = sprite.spritecollide(self, scene.enemyGroup, False)

			for enemy in enemies_hit:
				# Friendly fire
				if self.creator.__class__.__name__ == enemy.__class__.__name__:
					continue
				enemy.receive_attack(self.atk)

			if sprite.collide_rect(self, scene.player):
				scene.player.receive_attack(self.atk)

			self.rect = originalRect  # Restore the real rect

		self.timeToStop -= time

		if self.timeToStop <= 0:
			self.speedX = 0
			self.speedY = 0
コード例 #22
0
def bounce_in_box(bounce_obj_rect: Rect, bounce_obj_speed, box_rect: Rect):
    """
    The alternative version of `bounce_in_box_ip`. The function returns the result
    instead of updating the value of `bounce_obj_rect` and `bounce_obj_speed`.

    @return A tuple (new_bounce_obj_rect, new_bounce_obj_speed)
    """
    new_bounce_obj_rect = bounce_obj_rect.copy()
    new_bounce_obj_speed = bounce_obj_speed.copy()

    bounce_in_box_ip(new_bounce_obj_rect, new_bounce_obj_speed, box_rect)

    return (new_bounce_obj_rect, new_bounce_obj_speed)
コード例 #23
0
    def __init__(self, containing_rect: pygame.Rect, theming_parameters: Dict,
                 states: List[str], manager: IUIManagerInterface):

        self.containing_rect = containing_rect.copy()
        if self.containing_rect.width < 1:
            self.containing_rect.width = 1
        if self.containing_rect.height < 1:
            self.containing_rect.height = 1

        self.theming = theming_parameters

        self.shadow_width = 0
        self.border_width = 0

        self.states = {}
        for state in states:
            self.states[state] = DrawableShapeState(state)

        if 'normal' in states:
            self.active_state = self.states['normal']
        else:
            raise NotImplementedError(
                "No 'normal' state id supplied for drawable shape")

        self.previous_state = None

        if 'transitions' in self.theming:
            self.state_transition_times = self.theming['transitions']
        else:
            self.state_transition_times = {}

        self.ui_manager = manager
        self.shape_cache = self.ui_manager.get_theme().shape_cache

        self.aligned_text_rect = None
        self.click_area_shape = None

        self.states_to_redraw_queue = deque([])
        self.need_to_clean_up = True

        self.should_trigger_full_rebuild = True
        self.time_until_full_rebuild_after_changing_size = 0.35
        self.full_rebuild_countdown = self.time_until_full_rebuild_after_changing_size

        self.click_area_shape = None
        self.border_rect = None
        self.background_rect = None
        self.aligned_text_rect = None
        self.base_surface = None
コード例 #24
0
def bounce_off(bounce_obj_rect: Rect, bounce_obj_speed, hit_obj_rect: Rect,
               hit_obj_speed):
    """
    The alternative version of `bounce_off_ip`. The function returns the result
    instead of updating the value of `bounce_obj_rect` and `bounce_obj_speed`.

    @return A tuple (`new_bounce_obj_rect`, `new_bounce_obj_speed`)
    """
    new_bounce_obj_rect = bounce_obj_rect.copy()
    new_bounce_obj_speed = bounce_obj_speed.copy()

    bounce_off_ip(new_bounce_obj_rect, new_bounce_obj_speed, hit_obj_rect,
                  hit_obj_speed)

    return new_bounce_obj_rect, new_bounce_obj_speed
コード例 #25
0
    def __init__(self, input_data_queue: Deque[TextLayoutRect],
                 layout_rect: pygame.Rect, view_rect: pygame.Rect,
                 line_spacing: float):
        # TODO: supply only a width and create final rect shape or just a final height?
        self.input_data_rect_queue = input_data_queue.copy()
        self.layout_rect = layout_rect.copy()
        self.line_spacing = line_spacing

        self.view_rect = view_rect

        self.expand_width = False
        if self.layout_rect.width == -1:
            self.layout_rect.width = 0
            self.expand_width = True
            for rect in self.input_data_rect_queue:
                self.layout_rect.width += rect.width

        self.layout_rect_queue = None
        self.finalised_surface = None
        self.floating_rects: List[TextLayoutRect] = []
        self.layout_rows: List[TextBoxLayoutRow] = []
        self.row_lengths = []
        self.link_chunks = []
        self.letter_count = 0
        self.current_end_pos = 0

        self.alpha = 255
        self.pre_alpha_final_surf = None  # only need this if we apply non-255 alpha

        self.layout_rect_queue = self.input_data_rect_queue.copy()
        current_row = TextBoxLayoutRow(row_start_x=self.layout_rect.x,
                                       row_start_y=self.layout_rect.y,
                                       row_index=0,
                                       layout=self,
                                       line_spacing=self.line_spacing)
        self._process_layout_queue(self.layout_rect_queue, current_row)

        self.edit_buffer = 2
        self.cursor_text_row = None

        self.selection_colour = pygame.Color(128, 128, 200, 255)
        self.selected_chunks = []
        self.selected_rows = []

        self.x_scroll_offset = 0

        self.cursor_colour = pygame.Color('#FFFFFFFF')
コード例 #26
0
class Sprite:
    """
	A class to represent a sprite.
	
	Used for pygame displaying.
	Image generated with given color and size.
	"""

    # default constructor (must be called if overrided by inheritance)
    def __init__(self, x: int, y: int, w: int, h: int, color: tuple):
        self.__color = color
        self._image = Surface((w, h))
        self._image.fill(self.color)
        self._image = self._image.convert()
        self.rect = Rect(x, y, w, h)
        self.camera_rect = self.rect.copy()

    # Public getters for _image & __color so they remain private
    @property
    def image(self) -> Surface:
        return self._image

    @property
    def color(self) -> tuple:
        return self.__color

    @color.setter
    def color(self, new: tuple) -> None:
        " Called when Sprite.__setattr__('color',x)."
        assert isinstance(new, tuple) and len(new) == 3, "Value is not a color"
        self.__color = new
        #update image surface
        self._image.fill(self.color)

    def draw(self, surface: Surface) -> None:
        """ Render method,Should be called every frame after update.
		:param surface pygame.Surface: the surface to draw on.
		"""
        # If camera instancied: calculate render positon
        if Camera.instance:
            self.camera_rect = Camera.instance.apply(self)
            surface.blit(self._image, self.camera_rect)
        else:
            surface.blit(self._image, self.rect)
コード例 #27
0
    def world_to_screen_rect(self, rect: pg.Rect, is_world=True, clip=True):
        rect = rect.copy()
        if is_world:
            rect.x -= self.position[0]
            rect.y -= self.position[1]
        rect.x *= self.scale
        rect.y *= self.scale
        rect.w *= self.scale
        rect.h *= self.scale

        if self.cam_alignment[0] == self.ALIGNMENT_RIGHT:
            rect.x += self.display_port.x
        elif self.cam_alignment[0] == self.ALIGNMENT_CENTER:
            rect.x += self.display_port.x + (self.display_port.w // 2)
        elif self.cam_alignment[0] == self.ALIGNMENT_LEFT:
            rect.x += self.display_port.x + self.display_port.w
        if self.cam_alignment[1] == self.ALIGNMENT_BOTTOM:
            rect.y += self.display_port.y
        elif self.cam_alignment[1] == self.ALIGNMENT_CENTER:
            rect.y += self.display_port.y + (self.display_port.h // 2)
        elif self.cam_alignment[1] == self.ALIGNMENT_TOP:
            rect.y += self.display_port.y + self.display_port.h

        if clip:
            if rect.x < self.display_port.x:
                difference = self.display_port.x - rect.x
                rect.x += difference
                rect.w -= difference
            if rect.x + rect.w > self.display_port.x + self.display_port.w:
                difference = (rect.x + rect.w) - (self.display_port.x + self.display_port.w)
                rect.w -= difference

            if rect.y < self.display_port.y:
                difference = self.display_port.y - rect.y
                rect.y += difference
                rect.h -= difference
            if rect.y + rect.h > self.display_port.y + self.display_port.h:
                difference = (rect.y + rect.h) - (self.display_port.y + self.display_port.h)
                rect.h -= difference

            rect.w = max(rect.w, 0)
            rect.h = max(rect.h, 0)

        return rect
コード例 #28
0
 def draw_in_world(self, camera=None):
     """
     Отрисовка объекта в мире.
     :param camera: Камера, относительно которой нужно отрисовывать объект
     :return:
     """
     # Внимание! Меняя что-то здесь, не забывай поменять данную функцию в RotatableWorldObject!
     if self.visible:
         if self.image is not None:
             surface_to_draw = self.image.get_current_and_next()
             rect_to_draw = Rect.copy(self.object_rect)  # TODO: подумать, можно ли избежать здесь ненужного копирования
             if self.image.get_size() != self.object_rect.size:
                 # Если размер изображения не совпадает с размером объекта
                 surface_to_draw = pygame.transform.scale(self.image.get_current(), (self.object_rect.width, self.object_rect.height))
             if camera is not None:
                 rect_to_draw.x += camera.get_coords()[0]
                 rect_to_draw.y += camera.get_coords()[1]
             self.parent_world.parent_surface.blit(surface_to_draw, rect_to_draw)
             if self.need_to_animate:
                 self.image.next()
コード例 #29
0
ファイル: sprite.py プロジェクト: jedesjardins/pylike
class Sprite(Component):
    def __init__(self,
                 file,
                 frames,
                 columns,
                 frame_rect,
                 edge_buffer={
                     "left": 0,
                     "right": 0,
                     "top": 0,
                     "bottom": 0
                 }):
        self.file = file
        self.image = pygame.image.load("resources/" + file)
        self.frames = frames
        self.columns = columns
        self.frame_rect = Rect(frame_rect["x"], frame_rect["y"],
                               frame_rect["w"], frame_rect["h"])
        self.edge_buffer = edge_buffer
        self.curr_frame_rect = self.frame_rect.copy()
コード例 #30
0
ファイル: draw.py プロジェクト: nyukhalov/carla-ai
def round_rect(surface,
               rect: pg.Rect,
               color,
               rad: int = 20,
               border: int = 0,
               inside=(0, 0, 0, 0)):
    """
    Draw a rect with rounded corners to surface.  Argument rad can be specified
    to adjust curvature of edges (given in pixels).  An optional border
    width can also be supplied; if not provided the rect will be filled.
    Both the color and optional interior color (the inside argument) support
    alpha.
    """
    rect = pg.Rect(rect)
    zeroed_rect = rect.copy()
    zeroed_rect.topleft = 0, 0
    image = pg.Surface(rect.size).convert_alpha()
    image.fill((0, 0, 0, 0))
    _render_region(image, zeroed_rect, color, rad)
    if border:
        zeroed_rect.inflate_ip(-2 * border, -2 * border)
        _render_region(image, zeroed_rect, inside, rad)
    surface.blit(image, rect)
コード例 #31
0
ファイル: rect_test.py プロジェクト: CTPUG/pygame_cffi
 def test_copy(self):
     r = Rect(1, 2, 10, 20)
     c = r.copy()
     self.failUnlessEqual(c, r)
コード例 #32
0
 def test_copy(self):
     r = Rect(1, 2, 10, 20)
     c = r.copy()
     self.assertEqual(c, r)
コード例 #33
0
ファイル: ui_element.py プロジェクト: pepe1977/pygame_gui
    def __init__(self,
                 relative_rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 container: Union[IContainerLikeInterface, None],
                 *,
                 starting_height: int,
                 layer_thickness: int,
                 object_ids: Union[List[Union[str, None]], None] = None,
                 element_ids: Union[List[str], None] = None,
                 anchors: Dict[str, str] = None):

        self._layer = 0
        self.ui_manager = manager
        super().__init__(self.ui_manager.get_sprite_group())
        self.relative_rect = relative_rect.copy()
        self.rect = self.relative_rect.copy()
        self.ui_group = self.ui_manager.get_sprite_group()
        self.ui_theme = self.ui_manager.get_theme()
        self.object_ids = object_ids
        self.element_ids = element_ids
        self.anchors = anchors
        if self.anchors is None:
            self.anchors = {
                'left': 'left',
                'top': 'top',
                'right': 'left',
                'bottom': 'top'
            }
        self.drawable_shape = None  # type: Union['DrawableShape', None]
        self.image = None

        self.relative_bottom_margin = None
        self.relative_right_margin = None

        self.layer_thickness = layer_thickness
        self.starting_height = starting_height

        self.is_enabled = True
        self.hovered = False
        self.is_focused = False
        self.hover_time = 0.0

        self.pre_debug_image = None
        self._pre_clipped_image = None

        self._image_clip = None

        self._visual_debug_mode = False

        # Themed parameters
        self.shadow_width = None  # type: Union[None, int]
        self.border_width = None  # type: Union[None, int]
        self.shape_corner_radius = None  # type: Union[None, int]

        combined_ids = self.ui_manager.get_theme().build_all_combined_ids(
            self.element_ids, self.object_ids)
        if combined_ids is not None and len(combined_ids) > 0:
            self.most_specific_combined_id = combined_ids[0]
        else:
            self.most_specific_combined_id = 'no_id'

        if container is None:
            if self.ui_manager.get_root_container() is not None:
                container = self.ui_manager.get_root_container()
            else:
                container = self

        if isinstance(container, IContainerLikeInterface):
            self.ui_container = container.get_container()

        if self.ui_container is not None and self.ui_container is not self:
            self.ui_container.add_element(self)

        self._update_absolute_rect_position_from_anchors()

        self._update_container_clip()
コード例 #34
0
ファイル: level.py プロジェクト: ikn/wvoas
class Level (object):
    def __init__ (self, game, event_handler = None, ID = 0, cp = -1):
        self.game = game
        # input
        if event_handler is not None:
            event_handler.add_event_handlers({
                pg.KEYDOWN: self.skip,
                pg.MOUSEBUTTONDOWN: self.skip
            })
            event_handler.add_key_handlers([
                (conf.KEYS_BACK, self.pause, eh.MODE_ONDOWN),
                (conf.KEYS_RESET, self.reset, eh.MODE_ONDOWN),
                (conf.KEYS_JUMP, self.jump, eh.MODE_ONDOWN_REPEAT, 1, 1)
            ] + [
                (ks, [(self.move, (i,))], eh.MODE_HELD)
                for i, ks in enumerate((conf.KEYS_LEFT, conf.KEYS_RIGHT))
            ])
        w, h = conf.RES
        self.centre = (w / 2, h / 2)
        ww, wh = conf.WINDOW_SIZE
        border = (2 * (ww + 5), 2 * (wh + 5))
        self.window_bds = pg.Rect(0, 0, w, h).inflate(border)
        self.clouds = []
        self.load_graphics()
        if event_handler is not None:
            self.move_channel = game.move_channel
            self.star_channel = game.star_channel
        else:
            self.move_channel = None
            self.star_channel = None
        # load first level
        self.ID = None
        self.init(ID, cp)

    def init (self, ID = None, cp = None):
        self.paused = False
        self.dying = False
        self.first_dying = False
        self.winning = False
        self.fading = False
        self.particles = []
        self.particle_rects = []
        self.void_jitter = [conf.VOID_JITTER_X, conf.VOID_JITTER_Y, conf.VOID_JITTER_T]
        self.first = True
        # get level/current checkpoint
        if ID is None:
            # same level
            ID = self.ID
        if ID != self.ID:
            # new level
            self.ID = ID
            self.current_cp = cp if cp is not None else -1
            # clouds: randomise initial positions and velocities
            self.clouds = cs = []
            w, h = conf.RES
            imgs = self.imgs
            vx0 = conf.CLOUD_SPEED
            vy0 = vx0 * conf.CLOUD_VERT_SPEED_RATIO
            self.cloud_vel = [vx0 * random0(), vy0 * random0()]
            vx = conf.CLOUD_MOD_SPEED_RATIO
            vy = vx * conf.CLOUD_VERT_SPEED_RATIO
            for c in conf.CLOUDS:
                c_w, c_h = imgs[c].get_size()
                s = (c_w, c_h)
                c_w /= 2
                c_h /= 2
                pos = [randint(-c_w, w - c_w), randint(-c_h, h - c_h)]
                vel = [vx * random0(), vy * random0()]
                cs.append((pos, vel, s))
        elif cp is not None:
            self.current_cp = cp
        data = conf.LEVELS[ID]
        # background
        self.bgs = data.get('bgs', conf.DEFAULT_BGS)
        # player
        if self.current_cp >= 0:
            p = list(data['checkpoints'][self.current_cp][:2])
            s_p, s_c = conf.PLAYER_SIZE, conf.CHECKPOINT_SIZE
            for i in (0, 1):
                p[i] += float(s_c[i] - s_p[i]) / 2
        else:
            p = data['player_pos']
        self.player = Player(self, p)
        # window
        x, y = Rect(self.to_screen(self.player.rect)).center
        w, h = conf.HALF_WINDOW_SIZE
        self.window = Rect(x - w, y - h, 2 * w, 2 * h)
        self.old_window = self.window.copy()
        # checkpoints
        s = conf.CHECKPOINT_SIZE
        self.checkpoints = [Rect(p + s) for p in data.get('checkpoints', [])]
        # goal
        self.goal = Rect(data['goal'] + conf.GOAL_SIZE)
        self.goal_img = self.goal.move(conf.GOAL_OFFSET)
        self.goal_img.size = self.imgs['goal'].get_size()
        # stars
        self.stars = [Star(self, p, [ID, i] in conf.STARS)
                      for i, p in enumerate(data.get('stars', []))]
        if self.star_channel is not None and not all(s.got for s in self.stars):
            self.star_channel.unpause()
        # rects
        self.all_rects = [Rect(r) for r in data.get('rects', [])]
        self.all_vrects = [Rect(r) for r in data.get('vrects', [])]
        self.arects = [Rect(r) for r in data.get('arects', [])]
        self.update_rects()

    def skip (self, evt):
        if self.dying and self.dying_counter < conf.DIE_SKIP_THRESHOLD and \
           not (evt.type == pg.KEYDOWN and evt.key in conf.KEYS_BACK) and \
           not self.winning:
            self.init()
        elif conf.DEBUG and evt.type == pg.MOUSEBUTTONDOWN:
            r = self.player.rect
            c = self.window.center
            print 'moving to', c
            for i in (0, 1):
                r[i] = c[i] - (r[i + 2] / 2)
            self.player.old_rect = r

    def pause (self, *args):
        if self.move_channel is not None:
            self.move_channel.pause()
        if self.star_channel is not None:
            self.star_channel.pause()
        self.game.start_backend(ui.Paused, self)
        self.paused = True

    def reset (self, *args):
        if not self.winning:
            self.init()

    def jump (self, key, mode, mods):
        self.player.jump(mode == 0)

    def move (self, key, mode, mods, i):
        self.player.move(i)

    def update_window (self):
        w = self.window
        wp0 = w.topleft
        wp1 = w.bottomright
        s = conf.RES
        self.inverse_win = rs = []
        for px in (0, 1, 2):
            for py in (0, 1, 2):
                if px == py == 1:
                    continue
                r = [0, 0, 0, 0]
                for i, p in enumerate((px, py)):
                    if p == 0:
                        r[i + 2] = wp0[i]
                    if p == 1:
                        r[i] = wp0[i]
                        r[i + 2] = wp1[i] - wp0[i]
                    elif p == 2:
                        r[i] = wp1[i]
                        r[i + 2] = s[i] - wp1[i]
                if r[2] > 0 and r[3] > 0:
                    rs.append(Rect(r))

    def get_clip (self, r1, r2, err = 0):
        x01, y01, w, h = r1
        x11, y11 = x01 + w, y01 + h
        x02, y02, w, h = r2
        x12, y12 = x02 + w, y02 + h
        x0, y0 = max(x01, x02), max(y01, y02)
        x1, y1 = min(x11, x12), min(y11, y12)
        w, h = x1 - x0, y1 - y0
        if w > err and h > err:
            return (x0, y0, w, h)

    def update_rects (self):
        self.update_window()
        # rects
        self.rects = rects = []
        self.draw_rects = draw = []
        w = self.window
        for r in self.all_rects:
            c = w.clip(r)
            if c:
                rects.append(c)
                draw.append(r)
        # vrects
        self.vrects = rects = []
        ws = self.inverse_win
        for r in self.all_vrects:
            for w in ws:
                c = w.clip(r)
                if c:
                    rects.append(c)

    def handle_collisions (self):
        get_clip = self.get_clip
        p = self.player.rect
        p0 = list(p)
        for r in self.rects + self.vrects + self.arects:
            if get_clip(r, p):
                r_x0, r_y0, w, h = r
                r_x1, r_y1 = r_x0 + w, r_y0 + h
                p_x0, p_y0, w, h = p
                p_x1, p_y1 = p_x0 + w, p_y0 + h
                x, dirn = min((p_x1 - r_x0, 0), (p_y1 - r_y0, 1),
                              (r_x1 - p_x0, 2), (r_y1 - p_y0, 3))
                axis = dirn % 2
                p[axis] += (1 if dirn >= 2 else -1) * x
                self.player.impact(axis, 0)
                if axis == 1:
                    self.vert_dirn = dirn
        # screen left/right
        if p[0] < 0:
            p[0] = 0
            self.player.impact(0, 0)
        elif p[0] + p[2] > conf.RES[0]:
            p[0] = conf.RES[0] - p[2]
            self.player.impact(0, 0)
        # die if still colliding
        axes = set()
        e = conf.ERR
        colliding = [r for r in self.rects + self.vrects + self.arects \
                     if get_clip(r, p, e)]
        if colliding:
            for r in colliding:
                r_x0, r_y0, w, h = r
                r_x1, r_y1 = r_x0 + w, r_y0 + h
                p_x0, p_y0, w, h = p
                p_x1, p_y1 = p_x0 + w, p_y0 + h
                x, dirn = min((p_x1 - r_x0, 0), (p_y1 - r_y0, 1),
                              (r_x1 - p_x0, 2), (r_y1 - p_y0, 3))
                axes.add(dirn % 2)
            if len(axes) == 2:
                dirn = .5
            else:
                dirn = .95 if axes.pop() == 0 else .1
            self.die(dirn)

    def die (self, dirn = .5):
        self.first_dying = True
        self.dying = True
        self.dying_counter = conf.DIE_TIME
        # particles
        pos = list(Rect(self.to_screen(self.player.rect)).center)
        self.add_ptcls('die', pos, dirn)
        # sound
        if self.move_channel is not None:
            self.move_channel.pause()
        self.game.play_snd('die')

    def next_level (self, save = True, progress = True):
        if progress:
            if self.move_channel is not None:
                self.move_channel.pause()
            if self.star_channel is not None:
                self.star_channel.pause()
        i = self.ID
        if not conf.COMPLETED and i + 1 in conf.EXISTS:
            # there's a next level
            if save:
                conf.CURRENT_LEVEL = i + 1
            if progress:
                self.init(i + 1)
        else:
            if save:
                conf.COMPLETED = True
            if progress:
                self.game.switch_backend(ui.LevelSelect)

    def win (self):
        if self.winning:
            return
        self.winning = True
        self.next_level(progress = False)
        if self.ID not in conf.COMPLETED_LEVELS:
            conf.COMPLETED_LEVELS.append(self.ID)
        conf.dump()
        self.start_fading(lambda: self.next_level(False))

    def update (self):
        # fade counter
        if self.fading:
            self.fade_counter -= 1
            if self.fade_counter == 0:
                self.fading = False
                del self.fade_sfc
                self.fade_cb()
        # move player
        if not self.dying:
            pl = self.player
            pl.update()
        # get amount to move window by
        w = self.window
        self.old_window = w.copy()
        x0, y0 = self.centre
        if self.paused or self.first:
            dx = dy = 0
            self.first = False
        else:
            x, y = pg.mouse.get_pos()
            dx, dy = x - x0, y - y0
            # don't move too far outside the screen
            w_moved = w.move(dx, dy).clamp(self.window_bds)
            dx, dy = w_moved[0] - w[0], w_moved[1] - w[1]
        pg.mouse.set_pos(x0, y0)
        wx0, wy0, ww, wh = self.total_window = w.union(w.move(dx, dy))
        # move window
        if self.dying:
            # just move window
            w.move_ip(dx, dy)
            self.update_rects()
        else:
            self.vert_dirn = 3
            if dx == dy == 0:
                # just handle collisions
                self.handle_collisions()
            else:
                # check if player and window intersect
                wx1, wy1 = wx0 + ww, wy0 + wh
                r = pl.rect
                o_r = pl.old_rect
                px0, py0 = min(r[0], o_r[0]), min(r[1], o_r[1])
                px1 = max(r[0] + r[2], o_r[0] + o_r[2])
                py1 = max(r[1] + r[3], o_r[1] + o_r[3])
                if px1 > wx0 and py1 > wy0 and px0 < wx1 and py0 < wy1:
                    # if so, move window a few pixels at a time
                    c = conf.WINDOW_MOVE_AMOUNT
                    for axis, d in ((0, dx), (1, dy)):
                        dirn = 1 if d > 0 else -1
                        while d * dirn > 0:
                            d -= dirn * c
                            rel = [0, 0]
                            rel[axis] += c * dirn + (0 if d * dirn > 0 else d)
                            w.move_ip(rel)
                            self.update_rects()
                            if not self.dying:
                                self.handle_collisions()
                else:
                    # else move it the whole way
                    w.move_ip(dx, dy)
                    self.update_rects()
                    self.handle_collisions()
            if self.vert_dirn == 1:
                pl.on_ground = conf.ON_GROUND_TIME
        # clouds
        if self.clouds:
            # jitter
            jx = conf.CLOUD_JITTER
            jy = jx * conf.CLOUD_VERT_SPEED_RATIO
            v0 = self.cloud_vel
            v0[0] += jx * random0()
            v0[1] += jy * random0()
            r = conf.RES
            for p, v, s in self.clouds:
                for i, (i_w, r_w) in enumerate(zip(s, r)):
                    # move
                    x = p[i]
                    x += v0[i] + v[i]
                    # wrap
                    if x + i_w < 0:
                        x = r_w
                    elif x > r_w:
                        x = -i_w
                    p[i] = x
        # particles
        ptcls = []
        rects = []
        for k, j, group in self.particles:
            g = []
            x0, y0 = conf.RES
            x1 = y1 = 0
            for c, p, v, size, t in group:
                x, y = p
                # update boundary
                if x < x0:
                    x0 = x
                if y < y0:
                    y0 = y
                if x + size > x1:
                    x1 = x + size
                if y + size > y1:
                    y1 = y + size
                t -= 1
                if t != 0:
                    # move
                    vx, vy = v
                    x += vx
                    y += vy
                    # update boundary
                    if x < x0:
                        x0 = x
                    if y < y0:
                        y0 = y
                    if x + size > x1:
                        x1 = x + size
                    if y + size > y1:
                        y1 = y + size
                    # damp/jitter
                    vx *= k
                    vy *= k
                    vx += j * random0()
                    vy += j * random0()
                    g.append((c, (x, y), (vx, vy), size, t))
            if g:
                ptcls.append((k, j, g))
            if x1 > x0 and y1 > y0:
                rects.append((int(x0), int(y0), ceil(x1 - x0), ceil(y1 - y0)))
        self.particles = ptcls
        self.particle_rects = rects
        # death counter
        if self.dying:
            self.dying_counter -= 1
            if self.dying_counter == 0:
                self.init()
            return
        # player velocity
        pl.update_vel()
        # die if OoB
        if pl.rect[1] > conf.RES[1]:
            self.die()
        # win if at goal
        p = pl.rect
        c = w.clip(self.goal)
        if c and self.get_clip(p, c):
            self.win()
        # check if at checkpoints
        for c in self.checkpoints[self.current_cp + 1:]:
            if w.clip(c) and self.get_clip(p, c):
                self.current_cp += 1
        # check if at stars
        for i, s in enumerate(self.stars):
            if not s.got and w.clip(s.rect) and self.get_clip(p, s.rect):
                #self.game.play_snd('collectstar')
                if self.star_channel is not None and all(s.got for s in self.stars):
                    self.star_channel.pause()
                s.got = True
                conf.STARS.append([self.ID, i])
                conf.dump()

    def load_graphics (self):
        self.imgs = imgs = {}
        for img in ('void', 'window', 'rect', 'vrect', 'arect',
                    'checkpoint-current', 'checkpoint', 'goal') + \
                   conf.BGS + conf.CLOUDS:
            imgs[img] = self.game.img(img + '.png')
        self.window_sfc = pg.Surface(conf.WINDOW_SIZE).convert_alpha()

    def to_screen (self, rect):
        return [ir(x) for x in rect]

    def add_ptcls (self, key, pos, dirn = .5):
        particles = []
        data = conf.PARTICLES[key]
        max_speed = data['speed']
        max_size = data['size']
        k = data['damping']
        j = data['jitter']
        max_life = data['life']
        dirn *= pi / 2
        for c, amount in data['colours']:
            a, b = divmod(amount, 1)
            amount = int(a) + (1 if random() < b else 0)
            while amount > 0:
                size = randint(1, max_size)
                amount -= size
                angle = random() * 2 * pi
                speed = max_speed * expovariate(5)
                v = (speed * cos(dirn) * cos(angle), speed * sin(dirn) * sin(angle))
                life = int(random() * max_life)
                if life > 0:
                    particles.append((c, tuple(pos), v, size, life))
        self.particles.append((k, j, particles))

    def start_fading (self, cb):
        if not self.fading:
            self.fading = True
            self.fade_counter = conf.FADE_TIME
            self.fade_sfc = pg.Surface(conf.RES).convert_alpha()
            self.fade_cb = cb

    def update_jitter (self, jitter):
        if len(jitter) == 3:
            jx, jy, t0 = jitter
            t = t0
            ox, oy = randint(0, jx), randint(0, jy)
            jitter += [ox, oy, t]
        else:
            jx, jy, t0, ox, oy, t = jitter
            if t == 0:
                ox, oy = randint(0, jx), randint(0, jy)
                jitter[3] = ox
                jitter[4] = oy
                jitter[5] = t0
        jitter[5] -= 1

    def draw (self, screen):
        # don't draw on last frame
        #if not self.game.running:
            #return False
        imgs = self.imgs
        w = self.window
        pl = self.player
        pl.pre_draw()
        # background
        jitter = self.void_jitter
        self.update_jitter(jitter)
        ox, oy = jitter[3], jitter[4]
        img = imgs['void']
        draw_all = jitter[5] == conf.VOID_JITTER_T - 1 or self.fading or self.paused
        if self.paused:
            self.paused = False
        if draw_all:
            tile(screen, img, (0, 0) + screen.get_size(), ox, oy)
        else:
            draw_rects = self.particle_rects + [self.total_window, self.goal_img]
            if self.first_dying or not self.dying:
                draw_rects.append(pl.rect_img.union(pl.old_rect_img))
            for r in draw_rects:
                tile(screen, img, r, ox, oy, (0, 0))
        # vrects
        img = imgs['vrect']
        for r in self.all_vrects:
            tile(screen, img, r)
        # window
        offset = (-w[0], -w[1])
        w_sfc = self.window_sfc
        # window background: static images
        for img in self.bgs:
            if isinstance(img, str):
                pos = (0, 0)
            else:
                img, pos = img
            w_sfc.blit(imgs[img], Rect(pos + (0, 0)).move(offset))
        # clouds
        for c, (p, v, s) in zip(conf.CLOUDS, self.clouds):
            w_sfc.blit(imgs[c], Rect(self.to_screen(p + [0, 0])).move(offset))
        # rects in window
        img = imgs['rect']
        for r, r_full in zip(self.rects, self.draw_rects):
            tile(w_sfc, img, r.move(offset), full = r_full.move(offset))
        # checkpoints
        for i, r in enumerate(self.checkpoints):
            img = imgs['checkpoint' + ('-current' if i == self.current_cp else '')]
            w_sfc.blit(img, r.move(offset))
        # window border
        w_sfc.blit(imgs['window'], (0, 0), None, pg.BLEND_RGBA_MULT)
        # copy window area to screen
        screen.blit(w_sfc, w)
        # arects
        img = imgs['arect']
        for r in self.arects:
            tile(screen, img, r)
        # goal
        screen.blit(imgs['goal'], self.goal_img)
        # stars
        for s in self.stars:
            if not s.got:
                s.draw(screen, (0, 0))
        # player
        if not self.dying:
            pl.draw(screen)
        # particles
        for k, j, g in self.particles:
            for c, p, v, size, t in g:
                screen.fill(c, p + (size, size))
        # fadeout
        if self.fading:
            t = conf.FADE_TIME - self.fade_counter
            alpha = conf.FADE_RATE * float(t) / conf.FADE_TIME
            alpha = min(255, ir(alpha))
            self.fade_sfc.fill((0, 0, 0, alpha))
            screen.blit(self.fade_sfc, (0, 0))
            draw_all = True
        if self.first_dying:
            self.first_dying = False
        if draw_all:
            return True
        else:
            return draw_rects + self.arects
コード例 #35
0
ファイル: object.py プロジェクト: DanCardin/PyPlatformer
class Object(object):
    def __init__(self, **kwargs):
        x, y, w, h = None, None, None, None
        if kwargs.get("rect", None):
            x, y, w, h = kwargs.pop("rect", None)
        elif kwargs.get("pos") or kwargs.get("size"):
            x, y = kwargs.pop("pos", (0, 0))
            w, h = kwargs.pop("size", (0, 0))
        else:
            x, y = kwargs.pop("x", 0), kwargs.pop("y", 0)
            w, h = kwargs.pop("w", 0), kwargs.pop("h", 0)

        super().__init__(**kwargs)

        assert None not in [x, y, w, h]

        self._rect = Rect(x, y, w, h)

    def asRect(self):
        return Rect(self.x, self.y, self.w, self.h)

    def copy(self):
        return self._rect.copy()

    def colliderect(self, collide):
        return self._rect.colliderect(collide.asRect())

    @property
    def top(self):
        return self._rect.top

    @top.setter
    def top(self, value):
        self._rect.top = value

    @property
    def bottom(self):
        return self._rect.bottom

    @bottom.setter
    def bottom(self, value):
        self._rect.bottom = value

    @property
    def left(self):
        return self._rect.left

    @left.setter
    def left(self, value):
        self._rect.left = value

    @property
    def right(self):
        return self._rect.right

    @right.setter
    def right(self, value):
        self._rect.right = value

    @property
    def x(self):
        return self._rect.x

    @x.setter
    def x(self, value):
        self._rect.x = value

    @property
    def y(self):
        return self._rect.y

    @y.setter
    def y(self, value):
        self._rect.y = value

    @property
    def w(self):
        return self._rect.w

    @w.setter
    def w(self, value):
        self._rect.w = value

    @property
    def h(self):
        return self._rect.h

    @h.setter
    def h(self, value):
        self._rect.h = value

    def __repr__(self):
        return repr(self._rect)
コード例 #36
0
ファイル: textsprites.py プロジェクト: Fenixin/yogom
class MultiLineTextSprite(TryMovingSprite):

    A_LEFT = 0
    A_CENTER = 1
    A_RIGHT = 2

    def __init__(self, font_render, text, size, background, layers,
                 x=0, y=0, align=1, line_spacer=0, bg_transparent=True ):
        """ Background is transparent by defualt. 
        
        align:
        0 - left
        1 - center
        2 - right
        
        """

        # Render the image
        self.font = font_render
        self._text = text
        self.size = size
        self.background = background
        self.bg_transparent = bg_transparent
        self.align = align
        self.line_spacer = line_spacer
        self.layers = layers
        
        img = self.render(text)
        if bg_transparent:
            img.set_colorkey(background)

        TryMovingSprite.__init__(self, img, x, y, img.get_rect())

    @property
    def text(self):
        return self._text

    @text.setter
    def text(self, value):
        self._text = value
        self.image = self.render(value)
        self.rect = Rect((self.rect[0], self.rect[1]), self.image.get_rect()[2:])
        self.col_rect = self.rect.copy()
        self.mask = mask.from_surface(self.image)
        self.create_feet()

    def _calculate_image_size(self, font_render, text, size, line_spacer, layers):
        lines = text.splitlines()
        ls = line_spacer
        xs = 0
        ys = 0
        for l in lines:
            w, h = font_render.size(l, size, layers)
            xs = max(xs, w)
            ys += h + ls
        
        # Don't put a line spacer for one line text
        if len(lines) == 1:
            ys -= ls
        return xs, ys

    def render(self, text):
        """ Renders the text using the options first used. """

        lines = text.splitlines()
        img = Surface(self._calculate_image_size(self.font, 
                             self.text, self.size, self.line_spacer, self.layers))
        if self.bg_transparent:
            img.set_colorkey(self.background)
        full_rect = img.get_rect()
        
        y = 0
        for l in lines:
            r = self.font.render(l, self.size, self.background, self.bg_transparent, self.layers)
            r_rect = r.get_rect()
            if self.bg_transparent:
                r.set_colorkey(self.background)
            if self.align == self.A_CENTER:
                x = self._center_rect_inside_rect(r_rect, full_rect)
            elif self.align == self.A_LEFT:
                x = 0
            elif self.align == self.A_RIGHT:
                x = full_rect[3] - r_rect[3]
            img.blit(r, (x, y))
            y += self.line_spacer + r_rect[3]
        
        return img
            
    def _center_rect_inside_rect(self, rect1, rect2, offset=0):
        x = (rect2[2] - rect1[2])/2 + offset
        return x
コード例 #37
0
ファイル: rect_test.py プロジェクト: annie60/Xilarius
 def test_copy(self):
     r = Rect(1, 2, 10, 20)
     c = r.copy()
     self.failUnlessEqual(c, r)
コード例 #38
0
ファイル: model.py プロジェクト: YoannQDQ/pyweek-dojo
class PlayerModel(BaseModel):
    """Player model. Most of the game physics is implemented here."""

    # Physics
    air_friction = 0.5, 0.5   # s-1
    gravity = 0, 981          # pixel/s-2
    load_speed = 600          # pixel/s-2
    init_speed = 250          # pixel/s
    max_loading_speed = 1000  # pixel/s

    # Animation
    period = 2.0           # s
    pre_jump = 0.25        # s
    load_factor_min = 5    # period-1
    load_factor_max = 10   # period-1
    blinking_period = 0.2  # s

    # Hitbox
    hitbox_ratio = 0.33

    # Direction to Rect attributes for wall collision
    collide_dct = {Dir.DOWN: "bottom",
                   Dir.LEFT: "left",
                   Dir.RIGHT: "right",
                   Dir.UP: "top"}

    # Resource to get the player size
    ref = "player_1"

    def init(self, pid):
        """Initialize the player."""
        # Attributes
        self.id = pid
        self.border = self.parent.border
        self.resource = self.control.resource
        # Player rectangle
        self.size = self.resource.image.get(self.ref)[0].get_size()
        self.rect = Rect((0, 0), self.size)
        if pid == 1:
            self.rect.bottomleft = self.border.rect.bottomleft
        else:
            self.rect.bottomright = self.border.rect.bottomright
        # Player state
        self.speed = self.remainder = xytuple(0.0, 0.0)
        self.control_dir = Dir.NONE
        self.save_dir = Dir.NONE
        self.pos = Dir.DOWN
        self.fixed = True
        self.ko = False
        self.steps = [self.rect]
        # Animation timer
        self.timer = Timer(self,
                           stop=self.period,
                           periodic=True).start()
        # Loading timer
        self.loading_timer = Timer(self,
                                   start=self.init_speed,
                                   stop=self.max_loading_speed)
        # Delay timer
        self.delay_timer = Timer(self,
                                 stop=self.pre_jump,
                                 callback=self.delay_callback)
        # Dying timer
        self.blinking_timer = Timer(self.parent.parent,
                                    stop=self.blinking_period,
                                    periodic=True)
        # Debug
        if self.control.settings.debug_mode:
            RectModel(self, "head", Color("red"))
            RectModel(self, "body", Color("green"))
            RectModel(self, "legs", Color("blue"))

    def register_dir(self, direction):
        """Register a new direction from the controller."""
        if any(direction):
            self.save_dir = direction
        self.control_dir = direction

    @property
    def delta_tuple(self):
        """Delta time as an xytuple."""
        return xytuple(self.delta, self.delta)

    @property
    def colliding(self):
        """True when colliding with the other player, False otherwise."""
        return self.parent.colliding

    @property
    def loading(self):
        """True when the player is loading a jump, False otherwise."""
        return self.loading_timer.is_set or not self.loading_timer.is_paused

    @property
    def prepared(self):
        """True when the player is prepared a jump, False otherwise."""
        return self.loading or not self.delay_timer.is_paused

    @property
    def loading_speed(self):
        """The current loading speed value."""
        return self.loading_timer.get()

    def set_ko(self):
        """Knock the player out."""
        self.ko = True
        self.fixed = False

    def load(self):
        """Register a load action."""
        if self.colliding:
            return
        self.delay_timer.reset().start()
        self.timer.set(self.period*0.9)

    def delay_callback(self, timer):
        """Start loading the jump."""
        self.loading_timer.reset().start(self.load_speed)
        self.timer.reset().start()

    def jump(self):
        """Make the player jump."""
        if self.colliding:
            return
        # Check conditions
        if self.fixed and not self.ko:
            dir_coef = self.current_dir
            if any(dir_coef):
                dir_coef /= (abs(dir_coef),)*2
                # Update speed
                self.speed += dir_coef * ((self.loading_speed,)*2)
            # Update status
            if self.pos != Dir.DOWN or any(dir_coef):
                self.save_dir = Dir.NONE
                self.pos = Dir.NONE
                self.fixed = False
        # Reset loading
        self.delay_timer.reset()
        self.loading_timer.reset()
        # Reset animation
        self.timer.reset().start()

    def update_collision(self):
        """Handle wall collisions."""
        collide_dct = dict(self.collide_dct.items())
        # Loop over changes
        while not self.border.rect.contains(self.rect):
            self.fixed = True
            self.save_dir = self.control_dir
            dct = {}
            # Test against the 4 directions.
            for direc, attr in collide_dct.items():
                rect = self.rect.copy()
                value = getattr(self.border.rect, attr)
                setattr(rect, attr, value)
                distance = abs(xytuple(*rect.topleft) - self.rect.topleft)
                dct[distance] = rect, direc, attr
            # Aply the smallest change
            self.rect, self.pos, _ = dct[min(dct)]
            del collide_dct[self.pos]
        # Do not grab the wall when KO
        if self.ko and self.pos != Dir.DOWN:
            self.fixed = False

    @property
    def loading_ratio(self):
        """Loading ratio between 0 and 1."""
        res = float(self.loading_speed - self.init_speed)
        return res / (self.max_loading_speed - self.init_speed)

    @property
    def current_dir(self):
        """Current direction with x and y in (-1, 0, 1)."""
        # Static case
        if self.fixed:
            if not any(self.save_dir) or \
               sum(self.save_dir*self.pos) > 0:
                return xytuple(0, 0)
            current_dir = self.save_dir - self.pos
            sign = lambda arg: cmp(arg, 0)
            return current_dir.map(sign)
        # Dynamic case
        return Dir.closest_dir(self.speed)

    def get_rect_from_dir(self, direction):
        """Compute a hitbox inside the player in a given direction."""
        size = xytuple(*self.size) * ((self.hitbox_ratio,)*2)
        attr = Dir.DIR_TO_ATTR[direction]
        rect = Rect((0, 0), size)
        value = getattr(self.rect, attr)
        setattr(rect, attr, value)
        return rect

    @property
    def head(self):
        """Head hitbox. Currently not used."""
        if self.ko:
            return Rect(0, 0, 0, 0)
        if self.fixed:
            return self.get_rect_from_dir(self.pos * (-1, -1))
        return self.get_rect_from_dir(self.current_dir * (-1, -1))

    @property
    def body(self):
        """Body hitbox. Currently not used."""
        if self.ko:
            return Rect(0, 0, 0, 0)
        return self.get_rect_from_dir(Dir.NONE)

    @property
    def legs(self):
        """Legs hitbox."""
        if self.ko or self.fixed:
            return Rect(0, 0, 0, 0)
        return self.get_rect_from_dir(self.current_dir)

    def update(self):
        """Update the player state."""
        # Get acc
        acc = -self.speed * self.air_friction
        acc += self.gravity
        # Update speed
        self.speed += self.delta_tuple * acc
        if self.fixed:
            self.speed *= 0, 0
        # Get step
        step = self.delta_tuple * self.speed
        step += self.remainder
        intstep = step.map(round)
        self.remainder = step - intstep
        # Register steps
        args = Rect(self.rect), self.rect.move(intstep)
        self.steps = list(Dir.generate_rects(*args))
        # Update timer
        if self.loading:
            delta = self.load_factor_max - self.load_factor_min
            ratio = self.load_factor_min + self.loading_ratio * delta
            self.timer.start(ratio)
コード例 #39
0
ファイル: sprites.py プロジェクト: Fenixin/yogom
class TrySprite(DirtySprite):
    """ A sprite class with all the needed things for try-engine.

    TrySprite subclasses pygame.sprite.DirtySprite. It adds
    some mandatory attributes as col_rect and adds a few methods
    to control the render order.

    It also has a host-guest sprite thingy that makes sure the host sprite
    is updated before the guests sprites. You can attach sprites to sprites
    and it will look nice.

    TrySprites adds the rects: col_rect, i_rect, feet_rect
    dirty_rect, col_rect_left, col_rect_right

    TODO: This is probably outdated!
    The dirty attribute does NOT mean the same as in pygame. The
    meaning is:
     0 = The srpite has been drawn in this frame
     1 = hasn't been drawn in this frame yet
     2 = nothing at the moment

    """
    def __init__(self, img, x, y, col_rect):
        DirtySprite.__init__(self)
        self.image = img
        self.rect = Rect((x,y),self.image.get_rect()[2:])

        self.visible = 1
        self.dirty = 1

        # Directions in which this sprite collide
        self.col_direction = (True, True, True, True)
        
        # Has this sprite sprites attached to him? or the opposite
        # If this is used the guest sprite will be always updated
        # after the host sprite.
        self.guest = False
        self.guests = Group()
        self.host = None

        # Create all the needed rects:
        self.init_rects(self.rect, col_rect)
        
        # Init mask
        self.init_masks()
        
        # if True will print lots of debugging stuff
        self.debugging = False

    def init_rects(self, rect, col_rect):
        """ Create all the rects needed for the sprite
        
        Creates: collision rect, feet rect, interpolation rect, 
        dirty rect and collision mask.

        """
        # List holding all the rects, allow for fast iteration 
        # over all the rects
        self.rect_list = rl = []
        rl.append(self.rect)
        
        # Rect used for collisions
        self.col_rect = col_rect.copy().move(rect[:2])
        rl.append(self.col_rect)
        
        # Used to know where was the last interpolated position
        # TODO: do we use this????
        self.i_rect = rect.copy()
        rl.append(self.i_rect)
        
        # Rect to clear this sprite when drawing
        self.dirty_rect = rect.copy()
        rl.append(self.i_rect)

        # Create a rect representing the feet
        self.feet_rect = self.create_feet()
        rl.append(self.feet_rect)
        
        # Create left and right collision rects
        self.col_rect_left, self.col_rect_right = self.create_left_right()
        rl.append(self.col_rect_left)
        rl.append(self.col_rect_right)

    def create_feet(self):
        """ Creates a pygame Rect that will represent the feet. """
        
        cr = self.col_rect
        # One pixel height rect at the feet, overlapping the col_rect
        # PLEASE NOTE: Any additional rect used for collisions needs to
        # be contained by col_rect, if not bad things happens (colision
        # is detected by one rect but no the other and both are used in
        # orther to collide with all the platforms). That is way the
        # -1 is needed in cr.bottom.
        return Rect(cr.left, cr.bottom - 1, cr.width, 1)
        
        # TODO: This has a problem with col_rects the same size as the
        # normal rect

    def create_left_right(self):
        """ Creates two rects each one being a half of col_rect.
        
        These rects are used to detect which side of the sprites
        touches something.
        """
        
        cr = self.col_rect
        col_rect_left = Rect(cr.left, cr.top, cr.width /2 , cr.height)
        col_rect_right = Rect(cr.left + cr.width/2, cr.top,  cr.width /2, cr.height)
        
        return col_rect_left, col_rect_right

    def init_masks(self):
        """ Init the mask for the sprite. 

        NOTE: any additional rect created must be, in general, inside
        of col_rect. That way collisions will work properly
        
        """
        
        # Create a mask with the image
        # TODO, NOTE TO SELF: The mask will use the first frame
        # in the animation! ALWAYS
        self.mask = mask.from_surface(self.image)
        #~ self.view_mask()

        # Feet mask
        self.feet_mask = mask.Mask((self.rect.width, 1))
        h = self.rect.height
        s_at = self.feet_mask.set_at
        g_at = self.mask.get_at
        for x in xrange(self.rect.width):
            if g_at((x, h - 1)):
                s_at((x, 0), 1)

    #~ @property
    #~ def dirty(self):
        #~ return self._dirty
    #~ 
    #~ @dirty.setter
    #~ def dirty(self, value):
        #~ if self.dirty == 1:
            #~ old = self.dirty_rect
        #~ else:
            #~ old = self.rect
        #~ self.dirty_rect  = old.union(self.rect)
        #~ self._dirty = value

    def add_guest(self, sprite):
        """ Add a guest sprite to this sprite.
        
        The guest sprite will be updated after the host.
         """
         
        self.guests.add(sprite)
        sprite.guest = True
        sprite.host = self
    
    def remove_guest(self, sprite):
        """ Remove a guest sprite to this sprite. """
         
        self.guests.remove(sprite)
        sprite.guest = False
        sprite.host = None

    def add_host(self, sprite):
        """ Add a host for this sprite.
        
        This sprite will be updated after the host sprite.
        """
        self.host = sprite
        self.guest = True
        sprite.guests.add(self)
        
    def remove_host(self):
        """ Remove a host from this sprite. """
        self.host.guests.remove(self)
        self.host = None
        self.guest = False

    def one_layer_down(self):
        """ Moves the sprite one layer down in the render group. 
        
        This will make the sprite be seen below other sprites
        in the same group.

        """
        for g in self.groups():
            if isinstance(g, TryGroup):
                g.one_layer_down(self)

    def one_layer_up(self):
        """ Moves the sprites one layer up in the render group.
        
        This will make the sprite be seen over other sprites
        in the same group.
        
        """

        for g in self.groups():
            if isinstance(g, TryGroup):
                g.one_layer_up(self)

    def move_ontop(self, ref_sprite):
        """ Move this sprite just on top of ref_sprite in render order. """

        for g in self.groups():
            if isinstance(g, TryGroup):
                g.ref_render_order_change(ref_sprite, self, 0)

    def move_below(self, ref_sprite):
        """ Move this sprite just below of ref_sprite in render order. """

        for g in self.groups():
            if isinstance(g, TryGroup):
                g.ref_render_order_change(ref_sprite, self, 1)

    def properly_add_ontop(self, sprite):
        """ Add a new sprite on top of this one.
        
        sprite will be added to all the groups in which self is
        and when in render groups, it will be added on top of 
        self.

        """
        for g in self.groups():
            if isinstance(g, TryGroup):
                g.add_ontop(self, sprite)
            else:
                g.add(sprite)

    def properly_add_below(self, sprite):
        """ Add a new sprite below of this one.
        
        sprite will be added to all the groups in which self is
        and when in render groups, it will be added below of 
        self.

        """
        for g in self.groups():
            if isinstance(g,TryGroup):
                g.add_below(self, sprite)
            else:
                g.add(sprite)

    def change_sprite_pos(self, x, y):
        """ Changes the sprite position to x, y.

        Move all the needed rects to the new x, y position.

        """

        rect = self.rect
        dx, dy = x - rect.left, y - rect.top
        self.move_sprite(dx, dy)

    def move_sprite(self, delta_x, delta_y):
        """ Changes the sprite position by delta_x, delta_y.

        Move all the needed rects by delta_x, delta_y

        """

        rect = self.rect.copy()
        dirty_rect = self.dirty_rect

        # TODO: with movements mods this is probably outdated.
        # All movement is made at the same moment.
        # Note to self: This if-else is needed to clean old sprite
        # positions when two movements are done in the same frame, 
        # for example, teleporting/respawning
#         if self.dirty == 1:
#             old = dirty_rect
#         else:
#             old = rect
        old = rect

        # Move rects
        [r.move_ip(delta_x, delta_y) for r in self.rect_list]

        # Update dirty stuff
        self.dirty_rect = old.union(rect)
        self.dirty = 1

    def move_sprite_float(self, delta_x, delta_y):
        """ Move the sprite a float amount

        Uses the integer part to move the sprite and stores
        the float part in a variable.
        """

        self.fx += delta_x
        self.fy += delta_y

        self.fx, dx = modf(self.fx)
        self.fy, dy = modf(self.fy)

        # move rects
        self.move_sprite(dx, dy)

    def dprint(self,text):
        """ If debugging is True it will print debug text. """
        if self.debugging:
            print text

    def _view_mask(self):
        """ Prints the sprite mask to the terminal and exits

        For debugging purposes.
        """

        print self
        print "Printing mask and exiting."
        for y in xrange(self.mask.get_size()[1]):
            for x in xrange(self.mask.get_size()[0]):
                print self.mask.get_at((x,y)),
            print ""
        sys.exit(0)
コード例 #40
0
ファイル: monster.py プロジェクト: pawlos/battle-city-ai
class Monster(object):
    id = None  # type: UUID
    direction = Direction.UP
    speed = 0
    is_freeze = False
    position = None  # type: Rect
    old_position = None  # type: Rect
    parent = None  # type: Monster

    SIZE = 8

    def __init__(self, x: int, y: int, direction: Direction = None):
        self.id = uuid4()
        size = self.SIZE
        self.position = Rect(x, y, size, size)
        self.set_old_position()
        if direction:
            self.direction = direction

    def set_old_position(self):
        self.old_position = self.position.copy()

    def set_position(self, x: int, y: int):
        self.position.x = x
        self.position.y = y

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

    def set_freeze(self):
        self.is_freeze = True

    def unset_freeze(self):
        self.is_freeze = False

    def set_direction(self, direction: Direction):
        self.direction = direction

    def get_type(self):
        return self.__class__.__name__.lower()

    def get_grid_position(self):
        position = self.position
        return Rect(
            # (x >> 4) << 4 is faster than floor(x / 16) * 16
            (position.x >> 4) << 4,
            (position.y >> 4) << 4,
            32,
            32,
        )

    def check_collision_with_group(self, group, rect=None, callback=None):
        callback = callback or (lambda m: m.position)
        rect = rect or self.position
        if isinstance(group, SlicedArray):
            group = group.find_nearest(rect)

        rect_group = list(map(callback, group))
        indices = rect.collidelistall(rect_group)
        return [group[index] for index in indices]

    def check_collision_with_old_position(self, monster):
        return self.old_position.colliderect(monster.position)

    def union_new_position_with_old(self):
        return self.position.union(self.old_position)

    def set_parent(self, parent):
        self.parent = parent

    def get_position(self):
        return dict(
            x=self.position.x,
            y=self.position.y,
        )

    def move(self):
        if self.is_freeze:
            return
        self.move_with_speed(self.speed)

    def move_with_speed(self, speed):
        position = self.position
        direction = self.direction

        if direction is Direction.UP:
            position.y -= speed
        elif direction is Direction.DOWN:
            position.y += speed
        elif direction is Direction.LEFT:
            position.x -= speed
        elif direction is Direction.RIGHT:
            position.x += speed
コード例 #41
0
ファイル: sprite.py プロジェクト: vxgmichel/pygame-mvctools
 def wrapper(self, *args, **kwargs):
     temp = Rect.copy(self)
     res = method(self, *args, **kwargs)
     if temp != self:
         self.notify()
     return res