Ejemplo n.º 1
0
def _check_for_collision(sprite1: Sprite, sprite2: Sprite) -> bool:
    """
    Check for collision between two sprites.

    :param Sprite sprite1: Sprite 1
    :param Sprite sprite2: Sprite 2

    :returns: True if sprites overlap.
    :rtype: bool
    """
    collision_radius_sum = sprite1.collision_radius + sprite2.collision_radius

    diff_x = sprite1.position[0] - sprite2.position[0]
    diff_x2 = diff_x * diff_x

    if diff_x2 > collision_radius_sum * collision_radius_sum:
        return False

    diff_y = sprite1.position[1] - sprite2.position[1]
    diff_y2 = diff_y * diff_y
    if diff_y2 > collision_radius_sum * collision_radius_sum:
        return False

    distance = diff_x2 + diff_y2
    if distance > collision_radius_sum * collision_radius_sum:
        return False

    return are_polygons_intersecting(sprite1.get_adjusted_hit_box(), sprite2.get_adjusted_hit_box())
Ejemplo n.º 2
0
 def set_entity(self, entity: AbstractEntity = None) -> None:
     self.entity = entity
     self.sprite_entity = Sprite(ASSETS.entities_textures[entity.entity_id],
                                 entity.texture_scale)
     self.sprite_entity.set_position(self.center_x, self.center_y)
     self.sprite_entity._points = None
     self.entity.used_in_step = False
Ejemplo n.º 3
0
    def on_key_press(self, key, key_modifiers):
        """
        Called when a key is pressed. Sets the state of
        holding an arrow key.
        :param key: The key that was pressed
        :param key_modifiers: Things like shift, ctrl, etc
        """

        if key == arcade.key.LEFT or key == arcade.key.DOWN:
            self.player.change_x = -3

        if key == arcade.key.RIGHT or key == arcade.key.UP:
            self.player.change_x = 3

        if key == arcade.key.W or key == arcade.key.D:
            pass

        if key == arcade.key.S or key == arcade.key.A:
            pass

        if key == arcade.key.SPACE:
            bullet = Sprite(filename="game_piece_red.png", \
                center_x=self.player.center_x, center_y=self.player.center_y)
            bullet.change_y = 30
            bullet.scale = .25
            self.bullets.append(bullet)
Ejemplo n.º 4
0
def dash(
    sprite: arcade.Sprite,
    dir_x: int,
    dir_y: int,
    collide_with: arcade.SpriteList,
) -> None:
    """Move sprite until it reaches something."""
    sprite.bottom += 1
    prev_x = sprite.left
    prev_y = sprite.bottom
    default_x = sprite.left
    default_y = sprite.bottom

    for x, y in zip_longest(
            range(floor(sprite.left), floor(sprite.left + dir_x),
                  weird_sign(dir_x)),
            range(floor(sprite.bottom), floor(sprite.bottom + dir_y),
                  weird_sign(dir_y)),
    ):
        sprite.left = x if x else prev_x
        sprite.bottom = y if y else prev_y
        if sprite.collides_with_list(collide_with):
            sprite.left = prev_x
            sprite.bottom = prev_y
            break
        if x:
            prev_x = x
        if y:
            prev_y = y
Ejemplo n.º 5
0
def _move_sprite(moving_sprite: arcade.Sprite, walls: arcade.SpriteList):
    # Rotate
    moving_sprite.angle += moving_sprite.change_angle

    hit_list = check_for_collision_with_list(moving_sprite, walls)

    if len(hit_list) > 0:
        # Resolve any collisions by this weird kludge
        _circular_check(moving_sprite, walls)

    # --- Move in the y direction
    moving_sprite.center_y += moving_sprite.change_y

    # Check for wall hit
    hit_list_x = check_for_collision_with_list(moving_sprite, walls)
    # print(f"Post-y move {hit_list_x}")

    # If we hit a wall, move so the edges are at the same point
    if len(hit_list_x) > 0:
        if moving_sprite.change_y > 0:
            while check_for_collision_with_list(moving_sprite, walls):
                moving_sprite.center_y -= 1
        elif moving_sprite.change_y < 0:
            while check_for_collision_with_list(moving_sprite, walls):
                moving_sprite.center_y += 1
        was_falling = (abs(moving_sprite.change_y) > abs(
            moving_sprite.engine.gravity_constant))
        if was_falling:
            # they have been moving for more than one frame
            play_sound_effect('impact')
        moving_sprite.change_y = min(0.0, hit_list_x[0].change_y)

    moving_sprite.center_y = round(moving_sprite.center_y, 2)

    # --- Move in the x direction
    moving_sprite.center_x += moving_sprite.change_x

    check_again = True
    while check_again:
        check_again = False
        # Check for wall hit
        hit_list_y = check_for_collision_with_list(moving_sprite, walls)

        # If we hit a wall, move so the edges are at the same point
        if len(hit_list_y) > 0:
            change_x = moving_sprite.change_x
            if change_x > 0:
                while check_for_collision_with_list(moving_sprite, walls):
                    moving_sprite.center_x -= 1

            elif change_x < 0:
                while check_for_collision_with_list(moving_sprite, walls):
                    moving_sprite.center_x += 1

            else:
                raise AssertionError(
                    "Error, x collision while player wasn't moving.\n"
                    "Make sure you aren't calling multiple updates, like "
                    "a physics engine update and an all sprites list update.")
