Пример #1
0
    def update(self):
        # health regen/degen
        if self.hps_regen != 0:
            self.hp_current = min(
                self.hp_current + (self.hps_regen * self.game.delta_time),
                self.hp_max)

        # face the player if he's close enough to be seen
        player_dist = calc_dist(self.pos, self.game.player.pos)
        if player_dist <= self.vision_distance:
            self.rotate(Vec2(self.game.player.hit_rect.center))
        else:
            self.rot = randint(0, 360)
            self.image = pg.transform.rotate(self.orig_image, self.rot)
        self.acc = Vec2(self.speed, 0).rotate(-self.rot)

        # update image
        # TODO: give these guys some animation
        self.rect = self.image.get_rect(center=self.rect.center)
        self.rect.center = self.pos

        # ajdust angle tp spread out from other mobs
        self.avoid(self.game.mobs, self.avoid_radius)

        # run forwards
        if player_dist <= self.vision_distance:
            self.acc.scale_to_length(self.speed)
            self.acc += self.vel * -1
            self.vel += self.acc * self.game.delta_time
            self.pos += self.vel * self.game.delta_time + 0.5 * self.acc * self.game.delta_time**2
        else:
            self.acc.scale_to_length(self.speed * .3)
            self.acc += self.vel * -1
            self.vel += self.acc * self.game.delta_time
            self.pos += self.vel * self.game.delta_time + 0.5 * self.acc * self.game.delta_time**2

        # wall collision
        self.hit_rect.centerx = self.pos.x
        self.collide(self.game.walls, 'x')
        self.hit_rect.centery = self.pos.y
        self.collide(self.game.walls, 'y')

        # mouseover highlighting
        if self.rect.collidepoint(pg.mouse.get_pos() -
                                  self.game.camera.offset):
            # self.image = self.get_outline
            self.image.blit(self.get_outline(), self.image.get_rect())

        # death conditions check
        if self.hp_current <= 0:
            self.die()
Пример #2
0
    def process_input(self):
        self.vel = Vec2(
            0, 0
        )  # this might be a problem later on, if external forces can effect player position
        keys = pg.key.get_pressed()

        # rotational movement
        if self.game.configs.control_scheme == 'rotational':
            if keys[pg.K_LEFT] or keys[pg.K_a]:
                self.vel = Vec2(self.speed, 0).rotate(-self.rot - 90)
            if keys[pg.K_RIGHT] or keys[pg.K_d]:
                self.vel = Vec2(self.speed, 0).rotate(-self.rot + 90)
            if keys[pg.K_UP] or keys[pg.K_w]:
                self.vel = Vec2(self.speed, 0).rotate(-self.rot)
            if keys[pg.K_DOWN] or keys[pg.K_s]:
                self.vel = Vec2(-self.speed, 0).rotate(
                    -self.rot)  # no backwards speed penalty

        if self.game.configs.control_scheme == '4d':
            if keys[pg.K_LEFT] or keys[pg.K_a]:
                self.vel += Vec2(self.speed, 0).rotate(180)
            if keys[pg.K_RIGHT] or keys[pg.K_d]:
                self.vel += Vec2(self.speed, 0).rotate(0)
            if keys[pg.K_UP] or keys[pg.K_w]:
                self.vel += Vec2(self.speed, 0).rotate(270)
            if keys[pg.K_DOWN] or keys[pg.K_s]:
                self.vel += Vec2(-self.speed,
                                 0).rotate(270)  # no backwards speed penalty

        # skills
        # switch focus skill
        if keys[pg.K_PAGEDOWN]:
            if self.can_change_skills:
                self.focus_skill = next(self.all_skills_gen)
                self.last_skill_change = pg.time.get_ticks()

        # switch focus bonus
        if keys[pg.K_PAGEUP]:
            if self.can_change_skills and self.focus_skill:
                self.focus_skill.next_focus()
                self.last_skill_change = pg.time.get_ticks()

        # active skill
        if pg.mouse.get_pressed()[0]:
            self.equipped['active_skill'].fire()

        # melee attack
        if keys[pg.K_SPACE] or pg.mouse.get_pressed()[2]:
            self.equipped['melee_skill'].fire()

        # movement skill
        if keys[pg.K_LCTRL]:
            self.equipped['move_skill'].fire()
