예제 #1
0
    def calculate_reward(self, snake_bodyAI, snake_bodyPlayer, fruit_pos):
        # Player hits snake_AI's body
        for block in snake_bodyAI[1:]:
            if block == snake_bodyPlayer[0]:
                return 20

        # Snake_AI's head hits itself
        if (len(snake_bodyAI) > 6):
            if Vector2.distance_to(snake_bodyAI[-1],
                                   snake_bodyAI[0]) < 3 or Vector2.distance_to(
                                       snake_bodyAI[-2], snake_bodyAI[0]) < 3:
                return -100
        for block in snake_bodyAI[1:]:
            if block == snake_bodyAI[0]:
                return -100

        # Snake_AI's head near player's body
        for block in snake_bodyPlayer:
            if Vector2.distance_to(snake_bodyAI[0], block) <= 3:
                return -100

        # Snake_AI's head on apple position
        if (Vector2.distance_to(snake_bodyAI[0], fruit_pos) == 0):
            return 50
        # Empty square
        else:
            return -10
예제 #2
0
    def qix(self, pos: Vector2, facing: float, size: float) -> None:
        """
        Draws the Qix
        :param pos: Current position
        :param facing: Facing direction
        :param size: Size of object
        :return: None
        """
        draw_color = (255, 0, 0)
        delta = Vector2(0, size / 2)

        if pos.distance_to(
                self.prev_qix[-1][0]) >= 0.01 or facing - self.prev_qix[-1][
                    1] > 0.01 or facing - self.prev_qix[-1][1] < -0.01:
            self.qix_update(pos, facing)

        offset = delta.rotate(facing)
        start = (pos + offset) * self.scale + Vector2(self.offset)
        end = (pos - offset) * self.scale + Vector2(self.offset)
        pygame.draw.aaline(self.surface, draw_color, start, end, 2)
        self.qix_lines = [[start, end]]
        for (pos, facing, draw_color) in self.prev_qix:
            offset = delta.rotate(facing)
            start = (pos + offset) * self.scale + Vector2(self.offset)
            end = (pos - offset) * self.scale + Vector2(self.offset)
            pygame.draw.aaline(self.surface, draw_color, start, end, 2)
            self.qix_lines.append([start, end])
예제 #3
0
def main():
    pygame.init()
    clock = pygame.time.Clock()
    screen = pygame.display.set_mode((screen_width, screen_height))
    background = pygame.Surface(screen.get_size())
    background.fill(bg_color)
    background.convert()
    running = True
    stage = 6

    player, entities, edibles, clickables = reset(0, stage)

    while running:
        # restart if the player has eaten everything
        if len(edibles) == 0 or player.sfd:
            if not player.sfd:
                stage += 1
                if stage > max_difficulty:
                    stage = max_difficulty
            player, entities, edibles, clickables = reset(player.score, stage)
        time = clock.tick(
            FPS)  # get the time passed since the last frame (in milliseconds)
        dt = time / 1000
        # blit the background
        screen.blit(background, (0, 0))
        # event handling
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                pos = Vec(pygame.mouse.get_pos())
                for c in clickables:
                    if pos.distance_to(c.pos) < c.xsize + grace_distance:
                        player.target = c
                # The final clickable knows about the player
                if player.target is not None:
                    player.target.is_clicked = True
                    player.target.target = player
            elif event.type == pygame.MOUSEBUTTONUP:
                if player.target is not None:
                    player.target.is_clicked = False
                    player.target.target = None
                    player.target = None

        for entity in entities:
            entity.update(dt, entities)

        # Kill all entities scheduled for destruction
        entities = [e for e in entities if not e.sfd]
        edibles = [e for e in edibles if not e.sfd]
        clickables = [e for e in clickables if not e.sfd]

        for entity in entities:
            entity.draw(screen)

        pygame.display.update()
예제 #4
0
    def get_close_entity_in_state(self,
                                  name,
                                  states,
                                  location: Vector2,
                                  radius=20.):
        """ Find an entity within range of a location that is in one of the
            states provided. """

        for entity in self.entities.values():
            if entity.name == name:
                for state in states:
                    if entity.brain.active_state.name == state:
                        distance = location.distance_to(entity.location)
                        if distance < radius:
                            return entity
        return None
예제 #5
0
    def get_closest_entity(self, name, location: Vector2, radius=20.):
        """ Find the closest entity within range of a location """

        close_entities = []
        for entity in self.entities.values():
            if name is None or entity.name == name:
                distance = location.distance_to(entity.location)
                if distance < radius:
                    close_entities.append((distance, entity))

        # Return the closest of the entities within range.
        if len(close_entities) > 0:
            close_entities = sorted(close_entities, key=lambda e: e[0])
            distance, closest_entity = close_entities[0]
            return closest_entity

        return None
예제 #6
0
    def get_close_entity(self,
                         name,
                         location: Vector2,
                         radius=20.,
                         ignore_id=None):
        """ Finds the first entity within range of a location """

        for entity in self.entities.values():
            # If an ignore_id is passed, ignore the entity with that id.
            if ignore_id is not None and entity.id == ignore_id:
                continue

            if name is None or entity.name == name:
                distance = location.distance_to(entity.location)
                if distance < radius:
                    return entity
        return None
예제 #7
0
 def is_home(self, pos: Vector2) -> bool:
     for ent, (home, mov) in self.world.get_components(Home, Movable):
         if pos.distance_to(mov.position) < CONTACT_DISTANCE:
             return True
     return False