Ejemplo n.º 6
0
 def check_collisions(self, ships, base: Sprite):
     for ship in ships:
         if check_for_collision(ship, base):
             base.damage(ship.make_damage())
             explosion = Explosion(self.explosion_texture)
             explosion.center_x = base.center_x
             explosion.center_y = base.center_y
             explosion.update()
             self.explosions_list.append(explosion)
             ship.remove_from_sprite_lists()
Ejemplo n.º 7
0
 def __init__(self, components: list):
     self.components = components
     Sprite.__init__(self, components[0])
     self.dying_sprite = load_texture(components[1])
     self.cost = components[2]
     self.max_hp = components[3]
     self.damage = components[4]
     self.blow_damage = components[5]
     self.consumption = components[6]
     self.delta = 0
     self.side = None
Ejemplo n.º 8
0
    def setup(self):
        path = os.path.abspath(__file__)
        directory = os.path.dirname(path)
        spritefile = directory + '/static/ship_blue.png'
        self.player = Sprite(filename=spritefile, scale=0.6)
        self.player.center_x = self.WINDOW_W / 2
        self.player.center_y = self.WINDOW_H / 2

        self.speed = 0
        self.rotation = 0
        self.dangle = 0
Ejemplo n.º 9
0
 def create_map_sprite(self, x, y):
     sprite = Sprite(center_x=x, center_y=y)
     try:
         terrain_type, index, rotation = self.nodes_data[(x, y)]
         t, i, r = set_terrain_texture(terrain_type, index, rotation)
     except KeyError:
         terrain_type = 'mud'
         t, i, r = set_terrain_texture(terrain_type)
         self.nodes_data[(x, y)] = terrain_type, i, r
     sprite.texture = t
     self.game.terrain_tiles.append(sprite)
Ejemplo n.º 10
0
    def __setitem__(self, key: int, value: Sprite):
        self._vao1 = None

        item_to_be_removed = self.sprite_list[key]
        item_to_be_removed.sprite_lists.remove(self)

        if self._use_spatial_hash:
            self.spatial_hash.remove_object(item_to_be_removed)
            self.spatial_hash.insert_object_for_box(value)

        value.register_sprite_list(self)
        self.sprite_list[key] = value
        self.sprite_idx[value] = key
Ejemplo n.º 11
0
 def __init__(self,
              filename: str = None,
              scale: float = 1,
              image_x: float = 0,
              image_y: float = 0,
              image_width: float = 0,
              image_height: float = 0,
              center_x: float = 0,
              center_y: float = 0,
              repeat_count_x=1,
              repeat_count_y=1):
     GraphicDrawable.__init__(self)
     ArcadeSprite.__init__(self, filename, scale, image_x, image_y,
                           image_width, image_height, center_x, center_y,
                           repeat_count_x, repeat_count_y)
Ejemplo n.º 12
0
    def get_sprite(self) -> Sprite:
        _tex = arcade.Texture.create_empty(
            f"_error-{self.title}-{self.show_message}", (500, 200))
        _icon_tex = arcade.Texture(f"_error_icon_{self._icon}", self.icon)
        sprite = Sprite(texture=_tex)
        _sprite_list = arcade.SpriteList()
        _sprite_list.append(sprite)

        with _sprite_list.atlas.render_into(_tex) as fbo:
            fbo.clear()
            arcade.draw_lrtb_rectangle_filled(0, 500, 200, 0,
                                              arcade.color.BLANCHED_ALMOND)
            arcade.draw_lrtb_rectangle_filled(0, 500, 200, 150,
                                              arcade.color.BRANDEIS_BLUE)
            arcade.draw_text(self.title, 50, 165, font_size=24, bold=True)
            arcade.draw_text(self.show_message,
                             5,
                             146,
                             font_size=16,
                             anchor_y="top",
                             multiline=True,
                             width=492,
                             color=arcade.color.BLACK)
            arcade.draw_texture_rectangle(25, 175, 32, 32, _icon_tex)

        return sprite
Ejemplo n.º 13
0
 def create_sprite(self, scale):
     self.sprite = Sprite('assets/images/brick.png',
                          scale=scale * (self.width / 892),
                          center_x=self.x * scale,
                          center_y=self.y * scale)
     self.sprite.width = scale * self.width
     self.sprite.height = scale * self.height
     self.sprite.color = self.color
Ejemplo n.º 14
0
    def __init__(self, width, height):
        """
        Sets up the initial conditions of the game
        :param width: Screen width
        :param height: Screen height
        """
        super().__init__(width, height)

        self.score = 0

        self.player = Sprite(filename="demo_player.jpeg")
        self.player.center_x = SCREEN_WIDTH // 2
        self.player.center_y = SCREEN_HEIGHT // 3
        self.player.change_x = 3

        self.bullets = []

        arcade.set_background_color(arcade.color.BLACK_LEATHER_JACKET)
Ejemplo n.º 15
0
 def create_sprite(self, scale):
     """
     Create the sprite, the visuals of the bottle.
     """
     pos_x, pos_y = self.get_pos()
     self.sprite = Sprite('assets/images/bottle.png',
                          scale=scale * 2 * (self.radius / 948),
                          center_x=pos_x * scale,
                          center_y=pos_y * scale)
Ejemplo n.º 16
0
    def on_key_press(self, key, modifiers):
        """
        Called whenever a key is pressed.
        """

        if key == arcade.key.UP:
            self.ship.change_y += 5
        elif key == arcade.key.DOWN:
            self.ship.change_y -= 5
        elif key == arcade.key.LEFT:
            self.ship.change_x -= 5
        elif key == arcade.key.RIGHT:
            self.ship.change_x += 5
        elif key == arcade.key.SPACE:
            particule = Sprite("../ressources/Life_Orb.png",
                               center_x=self.ship.right,
                               center_y=self.ship.center_y)
            particule.change_x = 3
            self.particule_list.append(particule)