Пример #3
0
 def __init__(self,
              game,
              name,
              owner,
              image,
              damage,
              pos,
              vel,
              duration,
              align='center',
              moves_with_owner=False):
     self._layer = layers.projectile
     self.groups = game.all_sprites, game.aoe
     pg.sprite.Sprite.__init__(self, self.groups)
     self.game = game
     self.owner = owner
     self.name = name
     self.image = image
     self.rect = self.image.get_rect()
     self.pos = Vec2(pos)
     self.rect.center = pos
     self.vel = vel
     self.duration = duration
     self.damage = damage
     self.damage_rate = 2000
     self.spawn_time = pg.time.get_ticks()
     self.moves_with_owner = moves_with_owner
     self.align = align
Пример #4
0
    def __init__(self, game, start_pos):
        # pygame sprite stuff
        self._layer = layers.mob
        self.groups = game.all_sprites, game.mobs
        pg.sprite.Sprite.__init__(self, self.groups)

        # object references
        self.game = game

        # assets
        self.standing_frames = None
        self.load_images()

        # graphics
        self.image = self.standing_frames[0]
        self.orig_image = self.image

        # physics
        self.rect = self.image.get_rect(center=start_pos)
        self.hit_rect = pg.Rect(0, 0, settings.TILESIZE - 5,
                                settings.TILESIZE - 5)
        self.hit_rect.center = self.rect.center
        self.vel = Vec2(0, 0)
        self.acc = Vec2(0, 0)
        self.pos = Vec2(start_pos)
        self.rot = 0
        self.avoid_radius = 100

        # state
        self.last_damage = defaultdict(int)

        # default stats
        self.speed = 80
        self.hp_current = 100
        self.hp_max = 100
        self.hps_regen = 0
        self.collision_damage = 10
        self.damage_rate = 200
        self.collision_knockback = 20
        self.vision_distance = 300
        self.xp_value = 10

        # item management
        self.inventory = []
        self.food = randint(5, 20)
Пример #5
0
 def mouse_angle(self):
     x1, y1 = self.game.camera.apply(self).center
     x2, y2 = Vec2(pg.mouse.get_pos())
     dx = x2 - x1
     dy = y2 - y1
     rads = atan2(dy, dx)
     rads %= 2 * pi
     degs = int(degrees(rads)) + 90
     return degs % 360
Пример #6
0
    def rotate(self, target):
        """
        Turn to face the target

        :param target: pygame.math.Vector2
        :return: None
        """

        self.rot = (target - self.hit_rect.center).angle_to(Vec2(1, 0))
        self.image = pg.transform.rotate(self.orig_image, self.rot)
