Example #1
0
def fit_to_plane(sprite: Sprite, plane: Plane):
    scale = min(plane.width / sprite.image.width,
                plane.height / sprite.image.height)

    x = (plane.width - (sprite.image.width * scale)) / 2
    y = (plane.height - (sprite.image.height * scale)) / 2

    sprite.update(x=x, y=y, scale=scale)
    def _create_and_scale_sprite(self, resource_name):
        knight_image = image.load(resource_name)

        sprite_scaling = self._calculate_scaling_for_sprite(knight_image.width, SQUARE_SIZE * CHESS_PIECE_SCALING)
        sprite = Sprite(knight_image, self.x, self.y)
        sprite.update(self.x, self.y, scale=sprite_scaling)
        sprite.anchor_x = sprite.width // 2
        sprite.anchor_y = sprite.height // 2
        return sprite
Example #3
0
class O_Bullet:
    def __init__(self, x, y, rot, weapon, game):
        self.pos = Vector(x, y)

        self.rot = rot

        self.sprite = Sprite(game.bullet_img, x, y, batch=game.bullet_batch)
        self.sprite.update(rotation=rot, scale=WEAPONS[weapon]["bullet_size"])
        self.sprite.image.anchor_x = self.sprite.image.width / 2
        self.sprite.image.anchor_y = self.sprite.image.height / 2
Example #4
0
class MapSpriteV2(SpriteV2, ABC):
    def __init__(self, logger, parent_viewport, map_id):
        super().__init__(logger, parent_viewport)
        self.map_id = map_id
        self.rotation = 0
        self.x = 0
        self.y = 0

    @final
    def on_update(self):
        if not self.sprite and self.is_located_inside_viewport():
            self.sprite = PygletSprite(self.texture,
                                       x=self.x,
                                       y=self.y,
                                       batch=self.batch,
                                       group=self.group,
                                       usage=self.usage,
                                       subpixel=self.subpixel)
            self.sprite.opacity = self.opacity
            self.sprite.rotation = self.rotation
        elif self.is_located_outside_viewport() and self.sprite:
            self.sprite.delete()
            self.sprite = None

    @final
    def on_position_update(self, x=0, y=0, rotation=0):
        self.x = x
        self.y = y
        self.rotation = rotation
        if self.sprite:
            self.sprite.update(x=self.x, y=self.y, rotation=self.rotation)

    @final
    def is_located_outside_viewport(self):
        return self.x - self.texture.anchor_x \
               - (MAP_CAMERA.offset_x + self.parent_viewport.x2) / MAP_CAMERA.zoom \
               > SPRITE_VIEWPORT_EDGE_OFFSET_LIMIT_X \
               or self.x + self.texture.width - self.texture.anchor_x \
               - (MAP_CAMERA.offset_x + self.parent_viewport.x1) / MAP_CAMERA.zoom \
               < -SPRITE_VIEWPORT_EDGE_OFFSET_LIMIT_X \
               or self.y - self.texture.anchor_y \
               - (MAP_CAMERA.offset_y + self.parent_viewport.y2) / MAP_CAMERA.zoom \
               > SPRITE_VIEWPORT_EDGE_OFFSET_LIMIT_Y \
               or self.y + self.texture.height - self.texture.anchor_y \
               - (MAP_CAMERA.offset_y + self.parent_viewport.y1) / MAP_CAMERA.zoom \
               < -SPRITE_VIEWPORT_EDGE_OFFSET_LIMIT_Y

    @final
    def is_located_inside_viewport(self):
        return not self.is_located_outside_viewport()
Example #5
0
class Omobs:
    def __init__(self, x, y, rot, game):
        self.pos = Vector(x, y)

        self.rot = rot

        self.sprite = Sprite(game.mob_image, x, y, batch=game.mob_batch)
        self.sprite.update(rotation=rot)

        self.sprite.image.anchor_x = self.sprite.image.width / 2 - MOB_IMAGE_OFFSET.x
        self.sprite.image.anchor_y = self.sprite.image.height / 2 - MOB_IMAGE_OFFSET.y

        self.hit_box = MOB_HIT_BOX.copy()

        self.hit_box.x = self.pos.x - self.hit_box.width / 2
        self.hit_box.y = self.pos.y - self.hit_box.height / 2
Example #6
0
class UISpriteV2(SpriteV2, ABC):
    @abstractmethod
    def get_x(self):
        pass

    @abstractmethod
    def get_y(self):
        pass

    @abstractmethod
    def get_scale(self):
        pass

    @final
    @is_not_active
    def on_activate(self):
        super().on_activate()
        if not self.sprite:
            self.sprite = PygletSprite(self.texture,
                                       x=self.get_x(),
                                       y=self.get_y(),
                                       batch=self.batch,
                                       group=self.group,
                                       usage=self.usage,
                                       subpixel=self.subpixel)

        self.sprite.opacity = self.opacity
        self.sprite.scale = self.get_scale()

    @final
    @window_size_has_changed
    def on_window_resize(self, width, height):
        super().on_window_resize(width, height)
        if self.sprite:
            self.sprite.update(x=self.get_x(),
                               y=self.get_y(),
                               scale=self.get_scale())

    @final
    @is_active
    def on_position_update(self):
        self.sprite.update(x=self.get_x(), y=self.get_y())