Ejemplo n.º 17
0
 def create_sprite(self, scale):
     """
     Create the sprite of the rock based on the scale.
     """
     pos_x, pos_y = self.get_pos()
     self.sprite = Sprite('assets/images/brick.png',
                          scale=scale * (self.width / 892),
                          center_x=pos_x * scale,
                          center_y=pos_y * scale)
     self.sprite.width = scale * self.width
     self.sprite.height = scale * self.height
     self.sprite.color = self.color
Ejemplo n.º 18
0
def generate_sprites(map_object, layer_name, scaling, base_directory=""):
    sprite_list = SpriteList()

    if layer_name not in map_object.layers_int_data:
        print(f"Warning, no layer named '{layer_name}'.")
        return sprite_list

    map_array = map_object.layers_int_data[layer_name]

    # Loop through the layer and add in the wall list
    for row_index, row in enumerate(map_array):
        for column_index, item in enumerate(row):
            if str(item) in map_object.global_tile_set:
                tile_info = map_object.global_tile_set[str(item)]
                filename = base_directory + tile_info.source

                my_sprite = Sprite(filename, scaling)
                my_sprite.right = column_index * (map_object.tilewidth * scaling)
                my_sprite.top = (map_object.height - row_index) * (map_object.tileheight * scaling)

                if tile_info.points is not None:
                    my_sprite.set_points(tile_info.points)
                sprite_list.append(my_sprite)
            elif item != 0:
                print(f"Warning, could not find {item} image to load.")

    return sprite_list
Ejemplo n.º 19
0
    def __init__(self, selected: PlayerEntity):
        selected.selection_marker = self
        self.position = selected.position
        self.selected = selected
        self.borders = Sprite()
        self.sprites = []  # not updated, used to cache and kill sprites only

        self.health = health = selected.health
        width, height, color = self.health_to_color_and_size(health)
        self.healthbar = healthbar = SpriteSolidColor(width, height, color)

        self.sprites = sprites = [self.borders, healthbar]
        self.game.selection_markers_sprites.extend(sprites)
Ejemplo n.º 20
0
    def key_place_success(self, key_placed_successfully: bool,
                          normal_key: arcade.Sprite, x_list: List[int],
                          y_list: List[int]):
        """
        Use recursion to check if key place is successful
        Attrs:
        key_placed_successfully(bool): break statement of the recursion function
        normal_key(arcade.Sprite): a key Sprite
        x_list: List[int]: all the x coordinates of the keys has been created
        y_list: List[int]: all the y coordinates of the keys has been created

        Return:
           the position of the key (x, y)
        """
        if key_placed_successfully:
            return normal_key.center_x, normal_key.center_y
        normal_key.center_x = random.randrange(1500)
        normal_key.center_y = random.randrange(1500)

        # See if the key is hitting a wall, hitting another key, or too close from each other
        wall_hit_list = arcade.check_for_collision_with_list(
            normal_key, self.wall_list)
        key_hit_list = arcade.check_for_collision_with_list(
            normal_key, self.key_list)
        flag = True
        for item_x in x_list:
            if abs(int(item_x - normal_key.center_x)) < 30:
                flag = False
        for item_y in y_list:
            if abs(int(item_y - normal_key.center_y)) < 20:
                flag = False
        if len(wall_hit_list) == 0 and len(key_hit_list) == 0 and flag:
            key_placed_successfully = True

        return self.key_place_success(key_placed_successfully, normal_key,
                                      x_list, y_list)
Ejemplo n.º 21
0
    def _pointAtTarget(self,
                       shooter: Sprite,
                       target: GamePiece,
                       rotationAngle: int = 125):

        currentPoint: ArcadePoint = ArcadePoint(x=shooter.center_x,
                                                y=shooter.center_y)
        destinationPoint: ArcadePoint = ArcadePoint(x=target.center_x,
                                                    y=target.center_y)

        normalAngle: float = self._computer.computeAngleToTarget(
            shooter=currentPoint, deadMeat=destinationPoint)
        shooter.angle = normalAngle + rotationAngle

        self._baseMediatorLogger.info(f'{normalAngle=} -  {shooter.angle=}')
Ejemplo n.º 22
0
def _circular_check(player: arcade.Sprite, walls: arcade.SpriteList):
    """Guess our way out of a collision."""
    original_x = player.center_x
    original_y = player.center_y

    vary = 1
    while True:
        last_x = player.center_x
        last_y = player.center_y
        try_list = [
            [original_x + vary, original_y],
            [original_x - vary, original_y],
        ]

        for my_item in try_list:
            x, y = my_item
            player.center_x = x
            player.center_y = y
            check_hit_list = check_for_collision_with_list(player, walls)
            if len(check_hit_list) == 0:
                return
        vary += 1
    player.center_x = last_x
    player.center_y = last_y
Ejemplo n.º 23
0
    def sprite_update(self, vec: Vector, spr: arcade.Sprite, tex: int):
        """
        Updates pos, and tex_index
        """
        spr.center_x = vec.x * self._scale
        spr.center_y = vec.y * self._scale
        spr.set_texture(tex)

        spr.width = self._scale
        spr.height = self._scale
