Пример #1
0
 def ai(self):
     pos = game_vars.player_pos()
     if self.stage == 0:
         self.v[1] = -15
         dx = self.rect.centerx - pos[0]
         if abs(dx) > 10 * BLOCK_W:
             self.v[0] = math.copysign(15, -dx)
         else:
             self.v[0] = 0
         # When we get high enough and close enough, switch modes
         if self.pos[1] < pos[1] - 10 * BLOCK_W:
             # 60% chance to go to stage one (diving)
             if randint(1, 5) > 2:
                 self.start_diving()
             # 40% chance to go to stage two (shoot fireballs)
             else:
                 self.time = 0
                 self.stage = 2
     # If we get too far away, switch modes
     elif self.stage == 1:
         dx = self.pos[0] - pos[0]
         dy = self.pos[1] - pos[1]
         if dy > 10 * BLOCK_W or (dy >= 0 and abs(dx) > 10 * BLOCK_W):
             self.set_image(self.rising_anim.get_frame())
             self.stage = 0
     elif self.stage == 2:
         num_shot_i = int(self.time)
         self.time += game_vars.dt
         num_shot_f = int(self.time)
         # Shoot fire balls!
         for i in range(num_shot_f - num_shot_i):
             game_vars.shoot_projectile(
                 self.FireBall(self.rect.center,
                               game_vars.player_pos(False)))
         if num_shot_f >= 9:
             self.start_diving()
         else:
             # Get distance to 8 blocks above and to the side of the player
             dy = pos[1] - BLOCK_W * 8 - self.rect.centery
             dx = pos[0] - self.rect.centerx
             dx -= math.copysign(BLOCK_W * 8, dx)
             self.v[0] = math.copysign(7, dx) if dx != 0 else 0
             self.v[1] = math.copysign(7, dy) if dy != 0 else 0
     # Update animation
     if self.stage == 0 or self.stage == 2:
         i = self.rising_anim.idx
         self.rising_anim.update(game_vars.dt)
         if i != self.rising_anim.idx:
             self.set_image(self.rising_anim.get_frame())
Пример #2
0
 def start_diving(self):
     self.rising_anim.reset()
     pos = game_vars.player_pos()
     theta = get_angle(self.rect.center, pos)
     self.v = [15 * math.cos(theta), 15 * math.sin(theta)]
     self.set_image(self.attacking_img)
     self.stage = 1
Пример #3
0
 def ai(self):
     pos = game_vars.player_pos()
     if self.stage == 0:
         # If we aren't launching, move normally
         if self.hits_blocks:
             self.time += game_vars.dt
             # Check if we are switching to jump stage
             if self.time >= 7.75:
                 self.a = [0, 20]
                 if self.collisions[1] == 1:
                     self.v = [0, 0]
                     if self.time >= 8:
                         self.time = 0
                         self.stage = 1
                         self.v[1] = -self.stats.get_stat("max_speed")
                         self.hits_blocks = True
                 else:
                     self.time = 7.75
             else:
                 dx = pos[0] - self.rect.centerx
                 if dx != 0:
                     self.a[0] = math.copysign(10, dx)
                 if self.collisions[0] != 0 and self.collisions[1] == 1:
                     self.v[1] = -10
                     self.jump_count += 1
                     if self.jump_count > 2:
                         self.launch()
                 # Reset jumps if we aren't hitting something to the side
                 if self.collisions[0] == 0:
                     self.jump_count = 0
         else:
             # If we are in a block, keep launching
             if game_vars.in_block(self.pos, self.dim):
                 # If we went past out launch target, relaunch
                 angle = get_angle(self.rect.center, self.launch_target)
                 if abs(self.launch_angle - angle) > math.pi // 2:
                     self.launch_target = pos
                     self.launch_angle = get_angle(self.rect.center, pos)
                 self.v[0] = 15 * math.cos(self.launch_angle)
                 self.v[1] = 15 * math.sin(self.launch_angle)
             # Stop launching
             else:
                 self.a[1] = 20
                 self.v[1] = -5
                 self.hits_blocks = True
     elif self.stage == 1:
         if self.v[1] > -3:
             self.v[1] = 25
         if self.collisions[1] == 1:
             self.stage = 0
             self.v[1] = 0
             p = self.GroundP(self.pos, -1)
             p.set_pos(self.rect.centerx - p.dim[0] * BLOCK_W,
                       self.rect.bottom - p.dim[1] * BLOCK_W)
             game_vars.shoot_projectile(p)
             p = self.GroundP(self.pos, 1)
             p.set_pos(self.rect.centerx,
                       self.rect.bottom - p.dim[1] * BLOCK_W)
             game_vars.shoot_projectile(p)