Example #7
0
 def draw_snake(self):
     if self.__alive:
         for block in self.__body:
             block_pic = Sprite(self.body_sprite,
                                x=block[0] * BLOCK_SIZE[0],
                                y=block[1] * BLOCK_SIZE[1])
             block_pic.update(scale_x=SCALE_X, scale_y=SCALE_Y)
             block_pic.draw()
         if self.__direction == Side.west:
             head_sprite = self.head_sprites.w
         elif self.__direction == Side.north:
             head_sprite = self.head_sprites.n
         elif self.__direction == Side.south:
             head_sprite = self.head_sprites.s
         else:
             head_sprite = self.head_sprites.e
         head_pic = Sprite(head_sprite,
                           x=self.__head[0] * BLOCK_SIZE[0],
                           y=self.__head[1] * BLOCK_SIZE[1])
         head_pic.update(scale_x=SCALE_X, scale_y=SCALE_Y)
         head_pic.draw()
Example #8
0
class MuzzleFlash:
    def __init__(self, pos, rot, game):
        self.pos = pos

        self.rot = rot

        self.time = 0

        self.sprite = Sprite(game.muzzle_flash_img, batch=game.effects_batch)
        self.sprite.update(rotation=rot)
        self.sprite.image.anchor_x = self.sprite.width / 3
        self.sprite.image.anchor_y = self.sprite.height / 2
        self.dead = False

        self.sprite.x = pos.x
        self.sprite.y = pos.y

    def update(self, dt):
        self.time += dt

        if self.time > MUZZLE_FLASH_LIFESPAWN:
            self.sprite.delete()
            self.dead = True