Ejemplo n.º 24
0
 def __init__(self,
              loaded_view: Optional[LoadableWindowView] = None,
              loading_text: str = 'Loading',
              background_name: Optional[str] = None):
     super().__init__()
     self.sprite_list = SpriteList()
     self.loading_text = loading_text
     self.progress = 0
     self.progress_bar = self.create_progress_bar()
     self.loading_background = Sprite(background_name) if \
         background_name is not None else None
     self.sprite_list.extend(
         [e for e in (self.progress_bar, self.loading_background) if e]
     )
     self.set_updated_and_drawn_lists()
     self.loaded_view = loaded_view
Ejemplo n.º 25
0
def generate_sprites(map_object: TiledMap,
                     layer_name: str,
                     scaling: float,
                     base_directory="") -> SpriteList:
    """
    generate_sprites has been deprecated. Use arcade.tilemap.process_layer instead.
    Generate the sprites for a layer in a map.

    :param TiledMap map_object: Map previously read in from read_tiled_map function
    :param layer_name: Name of the layer we want to generate sprites from. Case sensitive.
    :param scaling: Scaling factor.
    :param base_directory: Directory to read images from. Defaults to current directory.
    :return: List of sprites
    :rtype: SpriteList
    """
    sprite_list = SpriteList()

    if layer_name not in map_object.layers_int_data:
        print(f"Warning, no layer named '{layer_name}'.")
        return sprite_list

    map_array = map_object.layers_int_data[layer_name]

    # Loop through the layer and add in the wall list
    for row_index, row in enumerate(map_array):
        for column_index, item in enumerate(row):
            if str(item) in map_object.global_tile_set:
                tile_info = map_object.global_tile_set[str(item)]
                tmx_file = base_directory + tile_info.source

                my_sprite = Sprite(tmx_file, scaling)
                my_sprite.center_x = column_index * (
                    map_object.tilewidth *
                    scaling) - map_object.tilewidth / 2 * scaling
                my_sprite.center_y = (map_object.height - row_index) * (
                    map_object.tileheight *
                    scaling) - map_object.tileheight / 2 * scaling

                if tile_info.points is not None:
                    my_sprite.set_points(tile_info.points)
                sprite_list.append(my_sprite)
            elif item != 0:
                print(f"Warning, could not find {item} image to load.")

    return sprite_list
Ejemplo n.º 26
0
def _move_sprite(moving_sprite: Sprite, walls: SpriteList, ramp_up: bool):
    # Rotate
    moving_sprite.angle += moving_sprite.change_angle

    hit_list = check_for_collision_with_list(moving_sprite, walls)

    if len(hit_list) > 0:
        # Resolve any collisions by this weird kludge
        _circular_check(moving_sprite, walls)

    # --- Move in the y direction
    moving_sprite.center_y += moving_sprite.change_y

    # Check for wall hit
    hit_list_x = check_for_collision_with_list(moving_sprite, walls)
    # print(f"Post-y move {hit_list_x}")
    complete_hit_list = hit_list_x

    # If we hit a wall, move so the edges are at the same point
    if len(hit_list_x) > 0:
        if moving_sprite.change_y > 0:
            while len(check_for_collision_with_list(moving_sprite, walls)) > 0:
                moving_sprite.center_y -= 1
            # print(f"Spot X ({self.player_sprite.center_x}, {self.player_sprite.center_y})"
            #       f" {self.player_sprite.change_y}")
        elif moving_sprite.change_y < 0:
            # Reset number of jumps
            for item in hit_list_x:
                while check_for_collision(moving_sprite, item):
                    # self.player_sprite.bottom = item.top <- Doesn't work for ramps
                    moving_sprite.center_y += 0.25

                if item.change_x != 0:
                    moving_sprite.center_x += item.change_x

            # print(f"Spot Y ({self.player_sprite.center_x}, {self.player_sprite.center_y})")
        else:
            pass
            # TODO: The code below can't execute, as "item" doesn't
            # exist. In theory, this condition should never be arrived at.
            # Collision while player wasn't moving, most likely
            # moving platform.
            # if self.player_sprite.center_y >= item.center_y:
            #     self.player_sprite.bottom = item.top
            # else:
            #     self.player_sprite.top = item.bottom
        moving_sprite.change_y = min(0.0, hit_list_x[0].change_y)

    # print(f"Spot D ({self.player_sprite.center_x}, {self.player_sprite.center_y})")
    moving_sprite.center_y = round(moving_sprite.center_y, 2)
    # print(f"Spot Q ({self.player_sprite.center_x}, {self.player_sprite.center_y})")

    # --- Move in the x direction
    moving_sprite.center_x += moving_sprite.change_x

    check_again = True
    while check_again:
        check_again = False
        # Check for wall hit
        hit_list_y = check_for_collision_with_list(moving_sprite, walls)
        complete_hit_list = hit_list_x
        for sprite in hit_list_y:
            if sprite not in complete_hit_list:
                complete_hit_list.append(sprite)

        # If we hit a wall, move so the edges are at the same point
        if len(hit_list_y) > 0:
            change_x = moving_sprite.change_x
            if change_x > 0:
                if ramp_up:

                    for _ in hit_list_y:
                        # print(f"Spot 1 ({self.player_sprite.center_x}, {self.player_sprite.center_y})")
                        # See if we can "run up" a ramp
                        moving_sprite.center_y += change_x
                        if len(
                                check_for_collision_with_list(
                                    moving_sprite, walls)) > 0:
                            # No, ramp run-up doesn't work.
                            moving_sprite.center_y -= change_x
                            moving_sprite.center_x -= 1
                            # print(f"Spot R ({self.player_sprite.center_x}, {self.player_sprite.center_y})")
                            check_again = True
                            break
                        # else:
                        # print("Run up ok 1")
                        # print(f"Spot 2 ({self.player_sprite.center_x}, {self.player_sprite.center_y})")
                else:
                    while len(
                            check_for_collision_with_list(
                                moving_sprite, walls)) > 0:
                        moving_sprite.center_x -= 1

            elif change_x < 0:
                if ramp_up:
                    for item in hit_list_y:
                        # See if we can "run up" a ramp
                        moving_sprite.center_y -= change_x
                        if len(
                                check_for_collision_with_list(
                                    moving_sprite, walls)) > 0:
                            # Can't run up the ramp, reverse
                            moving_sprite.center_y += change_x
                            moving_sprite.left = max(item.right,
                                                     moving_sprite.left)
                            # print(f"Reverse 1 {item.right}, {self.player_sprite.left}")
                            # Ok, if we were shoved back to the right, we need to check this whole thing again.
                            check_again = True
                            break
                        # print(f"Spot 4 ({self.player_sprite.center_x}, {self.player_sprite.center_y})")
                else:
                    while len(
                            check_for_collision_with_list(
                                moving_sprite, walls)) > 0:
                        moving_sprite.center_x += 1

            else:
                print(
                    "Error, x collision while player wasn't moving.\n"
                    "Make sure you aren't calling multiple updates, like "
                    "a physics engine update and an all sprites list update.")

        # print(f"Spot E ({self.player_sprite.center_x}, {self.player_sprite.center_y})")
    return complete_hit_list
