Beispiel #1
0
    def __init__(self,
                 main,
                 size=None,
                 screen=None,
                 zoom_offset=1,
                 zoom_constraint=None):
        self.main = main
        self.size = size if size is not None else [6000, 6000]
        self.screen = pygame.Rect(
            screen if screen is not None else [0, 0, 800, 600])
        self.update_rect = pygame.Rect(0, 0, *self.size)
        z_const = zoom_constraint if zoom_constraint else [None, 4]

        self.camera = Camera((0, 0),
                             self.screen,
                             self.get_world_rect(),
                             z_const,
                             zoom_offset=zoom_offset)
        self.visible = self.camera.get_rect()

        self.player = None
        self.step_time = 1
        self.space_time_coef = 1
        self.event_system = None
        self.phys_group = None
        self.gui = None
        self.pressed = []
        self.paused = False
        self.mouse_window_prev = Vec2d(0, 0)
        self.mouse_world_prev = Vec2d(0, 0)
        self.mouse_window = Vec2d(0, 0)
        self.mouse_world = Vec2d(0, 0)
Beispiel #2
0
 def __init__(self, parent, position=None, angle=0, allowed=True, top=True):
     """
     :param parent: PhysObject
     :param position: (x, y) in local coords
     :param angle: float (degrees) angle in local coords.
     :param allowed: [config.ROLE, ...] | None | True
     :param top: bool - is object above creature or not.
     """
     self.parent = parent
     self._pos = Vec2d(0, 0) if position is None else Vec2d(position)
     self._ang = angle
     self.allowed = True if allowed is True else ([] if allowed is None else list(allowed))
     self.object = None
     self.role = None
     self.top = top
Beispiel #3
0
    def __init__(self, *args, **kwargs):
        """
        Necessary assignment
           - rect
           - image
        """
        self._pos = Vec2d(0, 0)
        self._size = Vec2d(0, 0)
        self._angle = 0

        self._image = None

        self.damping = 0
        self.step_time = 1
        super().__init__(*args, **kwargs)
        self.play_sound('creation')
Beispiel #4
0
class ImageHandler(PhysObject):
    """
    Sprite with GObject image in class attributes for RAM economy
    """
    size_inc = 1
    _frames = []
    IMAGE_SHIFT = Vec2d(0, 0)

    def __init__(self, *args, obj=None, **kwargs):
        super().__init__(*args, **kwargs)
        if obj is None:
            self._image = GObject(self._frames)
        else:
            self._image = GObject(obj)

    def end_step(self):
        super().end_step()
        self._image.update(self.step_time)

    @classmethod
    def image_to_local(cls, pos):
        return Vec2d(pos) * cls.size_inc + cls.IMAGE_SHIFT

    def _get_image(self):
        return self._image.read()
Beispiel #5
0
class Weapon(YTGBaseWeapon):
    size_inc = 1
    max_health = 50
    proj_velocity = 1000
    fire_delay = 1000
    fire_pos = Vec2d(0, 0)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.i_body = pymunk.Body()
        self.shape = pymunk.Poly(self.body, self.POLY_SHAPE)
        self.shape.density = 1

    @classmethod
    def init_class(cls):
        cls._frames, cls.IMAGE_SHIFT = cast_model(MODEL, CS, cls.size_inc)
        cls.precalculate_shape()
        cls.calculate_poly_shape()

    @classmethod
    def precalculate_shape(cls):
        radius = 10

        cls.RADIUS = radius * cls.size_inc

    @classmethod
    def calculate_poly_shape(cls):
        img_poly_left = []
        poly_left = [tuple(e[n] - CS[n] for n in range(2)) for e in img_poly_left]
        poly_right = [(e[0], -e[1]) for e in poly_left[::-1]]
        cls.POLY_SHAPE = [(e[0] * cls.size_inc, e[1] * cls.size_inc) for e in poly_left + poly_right]
Beispiel #6
0
 def local_to_world(self, pos):
     """
     Конвертация из локальной системы координат в уровневую.
     Положение точки в локальной системе не зависит от углов наклона тела к глобальным осям.
     :param pos: (x, y)
     :return: Vec2d(x, y)
     """
     return self.position + Vec2d(pos).rotated(self.angle)