Пример #7
0
    def generate_maptiles(self):
        """
        loops through self.map.data and spawns walls
        currently, this function also sets the player start position when it finds an empty tile
            - this is kind of an efficiency hack since we're looping through the data anyways,
              but might need to be replaced later to separate functionality or as part of procedural gen
        """
        mob_types = [
            self.worldmap.graph.node[self.worldmap.current_node]['mobtype']
        ]

        if self.worldmap.destination_node:
            mob_types += [
                self.worldmap.graph.node[self.worldmap.destination_node]
                ['mobtype']
            ]

        for x in range(self.current_map.tilewidth):
            for y in range(self.current_map.tileheight):

                if self.current_map.data[x][y] == 1:
                    self.spawn(Wall,
                               (x * settings.TILESIZE, y * settings.TILESIZE))

                elif self.current_map.player_start is None:
                    tile_center_x = x * settings.TILESIZE + settings.TILESIZE / 2
                    tile_center_y = y * settings.TILESIZE + settings.TILESIZE / 2
                    self.current_map.player_start = Vec2(
                        int(tile_center_x), int(tile_center_y))

                    if self.configs.debug:
                        print("Player starting coordinates set to: {}".format(
                            self.current_map.player_start))

                else:
                    # distance from player spawn
                    player_dist = calc_dist(
                        (x * settings.TILESIZE, y * settings.TILESIZE),
                        self.current_map.player_start)
                    # distance from other clusters
                    cluster_space = not any([
                        calc_dist((x, y), cluster) < settings.cluster_dist
                        for cluster in self.current_map.clusters
                    ])
                    if player_dist > settings.safe_spawn_dist and cluster_space:  # random.random() > .9:
                        # self.spawn(Mob, (x * settings.TILESIZE, y * settings.TILESIZE))
                        self.current_map.clusters.append((x, y))

        for cluster in self.current_map.clusters:
            for i in range(settings.pack_size):
                x = (cluster[0] * settings.TILESIZE +
                     i) + (settings.TILESIZE // 2)
                y = (cluster[1] * settings.TILESIZE +
                     i) + (settings.TILESIZE // 2)
                self.spawn(choice(mob_types), (x, y))
Пример #8
0
    def handle_event(self, event):
        # left click
        if event.type == pg.MOUSEBUTTONDOWN and event.button == 1:
            self.highlight()
            button_up_relative_pos = Vec2(event.pos) - Vec2(
                self.button_up.get_abs_offset()) - Vec2(self.rect.topleft)
            button_down_relative_pos = Vec2(event.pos) - Vec2(
                self.button_down.get_abs_offset()) - Vec2(self.rect.topleft)
            if self.button_up.get_rect().collidepoint(button_up_relative_pos):
                print('button up clicked')
                if self.index < len(self.content_left) - self.items_per_screen:
                    self.index += 1
            if self.button_down.get_rect().collidepoint(
                    button_down_relative_pos):
                print('button down clicked')
                if self.index:
                    self.index -= 1

        # scroll wheel up
        elif event.type == pg.MOUSEBUTTONDOWN and event.button == 4:
            if self.index:
                self.index -= 1
        # scroll wheel down
        elif event.type == pg.MOUSEBUTTONDOWN and event.button == 5:
            if self.index < len(self.content_left) - self.items_per_screen:
                self.index += 1
Пример #9
0
 def __init__(self, game, image, damage, pos, vel, duration, kickback):
     self.groups = game.all_sprites, game.projectiles
     pg.sprite.Sprite.__init__(self, self.groups)
     self.game = game
     self.image = image
     self.rect = self.image.get_rect()
     self.pos = Vec2(pos)
     self.rect.center = pos
     self.vel = vel
     self.duration = duration
     self.kickback = kickback
     self.damage = damage
     self.damage_rate = 2000
     self.spawn_time = pg.time.get_ticks()
Пример #10
0
    def fire(self):
        spawn_point = self.owner.projectile_spawn
        proj_direction = Vec2(1, 0).rotate(-self.owner.rot)
        proj_vel = proj_direction * self.proj_speed
        proj_vel += self.owner.vel  # no need to save

        if self.can_fire:
            MovingDamageArea(game=self.game,
                             name=self.name,
                             owner=self.owner,
                             image=self.rotated_img,
                             damage=self.proj_damage,
                             pos=spawn_point,
                             vel=proj_vel,
                             duration=self.proj_duration,
                             align=self.aligns[self.owner.facing],
                             moves_with_owner=True)
            self.last_fired = pg.time.get_ticks()
            self.owner.attacking = True
Пример #11
0
    def update(self):
        """ update logic for main game loop """
        self.effects_screen.fill((0, 0, 0, 0))

        self.all_sprites.update()
        self.camera.update(target=self.player, hit_rect=True)

        self.trigger_delayed_events()
        for skill in self.active_skills:
            skill.update()

        # projectiles hit mobs
        hits = pg.sprite.groupcollide(self.mobs, self.projectiles, False, True)
        for hit in hits:
            hit.take_damage(hits[hit][0])
            # hit.hp_current -= hits[hit][0].damage

        # mobs take area damage
        hits = pg.sprite.groupcollide(self.mobs, self.aoe, False, False)
        for hit in hits:
            hit.take_damage(hits[hit][0])
            # hit.hp_current -= hits[hit][0].damage

        # mobs hit player
        hits = pg.sprite.spritecollide(self.player, self.mobs, False,
                                       Collider.collide_hit_rect)
        for hit in hits:
            # self.player.hp_current -= hit.collision_damage
            self.player.take_damage(hits[0])
        if hits:
            # if :
            self.player.pos += Vec2(hits[0].collision_knockback,
                                    0).rotate(-hits[0].rot)

        if len(self.mobs) == 0:
            print('All mobs defeated')
            self.flash_message('All Mobs Defeated', 3)
            if not self.worldmap.destination_node:
                self.fsm('select_destination')
            else:
                self.travel()
Пример #12
0
    def update(self, action):
        if action[0] == 1:
            self.angle += max_turn_rate
        if action[1] == 1:
            self.angle -= max_turn_rate

        if self.timestep % 300 == 0:
            n = random.randint(0, 100)
            if n <= cut_percentage:
                self.append_history = False

        if self.t_cut == cut_len:
            self.append_history = True
            self.t_cut = 0

        position = self.position + Vec2(1, 0).rotate(self.angle) * speed
        if self.append_history:
            self.history.append(position)
        else:
            self.t_cut += 1

        self.position = position
        self.timestep += 1
Пример #13
0
    def __init__(self, px, py, pz, rx, ry, rz, sx, sy, sz):
        self.pos = Vec(px, py, pz)
        self.rotation = Vec(rx, ry, rz)
        self.size = Vec(sx, sy, sz)

        self.load_image()
        self.image_size = Vec2(self.image.get_size())
        self.plate = ''

        self.font = pygame.font.Font('UKNumberPlate.ttf', 290)

        self.verts = [
            Vec(-1, -1, -1),
            Vec(-1, -1, 1),
            Vec(1, -1, 1),
            Vec(1, -1, -1),
            Vec(-1, 1, -1),
            Vec(-1, 1, 1),
            Vec(1, 1, 1),
            Vec(1, 1, -1),
        ]
        self.faces = [(3, 7, 6, 2), (4, 3, 7, 8), (1, 4, 8, 5), (2, 1, 5, 6),
                      (2, 3, 4, 1), (6, 7, 8, 5)]
Пример #14
0
    def __init__(self, game, start_pos):
        # pygame sprite stuff
        self._layer = layers.player
        self.groups = game.all_sprites
        pg.sprite.Sprite.__init__(self, self.groups)
        super().__init__()
        self.name = 'Player'

        # object references
        self.game = game

        # assets
        self.standing_frames = None
        self.moving_frames = None
        self.attacking_frames = None
        self.load_images()

        # graphics
        self.last_update = pg.time.get_ticks()
        self.frame_delay = 200
        # self.image = next(self.standing_frames['down'])
        self.image = next(self.standing_frames['S'])
        self.orig_image = self.image

        # physics
        self.rect = self.image.get_rect(center=start_pos)
        self.hit_rect = pg.Rect(0, 0, 30, 60)
        self.hit_rect.midbottom = self.rect.midbottom
        self.vel = Vec2(0, 0)
        # self.vx, self.vy = 0, 0
        # self.x, self.y = start_pos
        self.pos = Vec2(start_pos)
        self.rot = 0
        self.proj_offset = Vec2(15,
                                15)  # hardcoded to the placeholder graphics

        # state
        self.last_damage = defaultdict(int)
        self.dead = False
        self.last_shot = 0
        self.last_skill_change = 0
        self.focus_skill = None
        self.attacking = False
        self.speed_mul = 1.0
        # self.last_positions = Queue(maxsize=10)

        # default stats
        self.vision_radius = 300
        self.skill_change_delay = 100
        self.xp_total = 0
        self.speed = 100
        self.hp_current = 80
        self.hp_max = 100
        self.hps_regen = 1  # hp per second
        self.resource_current = 50
        self.resource_max = 100
        self.rps_regen = 3  # resource per second
        self.eating_rate = 1  # food per second

        self.starving_penalties = {'speed': 50}

        # item management
        self.food = 100
        self.inventory = []
        self.equipped = {
            'armor': None,
            'weapon': None,
            'active_skill': None,
            'melee_skill': None,
            'move_skill': None,
            'passives': []
        }

        self.load_placeholder_skills()
        self.all_skills_gen = cycle(self.all_skills)
Пример #15
0
    def display(self, screen):
        self.load_image()
        self.add_number()

        polygon = []

        verts = []
        for v in self.verts:
            cv = Vec(v.x, v.y, v.z)

            cv.x *= self.size.x
            cv.y *= self.size.y
            cv.z *= self.size.z

            cv = cv.rotate_x_rad(radians(self.rotation.x))
            cv = cv.rotate_y_rad(radians(self.rotation.y))
            cv = cv.rotate_z_rad(radians(self.rotation.z))

            cv.x += self.pos.x
            cv.y += self.pos.y
            cv.z += self.pos.z

            verts.append(cv)

        ps = []
        front = None
        for i1, i2, i3, i4 in map(lambda f: tuple([i - 1 for i in f]),
                                  self.faces):
            polygon = [
                get(verts[i1]),
                get(verts[i2]),
                get(verts[i3]),
                get(verts[i4])
            ]

            if self.faces[2] == (i1 + 1, i2 + 1, i3 + 1, i4 + 1):
                front = polygon

            ps.append(polygon)

        ps.sort(key=distance_sorter, reverse=True)

        for p in ps:
            check = p
            p = list(map(lambda elem: elem[:2], p))
            pygame.draw.polygon(screen, [150, 150, 0], p)
            pygame.draw.polygon(screen, [0, 0, 0], p, 1)

            if check == front:
                top_left = Vec2(p[0])
                top_right = Vec2(p[1])
                bottom_right = Vec2(p[2])
                bottom_left = Vec2(p[3])

                start = Vec2(p[0])
                end = Vec2(p[1])
                current = Vec2(p[0])

                x_move = (end - start).normalize()
                y_move = (bottom_left - top_left).normalize()

                while True:
                    current += x_move
                    draw = True

                    uv = Vec2(
                        translate(current.x, start.x, end.x, 0,
                                  self.image_size.x),
                        translate(current.y, top_left.y, bottom_left.y, 0,
                                  self.image_size.y))

                    try:
                        c = self.image.get_at((int(uv.x), int(uv.y)))
                    except IndexError:
                        draw = False

                    if draw:
                        screen.set_at((int(current.x), int(current.y)), c)

                    if abs(current.x - end.x) + abs(current.y - end.y) < 1:
                        start += y_move
                        end += y_move

                        current = Vec2(start.x, start.y)

                    if abs(start.x - bottom_left.x) + abs(start.y -
                                                          bottom_left.y) < 1:
                        break
Пример #16
0
from pygame.math import Vector2 as Vec2

moves = []
with open('input.txt') as f:
    moves = f.readline().split(", ")

cur_pos = Vec2(0, 0)

DIRECTION = {
    'N': Vec2(0, 1),
    'S': Vec2(0, -1),
    'E': Vec2(-1, 0),
    'W': Vec2(1, 0)
}

cur_direction = 'N'

DIRECTION_MAP = {
    'N': {
        'R': 'E',
        'L': 'W'
    },
    'S': {
        'R': 'W',
        'L': 'E'
    },
    'E': {
        'R': 'S',
        'L': 'N'
    },
    'W': {
Пример #17
0
 def mouse_pos(self):
     return Vec2(pg.mouse.get_pos()) - self.camera.offset
Пример #18
0
import pygame
from game import Game
from fever import Curve
from pygame.math import Vector2 as Vec2
import random
import numpy as np
import matplotlib.pyplot as plt

game = Game(640, 480)
curve = Curve(Vec2(100, 100))
game.curve = curve

while (1):
    action = random.choice([0, 1, 2])
    frame, reward = game.step(action)
Пример #19
0
 def rotate(self, target):
     """ face the target """
     self.rot = (target - self.hit_rect.center).angle_to(Vec2(1, 0))
Пример #20
0
def random_disk():
    sqrtr = random.random()**0.5
    theta = 2.0 * pi * random.random()
    return sqrtr * Vec2(cos(theta), sin(theta))