Example #9
0
class Player:
    def __init__(self, x, y, game, weapon):
        self.pos = Vector(x, y)
        self.vel = Vector(0, 0)

        self.rot = 0

        self.game = game

        self.weapons = [None, Weapon("pistol")]

        self.grenades = [
            Grenade(self.game, "grenade"),
            Grenade(self.game, "grenade"),
            Grenade(self.game, "grenade"),
            Grenade(self.game, "grenade"),
            Grenade(self.game, "grenade")
        ]
        self.grenade_num = 0

        self.last_shot = 0

        self.hit_box = PLAYER_HIT_BOX.copy()
        self.hit_box.x = x
        self.hit_box.y = y

        self.o = Vector(self.pos.x, self.pos.y)

        self.health = PLAYER_HEALTH

        self.num = 1

        self.sprite = Sprite(game.player_images[self.weapons[self.num].name])
        self.width = self.sprite.width
        self.height = self.sprite.height

        self.sprite.image.anchor_x = self.sprite.image.width / 2 - WEAPONS[
            self.weapons[self.num].name]['img_offset'].x
        self.sprite.image.anchor_y = self.sprite.image.height / 2 - WEAPONS[
            self.weapons[self.num].name]['img_offset'].y

        self.knock_back = Vector(0, 0)

    def see_player(self, player):
        corner2 = Vector(self.hit_box.x + self.hit_box.width / 2,
                         self.hit_box.y + self.hit_box.height / 2)

        return self.see_point(player, corner2)

    def see_point(self, player, point_1):
        o_point_1 = player.hit_box.copy()
        o_point_2 = Vector(player.hit_box.x,
                           player.hit_box.y + player.hit_box.height)
        o_point_3 = Vector(player.hit_box.x + player.hit_box.width,
                           player.hit_box.y + player.hit_box.height)
        o_point_4 = Vector(player.hit_box.x + player.hit_box.width,
                           player.hit_box.y)

        glBegin(GL_LINES)
        glVertex2i(int(point_1.x), int(point_1.y))
        glVertex2i(int(o_point_1.x), int(o_point_1.y))
        glEnd()

        glBegin(GL_LINES)
        glVertex2i(int(point_1.x), int(point_1.y))
        glVertex2i(int(o_point_2.x), int(o_point_2.y))
        glEnd()

        glBegin(GL_LINES)
        glVertex2i(int(point_1.x), int(point_1.y))
        glVertex2i(int(o_point_3.x), int(o_point_3.y))
        glEnd()

        glBegin(GL_LINES)
        glVertex2i(int(point_1.x), int(point_1.y))
        glVertex2i(int(o_point_4.x), int(o_point_4.y))
        glEnd()

        if self.line_collide(self.game, point_1, o_point_1) and self.line_collide(self.game, point_1, o_point_2) and self.line_collide(self.game, point_1, o_point_3) \
            and self.line_collide(self.game, point_1, o_point_4):
            return False

        return True

    def line_collide(self, game, pos, o):
        for wall in game.walls:
            topleft = [wall.pos.x, wall.pos.y + wall.height]
            topright = [wall.pos.x + wall.width, wall.pos.y + wall.height]

            bottomleft = [wall.pos.x, wall.pos.y]
            bottomright = [wall.pos.x + wall.width, wall.pos.y]

            left = lineLine(pos.x, pos.y, o.x, o.y, topleft[0], topleft[1],
                            topleft[0], bottomleft[1])

            right = lineLine(pos.x, pos.y, o.x, o.y, topright[0], topright[1],
                             topright[0], bottomright[1])

            top = lineLine(pos.x, pos.y, o.x, o.y, topleft[0], topleft[1],
                           topright[0], topright[1])

            bottom = lineLine(pos.x, pos.y, o.x, o.y, bottomleft[0],
                              bottomleft[1], bottomright[0], bottomright[1])

            if left or right or top or bottom:
                return True

        return False

    def switch(self):

        self.num += 1

        if len(self.weapons) - 1 < self.num:
            self.num = 0

        if self.weapons[self.num] is None:
            self.switch()

    def get_rotation(self, point1, point2):
        return math.degrees(
            math.atan2(point1.x - point2.x, point1.y - point2.y))

    def throw(self, dt):
        if len(self.grenades) > 0:
            self.grenades[self.grenade_num].throw(
                Vector(self.pos.x, self.pos.y),
                GRENADE_STARTING_VEL + self.vel * Vector(dt, dt), self.rot)
            self.grenades.remove(self.grenades[self.grenade_num])

            self.grenade_num = 0

    def shoot(self):
        if self.last_shot <= 0 < self.health:
            rot = self.get_rotation(self.o, self.game.mouse.get_map_pos()) + 90

            if abs(self.rot) - abs(rot) > 10 or abs(rot) - abs(self.rot) > 10:
                rot = self.rot

            if self.weapons[self.num].ammo_in_mag > 0 and (
                    not self.weapons[self.num].fired
                    or self.weapons[self.num].type == "auto"):
                self.knock_back = WEAPONS[self.weapons[
                    self.num].name]["knock_back"].rotate(self.rot)

            self.weapons[self.num].shoot(self.o, self.pos, rot, self.game)

            self.last_shot = WEAPONS[self.weapons[self.num].name]["rate"]

    def rotate_to_mouse(self):
        '''
        v = self.pos - self.game.mouse.get_map_pos()


        s = self.game.mouse.get_map_pos()
        pos = pg.Vector2(self.pos.x, self.pos.y)
        pos2 = pg.Vector2(s.x, s.y)

        v2 = pos - pos2


        print("v: ", v)
        print("v2: ", v2)


        # print(v.angle_to(Vector(-1, 0)))
        # print(v2.angle_to(pg.Vector2(-1, 0)))

        # print(self.rot)

        print(v.magnitude())
        print(v2.magnitude())
        '''

        self.rot = self.get_rotation(self.pos,
                                     self.game.mouse.get_map_pos()) + 90

    def collide_with_walls(self, dir):
        if self.health > 0:
            if dir == "x":
                for wall in self.game.walls:
                    if (self.hit_box.x + self.hit_box.width > wall.pos.x and
                            self.hit_box.y + self.hit_box.height > wall.pos.y
                        ) and (self.hit_box.x < wall.pos.x + wall.width
                               and self.hit_box.y < wall.pos.y + wall.height):
                        if wall.center.x > self.hit_box.get_center().x:
                            self.hit_box.x = wall.pos.x - self.hit_box.width

                        elif wall.center.x < self.hit_box.get_center().x:
                            self.hit_box.x = wall.pos.x + wall.width

                        self.vel.x = 0

                for mob in self.game.mobs:
                    if (self.hit_box.x + self.hit_box.width > mob.hit_box.x
                            and self.hit_box.y + self.hit_box.height >
                            mob.hit_box.y) and (
                                self.hit_box.x < mob.hit_box.x +
                                mob.hit_box.width and self.hit_box.y <
                                mob.hit_box.y + mob.hit_box.height):
                        if mob.hit_box.get_center(
                        ).x > self.hit_box.get_center().x:
                            self.hit_box.x = mob.hit_box.x - self.hit_box.width

                        elif mob.hit_box.get_center(
                        ).x < self.hit_box.get_center().x:
                            self.hit_box.x = mob.hit_box.x + mob.hit_box.width

                        self.vel.x = 0

            elif dir == "y":
                for wall in self.game.walls:
                    if (self.hit_box.x + self.hit_box.width > wall.pos.x and
                            self.hit_box.y + self.hit_box.height > wall.pos.y
                        ) and (self.hit_box.x < wall.pos.x + wall.width
                               and self.hit_box.y < wall.pos.y + wall.height):
                        if wall.center.y > self.hit_box.get_center().y:
                            self.hit_box.y = wall.pos.y - self.hit_box.height

                        elif wall.center.y < self.hit_box.get_center().y:
                            self.hit_box.y = wall.pos.y + wall.height

                        self.vel.y = 0

                for mob in self.game.mobs:
                    if (self.hit_box.x + self.hit_box.width > mob.hit_box.x
                            and self.hit_box.y + self.hit_box.height >
                            mob.hit_box.y) and (
                                self.hit_box.x < mob.hit_box.x +
                                mob.hit_box.width and self.hit_box.y <
                                mob.hit_box.y + mob.hit_box.height):
                        if mob.hit_box.get_center(
                        ).y > self.hit_box.get_center().y:
                            self.hit_box.y = mob.hit_box.y - self.hit_box.height

                        elif mob.hit_box.get_center(
                        ).y < self.hit_box.get_center().y:
                            self.hit_box.y = mob.hit_box.y + mob.hit_box.height

                        self.vel.y = 0

    def update(self, dt, server=False):
        self.sprite = Sprite(
            self.game.player_images[self.weapons[self.num].name])
        self.width = self.sprite.width
        self.height = self.sprite.height

        self.sprite.image.anchor_x = self.sprite.image.width / 2 - WEAPONS[
            self.weapons[self.num].name]['img_offset'].x
        self.sprite.image.anchor_y = self.sprite.image.height / 2 - WEAPONS[
            self.weapons[self.num].name]['img_offset'].y

        self.vel.x -= self.knock_back.x
        self.vel.y += self.knock_back.y

        # check hit box collisions
        self.hit_box.x += self.vel.x * dt
        if not server:
            self.collide_with_walls("x")

        self.hit_box.y += self.vel.y * dt
        if not server:
            self.collide_with_walls("y")

        self.knock_back.multiply(0)

        self.pos.x = self.hit_box.x + self.hit_box.width / 2
        self.pos.y = self.hit_box.y + self.hit_box.height / 2

        o = WEAPONS[self.weapons[self.num].name]['offset'].copy().rotate(
            -self.rot)

        self.o = Vector(self.pos.x, self.pos.y)

        self.o.x += o.x
        self.o.y += o.y

        if self.last_shot > 0:
            self.last_shot -= dt

        if not self.game.buy_menu:
            self.rotate_to_mouse()

        self.sprite.update(rotation=self.rot)

        self.sprite.x = self.hit_box.get_center().x
        self.sprite.y = self.hit_box.get_center().y

        self.weapons[self.num].update(dt)

    def draw_hit_box(self):
        glBegin(GL_LINES)

        glVertex2i(int(self.hit_box.x), int(self.hit_box.y))
        glVertex2i(int(self.hit_box.x),
                   int(self.hit_box.y + self.hit_box.height))

        glVertex2i(int(self.hit_box.x),
                   int(self.hit_box.y + self.hit_box.height))
        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y + self.hit_box.height))

        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y + self.hit_box.height))
        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y))

        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y))
        glVertex2i(int(self.hit_box.x), int(self.hit_box.y))

        glEnd()

    def draw(self):
        s = self.game.mouse.get_map_pos()

        pyglet.gl.glBegin(pyglet.gl.GL_LINES)
        pyglet.gl.glVertex2i(int(self.pos.x), int(self.pos.y))
        pyglet.gl.glVertex2i(int(s.x), int(s.y))
        pyglet.gl.glEnd()

        pyglet.gl.glBegin(pyglet.gl.GL_LINES)
        pyglet.gl.glVertex2i(int(self.o.x), int(self.o.y))
        pyglet.gl.glVertex2i(int(s.x), int(s.y))
        pyglet.gl.glEnd()

        self.draw_hit_box()
        self.sprite.draw()