Ejemplo n.º 27
0
def _create_sprite_from_tile(map_object,
                             tile: pytiled_parser.objects.Tile,
                             scaling,
                             base_directory: str = None):

    if base_directory:
        tmx_file = base_directory + tile.image.source
    else:
        tmx_file = tile.image.source

    if not os.path.exists(tmx_file):
        tmx_file = Path(map_object.parent_dir, tile.image.source)
        if not os.path.exists(tmx_file):
            print(f"Warning: can't file {tmx_file} ")
            return None

    # print(f"Creating tile: {tmx_file}")
    if tile.animation:
        # my_sprite = AnimatedTimeSprite(tmx_file, scaling)
        my_sprite: Sprite = AnimatedTimeBasedSprite(tmx_file, scaling)
    else:
        image_x = 0
        image_y = 0
        if tile.tileset.image is not None:
            row = tile.id_ // tile.tileset.columns
            image_y = row * tile.tileset.max_tile_size.height
            col = tile.id_ % tile.tileset.columns
            image_x = col * tile.tileset.max_tile_size.width

        if tile.image.size:
            # Individual image, use image width and height
            width = tile.image.size.width
            height = tile.image.size.height
        else:
            # Sprite sheet, use max width/height from sheet
            width = tile.tileset.max_tile_size.width
            height = tile.tileset.max_tile_size.height

        my_sprite = Sprite(tmx_file, scaling, image_x, image_y, width, height)

    if tile.properties is not None and len(tile.properties) > 0:
        for my_property in tile.properties:
            my_sprite.properties[my_property.name] = my_property.value

        # print(tile.image.source, my_sprite.center_x, my_sprite.center_y)
    if tile.objectgroup is not None:

        if len(tile.objectgroup) > 1:
            print(
                f"Warning, only one hit box supported for tile with image {tile.image.source}."
            )

        for hitbox in tile.objectgroup:
            points: List[Point] = []
            if isinstance(hitbox, pytiled_parser.objects.RectangleObject):
                if hitbox.size is None:
                    print(
                        f"Warning: Rectangle hitbox created for without a "
                        f"height or width for {tile.image.source}. Ignoring.")
                    continue

                # print(my_sprite.width, my_sprite.height)
                sx = hitbox.location[0] - (my_sprite.width / (scaling * 2))
                sy = -(hitbox.location[1] - (my_sprite.height / (scaling * 2)))
                ex = (hitbox.location[0] + hitbox.size[0]) - (my_sprite.width /
                                                              (scaling * 2))
                ey = -((hitbox.location[1] + hitbox.size[1]) -
                       (my_sprite.height / (scaling * 2)))

                # print(f"Size: {hitbox.size} Location: {hitbox.location}")
                p1 = [sx, sy]
                p2 = [ex, sy]
                p3 = [ex, ey]
                p4 = [sx, ey]
                # print(f"w:{my_sprite.width:.1f}, h:{my_sprite.height:.1f}", end=", ")
                points = [p1, p2, p3, p4]
                # for point in points:
                #     print(f"({point[0]:.1f}, {point[1]:.1f}) ")
                # print()

            elif isinstance(hitbox, pytiled_parser.objects.PolygonObject) \
                    or isinstance(hitbox, pytiled_parser.objects.PolylineObject):
                for point in hitbox.points:
                    adj_x = point[0] + hitbox.location[0] - my_sprite.width / (
                        scaling * 2)
                    adj_y = -(point[1] + hitbox.location[1] -
                              my_sprite.height / (scaling * 2))
                    adj_point = [adj_x, adj_y]
                    points.append(adj_point)

                # If we have a polyline, and it is closed, we need to
                # remove the duplicate end-point
                if points[0][0] == points[-1][0] and points[0][1] == points[
                        -1][1]:
                    points.pop()

            elif isinstance(hitbox, pytiled_parser.objects.ElipseObject):
                if hitbox.size is None:
                    print(
                        f"Warning: Ellipse hitbox created for without a height "
                        f"or width for {tile.image.source}. Ignoring.")
                    continue

                # print(f"Size: {hitbox.size} Location: {hitbox.location}")

                hw = hitbox.size[0] / 2
                hh = hitbox.size[1] / 2
                cx = hitbox.location[0] + hw
                cy = hitbox.location[1] + hh

                acx = cx - (my_sprite.width / (scaling * 2))
                acy = cy - (my_sprite.height / (scaling * 2))

                # print(f"acx: {acx} acy: {acy} cx: {cx} cy: {cy} hh: {hh} hw: {hw}")

                total_steps = 8
                angles = [
                    step / total_steps * 2 * math.pi
                    for step in range(total_steps)
                ]
                for angle in angles:
                    x = (hw * math.cos(angle) + acx)
                    y = (-(hh * math.sin(angle) + acy))
                    point = [x, y]
                    points.append(point)

                # for point in points:
                #     print(f"({point[0]:.1f}, {point[1]:.1f}) ")
                # print()

            else:
                print(f"Warning: Hitbox type {type(hitbox)} not supported.")

            my_sprite.points = points

    if tile.animation is not None:
        key_frame_list = []
        for frame in tile.animation:
            frame_tile = _get_tile_by_id(map_object, tile.tileset,
                                         frame.tile_id)
            if frame_tile:
                frame_tile.image.source = Path(map_object.parent_dir,
                                               frame_tile.image.source)
                if not os.path.exists(tmx_file):
                    print(f"Warning: can't file {tmx_file} ")
                    return None

                key_frame = AnimationKeyframe(frame.tile_id, frame.duration,
                                              frame_tile.image)
                key_frame_list.append(key_frame)
                # print(f"Add tile {frame.tile_id} for keyframe. Source: {frame_tile.image.source}")

        cast(AnimatedTimeBasedSprite, my_sprite).frames = key_frame_list

    return my_sprite