예제 #8
0
class GraplingHook():
    def __init__(self, x, y):
        self.image_master = \
            pygame.image.load("../ArtWork/Environment/graple.png")\
            .convert_alpha()
        self.image_master = pygame.transform.scale(self.image_master, (80, 40))
        self.image = self.image_master

        self.hook_image_master = \
            pygame.image.load("../ArtWork/Environment/hook2.png")\
            .convert_alpha()
        self.hook_image_master = pygame.transform.scale(
            self.hook_image_master, (40, 40))
        self.hook_image = self.hook_image_master

        self.displacement = (self.hook_image_master.get_width() +
                             self.image_master.get_width()) // 2
        self.hook_rect = Rectangle.get_rect(self.hook_image, (x, y))
        self.rect = Rectangle.get_rect(self.image, (x, y))

        self.hooker = Vector((self.hook_rect.x, self.hook_rect.y))
        self.hitmask = get_hitmask(self.hook_rect, self.hook_image, 0)
        self.aim = (x, y + 20)
        self.should_aim = True
        self.should_retract = False
        self.limit = Vector(1, 0)
        self.angle = 0
        self.rotation = 0
        self.step = 0
        self.should_release = False
        self.time = 0
        self.distance_limit = 150
        self.x = self.rect.x
        self.y = self.rect.y
        self.current_time = 0
        self.last_time = 0
        self.shooter = False
        self.calculate_pivot = True

    def calculate_angle(self):
        self.angle = self.rope.angle_to(self.limit)

    def retract(self, timer):
        if self.distance > self.distance_limit:
            self.rect.advance(self.rope.x * 700 * (timer / 1000),
                              self.rope.y * 700 * (timer / 1000))
            self.x += self.rope.x * 700 * (timer / 1000)
            self.y += self.rope.y * 700 * (timer / 1000)
            self.calculate_rope()
        else:
            self.swing()

    def calculate_rope(self):
        self.hook = Vector(self.aim)
        self.player = Vector(self.rect.center[0], self.rect.center[1])
        self.distance = self.hook.distance_to(self.player)
        self.rope = self.hook - self.player
        self.rope = self.rope.normalize()

    def swing(self):
        self.current_time = pygame.time.get_ticks()
        if self.current_time - self.last_time >= 17:
            self.bob.recompute_angle()
            self.step = self.bob.d_theta
            self.rope = self.rope.rotate(self.step)
            self.rect = Rectangle.get_rect(self.image, self.bob.rect.center)
            self.x = self.rect.x
            self.y = self.rect.y

            self.last_time = self.current_time

    def shoot(self, timer):
        for element in self.stop_rect:

            class Collide:
                def __init__(self, rect, hitmask):
                    self.rect = rect
                    self.hitmask = hitmask

            collider = Collide(self.hook_rect, self.hitmask)
            if not collide(collider, element):
                self.hook_rect.advance(self.rope.x * 500 * (timer / 1000),
                                       self.rope.y * 500 * (timer / 1000))
            else:
                if self.calculate_pivot:

                    self.hook_rect.rotate(90 - self.angle)
                    self.aim = (self.hook_rect.vertices[0].x +
                                self.hook_rect.vertices[1].x) // 2, \
                               (self.hook_rect.vertices[0].y +
                                self.hook_rect.vertices[1].y) // 2
                    self.bob = Pendulum(90 - self.angle, self.distance_limit,
                                        self.aim)
                    self.calculate_pivot = False
                self.shooter = False

    def update(self, timer, world, events):
        self.functionality(events, world)
        way_point = Vector(self.aim) - Vector(self.rect.center)
        bearing = way_point.normalize()
        self.image = pygame.transform.rotate(self.image_master,
                                             way_point.angle_to(Vector(1, 0)))
        self.rect = Rectangle.get_rect(self.image, self.rect.center)
        if not self.should_retract:
            self.hook_image = pygame.transform.rotate(
                self.hook_image_master, way_point.angle_to(Vector(1, 0)))
            self.hook_rect = Rectangle.get_rect(self.hook_image,
                                                self.hook_rect.center)
            self.hitmask = get_hitmask(self.hook_rect, self.hook_image, 0)

        self.x = self.rect.x
        self.y = self.rect.y

        if self.shooter:
            self.shoot(timer)
            self.should_retract = True
            self.should_aim = False

        elif not self.should_retract:
            self.hook_rect = Rectangle.get_rect(
                self.hook_image,
                (self.rect.center[0] + bearing.x * self.displacement,
                 self.rect.center[1] + bearing.y * self.displacement))
        if self.should_retract and not self.shooter:
            self.retract(timer)
        if self.should_release:
            self.release(timer)

    def functionality(self, events, world):
        for event in events:
            if event.type == pygame.MOUSEMOTION and self.should_aim:
                self.aim = pygame.mouse.get_pos()

            if event.type == pygame.MOUSEBUTTONUP and self.should_aim:
                for collider in world:
                    if collider.rect.is_point_in_body(self.aim):
                        self.stop_rect = world
                        self.shooter = True
                        self.calculate_rope()
                        self.calculate_angle()

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LCTRL:
                    self.should_release = True
                    self.should_retract = False

    def release(self, timer):
        self.calculate_rope()

        self.rect.advance((-self.rope.x * 10 -
                           (sin(self.bob.theta) * int(self.bob.d_theta))) *
                          40 * (timer / 1000),
                          (-self.rope.y * 10 + self.rope.y *
                           (30 - self.time)) * 15 * (timer / 1000))
        self.time += 0.8

    def draw(self, screen, camera):
        if not self.should_release:
            pygame.draw.aaline(screen, (0, 0, 0),
                               camera.apply(self.rect.center),
                               camera.apply(self.aim))
        screen.blit(self.image, camera.apply((self.x, self.y)))
        screen.blit(
            self.hook_image,
            camera.apply((self.hook_rect.center[0] - 20,
                          self.hook_rect.center[1] - 20)))

    def reposition(self, coordinates):
        self.rect.center = Vector(coordinates)