diff --git a/SourceCollector.py b/SourceCollector.py index a283f62..723ca6e 100644 --- a/SourceCollector.py +++ b/SourceCollector.py @@ -19,15 +19,21 @@ class SourceCollector: self.end_pos = None self.path = [] self.node_path = [] + self.boss_pos = None + self.lock_pos = None if self.filename: self.maze = [] with open(f"{self.filename}",'r') as f: reader = csv.reader(f) - for row in reader: + for idx,row in enumerate(reader): t = [] - for i in row: - if i.startswith('b') or i.startswith('l'): + for idy,i in enumerate(row): + if i.startswith('b'): t.append('0') + self.boss_pos = (idx,idy) + elif i.startswith('l'): + t.append('0') + self.lock_pos = (idx,idy) else: t.append(i) self.maze.append(t) @@ -142,8 +148,8 @@ class SourceCollector: children = sn.children[:] for child in children: self.dfs(child) - - children.sort(key=lambda c: len(c.path)) + if self.colNums < 11: + children.sort(key=lambda c: len(c.path)) cur = None for idx, child in enumerate(children): if child.dp > 0: @@ -203,11 +209,8 @@ class SourceCollector: if idx > 0: if item == self.path[idx-1]: del self.path[idx] - - if self.path and self.end_pos and self.path[-1] != self.end_pos: - bfs_tail = self.bfs_path(self.path[-1], self.end_pos) - if bfs_tail: - self.path.extend(bfs_tail[1:]) + + diff --git a/boss.png b/boss.png new file mode 100644 index 0000000..2aa04f6 Binary files /dev/null and b/boss.png differ diff --git a/cast.wav b/cast.wav new file mode 100644 index 0000000..f0dce31 Binary files /dev/null and b/cast.wav differ diff --git a/groan.wav b/groan.wav new file mode 100644 index 0000000..6918e2e Binary files /dev/null and b/groan.wav differ diff --git a/hit.wav b/hit.wav new file mode 100644 index 0000000..87404f3 Binary files /dev/null and b/hit.wav differ diff --git a/skill.png b/skill.png new file mode 100644 index 0000000..033d524 Binary files /dev/null and b/skill.png differ diff --git a/wan.py b/wan.py new file mode 100644 index 0000000..7f36cb4 --- /dev/null +++ b/wan.py @@ -0,0 +1,290 @@ +import pygame +import sys +import time +import random +import math + +# 配置 +SCREEN_WIDTH, SCREEN_HEIGHT = 900, 600 +BOSS_IMG = 'boss.png' # 替换为你的boss图片路径 +SKILL_IMG = 'skill.png' # 替换为你的技能图片路径 +FPS = 60 +HIT_SOUND = 'hit.wav' # 技能击中boss +CAST_SOUND = 'cast.wav' # 技能释放 +WIN_SOUND = 'win.wav' # 胜利 +GROAN_SOUND = 'groan.wav' # 怪物呻吟 +# 技能颜色和名称 +SKILL_COLORS = [(255, 80, 80), (80, 180, 255), (120, 255, 120), (255, 220, 80), (180, 80, 255)] +SKILL_NAMES = ["火球", "冰锥", "风刃", "雷击", "暗影"] +class Particle: + def __init__(self, x, y, color, shadow=False, glow=False): + self.x = x + random.randint(-10, 10) + self.y = y + random.randint(-10, 10) + self.radius = random.randint(2, 5) + self.color = color + self.life = random.randint(15, 30) + self.vx = random.uniform(-1.2, 1.2) + self.vy = random.uniform(-1.2, 1.2) + self.shadow = shadow + self.glow = glow + + def update(self): + self.x += self.vx + self.y += self.vy + self.life -= 1 + self.radius = max(0, self.radius - 0.08) + + def draw(self, screen): + if self.life > 0 and self.radius > 0: + if self.shadow: + s = pygame.Surface((int(self.radius*4), int(self.radius*2)), pygame.SRCALPHA) + pygame.draw.ellipse(s, (30,30,30,80), (0,0,int(self.radius*4),int(self.radius*2))) + screen.blit(s, (int(self.x-self.radius*2), int(self.y+self.radius))) + if self.glow: + s = pygame.Surface((int(self.radius*4), int(self.radius*4)), pygame.SRCALPHA) + pygame.draw.circle(s, (*self.color, 60), (int(self.radius*2), int(self.radius*2)), int(self.radius*2)) + screen.blit(s, (int(self.x-self.radius), int(self.y-self.radius))) + pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), int(self.radius)) +def draw_gradient_bg(screen): + for i in range(SCREEN_HEIGHT): + color = ( + 220 - i // 8, + 220 - i // 16, + 255 - i // 12 + ) + pygame.draw.line(screen, color, (0, i), (SCREEN_WIDTH, i)) + +def shake_pos(x, y, frame): + if frame % 2 == 0: + return x + 8, y + random.randint(-3, 3) + else: + return x - 8, y + random.randint(-3, 3) + +def draw_health_bar(screen, x, y, w, h, hp, max_hp): + pygame.draw.rect(screen, (180, 0, 0), (x, y, w, h), border_radius=8) + pygame.draw.rect(screen, (0, 220, 0), (x, y, int(w * hp / max_hp), h), border_radius=8) + pygame.draw.rect(screen, (0, 0, 0), (x, y, w, h), 2, border_radius=8) + +def draw_skill_cooldown(screen, x, y, w, h, cooldown, max_cd): + pygame.draw.rect(screen, (80, 80, 80), (x, y, w, h), border_radius=6) + if cooldown > 0: + pygame.draw.rect(screen, (120, 120, 255), (x, y, int(w * cooldown / max_cd), h), border_radius=6) + +class Skill: + def __init__(self, idx, dmg, img): + self.idx = idx + self.dmg = dmg + self.img = img + self.x = 60 + self.y = SCREEN_HEIGHT // 2 + random.randint(-60, 60) + self.active = True + self.color = SKILL_COLORS[idx % len(SKILL_COLORS)] + self.angle = random.uniform(-0.2, 0.2) + self.trail = [] + self.shadow = True + self.glow = True + self.speed = 7 + self.idx * 0.7 # 更慢 + self.cast_sound_played = False + + def update(self): + self.trail.append((self.x, self.y)) + if len(self.trail) > 12: + self.trail.pop(0) + self.x += self.speed + self.y += math.sin(self.x / 40) * 3 + self.angle * 8 + if self.x > SCREEN_WIDTH: + self.active = False + + def draw(self, screen): + # 阴影 + s = pygame.Surface((self.img.get_width(), self.img.get_height()), pygame.SRCALPHA) + pygame.draw.ellipse(s, (30,30,30,80), (0, self.img.get_height()//2, self.img.get_width(), self.img.get_height()//2)) + screen.blit(s, (self.x, self.y+self.img.get_height()//2)) + # 光晕 + s2 = pygame.Surface((self.img.get_width()*2, self.img.get_height()*2), pygame.SRCALPHA) + pygame.draw.circle(s2, (*self.color, 60), (self.img.get_width(), self.img.get_height()), self.img.get_width()) + screen.blit(s2, (self.x-self.img.get_width()//2, self.y-self.img.get_height()//2)) + # 轨迹 + for i, (tx, ty) in enumerate(self.trail): + alpha = int(255 * (i + 1) / len(self.trail)) + s = pygame.Surface((self.img.get_width(), self.img.get_height()), pygame.SRCALPHA) + s.fill((*self.color, alpha // 2)) + screen.blit(s, (tx, ty)) + screen.blit(self.img, (self.x, self.y)) + + +class Boss: + def __init__(self, img, hp, groan_sound=None): + self.img = img + self.hp = hp + self.max_hp = hp + self.x = SCREEN_WIDTH - img.get_width() - 80 + self.y = SCREEN_HEIGHT // 2 - img.get_height() // 2 + self.shake_frame = 0 + self.shake = False + self.dead = False + self.death_anim = 0 + self.particles = [] + self.groan_sound = groan_sound + self.groan_cooldown = 0 + + def hit(self, dmg): + if self.hp > 0: + self.hp = max(0, self.hp - dmg) + self.shake = True + self.shake_frame = 12 + # 受击粒子 + for _ in range(16): + self.particles.append(Particle(self.x + self.img.get_width() // 2, self.y + self.img.get_height() // 2, (255, 80, 80), shadow=True, glow=True)) + if self.groan_sound and self.groan_cooldown == 0: + self.groan_sound.play() + self.groan_cooldown = 30 + if self.hp == 0: + self.dead = True + self.death_anim = 60 + + def update(self): + if self.shake: + self.shake_frame -= 1 + if self.shake_frame <= 0: + self.shake = False + if self.groan_cooldown > 0: + self.groan_cooldown -= 1 + # 死亡动画 + if self.dead and self.death_anim > 0: + self.death_anim -= 1 + for _ in range(8): + self.particles.append(Particle(self.x + self.img.get_width() // 2, self.y + self.img.get_height() // 2, (80, 80, 80), shadow=True, glow=True)) + # 更新粒子 + for p in self.particles: + p.update() + self.particles = [p for p in self.particles if p.life > 0] + + def draw(self, screen): + # 投影 + s = pygame.Surface((self.img.get_width()*2, self.img.get_height()), pygame.SRCALPHA) + pygame.draw.ellipse(s, (30,30,30,90), (0, self.img.get_height()//2, self.img.get_width()*2, self.img.get_height()//2)) + screen.blit(s, (self.x-self.img.get_width()//2, self.y+self.img.get_height()-10)) + # 光晕 + s2 = pygame.Surface((self.img.get_width()*2, self.img.get_height()*2), pygame.SRCALPHA) + pygame.draw.circle(s2, (200,200,255,60), (self.img.get_width(), self.img.get_height()), self.img.get_width()) + screen.blit(s2, (self.x-self.img.get_width()//2, self.y-self.img.get_height()//2)) + if self.shake: + x, y = shake_pos(self.x, self.y, self.shake_frame) + else: + x, y = self.x, self.y + if not self.dead or self.death_anim > 0: + screen.blit(self.img, (x, y)) + draw_health_bar(screen, x, y - 40, 240, 24, self.hp, self.max_hp) + for p in self.particles: + p.draw(screen) +def main(boss_hp, skill_seq): + pygame.init() + screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) + pygame.display.set_caption('自动打Boss - 3D炫酷升级版') + clock = pygame.time.Clock() + boss_img = pygame.image.load(BOSS_IMG).convert_alpha() + skill_img = pygame.image.load(SKILL_IMG).convert_alpha() + # 音效 + try: + hit_sound = pygame.mixer.Sound(HIT_SOUND) + cast_sound = pygame.mixer.Sound(CAST_SOUND) + win_sound = pygame.mixer.Sound(WIN_SOUND) + groan_sound = pygame.mixer.Sound(GROAN_SOUND) + except Exception: + hit_sound = cast_sound = win_sound = groan_sound = None + boss = Boss(boss_img, boss_hp, groan_sound=groan_sound) + skills = [] + skill_idx = 0 + running = True + skill_cooldown = 0 + max_cd = 40 # 冷却更长 + font = pygame.font.SysFont('SimHei', 36) + big_font = pygame.font.SysFont('SimHei', 60) + particles = [] + + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + draw_gradient_bg(screen) + + # 随机背景粒子 + if random.random() < 0.18: + particles.append(Particle(random.randint(0, SCREEN_WIDTH), random.randint(0, SCREEN_HEIGHT), (200, 200, 255), shadow=True, glow=True)) + for p in particles: + p.update() + p.draw(screen) + particles = [p for p in particles if p.life > 0] + + boss.update() + boss.draw(screen) + + # 技能释放 + if skill_idx < len(skill_seq) and skill_cooldown == 0 and not boss.dead: + s = skill_seq[skill_idx] + skills.append(Skill(s['first'], s['second'], skill_img)) + if cast_sound: + cast_sound.play() + skill_cooldown = max_cd + skill_idx += 1 + if skill_cooldown > 0: + skill_cooldown -= 1 + + # 技能动画 + for skill in skills: + if skill.active: + skill.update() + skill.draw(screen) + # 判断是否击中boss + if skill.x + skill.img.get_width() > boss.x and boss.hp > 0 and not boss.dead: + boss.hit(skill.dmg) + # 爆炸粒子 + for _ in range(24): + particles.append(Particle(boss.x+boss.img.get_width()//2, boss.y+boss.img.get_height()//2, random.choice(SKILL_COLORS), shadow=True, glow=True)) + if hit_sound: + hit_sound.play() + skill.active = False + # 移除无效技能 + skills = [s for s in skills if s.active] + + # 技能冷却条和技能名 + if skill_idx < len(skill_seq): + s = skill_seq[skill_idx] + skill_name = SKILL_NAMES[s['first'] % len(SKILL_NAMES)] + name_text = font.render(f"下一个技能:{skill_name}", True, SKILL_COLORS[s['first'] % len(SKILL_COLORS)]) + screen.blit(name_text, (60, SCREEN_HEIGHT - 80)) + draw_skill_cooldown(screen, 60, SCREEN_HEIGHT - 40, 200, 18, skill_cooldown, max_cd) + + # 显示血量数字 + hp_text = font.render(f'Boss HP: {boss.hp}/{boss.max_hp}', True, (0,0,0)) + screen.blit(hp_text, (60, 30)) + + # Boss死亡动画 + if boss.dead and boss.death_anim == 0: + win_text = big_font.render("胜利!", True, (255, 120, 80)) + screen.blit(win_text, (SCREEN_WIDTH // 2 - 80, SCREEN_HEIGHT // 2 - 60)) + if win_sound: + win_sound.play() + + pygame.display.flip() + clock.tick(FPS) + if boss.hp <= 0 and not skills and boss.death_anim == 0: + time.sleep(1.5) + running = False + pygame.quit() + + +if __name__ == "__main__": + # 示例参数:boss血量1000,技能序列 + boss_hp = 1000 + skill_seq = [ + {'first': 0, 'second': 120}, + {'first': 1, 'second': 200}, + {'first': 2, 'second': 150}, + {'first': 3, 'second': 300}, + {'first': 4, 'second': 250}, + ] + main(boss_hp, skill_seq) + diff --git a/win.wav b/win.wav new file mode 100644 index 0000000..6918e2e Binary files /dev/null and b/win.wav differ