Ejemplo n.º 28
0
def _create_sprite_from_tile(map_object: pytiled_parser.objects.TileMap,
                             tile: pytiled_parser.objects.Tile,
                             scaling: float = 1.0,
                             base_directory: str = None,
                             hit_box_algorithm="Simple",
                             hit_box_detail: float = 4.5):
    """
    Given a tile from the parser, see if we can create a sprite from it
    """

    # --- Step 1, find a reference to an image this is going to be based off of
    map_source = map_object.tmx_file
    map_directory = os.path.dirname(map_source)
    image_file = _get_image_source(tile, base_directory, map_directory)

    # print(f"Creating tile: {tmx_file}")
    if tile.animation:
        # my_sprite = AnimatedTimeSprite(tmx_file, scaling)
        my_sprite: Sprite = AnimatedTimeBasedSprite(image_file, scaling)
    else:
        image_x, image_y, width, height = _get_image_info_from_tileset(tile)
        my_sprite = Sprite(image_file,
                           scaling,
                           image_x,
                           image_y,
                           width,
                           height,
                           flipped_horizontally=tile.flipped_horizontally,
                           flipped_vertically=tile.flipped_vertically,
                           flipped_diagonally=tile.flipped_diagonally,
                           hit_box_algorithm=hit_box_algorithm,
                           hit_box_detail=hit_box_detail)

    if tile.properties is not None and len(tile.properties) > 0:
        for my_property in tile.properties:
            my_sprite.properties[my_property.name] = my_property.value

    if tile.type_:
        my_sprite.properties['type'] = tile.type_

        # print(tile.image.source, my_sprite.center_x, my_sprite.center_y)
    if tile.objectgroup is not None:

        if len(tile.objectgroup) > 1:
            print(
                f"Warning, only one hit box supported for tile with image {tile.image.source}."
            )

        for hitbox in tile.objectgroup:
            points: List[Point] = []
            if isinstance(hitbox, pytiled_parser.objects.RectangleObject):
                if hitbox.size is None:
                    print(
                        f"Warning: Rectangle hitbox created for without a "
                        f"height or width for {tile.image.source}. Ignoring.")
                    continue

                # print(my_sprite.width, my_sprite.height)
                sx = hitbox.location[0] - (my_sprite.width / (scaling * 2))
                sy = -(hitbox.location[1] - (my_sprite.height / (scaling * 2)))
                ex = (hitbox.location[0] + hitbox.size[0]) - (my_sprite.width /
                                                              (scaling * 2))
                ey = -((hitbox.location[1] + hitbox.size[1]) -
                       (my_sprite.height / (scaling * 2)))

                # print(f"Size: {hitbox.size} Location: {hitbox.location}")
                p1 = [sx, sy]
                p2 = [ex, sy]
                p3 = [ex, ey]
                p4 = [sx, ey]
                # print(f"w:{my_sprite.width:.1f}, h:{my_sprite.height:.1f}", end=", ")
                points = [p1, p2, p3, p4]
                # for point in points:
                #     print(f"({point[0]:.1f}, {point[1]:.1f}) ")
                # print()

            elif isinstance(hitbox, pytiled_parser.objects.PolygonObject) \
                    or isinstance(hitbox, pytiled_parser.objects.PolylineObject):
                for point in hitbox.points:
                    adj_x = point[0] + hitbox.location[0] - my_sprite.width / (
                        scaling * 2)
                    adj_y = -(point[1] + hitbox.location[1] -
                              my_sprite.height / (scaling * 2))
                    adj_point = [adj_x, adj_y]
                    points.append(adj_point)

                # If we have a polyline, and it is closed, we need to
                # remove the duplicate end-point
                if points[0][0] == points[-1][0] and points[0][1] == points[
                        -1][1]:
                    points.pop()

            elif isinstance(hitbox, pytiled_parser.objects.ElipseObject):
                if hitbox.size is None:
                    print(
                        f"Warning: Ellipse hitbox created for without a height "
                        f"or width for {tile.image.source}. Ignoring.")
                    continue

                # print(f"Size: {hitbox.size} Location: {hitbox.location}")

                hw = hitbox.size[0] / 2
                hh = hitbox.size[1] / 2
                cx = hitbox.location[0] + hw
                cy = hitbox.location[1] + hh

                acx = cx - (my_sprite.width / (scaling * 2))
                acy = cy - (my_sprite.height / (scaling * 2))

                # print(f"acx: {acx} acy: {acy} cx: {cx} cy: {cy} hh: {hh} hw: {hw}")

                total_steps = 8
                angles = [
                    step / total_steps * 2 * math.pi
                    for step in range(total_steps)
                ]
                for angle in angles:
                    x = (hw * math.cos(angle) + acx)
                    y = (-(hh * math.sin(angle) + acy))
                    point = [x, y]
                    points.append(point)

                # for point in points:
                #     print(f"({point[0]:.1f}, {point[1]:.1f}) ")
                # print()

            else:
                print(f"Warning: Hitbox type {type(hitbox)} not supported.")

            my_sprite.set_hit_box(points)

    if tile.animation is not None:
        # Animated image
        key_frame_list = []
        # Loop through each frame
        for frame in tile.animation:
            # Get the tile for the frame
            frame_tile = _get_tile_by_id(map_object, tile.tileset,
                                         frame.tile_id)
            if frame_tile:

                image_file = _get_image_source(frame_tile, base_directory,
                                               map_directory)

                # Does the tile have an image?
                if frame_tile.image:
                    # Yes, use it
                    texture = load_texture(image_file)
                else:
                    # No image for tile? Pull from tilesheet
                    image_x, image_y, width, height = _get_image_info_from_tileset(
                        frame_tile)

                    texture = load_texture(image_file, image_x, image_y, width,
                                           height)

                key_frame = AnimationKeyframe(frame.tile_id, frame.duration,
                                              texture)
                key_frame_list.append(key_frame)
                # If this is the first texture in the animation, go ahead and
                # set it as the current texture.
                if len(key_frame_list) == 1:
                    my_sprite.texture = key_frame.texture
                # print(f"Add tile {frame.tile_id} for keyframe. Source: {frame_tile.image.source}")

        cast(AnimatedTimeBasedSprite, my_sprite).frames = key_frame_list

    return my_sprite
