def shoot(self, enemy):
     result = [
         self.P1(self.pos, data.get_angle_pixels(self.pos, enemy.pos))
     ]
     if self.upgrade_lvl >= 3 and randint(0, 1) == 0:
         result.append(
             self.P1(self.pos, data.get_angle_pixels(self.pos, enemy.pos)))
     return result
 def tick(self, dt):
     self.timer += dt
     while self.timer >= self.cooldown:
         self.timer -= self.cooldown
         # Get all enemies in range
         in_range = [
             e for e in data.lvlDriver.enemies
             if data.get_distance(self.pos, e.pos) < self.range
         ]
         # Shoot the enemies based on shooting ai
         if len(in_range) > 0:
             # Get target enemy based on targeting method
             if self.targeting == "First":
                 enemy = first_enemy(in_range)
             elif self.targeting == "Closest":
                 enemy = closest_enemy(in_range, self.pos)
             elif self.targeting == "Strongest":
                 enemy = strongest_enemy(in_range)
             else:
                 continue
             # Shoot the projectile(s)
             arr = self.shoot(enemy)
             if arr:
                 pg.mixer.Channel(1).play(data.shoot_audio)
             for projectile in arr:
                 self.modify_projectile(projectile)
                 data.lvlDriver.projectiles.append(projectile)
             # Rotate to face the enemy
             self.set_angle(
                 data.get_angle_pixels(self.pos, enemy.pos) * 360 //
                 data.TWO_PI)
 def shoot(self, enemy):
     return [self.P1(self.pos, data.get_angle_pixels(self.pos, enemy.pos))]