Beispiel #7
0
 def world_to_local(self, pos):
     """
     Конвертация из уровневой системы координат в локальную.
     Положение точки в локальной системе не зависит от углов наклона тела к глобальным осям.
     :param pos: (x, y)
     :return: Vec2d(x, y)
     """
     return (Vec2d(pos) - self.position).rotated(-self.angle)
Beispiel #8
0
    def __init__(self):
        """
        Necessary assignment
           - rect
           - image
        """
        super().__init__()
        self._image = None

        self._pos = Vec2d(0, 0)
        self._size = Vec2d(0, 0)
        self._angle = 0

        self.step_time = 1
        self.age = 0

        self.play_sound('creation')
Beispiel #9
0
    def draw(self, surface, camera):
        cam_rect = camera.get_rect()
        cam_bb = pymunk.BB(cam_rect.left, cam_rect.top, cam_rect.right,
                           cam_rect.bottom)
        cam_tl = Vec2d(cam_rect.topleft)
        cam_offset = Vec2d(self.draw_offset)
        zoom = camera.get_current_zoom()

        blit = surface.blit
        sprite_dict = self.spritedict

        for sprite in self.layer_sorted():
            if sprite.bb.intersects(cam_bb):
                s_img = sprite.image
                img = pygame.transform.rotozoom(s_img, -sprite.angle, zoom)

                img_size = img.get_size()
                s_pos = sprite.position
                sc = (int(cam_offset[0] + (s_pos[0] - cam_tl[0]) * zoom -
                          img_size[0] / 2),
                      int(cam_offset[1] + (s_pos[1] - cam_tl[1]) * zoom -
                          img_size[1] / 2))
                sprite_dict[sprite] = blit(img, sc)

        cam_c = Vec2d(cam_rect.center)
        cam_h = (CAMERA_SOUND_HEIGHT / zoom)**2
        for snd in self.sounds:
            sound = snd[0]
            kwargs = snd[2]
            c = kwargs.get('channel', None)
            if c is not None:
                c = pygame.mixer.Channel(c)
                c.play(sound)
            else:
                c = sound.play(kwargs.get('loops', 0),
                               kwargs.get('max_time', 0),
                               kwargs.get('fade_ms', 0))
            if c is not None:
                to_s = snd[1].position - cam_c
                d = to_s.get_length_sqrd()
                v = SOUND_COEF / (math.sqrt(d + cam_h) + 1)
                c.set_volume(v)

        self.sounds.clear()
        self.lostsprites = []
Beispiel #10
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self._pos = Vec2d(0, 0)
        self._ang = 0
        self._parent = None
        self._i_shape = None
        self._i_body = None
        self.activated = False
Beispiel #11
0
 def force_fire(self, **kwargs):
     self.play_sound('fire')
     proj = self.spawn_proj()
     ang = self.miss_angle()
     rad = math.radians(ang)
     vel = self.proj_velocity
     vec = Vec2d(vel * math.cos(rad), vel * math.sin(rad))
     proj.velocity = vec
     proj.angle = ang
Beispiel #12
0
 def set_local_placement(self, pos, ang):
     """
     Установить позицию и угол наклона относительно родителя.
     :param pos: (x, y)
     :param ang: float (degrees)
     """
     self._pos = Vec2d(pos)
     self._ang = ang
     self.update_local_placement()
Beispiel #13
0
 def calculate_mouse_world(self):
     """
     Не рекомендуется к использованию - функция перерасчёта.
     Её результат записывается в Level.mouse_world
     :return: Vec2d(x, y)
     """
     ms = pygame.mouse.get_pos()
     sc, vs = self.screen.size, self.visible.size
     zoom = max((sc[0] / vs[0], sc[1] / vs[1]))
     return (Vec2d(ms) - self.screen.topleft) / zoom + self.visible.topleft