Ejemplo n.º 29
0
class SpriteGame(arcade.Window):

    player : object
    
    def __init__(self, width=800, height=660, title="SpriteGame"):
        super().__init__(width,height,title)
        self.WINDOW_H = height
        self.WINDOW_W = width

        self.ddx = 0
        self.ddy = 0
        self.dx = 0
        self.dy = 0


    def setup(self):
        path = os.path.abspath(__file__)
        directory = os.path.dirname(path)
        spritefile = directory + '/static/ship_blue.png'
        self.player = Sprite(filename=spritefile, scale=0.6)
        self.player.center_x = self.WINDOW_W/2
        self.player.center_y = self.WINDOW_H/2

        self.speed = 0
        self.force = 0
        self.rotation = 0
        self.dangle = 0


        

    def run(self):
        arcade.run()


    def on_key_press(self, key, modifiers):

        if key == arcade.key.W:
            self.force += 10
        if key == arcade.key.S:
            self.force += -5
        if key == arcade.key.A:
            self.dangle += 10
        if key == arcade.key.D:
            self.dangle += -10

    def on_key_release(self, key, modifiers):

        if key == arcade.key.W:
            self.force -= 10
        if key == arcade.key.S:
            self.force -= -5
        if key == arcade.key.A:
            self.dangle -= 10
        if key == arcade.key.D:
            self.dangle -= -10





    def on_update(self, deltatime):
        # 0 - 360          
        self.rotation += self.dangle        
        ddx = -math.sin(math.radians(self.rotation))
        ddy = math.cos(math.radians(self.rotation))

        self.dx = arcade.lerp(self.dx, ddx, 0.05)
        self.dy = arcade.lerp(self.dy, ddy, 0.05)

        self.speed = arcade.lerp(self.speed, self.force, 0.05)
        
        self.player.change_x = self.dx * self.speed
        self.player.change_y = self.dy * self.speed
        self.player.angle = self.rotation
        self.player.update()


    def on_draw(self):

        arcade.start_render()

        self.player.draw()