Пример #4
0
 def launch(self):
     self.stage = 0
     self.a = [0, 0]
     self.v[0] = 15 * math.cos(self.launch_angle)
     self.v[1] = 15 * math.sin(self.launch_angle)
     self.hits_blocks = False
     self.launch_target = game_vars.player_pos()
     self.launch_angle = get_angle(self.rect.center, self.launch_target)
Пример #5
0
def follow_player(entity):
    # Check if we are standing on the ground
    if entity.collisions[1]:
        entity.a[0] = math.copysign(
            entity.stats.get_stat("acceleration"),
            game_vars.player_pos()[0] - entity.rect.centerx)
        # Check if we need to jump
        if entity.collisions[0] != 0:
            entity.v[1] = -entity.stats.get_stat("jump_speed")
Пример #6
0
def fly_follow(entity):
    # Move towards player when we get to far away from the player
    pos = game_vars.player_pos()
    if entity.a[0] == 0 or abs(entity.rect.centerx - pos[0]) >= 5 * BLOCK_W:
        entity.a[0] = math.copysign(entity.stats.get_stat("acceleration"),
                                    pos[0] - entity.rect.centerx)
    if entity.a[1] == 0 or abs(entity.rect.centery - pos[1]) >= 2 * BLOCK_W:
        entity.a[1] = math.copysign(entity.stats.get_stat("acceleration"),
                                    pos[1] - entity.rect.centery)
 def spawn(self):
     conditions = SpawnConditions()
     conditions.check_world()
     player_pos = [i // BLOCK_W for i in game_vars.player_pos()]
     spawners = game_vars.world.spawners
     world_dim = game_vars.world_dim()
     for x in range(max(0, player_pos[0] - 50), min(world_dim[0], player_pos[0] + 50)):
         if x in spawners.keys():
             for y in range(max(0, player_pos[1] - 50, min(world_dim[1], player_pos[1] + 50))):
                 if y in spawners[x].keys():
                     if randint(1, 10000) == 1:
                         entity = game_vars.tiles[spawners[x][y]].spawn((x, y), conditions)
                         if entity is not None:
                             self.add_entity(entity)
Пример #8
0
    def tick(self, dt):
        # Check chunk loading/unloading
        pos = game_vars.player_pos(in_blocks=True)
        rect = self.get_rect()
        dx = [pos[0] - rect.x, rect.right - pos[0]]
        dy = [pos[1] - rect.top, rect.bottom - pos[1]]
        for i in range(2):
            # X chunks
            if dx[i] >= CHUNK_W * 3:
                for row in self.chunks:
                    row[-i].unload()
                    del row[-i]
            elif dx[i] <= CHUNK_W * 3 // 2 and (
                    rect.x >= CHUNK_W
                    if i == 0 else rect.right <= self.world.dim[0] - CHUNK_W):
                x = self.chunks[0][-i].x + (-CHUNK_W if i == 0 else CHUNK_W)
                for row in self.chunks:
                    new = Chunk(x, row[0].y, blocks=self.world.blocks)
                    if i == 0:
                        row.insert(0, new)
                    else:
                        row.append(new)

            # Y chunks
            if dy[i] >= CHUNK_W * 3:
                for chunk in self.chunks[-i]:
                    chunk.unload()
                del self.chunks[-i]
            elif dy[i] <= CHUNK_W * 3 // 2 and (
                    rect.y >= CHUNK_W
                    if i == 0 else rect.bottom <= self.world.dim[1] - CHUNK_W):
                y = self.chunks[0][-i].y + (-CHUNK_W if i == 0 else CHUNK_W)
                new_row = [
                    Chunk(c.x, y, blocks=self.world.blocks)
                    for c in self.chunks[0]
                ]
                if i == 0:
                    self.chunks.insert(0, new_row)
                else:
                    self.chunks.append(new_row)

        # Update chunks
        for row in self.chunks:
            for chunk in row:
                chunk.tick(dt)