Example #10
0
class Oplayers:
    def __init__(self, id, pos, rot, weapon, game):
        self.id = id

        self.pos = pos

        self.rot = rot

        self.weapon = weapon

        self.sprite = Sprite(game.player_images[weapon])
        self.width = self.sprite.width
        self.height = self.sprite.height

        self.hit_box = PLAYER_HIT_BOX.copy()
        self.hit_box.x = pos.x
        self.hit_box.y = pos.y

        self.sprite.image.anchor_x = self.sprite.image.width / 2 - WEAPONS[
            weapon]['img_offset'].x
        self.sprite.image.anchor_y = self.sprite.image.height / 2 - WEAPONS[
            weapon]['img_offset'].y

        self.game = game

        self.health = PLAYER_HEALTH
        self.dead = False

    def update(self):
        self.sprite = Sprite(self.game.player_images[self.weapon])
        self.width = self.sprite.width
        self.height = self.sprite.height

        self.sprite.image.anchor_x = self.sprite.image.width / 2 - WEAPONS[
            self.weapon]['img_offset'].x
        self.sprite.image.anchor_y = self.sprite.image.height / 2 - WEAPONS[
            self.weapon]['img_offset'].y

        self.sprite.update(rotation=self.rot)

        self.sprite.x = self.pos.x
        self.sprite.y = self.pos.y

        self.hit_box.x = self.pos.x - self.hit_box.width / 2
        self.hit_box.y = self.pos.y - self.hit_box.height / 2

        # print(self.pos)

    def draw_hit_box(self):
        glBegin(GL_LINES)

        glVertex2i(int(self.hit_box.x), int(self.hit_box.y))
        glVertex2i(int(self.hit_box.x),
                   int(self.hit_box.y + self.hit_box.height))

        glVertex2i(int(self.hit_box.x),
                   int(self.hit_box.y + self.hit_box.height))
        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y + self.hit_box.height))

        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y + self.hit_box.height))
        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y))

        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y))
        glVertex2i(int(self.hit_box.x), int(self.hit_box.y))

        glEnd()