Ejemplo n.º 30
0
def _move_sprite(moving_sprite: Sprite, walls: SpriteList, ramp_up: bool):

    # start_time = time.time()

    # See if we are starting this turn with a sprite already colliding with us.
    if len(check_for_collision_with_list(moving_sprite, walls)) > 0:
        _circular_check(moving_sprite, walls)

    original_x = moving_sprite.center_x
    original_y = moving_sprite.center_y
    original_angle = moving_sprite.angle

    # --- Rotate
    rotating_hit_list = []
    if moving_sprite.change_angle:

        # Rotate
        moving_sprite.angle += moving_sprite.change_angle

        # Resolve collisions caused by rotating
        rotating_hit_list = check_for_collision_with_list(moving_sprite, walls)

        if len(rotating_hit_list) > 0:

            max_distance = (moving_sprite.width + moving_sprite.height) / 2

            # Resolve any collisions by this weird kludge
            _circular_check(moving_sprite, walls)
            if get_distance(original_x, original_y, moving_sprite.center_x,
                            moving_sprite.center_y) > max_distance:
                # Ok, glitched trying to rotate. Reset.
                moving_sprite.center_x = original_x
                moving_sprite.center_y = original_y
                moving_sprite.angle = original_angle

    # --- Move in the y direction
    moving_sprite.center_y += moving_sprite.change_y

    # Check for wall hit
    hit_list_x = check_for_collision_with_list(moving_sprite, walls)
    # print(f"Post-y move {hit_list_x}")
    complete_hit_list = hit_list_x

    # If we hit a wall, move so the edges are at the same point
    if len(hit_list_x) > 0:
        if moving_sprite.change_y > 0:
            while len(check_for_collision_with_list(moving_sprite, walls)) > 0:
                moving_sprite.center_y -= 1
            # print(f"Spot X ({self.player_sprite.center_x}, {self.player_sprite.center_y})"
            #       f" {self.player_sprite.change_y}")
        elif moving_sprite.change_y < 0:
            # Reset number of jumps
            for item in hit_list_x:
                while check_for_collision(moving_sprite, item):
                    # self.player_sprite.bottom = item.top <- Doesn't work for ramps
                    moving_sprite.center_y += 0.25

                if item.change_x != 0:
                    moving_sprite.center_x += item.change_x

            # print(f"Spot Y ({self.player_sprite.center_x}, {self.player_sprite.center_y})")
        else:
            pass
            # TODO: The code below can't execute, as "item" doesn't
            # exist. In theory, this condition should never be arrived at.
            # Collision while player wasn't moving, most likely
            # moving platform.
            # if self.player_sprite.center_y >= item.center_y:
            #     self.player_sprite.bottom = item.top
            # else:
            #     self.player_sprite.top = item.bottom
        moving_sprite.change_y = min(0.0, hit_list_x[0].change_y)

    # print(f"Spot D ({self.player_sprite.center_x}, {self.player_sprite.center_y})")
    moving_sprite.center_y = round(moving_sprite.center_y, 2)
    # print(f"Spot Q ({self.player_sprite.center_x}, {self.player_sprite.center_y})")

    # end_time = time.time()
    # print(f"Move 1 - {end_time - start_time:7.4f}")
    # start_time = time.time()

    loop_count = 0
    # --- Move in the x direction
    if moving_sprite.change_x:
        # Keep track of our current y, used in ramping up
        almost_original_y = moving_sprite.center_y

        # Strip off sign so we only have to write one version of this for
        # both directions
        direction = math.copysign(1, moving_sprite.change_x)
        cur_x_change = abs(moving_sprite.change_x)
        upper_bound = cur_x_change
        lower_bound = 0
        cur_y_change = 0

        exit_loop = False
        while not exit_loop:

            loop_count += 1
            # print(f"{cur_x_change=}, {upper_bound=}, {lower_bound=}, {loop_count=}")

            # Move sprite and check for collisions
            moving_sprite.center_x = original_x + cur_x_change * direction
            collision_check = check_for_collision_with_list(
                moving_sprite, walls)

            # Update collision list
            for sprite in collision_check:
                if sprite not in complete_hit_list:
                    complete_hit_list.append(sprite)

            # Did we collide?
            if len(collision_check) > 0:
                # We did collide. Can we ramp up and not collide?
                if ramp_up:
                    cur_y_change = cur_x_change
                    moving_sprite.center_y = original_y + cur_y_change

                    collision_check = check_for_collision_with_list(
                        moving_sprite, walls)
                    if len(collision_check) > 0:
                        cur_y_change -= cur_x_change
                    else:
                        while (len(collision_check) == 0) and cur_y_change > 0:
                            # print("Ramp up check")
                            cur_y_change -= 1
                            moving_sprite.center_y = almost_original_y + cur_y_change
                            collision_check = check_for_collision_with_list(
                                moving_sprite, walls)
                        cur_y_change += 1
                        collision_check = []

                if len(collision_check) > 0:
                    # print(f"Yes @ {cur_x_change}")
                    upper_bound = cur_x_change - 1
                    if upper_bound - lower_bound <= 1:
                        cur_x_change = lower_bound
                        exit_loop = True
                        # print(f"Exit 2 @ {cur_x_change}")
                    else:
                        cur_x_change = (upper_bound + lower_bound) / 2
                else:
                    exit_loop = True
                    # print(f"Exit 1 @ {cur_x_change}")

            else:
                # No collision. Keep this new position and exit
                lower_bound = cur_x_change
                if upper_bound - lower_bound <= 1:
                    # print(f"Exit 3 @ {cur_x_change}")
                    exit_loop = True
                else:
                    # print(f"No @ {cur_x_change}")
                    cur_x_change = (upper_bound + lower_bound) / 2

        # print(cur_x_change * direction, cur_y_change)
        moving_sprite.center_x = original_x + cur_x_change * direction
        moving_sprite.center_y = almost_original_y + cur_y_change
        # print(f"({moving_sprite.center_x}, {moving_sprite.center_y}) {cur_x_change * direction}, {cur_y_change}")

    # Add in rotating hit list
    for sprite in rotating_hit_list:
        if sprite not in complete_hit_list:
            complete_hit_list.append(sprite)

    # end_time = time.time()
    # print(f"Move 2 - {end_time - start_time:7.4f} {loop_count}")

    return complete_hit_list