Beispiel #14
0
def cast_frames(source, centers, size_incs):
    """
    Обрезать по содержимому, центрировать и масштабировать кадры.
    :param source: pygame.Surface
    :param centers: [(x, y), ...]
    :param size_incs: [int, ...]
    :return: [pygame.Surface, ...], (x, y) - image shift
    """
    frames = []
    c0 = Vec2d(0, 0)
    for n, f in enumerate(source):
        i_size = f.get_size()
        center = centers[n]
        size_inc = size_incs[n]
        if center is None:
            center = [e / 2 for e in i_size]
        else:
            if center[0] is None:
                center[0] = i_size[0] / 2
            if center[1] is None:
                center[1] = i_size[1] / 2
        b_rect = f.get_bounding_rect()
        b_size = ceil(Vec2d(b_rect.size) * size_inc)
        h_size = b_size / 2
        img_center = ceil((Vec2d(center) - b_rect.topleft) * size_inc)
        if n == 0:
            c0 = -img_center
        inc_vector = abs(img_center - h_size)
        hf_size = h_size + inc_vector
        tl = hf_size - img_center

        bs = f.subsurface(b_rect)
        img = pygame.Surface(hf_size * 2).convert_alpha()
        img.fill((255, 255, 255, 0))
        img.blit(pygame.transform.scale(bs, b_size),
                 tl)
        if DEBUG.DRAW:
            r = img.get_rect()
            r.w -= 2
            r.h -= 2
            pygame.draw.rect(img, (255, 0, 0), r, 2)
        frames.append(img)
    return frames, c0
Beispiel #15
0
    def force_fire(self, **kwargs):
        self.play_sound('fire')
        ang = self.angle + (self.fire_n - 1) * self.inaccuracy * 180

        proj = self.spawn_proj()
        proj.velocity = Vec2d.from_anglen(ang, self.proj_velocity)
        proj.angle = self.angle
        proj.target = kwargs.get('target_function', kwargs.get('target', None))

        self.fire_n = (self.fire_n + 1) % 3
Beispiel #16
0
def cast_image(source, center=None, size_inc=1):
    """
    Обрезать по содержимому, центрировать и масштабировать изображение.
    :param source: pygame.Surface
    :param center: (x, y)
    :param size_inc: int
    :return: pygame.Surface, (x, y) - image shift
    """
    i_size = source.get_size()
    if center is None:
        center = [e / 2 for e in i_size]
    else:
        if center[0] is None:
            center[0] = i_size[0] / 2
        if center[1] is None:
            center[1] = i_size[1] / 2
    # Область, которую есть смысл отображать.
    b_rect = source.get_bounding_rect()
    # Её размер после масштабирования.
    b_size = ceil(Vec2d(b_rect.size) * size_inc)
    # Половина.
    h_size = b_size / 2
    # Центр обрезанного и масштабированного изображения относительно просто обрезанного.
    img_center = ceil((Vec2d(center) - b_rect.topleft) * size_inc)
    # Вектор масштабирования, вдоль которого растягивается новая поверхность,
    # чтобы центрированное изображение вместилось.
    inc_vector = abs(img_center - h_size)
    hf_size = h_size + inc_vector
    tl = hf_size - img_center

    bs = source.subsurface(b_rect)
    img = pygame.Surface(hf_size * 2).convert_alpha()
    img.fill((255, 255, 255, 0))
    img.blit(pygame.transform.scale(bs, b_size),
             tl)

    if DEBUG.DRAW:
        r = img.get_rect()
        r.w -= 2
        r.h -= 2
        pygame.draw.rect(img, (255, 0, 0), r, 2)
    return img, -img_center
Beispiel #17
0
 def update(self):
     if self.boost:
         self.body.apply_force_at_local_point((5000000, 0), (0, 0))
         if self.target is not None:
             if hasattr(self.target, '__call__'):
                 tp = self.target()
             else:
                 tp = list(self.target)
             da = angular_distance(self.angle,
                                   (Vec2d(tp) - self.position).angle)
             self.angle += da * .1
Beispiel #18
0
 def calculate_global_rect(self):
     """
     Абсолютная позиция (прямоугольник) относительно области отрисовки.
     Рекомендуется вызывать только в Division.start_step, используйте get_global_rect
     :return: Rect()
     """
     if self._parent is not None:
         rect = self._parent.global_rect
     elif self._main is not None:
         rect = self._main.get_visible_rect()
     else:
         return FRect(self._rect)
     if self.absolute_position:
         return FRect(*map(sum, zip(rect.topleft, self._rect.topleft)),
                      *self._rect.size)
     else:
         s_rect = self._rect
         s_tl = Vec2d(s_rect.topleft)
         s_sz = Vec2d(s_rect.size)
         return FRect(*(s_tl / 100 * rect.size + rect.topleft),
                      *(s_sz / 100 * rect.size))