Exemple #4
0
def new_level(lvl=None):
    reset()

    if lvl:
        global level
        level = lvl

    draw()

    mode = 0
    while True:
        for e in pg.event.get():
            if e.type == QUIT:
                return
            elif e.type == VIDEORESIZE:
                data.resize(e.w, e.h, False)
                draw()
            elif e.type == MOUSEBUTTONUP and e.button == BUTTON_LEFT:
                global selected, last_level, current
                pos = pg.mouse.get_pos()
                if rect.collidepoint(*pos):
                    pos = [(pos[0] - rect.x) / rect.w,
                           (pos[1] - rect.y) / rect.h]
                    if current.idx == START:
                        current.pos = pos
                        # If we are overriding other level, save them for undo button
                        if level.len > 1:
                            last_level = level
                        level.paths.clear()
                        level.add(current)
                        current = Start()
                    elif current.idx == LINE:
                        level.add(current)
                        current = Line(start=level.end)
                    elif current.idx == CIRCLE:
                        if mode == 0:
                            mode = 1
                        else:
                            level.add(current)
                            current = Circle()
                            mode = 0
                elif pos[0] - data.off_x < side_w:
                    idx = (pos[1] - data.off_y) * len(buttons) // data.screen_w
                    button = buttons[idx]
                    # Clicked save, make sure we have at least one non-start path
                    if button == "Save & Exit" and level.len >= 2:
                        return level
                    # Select background image
                    elif button == "Background":
                        file = choose_file([".png", ".jpg"])
                        if file:
                            # Get parts of the file
                            name = file[file.rfind("/") + 1:]
                            extension = name[name.index("."):]
                            name = name[:-len(extension)]
                            # Target file
                            target = "res/levels/" + name + extension
                            # Make sure we don't overwrite a file
                            i = -1
                            while isfile(target):
                                with open(file,
                                          'rb') as f1, open(target,
                                                            'rb') as f2:
                                    # Files are the same, jus use this file
                                    if f1.read() == f2.read():
                                        break
                                    # Files are different, change the name
                                    else:
                                        i += 1
                                        target = "res/levels/" + name + "_{}".format(
                                            i) + extension
                            # If the target isn't an existing file, copy our old file to it
                            if not isfile(target):
                                copyfile(file, target)
                            level.img = target
                        data.calculate_dimensions(False)
                        draw()
                    # Clicked undo
                    elif button == "Undo":
                        if level.len > 0:
                            level.paths.pop(-1)
                        elif last_level.len > 0:
                            level.paths = last_level.paths.copy()
                            last_level.paths.clear()
                        else:
                            continue
                        # Change the index so that it recreates the current path object
                        if level.len == 0:
                            current = Start()
                            selected = "Start"
                            draw_options()
                        else:
                            if selected == "Start":
                                current = Start()
                            elif selected == "Line":
                                current = Line(start=level.end)
                            elif selected == "Circle":
                                current = Circle()
                        mode = 0
                        draw_level()
                    elif selected != buttons[idx] and level.len > 0:
                        selected = buttons[idx]
                        draw_options()
                        if selected == "Start":
                            current = Start()
                        elif selected == "Line":
                            current = Line(start=level.end)
                        elif selected == "Circle":
                            current = Circle()
                        mode = 0
            elif e.type == MOUSEMOTION:
                pos = pg.mouse.get_pos()
                pos = [(pos[0] - rect.x) / rect.w, (pos[1] - rect.y) / rect.h]
                pos_ = [min(max(i, 0.), 1.) for i in pos]
                if current.idx == START:
                    current.pos = pos_
                    for i in range(2):
                        if abs(.5 - current.pos[i]) < .025:
                            current.pos[i] = .5
                elif current.idx == LINE:
                    current.end = pos_
                    dx, dy = current.end[0] - current.start[0], current.end[
                        1] - current.start[1]
                    if abs(dx) < .025:
                        current.end[0] = current.start[0]
                    if abs(dy) < .025:
                        current.end[1] = current.start[1]
                    if abs(abs(dx) - abs(dy)) < .025:
                        r = math.sqrt(dx * dx + dy * dy)
                        delta = r * math.sqrt(2) / 2
                        current.end[0] = current.start[0] + math.copysign(
                            delta, dx)
                        current.end[1] = current.start[1] + math.copysign(
                            delta, dy)
                elif current.idx == CIRCLE:
                    if mode == 0:
                        # Get end of last segment
                        end = level.end
                        for i in range(2):
                            if abs(end[i] - pos[i]) < .025:
                                pos[i] = end[i]
                        r = data.get_distance(end, pos)
                        # Set initial circle angle
                        current.theta_i = data.get_angle_pixels(pos, end)
                        current.theta_f = current.theta_i + data.TWO_PI
                        if pos[0] - r >= 0 and pos[0] + r <= 1 and pos[
                                1] - r >= 0 and pos[1] + r <= 1:
                            current.center = pos
                            current.radius = r
                        else:
                            trig = [
                                math.cos(current.theta_i),
                                -math.sin(current.theta_i)
                            ]
                            diameter = 1
                            for i in range(2):
                                # Distance to negative edge
                                d = end[i]
                                # Number of diameters from starting point to negative edge
                                v = .5 + trig[i] / 2
                                if v > 0 and d / v < diameter:
                                    diameter = d / v
                                # Same for positive edge
                                d = 1 - d
                                v = 1 - v
                                if v > 0 and d / v < diameter:
                                    diameter = d / v
                            radius = diameter / 2
                            # Set center position and radius
                            current.center = [
                                end[i] - radius * trig[i] for i in range(2)
                            ]
                            current.radius = radius
                    else:
                        # Calculate change in angle
                        dtheta = data.get_angle_pixels(current.center, pos) - (
                            current.theta_f % data.TWO_PI)
                        # Make sure we are going in the correct direction
                        if dtheta > math.pi:
                            dtheta -= data.TWO_PI
                        elif dtheta < -math.pi:
                            dtheta += data.TWO_PI
                        current.theta_f += dtheta
                        diff = current.theta_f - current.theta_i
                        ten_pi = data.TWO_PI * 5
                        if diff > ten_pi:
                            current.theta_f = ten_pi + current.theta_i
                        elif diff < -ten_pi:
                            current.theta_f = -ten_pi + current.theta_i
                        half_pi, quarter_pi = math.pi / 2, math.pi / 4
                        factor = (diff + quarter_pi) // half_pi
                        if abs(diff - half_pi * factor) < half_pi / 10:
                            current.theta_f = factor * half_pi + current.theta_i
                draw_level()
        pg.display.flip()