Example #11
0
class Mob:
    def __init__(self, x, y, game):
        self.pos = Vector(x, y)
        self.vel = Vector(0, 0)
        self.acc = Vector(0, 0)

        self.game = game

        self.rot = 0

        self.hit_box = MOB_HIT_BOX.copy()

        self.sprite = Sprite(game.mob_image, batch=game.mob_batch)
        self.width = self.sprite.width
        self.height = self.sprite.height

        self.sprite.image.anchor_x = self.sprite.image.width / 2 - MOB_IMAGE_OFFSET.x
        self.sprite.image.anchor_y = self.sprite.image.height / 2 - MOB_IMAGE_OFFSET.y

        self.sprite.x = x
        self.sprite.y = y

        self.health = MOB_HEALTH

        self.hit_box.x = self.pos.x - self.hit_box.width / 2
        self.hit_box.y = self.pos.y - self.hit_box.height / 2

        self.target = None

        self.q = Queue(self.game)

        self.id = game.new_mob_id()

        self.last_hit = datetime.now()

    def collide_with_walls(self, dir):
        if self.health > 0:
            if dir == "x":
                for wall in self.game.walls:
                    if (self.hit_box.x + self.hit_box.width > wall.pos.x and
                            self.hit_box.y + self.hit_box.height > wall.pos.y
                        ) and (self.hit_box.x < wall.pos.x + wall.width
                               and self.hit_box.y < wall.pos.y + wall.height):
                        if wall.center.x > self.hit_box.get_center().x:
                            self.hit_box.x = wall.pos.x - self.hit_box.width

                        elif wall.center.x < self.hit_box.get_center().x:
                            self.hit_box.x = wall.pos.x + wall.width

                        self.vel.x = 0

                for mob in self.game.mobs:
                    if (self.hit_box.x + self.hit_box.width > mob.hit_box.x
                            and self.hit_box.y + self.hit_box.height >
                            mob.hit_box.y) and (
                                self.hit_box.x < mob.hit_box.x +
                                mob.hit_box.width and self.hit_box.y <
                                mob.hit_box.y + mob.hit_box.height):
                        if mob.hit_box.get_center(
                        ).x > self.hit_box.get_center().x:
                            self.hit_box.x = mob.hit_box.x - self.hit_box.width

                        elif mob.hit_box.get_center(
                        ).x < self.hit_box.get_center().x:
                            self.hit_box.x = mob.hit_box.x + mob.hit_box.width

                        self.vel.x = 0

                for player in self.game.o_players:
                    if (self.hit_box.x + self.hit_box.width > player.hit_box.x
                            and self.hit_box.y + self.hit_box.height >
                            player.hit_box.y) and (
                                self.hit_box.x < player.hit_box.x +
                                player.hit_box.width and self.hit_box.y <
                                player.hit_box.y + player.hit_box.height):
                        if player.hit_box.get_center(
                        ).x > self.hit_box.get_center().x:
                            self.hit_box.x = player.hit_box.x - self.hit_box.width

                        elif player.hit_box.get_center(
                        ).x < self.hit_box.get_center().x:
                            self.hit_box.x = player.hit_box.x + player.hit_box.width

                        self.vel.x = 0
                        self.hit(player)

            elif dir == "y":
                for wall in self.game.walls:
                    if (self.hit_box.x + self.hit_box.width > wall.pos.x and
                            self.hit_box.y + self.hit_box.height > wall.pos.y
                        ) and (self.hit_box.x < wall.pos.x + wall.width
                               and self.hit_box.y < wall.pos.y + wall.height):
                        if wall.center.y > self.hit_box.get_center().y:
                            self.hit_box.y = wall.pos.y - self.hit_box.height

                        elif wall.center.y < self.hit_box.get_center().y:
                            self.hit_box.y = wall.pos.y + wall.height

                        self.vel.y = 0

                for mob in self.game.mobs:
                    if (self.hit_box.x + self.hit_box.width > mob.hit_box.x
                            and self.hit_box.y + self.hit_box.height >
                            mob.hit_box.y) and (
                                self.hit_box.x < mob.hit_box.x +
                                mob.hit_box.width and self.hit_box.y <
                                mob.hit_box.y + mob.hit_box.height):
                        if mob.hit_box.get_center(
                        ).y > self.hit_box.get_center().y:
                            self.hit_box.y = mob.hit_box.y - self.hit_box.height

                        elif mob.hit_box.get_center(
                        ).y < self.hit_box.get_center().y:
                            self.hit_box.y = mob.hit_box.y + mob.hit_box.height

                        self.vel.y = 0

                for player in self.game.o_players:
                    if (self.hit_box.x + self.hit_box.width > player.hit_box.x
                            and self.hit_box.y + self.hit_box.height >
                            player.hit_box.y) and (
                                self.hit_box.x < player.hit_box.x +
                                player.hit_box.width and self.hit_box.y <
                                player.hit_box.y + player.hit_box.height):
                        if player.hit_box.get_center(
                        ).y > self.hit_box.get_center().y:
                            self.hit_box.y = player.hit_box.y - self.hit_box.height

                        elif player.hit_box.get_center(
                        ).y < self.hit_box.get_center().y:
                            self.hit_box.y = player.hit_box.y + player.hit_box.height

                        self.vel.y = 0
                        self.hit(player)

    def hit(self, player):
        if (datetime.now() - self.last_hit).seconds > MOB_DAMGAGE_RATE:
            player.health -= MOB_DAMAGE
            self.last_hit = datetime.now()

    def rot_towards_target(self, target_dist):
        rotT = target_dist.get_angle() - 90

        angle = math.atan2(-target_dist.x, -target_dist.y) / math.pi * 180.0

        diff = (angle - self.rot - 90) % 360

        if 175 < int(diff) < 183:
            rot = rotT

        elif diff > 180:
            rot = self.rot + MOB_ROTATION_SPEED

        else:
            rot = self.rot - MOB_ROTATION_SPEED

        return rot

    def move(self, target, player=False):
        dist = Vector(target.x, target.y) - self.pos

        if dist.magnitude() <= MOB_NODE_DIST and player is False:
            self.get_path()

        dist.set_length(MOB_SPEED)

        self.vel = dist

        self.rot = self.rot_towards_target(dist)

    def get_closest(self):
        dist = None
        player_pos = None
        for player in self.game.o_players:
            if not player.dead:
                new_dist = player.pos - self.pos

                if dist is None:
                    dist = new_dist
                    player_pos = player

                elif new_dist.magnitude() < dist.magnitude():
                    dist = new_dist
                    player_pos = player

        return player_pos

    def see_player(self, player):
        if self.q.line_collide(self.game, Vector(player.hit_box.x, player.hit_box.y), self.pos) \
        or self.q.line_collide(self.game, Vector(player.hit_box.x + player.hit_box.width, player.hit_box.y), self.pos) \
        or self.q.line_collide(self.game, Vector(player.hit_box.x + player.hit_box.width, player.hit_box.y + player.hit_box.height), self.pos) \
        or self.q.line_collide(self.game, Vector(player.hit_box.x, player.hit_box.y + player.hit_box.height), self.pos):
            return False

        else:
            return True

    def get_path(self):
        player_pos = self.get_closest()

        if player_pos is not None:
            if not self.see_player(player_pos):
                self.q.find_path(self.pos, player_pos.pos.copy())

            else:
                self.move(player_pos.pos, True)

        else:
            self.q.s = None
            self.vel.multiply(0)

    def update(self, dt):
        if self.q.s is None:
            self.get_path()

        else:
            pos = self.get_closest()
            if pos is not None:
                pos = pos.pos
                if self.q.line_collide(self.game, pos, self.pos):
                    self.move(self.q.s[0])

                else:
                    self.move(pos, True)
                    self.q.s = None

            else:
                self.q.s = None

        self.hit_box.x += self.vel.x * dt
        self.collide_with_walls("x")

        self.hit_box.y += self.vel.y * dt
        self.collide_with_walls("y")

        self.pos.x = self.hit_box.x + self.hit_box.width / 2
        self.pos.y = self.hit_box.y + self.hit_box.height / 2

        self.sprite.update(rotation=self.rot)
        self.sprite.x = self.hit_box.get_center().x
        self.sprite.y = self.hit_box.get_center().y

    def draw_hit_box(self):
        glBegin(GL_LINES)

        glVertex2i(int(self.hit_box.x), int(self.hit_box.y))
        glVertex2i(int(self.hit_box.x),
                   int(self.hit_box.y + self.hit_box.height))

        glVertex2i(int(self.hit_box.x),
                   int(self.hit_box.y + self.hit_box.height))
        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y + self.hit_box.height))

        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y + self.hit_box.height))
        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y))

        glVertex2i(int(self.hit_box.x + self.hit_box.width),
                   int(self.hit_box.y))
        glVertex2i(int(self.hit_box.x), int(self.hit_box.y))

        glEnd()

        self.q.draw()