Пример #9
0
def jump(entity, follow):
    # If we are on the ground, progress our timer and make sure we aren't moving
    if entity.collisions[1] == 1:
        entity.a[0], entity.v[0] = 0, 0
        entity.time -= game_vars.dt
        # If we are done waiting, jump
        if entity.time <= 0:
            if follow:
                entity.a[0] = math.copysign(
                    entity.stats.get_stat("acceleration"),
                    game_vars.player_pos()[0] - entity.rect.centerx)
            else:
                entity.a[0] = entity.stats.get_stat(
                    "acceleration") * random_sign()
            entity.v[0] = math.copysign(entity.stats.get_stat("max_speedx"),
                                        entity.a[0])
            entity.v[1] = -randint(5, entity.stats.get_stat("jump_speed"))
            entity.time = uniform(1, 2)
Пример #10
0
    def draw_map(self, rect):
        src_dim = self.source.get_size()
        dim = rect.size

        dim = [min(dim[i], src_dim[i] * self.zoom) for i in (0, 1)]
        # Get map width in terms of blocks
        block_dim = (dim[0] / self.zoom, dim[1] / self.zoom)
        half_dim = (block_dim[0] / 2, block_dim[1] / 2)
        # Calculate top and left of our minimap
        for i in range(2):
            if self.center[i] < half_dim[i]:
                self.center[i] = half_dim[i]
            elif self.center[i] > src_dim[i] - half_dim[i]:
                self.center[i] = src_dim[i] - half_dim[i]
        left, top = self.center[0] - half_dim[0], self.center[1] - half_dim[1]
        # Get the blocks that will be in our map
        b_left, b_top = int(left), int(top)
        b_right, b_bot = math.ceil(left +
                                   block_dim[0]), math.ceil(top + block_dim[1])
        b_dim = (b_right - b_left, b_bot - b_top)
        # Draw them onto a surface
        s = pg.Surface(b_dim)
        s.blit(self.source, (0, 0), area=((b_left, b_top), b_dim))
        s = pg.transform.scale(
            s, (int(b_dim[0] * self.zoom), int(b_dim[1] * self.zoom)))
        # Cut off the edges
        off_x, off_y = int((left - b_left) * self.zoom), int(
            (top - b_top) * self.zoom)
        map_rect = pg.Rect((b_left, b_top), b_dim)
        self.draw_sprite(s, map_rect, game_vars.player.sprite,
                         game_vars.player_pos(in_blocks=True))
        for entity in [
                e for e in game_vars.handler.entities.values() if e.sprite
        ]:
            self.draw_sprite(s, map_rect, entity.sprite,
                             entity.get_block_pos())
        pg.display.get_surface().blit(
            s, (rect.centerx - dim[0] // 2, rect.centery - dim[1] // 2),
            area=((off_x, off_y), dim))
Пример #11
0
    def tick(self, dt):
        self.time = (self.time + dt) % c.SEC_PER_DAY
        # Run auto save
        self.next_save -= game_vars.dt
        if self.next_save <= 0:
            self.save_progress = self.save_world(self.save_progress)
            if self.save_progress >= 1:
                self.save_progress = 0
                self.next_save = 30
                game_vars.player.write()
        # Update minimap
        pos = game_vars.player_pos(True)
        left, top = max(int(pos[0] - 10), 0), max(int(pos[1] - 10), 0)
        # Go through every row, column pair where the color is black
        section = pg.surfarray.pixels2d(self.map)[left:math.ceil(pos[0] + 10),
                                                  top:math.ceil(pos[1] + 10)]
        for x, y in zip(*np.where(section == 0)):
            map_color = game_vars.tiles[game_vars.get_block_at(
                left + x, top + y)].map_color
            section[x][y] = self.map.map_rgb(map_color)
        del section

        self.manager.tick(dt)
Пример #12
0
 def ai(self):
     jump(
         self,
         abs(game_vars.player_pos()[0] - self.rect.centerx) // BLOCK_W <=
         10)
Пример #13
0
 def on_break(self, pos):
     game_vars.spawn_entity(mobs.Dragon(), [
         p + randint(10, 20) * BLOCK_W * c.random_sign()
         for p in game_vars.player_pos()
     ])
     return False
Пример #14
0
 def on_left_click(self):
     game_vars.spawn_entity(Mobs.MainBoss(),
                            [p + randint(15, 30) * BLOCK_W * random_sign() for p in game_vars.player_pos()])
Пример #15
0
 def on_left_click(self):
     super().on_left_click()
     game_vars.shoot_projectile(self.P1(game_vars.player_pos(), game_vars.global_mouse_pos()))