Beispiel #19
0
 def update_local_placement(self):
     """
     Обновляет относительное положение объекта (Изменяет текущий shape в соответствии с локальной позицей).
     """
     pos, ang = self.local_pos, self.local_angle
     i_shape = self._i_shape
     shape = self._shape
     if isinstance(i_shape, pymunk.Poly):
         shape.unsafe_set_vertices([e + pos for e in i_shape.get_vertices()])
     elif isinstance(i_shape, pymunk.Segment):
         shape.unsafe_set_endpoints(i_shape.a + pos, i_shape.b + pos)
     elif isinstance(i_shape, pymunk.Circle):
         shape.unsafe_set_offset(Vec2d(pos) + self._i_shape.offset)
Beispiel #20
0
 def force_fire(self, **kwargs):
     """
     Совершает выстрел независимо от обстоятельств.
     :param kwargs: Иногда нужен для прицеливания дочерним классам.
     """
     self.play_sound('fire')
     proj = self.spawn_proj()
     ang = self.miss_angle()
     rad = math.radians(ang)
     vel = self.proj_velocity
     vec = Vec2d(vel * math.cos(rad), vel * math.sin(rad))
     proj.velocity = vec
     proj.angle = ang
Beispiel #21
0
    def force_fire(self, **kwargs):
        self.play_sound('fire')
        ca = self.angle
        da = self.inaccuracy * 360
        sa = ca - da / 2

        frag = self.fragmentation
        vel = self.proj_velocity
        segments = []

        b_a = self.spawn(Ballast)
        b_a.set_parent(self)
        b_a.angle = sa
        b_a.velocity = Vec2d.from_anglen(sa, vel)

        b_b = self.spawn(Ballast)
        b_b.set_parent(self)
        b_b.angle = sa + da
        b_b.velocity = Vec2d.from_anglen(sa + da, vel)

        b_a.pair = b_b
        b_b.pair = b_a

        w = (self.Projectile.LENGTH - self.Projectile.RADIUS) / 2

        for n in range(frag):
            proj = self.spawn_proj()

            if segments:
                Pivot(proj.body, segments[-1].body, (-w, 0), (w, 0))

            segments.append(proj)
            ang = sa + da * (n / frag)
            proj.angle = ang - 90
            proj.velocity = Vec2d.from_anglen(ang, vel * .8)

        Pivot(b_a.body, segments[0].body, (0, 0), (-w, 0))
        Pivot(b_b.body, segments[-1].body, (0, 0), (w, 0))
Beispiel #22
0
 def send_event(self, event):
     super().send_event(event)
     if event.type == pygame.KEYDOWN and event.key == pygame.K_j:
         ind = self.w_inv.index
         for n in range(len(self.w_inv[ind])):
             w = self.w_inv.drop(ind)
             ang = math.radians(self.angle)
             vector = Vec2d(math.cos(ang), math.sin(ang))
             mv = 1000000 / w.mass
             vel = w.velocity_for_distance(
                 (self.level.mouse_world - self.position).length)
             if vel > mv:
                 vel = mv
             w.position += vector * 75
             w.velocity = vector * vel
Beispiel #23
0
 def start_step(self, upd_time, time_coef=1):
     if not self.paused:
         self.step_time = upd_time * time_coef
         self.pressed = pygame.key.get_pressed()
         self.mouse_window_prev = self.mouse_window
         self.mouse_world_prev = self.mouse_world
         self.mouse_window = Vec2d(pygame.mouse.get_pos())
         self.mouse_world = self.calculate_mouse_world()
         if self.event_system:
             self.event_system.start_step(upd_time)
         if self.player is not None:
             tp = self.mouse_window - self.screen.center
             self.camera.center = self.player.position + tp
     if self.gui is not None:
         self.gui.start_step(upd_time)
Beispiel #24
0
 def force_fire(self, **kwargs):
     self.play_sound('fire')
     proj = self.spawn_proj()
     ang = self.miss_angle()
     rad = math.radians(ang)
     if 'target' in kwargs.keys():
         dis = (proj.position - kwargs['target']).length
         vel = proj.velocity_for_distance(dis, proj.life_left)
         if vel > self.proj_velocity:
             vel = self.proj_velocity
     else:
         vel = self.proj_velocity
     vec = Vec2d(vel * math.cos(rad), vel * math.sin(rad))
     proj.velocity = vec
     proj.angle = ang