Example #12
0
class MobileEntity(Entity):
    defaults = {
        'collidable': True,
        'mobile': True,
        'width': 50,
        'height': 50,
        'stat_modifiers': {
            'str': 0,
            'dex': 0,
            'wis': 0,
            'int': 0,
            'con': 0,
            'lck': 0
        }
    }

    attributes = {
        'dead': False,
        'image_file': 'app/assets/zombie.png',
        'moving_to': None,
        'chunk': None,
        'sprinting': False,
        'in_combat': False,
        #'in_combat_with': [],
        'attack_cooldown': 0,
        'projectile_cooldown': 0,
        'damage_text_color': (255, 255, 255, 255),
        'chunk_container': 'npcs'
    }

    overwrite = {}

    def __init__(self, **kwargs):
        self.pre_init(**kwargs)
        super(MobileEntity, self).__init__(**kwargs)

    def init(self, **kwargs):
        self.in_combat_with = []
        self.image = load_image(self.image_file)
        self.sprite = Sprite(self.image, self.x, self.y)
        self.hp_image = load_image('app/assets/healthbar.png')
        self.hp_sprite = Sprite(self.hp_image, self.x + 1,
                                self.y + self.height + 5)
        self.set_sprite_render(self.group)
        self.stats = Stats(modifiers=self.stat_modifiers)

        entity_container = getattr(self.chunk, self.chunk_container)
        if self.chunk and self not in entity_container:
            entity_container.append(self)

        self.post_init(**kwargs)

    def pre_init(self, **kwargs):
        self.attributes = {**self.attributes, **self.overwrite}

    def post_init(self, **kwargs):
        pass

    def set_sprite_render(self, group):
        self.sprite.batch = self.chunk.draw_batch
        self.sprite.group = group
        self.hp_sprite.batch = self.chunk.draw_batch
        self.hp_sprite.group = group

    @property
    def speed(self):
        walk_speed = self.stats.dex // 3
        if self.sprinting:
            return walk_speed * config.sprint_modifier
        return walk_speed

    def check_state(self):
        if self.dead:
            self.on_death()
        elif self.in_combat:
            if not self.in_combat_with:
                self.in_combat = False
            else:
                self.do_combat()
        else:
            self.do_idle()

    def on_death(self):
        print(f'{self.name} died!')
        if self.in_combat:
            for entity in self.in_combat_with:
                if self in entity.in_combat_with:
                    entity.in_combat_with.remove(self)
        self.remove_from_chunk()
        self.sprite.delete()
        self.hp_sprite.delete()
        self.after_death()

    def remove_from_chunk(self):
        if self.chunk:
            container = getattr(self.chunk, self.chunk_container)
            if self in container:
                container.remove(self)

    def after_death(self):
        pass

    def do_combat(self):
        pass

    def do_idle(self):
        pass

    def check_bounds(self):
        if (self.x + self.width) > config.window_width:
            self.out_of_bounds('e')
        elif self.x < 0:
            self.out_of_bounds('w')
        elif (self.y + self.height) > config.window_height:
            self.out_of_bounds('n')
        elif self.y < 0:
            self.out_of_bounds('s')

    def out_of_bounds(self, direction):
        pass

    def on_collision(self, obj):
        x_intersect = calc_1D_intersect(*self.x_1D, *obj.x_1D)
        y_intersect = calc_1D_intersect(*self.y_1D, *obj.y_1D)

        if x_intersect < y_intersect:
            if self.x < obj.x:
                self.x = obj.x - self.width
            else:
                self.x = obj.x + obj.width
        else:
            if self.y < obj.y:
                self.y = obj.y - self.height
            else:
                self.y = obj.y + obj.height
        self.after_collision(obj)

    def after_collision(self, obj):
        pass

    def attack(self):
        if not self.attack_cooldown:
            atk_range = 75
            for entity in self.chunk.attackable_objects:
                if entity is not self:
                    if distance(*self.coord, *entity.coord) < atk_range:
                        self.in_combat = True
                        if entity not in self.in_combat_with:
                            self.in_combat_with.append(entity)
                        self.do_damage(entity, d6(num=self.stats.str // 2))
                        self.attack_cooldown = 50

    def do_damage(self, target, dmg):
        target.take_damage(self, dmg)

    def take_damage(self, source, dmg):
        dmg_text = Label(f'{dmg}',
                         x=randint((self.x - 5) // 1,
                                   (self.x + self.width + 5) // 1),
                         y=self.y + self.height + 15,
                         font_name='courier new',
                         color=self.damage_text_color,
                         bold=True,
                         batch=self.chunk.draw_batch,
                         group=self.chunk.foreground)
        clock.schedule_once(lambda df: dmg_text.delete(), 0.5)

        if (source is not None) and (source is not self):
            self.in_combat = True
            if source not in self.in_combat_with:
                self.in_combat_with.append(source)

        self.stats.hp -= dmg
        if self.stats.hp < 1:
            self.dead = True

        print(
            f'{self.name} ({self.stats.hp}/{self.stats.base_hp}) took {dmg} damage from {source.name}!'
        )

    def fire_proj(self):
        velocity = 10
        p_x = self.cursor_coord.x - self.center.x
        p_y = self.cursor_coord.y - self.center.y
        d = distance(self.center.x, self.center.y, self.cursor_coord.x,
                     self.cursor_coord.y)
        r = velocity / d
        r_p = 30 / d
        if not self.projectile_cooldown:
            proj = Projectile(owner=self,
                              chunk=self.chunk,
                              x=self.center.x + p_x * r_p,
                              y=self.center.y + p_y * r_p,
                              damage=d20(num=self.stats.int // 3),
                              velocity_x=p_x * r,
                              velocity_y=p_y * r,
                              batch=self.chunk.draw_batch,
                              group=self.chunk.foreground)
            self.chunk.objects.append(proj)
            self.projectile_cooldown = 10

    def update_cooldowns(self):
        if self.attack_cooldown > 0:
            self.attack_cooldown -= 1
        if self.projectile_cooldown > 0:
            self.projectile_cooldown -= 1

    def move(self):
        if self.moving_to:
            dist_from_target = np.sqrt((self.x - self.moving_to.x)**2 +
                                       (self.y - self.moving_to.y)**2)

            if dist_from_target <= self.speed:
                self.x = self.moving_to.x
                self.y = self.moving_to.y
            else:
                dist_ratio = self.speed / dist_from_target
                self.x = (1.0 -
                          dist_ratio) * self.x + dist_ratio * self.moving_to.x
                self.y = (1.0 -
                          dist_ratio) * self.y + dist_ratio * self.moving_to.y

    def update_sprites(self):
        self.sprite.update(x=self.x, y=self.y)
        self.hp_sprite.update(x=self.x + 1,
                              y=self.y + self.height + 5,
                              scale_x=self.stats.hp / self.stats.base_hp)

    def update(self):
        self.check_state()
        if not self.dead:
            self.update_cooldowns()
            self.move()
            self.check_bounds()
            self.update_sprites()
        else:
            self.after_death()

    def draw(self):
        self.sprite.draw()
Example #13
0
class Bullet:
    def __init__(self, x, y, rot, img, weapon, game, main=True, owner=None):
        self.o_pos = Vector(x, y)
        self.prev_pos = Vector(x - 1, y - 1)
        self.pos = Vector(x, y)
        self.vector = Vector(WEAPONS[weapon]["bullet_speed"], 0).rotate(-rot)

        self.weapon = weapon

        self.sprite = Sprite(img, batch=game.bullet_batch)
        self.sprite.update(rotation=rot, scale=WEAPONS[weapon]["bullet_size"])
        self.sprite.image.anchor_x = self.sprite.image.width / 2
        self.sprite.image.anchor_y = self.sprite.image.height / 2

        self.distance = 0

        self.rot = rot

        if main:
            game.o_bullets.append({
                "rot": rot,
                "pos": {
                    "x": x,
                    "y": y
                },
                "weapon": weapon
            })

        self.owner = owner

    def check(self, game):
        for wall in game.walls:
            if wall.pos.x + wall.width > self.pos.x > wall.pos.x and wall.pos.y + wall.height > self.pos.y > wall.pos.y:
                return True

            if lineLine(wall.pos.x, wall.pos.y, wall.pos.x,
                        wall.pos.y + wall.height, self.pos.x, self.pos.y,
                        self.prev_pos.x, self.prev_pos.y):
                return True

            if lineLine(wall.pos.x, wall.pos.y, wall.pos.x + wall.width,
                        wall.pos.y, self.pos.x, self.pos.y, self.prev_pos.x,
                        self.prev_pos.y):
                return True

            if lineLine(wall.pos.x + wall.width, wall.pos.y,
                        wall.pos.x + wall.width, wall.pos.y + wall.height,
                        self.pos.x, self.pos.y, self.prev_pos.x,
                        self.prev_pos.y):
                return True

            if lineLine(wall.pos.x + wall.width, wall.pos.y + wall.height,
                        wall.pos.x, wall.pos.y + wall.height, self.pos.x,
                        self.pos.y, self.prev_pos.x, self.prev_pos.y):
                return True

        return False

    def check_player(self, player):
        if player.hit_box.x + player.hit_box.width > self.pos.x > player.hit_box.x and player.hit_box.y + player.hit_box.height > self.pos.y > player.hit_box.y:
            return True

        if lineLine(player.hit_box.x, player.hit_box.y,
                    player.hit_box.x + player.hit_box.width, player.hit_box.y,
                    self.pos.x, self.pos.y, self.prev_pos.x, self.prev_pos.y):
            return True

        if lineLine(player.hit_box.x + player.hit_box.width, player.hit_box.y,
                    player.hit_box.x + player.hit_box.width,
                    player.hit_box.y + player.hit_box.height, self.pos.x,
                    self.pos.y, self.prev_pos.x, self.prev_pos.y):
            return True

        if lineLine(player.hit_box.x + player.hit_box.width,
                    player.hit_box.y + player.hit_box.height, player.hit_box.x,
                    player.hit_box.y + player.hit_box.height, self.pos.x,
                    self.pos.y, self.prev_pos.x, self.prev_pos.y):
            return True

        if lineLine(player.hit_box.x, player.hit_box.y + player.hit_box.height,
                    player.hit_box.x, player.hit_box.y, self.pos.x, self.pos.y,
                    self.prev_pos.x, self.prev_pos.y):
            return True

        return False

    def update(self, dt):
        self.prev_pos = self.pos.copy()

        self.pos.x += self.vector.x * dt
        self.pos.y += self.vector.y * dt

        self.sprite.x = self.pos.x
        self.sprite.y = self.pos.y

        self.distance = Vector(self.pos.x - self.o_pos.x,
                               self.pos.y - self.o_pos.y).magnitude()
Example #14
0
class Sprite2D(fixture2d.Fixture2D):
    def __init__(self, img, x, y, batch=default_batch, group=None):
        self._sprite = Sprite(img, x=x, y=y, batch=batch, group=group)

        super().__init__(x, y)

    def update(self, dt):
        super().update(dt)

        self._sprite.update(x=self._pos.x,
                            y=self._pos.y,
                            rotation=self._rot,
                            scale_x=self._sx,
                            scale_y=self._sy)

    def delete(self):
        super().delete()

        self._sprite.delete()

    def _create_physical_body(self):
        return pymunk.Body(self._mass, self._inertia, self._body_type)

    def _create_physical_shape(self):
        return pymunk.Poly(self._body, [(-self.width / 2, self.height / 2),
                                        (self.width / 2, self.height / 2),
                                        (self.width / 2, -self.height / 2),
                                        (-self.width / 2, -self.height / 2)])

    def _get_inertia_for_shape(self):
        return pymunk.moment_for_poly(self._mass,
                                      [(-self.width / 2, self.height / 2),
                                       (self.width / 2, self.height / 2),
                                       (self.width / 2, -self.height / 2),
                                       (-self.width / 2, -self.height / 2)])

    def _get_bounding_box(self):
        return AABB.computeAABB(self.x, self.y, self.width, self.height,
                                self._rot)

    @property
    def width(self):
        return self._sprite.width

    @property
    def height(self):
        return self._sprite.height

    @property
    def batch(self):
        return self._sprite.batch

    @batch.setter
    def batch(self, value):
        self._sprite.batch = value

    @property
    def image(self):
        return self._sprite.image

    @image.setter
    def image(self, value):
        self._sprite.image = value

    @property
    def group(self):
        return self._sprite.group

    @group.setter
    def group(self, value):
        self._sprite.group = value

    @property
    def opacity(self):
        return self._sprite.opacity

    @opacity.setter
    def opacity(self, value):
        self._sprite.opacity = value

    @property
    def color(self):
        return self._sprite.color

    @color.setter
    def color(self, value):
        self._sprite.color = value

    @property
    def visible(self):
        return self._sprite.visible

    @visible.setter
    def visible(self, value):
        self._sprite.visible = value