fd
from manim import *
class MonsterBattle(Scene):
def construct(self):
title = Text("第一次实验").to_edge(UP).set_color(YELLOW)
self.play(Write(title))
# Create a Triangle (as a person) and a Circle (as a monster)
person = Circle(color=BLUE).scale(0.5).to_edge(LEFT).shift(RIGHT*2) # Using a Circle as a person
monster = Triangle().scale(1).rotate(PI).to_edge(RIGHT).shift(LEFT*3) # Using a Downward Triangle as a monster
# Add labels for the person and the monster, and move them below the objects
person_label = Text("英雄").next_to(person, DOWN*2)
monster_label = Text("怪兽").next_to(monster, DOWN*2)
# Create a health bar above the monster
health_bar_background = Rectangle(width=2.5, height=0.3, color=WHITE, fill_opacity=0).next_to(monster, UP*2)
health_bar = Rectangle(width=2.5, height=0.21, color=RED, fill_opacity=1).next_to(monster, UP*2).shift(0.045*UP)
# Initial health value
initial_health = 1.0
health_text = Text(f"{initial_health:.2f}", font_size=36).next_to(health_bar_background, RIGHT)
# Add them to the scene
self.play(FadeIn(person), FadeIn(monster))
self.play(Write(person_label), Write(monster_label))
self.play(FadeIn(health_bar_background), FadeIn(health_bar), Write(health_text))
# Define the attack sequence
attacks = [0.3, 0.4, 0.5]
current_health = initial_health
bullet_records = VGroup() # Group to hold bullet record dots
for i, damage in enumerate(attacks):
# Bullet attack animation
bullet = Dot(color=RED).move_to(person.get_center())
target_point = monster.get_center()
damage_text = Text(f"-{damage:.2f}", font_size=36).next_to(health_text, RIGHT, buff=0.1)
# 子弹移动到目标位置,使用平滑的速度函数
self.play(
bullet.animate.move_to(target_point).set_rate_func(smooth),
FadeIn(damage_text),
run_time=0.3
)
# 短暂延迟以平滑过渡
self.wait(0.05)
# 怪兽缩放动画,加速进入
self.play(
monster.animate.scale(0.7).set_rate_func(rush_into),
FadeOut(damage_text),
run_time=0.2
)
# 子弹淡出,平滑过渡
self.play(
FadeOut(bullet),
run_time=0.05
)
# 更新血量和血条宽度
current_health = max(0, current_health - damage)
new_width = 3 * current_health
self.remove(health_text) # 移除旧的血量文本
health_text = Text(f"{current_health:.2f}", font_size=36).next_to(health_bar_background, RIGHT) # 创建新的血量文本
self.add(health_text) # 添加新的血量文本到场景
self.play(
health_bar.animate.stretch_to_fit_width(new_width).align_to(health_bar_background, LEFT).set_rate_func(smooth),
run_time=0.25
)
# 怪兽恢复原始大小,加速退出
self.play(
monster.animate.scale(1.0 / 0.7).set_rate_func(rush_from),
run_time=0.2
)
# 在屏幕下方记录子弹的图形和伤害值,放置在屏幕中间偏下的地方
bullet_record = Dot(color=RED).move_to(DOWN * 2 + RIGHT * (i - len(attacks) / 2) * 1.0) # 调整间隔
bullet_damage_text = Text(f"{abs(damage):.2f}", font_size=24).next_to(bullet_record, DOWN, buff=0.1) # 使用绝对值显示伤害
bullet_records.add(VGroup(bullet_record, bullet_damage_text)) # 将子弹图形和伤害文本作为一个组添加
self.play(FadeIn(bullet_record), FadeIn(bullet_damage_text), run_time=0.2)
self.wait(0.5)
# Transform monster into a line after the last attack
self.play(Transform(monster, Line(monster.get_left(), monster.get_right()).set_color(RED)), run_time=1)
self.play(
bullet_records.animate.scale(1.5).set_rate_func(rush_into),
run_time=0.7
)
self.play(
bullet_records.animate.scale(1/1.5).set_rate_func(rush_from),
run_time=0.7
)
self.play(
bullet_records.animate.set_color(YELLOW),
run_time=0.5
)
# End scene
self.wait(2)