Beispiel #25
0
 def update_local_placement(self):
     """
     Устанавливает форму объекта в соответсвтие с локальным положением
     :return:
     """
     pos, ang = self.local_pos, self.local_angle
     i_shape = self._i_shape
     shape = self._shape
     if isinstance(i_shape, pymunk.Poly):
         shape.unsafe_set_vertices(
             [e + pos for e in i_shape.get_vertices()])
     elif isinstance(i_shape, pymunk.Segment):
         shape.unsafe_set_endpoints(i_shape.a + pos, i_shape.b + pos)
     elif isinstance(i_shape, pymunk.Circle):
         shape.unsafe_set_offset(Vec2d(pos) + self._i_shape.offset)
Beispiel #26
0
 def walk(self, vec):
     cv = self.velocity
     if any(vec):
         tv = Vec2d(vec)
         tv.length = self.max_vel
         dif = tv - cv
         dif.length = self.engine_force
         self._body.force += dif
         self.working = True
     elif abs(cv[0]) > .01 and abs(cv[1] > .01):
         # stopping
         cv.length = self.engine_force
         self._body.force -= cv
     else:
         self.velocity = (0, 0)
Beispiel #27
0
 def walk(self, vec):
     cv = self.velocity
     if any(vec):
         tv = Vec2d(vec)
         tv.length = self.max_vel
         dif = tv - cv
         if any(dif):
             dif.length = self.walk_force
             self._body.force += dif
     elif abs(cv[0]) > .01 or abs(cv[1]) > .01:
         # На входе (0, 0) вектор. Замедляемся.
         cv.length = self.walk_force
         self._body.force -= cv
     else:
         # Скорость пренебрежимо мала
         self.velocity = (0, 0)
Beispiel #28
0
class BaseWeapon(BaseComponent):
    draw_layer = DRAW_LAYER.WEAPON
    role = ROLE.WEAPON
    fire_pos = Vec2d(0, 0)
    proj_velocity = 1000
    fire_delay = 1000
    inaccuracy = .02
    Projectile = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.recharge = 0

    def end_step(self):
        super().end_step()
        if self.recharge > 0:
            self.recharge -= self.step_time

    def shot(self, **kwargs):
        if self.recharge <= 0:
            self.force_fire(**kwargs)
            self.recharge = self.fire_delay

    def spawn(self, cls):
        obj = cls()
        obj.add(*self.groups())
        obj.position = self.local_to_world(self.fire_pos)
        return obj

    def spawn_proj(self):
        if self.Projectile:
            proj = self.spawn(self.Projectile)
            proj.set_parent(self)
            return proj

    def miss_angle(self):
        return self.angle + 360 * (random.random() - .5) * self.inaccuracy

    def force_fire(self, **kwargs):
        self.play_sound('fire')
        proj = self.spawn_proj()
        ang = self.miss_angle()
        rad = math.radians(ang)
        vel = self.proj_velocity
        vec = Vec2d(vel * math.cos(rad), vel * math.sin(rad))
        proj.velocity = vec
        proj.angle = ang
Beispiel #29
0
 def walk(self, vec):
     cv = self.velocity
     if any(vec):
         tv = Vec2d(vec)
         tv.length = self.max_vel
         dif = tv - cv
         dif.length = self.walk_force
         self._body.force += dif
     elif abs(cv[0]) > .01 or abs(cv[1]) > .01:
         # stopping
         cv.length = self.walk_force
         self._body.force -= cv
     else:
         self.velocity = (0, 0)
     if 'nan' in str(self.position):
         print(self.position)
     print(self.velocity, self._body.force, self.position)
Beispiel #30
0
class StaticImage(BaseSprite):
    draw_layer = DRAW_LAYER.VFX
    size_inc = 1
    _frames = []
    IMAGE_SHIFT = Vec2d(0, 0)

    def __init__(self, *args, obj=None, **kwargs):
        super().__init__(*args, **kwargs)
        if obj is None:
            self._image = GObject(self._frames)
        else:
            self._image = GObject(obj)

    def end_step(self):
        super().end_step()
        self._image.update(self.step_time)

    @classmethod
    def image_to_local(cls, pos):
        return Vec2d(pos) * cls.size_inc + cls.IMAGE_SHIFT

    def _get_image(self):
        return self._image.read()