Festival de las Cinco Especias: Celebre el Festival del Bote del Dragón con una aplicación

Tabla de contenido

 1.Preparación

1.1 Descarga de recursos

1.2 Instalar dependencias

2. Explicación detallada del principio.

2.1 Animación de partículas

2.2 Análisis estructural

Sin más preámbulos, primero te mostraré el efecto, si quieres el código, puedes descargar el paquete de códigos directamente.

 1.Preparación

1.1 Descarga de recursos

Después de descargar el paquete de código y descomprimirlo, el directorio debería ser el siguiente

 Entre ellos, background1 ~ background3 son 3 imágenes de fondo respectivamente, entre las cuales ITCKRIST.TTF es el archivo de fuente, Dragon Boat Festival.mp3 es la música de fondo y Dragon Boat Festival.py es el código fuente. 

1.2 Instalar dependencias

Necesitamos instalar algunas dependencias antes de comenzar oficialmente a codificar. Muestro las dependencias y sus funciones en la lista a continuación.

Biblioteca efecto
aleatorio Soporte de números aleatorios
tiempo Proveedor en pausa
pygame Proporcionar reproducción de música.
cochinillo leer fotos
cocos menú, animación de partículas

 Pulsamos win+r e ingresamos cmd para abrir la terminal.

Ingrese los comandos en secuencia para instalar dependencias.

pip install -U pygame
pip install -U pyglet
pip install -U cocos2d

Podemos comprobar si la instalación fue exitosa escribiendo

pip list

Si no tiene buenas habilidades prácticas, puede ejecutar run.bat directamente en el paquete de código para instalar dependencias. Si falla, puede buscar en Baidu usted mismo.

2. Explicación detallada del principio.

2.1 Animación de partículas
 

Lo principal en nuestro programa es la animación de partículas. ¿Qué es exactamente la animación de partículas?

La animación de partículas es una técnica que crea efectos de imagen dinámicos mediante el uso de muchos elementos visuales pequeños (partículas). Cada partícula tiene su propia posición, velocidad, aceleración, color y otros atributos, y se ajusta en el tiempo para producir diversos efectos dinámicos, como humo, llamas, ondas de agua, meteoritos, etc.

Sus principios se basan en principios físicos y matemáticos. En la animación de partículas, el movimiento de cada partícula se puede describir mediante la mecánica newtoniana, como fuerza, velocidad, aceleración, etc. Por lo general, es necesario aplicar algunos efectos físicos, como la gravedad, la fricción y la colisión, para simular el comportamiento al alcanzar el objetivo.

Además de los modelos físicos, también se pueden utilizar métodos matemáticos para producir efectos de animación de partículas. Por ejemplo, utilice funciones de ruido para generar valores aleatorios para simular irregularidades en entornos naturales.

En general, la animación de partículas es una forma de arte muy divertida e impresionante capaz de crear todo tipo de efectos visuales interesantes.

 En cuanto a cómo implementar la animación de partículas, lo explicaré más adelante.

2.2 Análisis estructural

Nuestro programa se implementa mediante una ventana. La ventana se compone de 2 escenas.

Capa de menú: Está compuesta por la capa de fondo público y la capa de menú MainMenu. 

Escena principal: compuesta por capa de animación y capa de fondo.

Creo que todo el mundo ya entiende la estructura de la ventana.

3. Implementación del código

3.1 Importación de módulos

# 导入必要的模块和库
from random import randint
from time import sleep
import pygame
from pygame import init
from pygame.mixer import music
from cocos.menu import *
from cocos.director import director
from cocos.scene import Scene
from cocos.actions import *
from cocos.layer import Layer
from cocos.text import Label
from cocos.particle_systems import *
from cocos.sprite import Sprite
from cocos.scenes import *
from pyglet.gl import *
from pyglet import resource
from pyglet.image import Animation

3.2 Definir clases públicas

# 音乐类,用来管理音乐播放
class Music:
    def __init__(self):
        init()
        try:
            music.load("端午节.mp3")#加载音乐
        except:
            print("cannot find mp3")

    def play(self):
        music.play()

# 自定义的一些粒子效果类
class MySpiral(Spiral):
    def __init__(self):
        super().__init__()

        self.total_particles = randint(300, 500)
        self.size = randint(7, 12)
        self.duration = randint(13, 20)
        self.position = (randint(100, 750), randint(100, 550))

class MyFlower(Flower):
    def __init__(self):
        super().__init__()

        self.total_particles = randint(300, 500)
        self.size = randint(12, 18)
        self.duration = randint(13, 20)
        self.position = (randint(50, 750), randint(50, 550))

class MyFlowerworks(Fireworks):
    def __init__(self):
        super().__init__()

        self.total_particles = randint(300, 500)
        self.size = randint(7, 12)
        self.duration = randint(13, 20)
        self.position = (randint(50, 750), 50)

class MyExplosion(Explosion):
    def __init__(self):
        super().__init__()

        self.total_particles = randint(300, 500)
        self.size = randint(7, 12)
        self.duration = randint(13, 20)
        self.position = (randint(50, 750), randint(50, 550))

# 背景图层类,用来加载和绘制背景图像
class BackgroundLayer(Layer):
    def __init__(self):
        super().__init__()
        try:
            self.images = [resource.image("background1.png"),
                           resource.image("background2.png"),
                           resource.image("background3.png")]#加载图片
        except:
            print("cannot find background image!")
        else:
            self.image = Animation.from_image_sequence(self.images, 2)

        self.idx = randint(0, 2)

    def draw(self):#绘制函数
        glPushMatrix()
        self.transform()
        self.images[self.idx].blit(0, 0)
        glPopMatrix()

3.3 Definir menú

# 菜单图层类,用来创建开始游戏的按钮和倒计时
class MenuLayer(Menu):
    def __init__(self):
        super().__init__("六一快乐")

        self.music = Music()
        music.play()

        self.time = 0

        self.font_title["font_size"] = 64
        self.font_title["color"] = (255, 128, 255, 255)

        self.menu_halign = CENTER
        self.menu_valign = CENTER

        self.items = []
        self.items.append(MenuItem("Start", self.on_stats))

        self.create_menu(self.items, shake(), shake_back())

        self.schedule(self.update)

    def on_stats(self):
        director.push(MainScene())

    def update(self, dt):
        self.time += dt

        if self.time >= 15.0:
            director.push(MainScene())

# 菜单场景类,用来加载菜单图层和背景图层
class MenuScene(Scene):
    def __init__(self):
        super().__init__()

        self.add(MenuLayer(), z=1)
        self.add(BackgroundLayer(), z=-1)

3.4 Definir la escena principal

# 游戏图层类,用来实现游戏界面和倒计时
class MainLayer(Layer):
    is_event_handler = True

    def __init__(self):
        super().__init__()

        # 设置文字的初始状态和动画效果
        self.texts = [list("祝各位端午节快乐!"), list("让我们一起欢庆吧!!")]
        self.idx1, self.idx2 = 0, 0
        self.new_text = ["", ""]

        try:
            self.text1 = Label(text=self.new_text[0],
                               font_size=64,
                               font_name="Kristen ITC",
                               color=(255, 128, 255, 255),
                               anchor_x="center",
                               anchor_y="center", )
        except:
            print("cannot find font file!")
        else:
            self.text1.position = (400, 450)
            self.text1.do(reversed(RotateBy(20, 1.5)) +
                          spawn(Repeat(RotateBy(40, 1.5) + reversed(RotateBy(40, 1.5))),
                                ScaleBy(1.25) + reversed(ScaleBy(1.25))))
            self.add(self.text1, z=0)

        try:
            self.text2 = Label(text=self.new_text[1],
                               font_size=64,
                               font_name="Kristen ITC",
                               color=(255, 128, 255, 255),
                               anchor_x="center",
                               anchor_y="center", )
        except:
            print("cannot find font file!")
        else:
            self.text2.position = (400, 300)
            self.text2.do(reversed(RotateBy(20, 1.5)) +
                          spawn(Repeat(RotateBy(40, 1.5) + reversed(RotateBy(40, 1.5))),
                                ScaleBy(1.25) + reversed(ScaleBy(1.25))))
            self.add(self.text2, z=0)

        # 添加背景图片,设置其初始位置
        self.background = Sprite(BackgroundLayer().image)
        self.background.position = (400, 300)
        self.add(self.background, z=-1)

        # 通过循环添加部分粒子效果
        for i in range(randint(15, 21)):
            self.systems = [MyFlower(), MyFlowerworks(), MyExplosion()]
            for j in range(randint(1, 3)):
                self.add(self.systems[randint(0, 2)], z=randint(3, 8))
        self.add(MySpiral())

        # 设置倒计时值,并设置定时器
        self.time1 = 0
        self.time2 = 0
        self.schedule(self.update_systems)
        self.schedule(self.update_text)

    # 更新文字部分的动画效果,实现逐字显示
    def update_text(self, dt):
        self.time1 += dt

        if self.time1 >= 1.0:
            if self.idx1 <= len(self.texts[0]) - 1:
                self.new_text[0] += self.texts[0][self.idx1]
                self.text1.element.text = self.new_text[0]
                self.idx1 += 1

            if self.idx2 <= len(self.texts[1]) - 1 and self.idx1 >= 8:
                self.new_text[1] += self.texts[1][self.idx2]
                self.text2.element.text = self.new_text[1]
                self.idx2 += 1
            self.time1 = 0

    # 更新粒子效果,每隔一段时间添加新的效果
    def update_systems(self, dt):
        self.time2 += dt

        if self.time2 >= randint(15, 20):
            for i in range(randint(15, 21)):
                self.systems = [MyFlower(), MyFlowerworks(), MyExplosion()]
                for j in range(randint(1, 3)):
                    self.add(self.systems[randint(0, 2)], z=randint(3, 8))
                    self.time2 = 0
            self.add(MySpiral())

# 游戏场景类,用来加载游戏图层和背景图层
class MainScene(Scene):
    def __init__(self):
        super().__init__()

        self.add(MainLayer(), z=2)
        self.add(BackgroundLayer(), z=0)

3.5 Crear ventana

if __name__ == '__main__':
    director.init(resizable=True, caption="六一快乐",
                  width=800, height=600)
    director.run(MenuScene())

4. Código completo

# 导入必要的模块和库
from random import randint
from time import sleep
import pygame
from pygame import init
from pygame.mixer import music
from cocos.menu import *
from cocos.director import director
from cocos.scene import Scene
from cocos.actions import *
from cocos.layer import Layer
from cocos.text import Label
from cocos.particle_systems import *
from cocos.sprite import Sprite
from cocos.scenes import *
from pyglet.gl import *
from pyglet import resource
from pyglet.image import Animation

# 音乐类,用来管理音乐播放
class Music:
    def __init__(self):
        init()
        try:
            music.load("端午节.mp3")
        except:
            print("cannot find mp3")

    def play(self):
        music.play()

# 自定义的一些粒子效果类
class MySpiral(Spiral):
    def __init__(self):
        super().__init__()

        self.total_particles = randint(300, 500)
        self.size = randint(7, 12)
        self.duration = randint(13, 20)
        self.position = (randint(100, 750), randint(100, 550))

class MyFlower(Flower):
    def __init__(self):
        super().__init__()

        self.total_particles = randint(300, 500)
        self.size = randint(12, 18)
        self.duration = randint(13, 20)
        self.position = (randint(50, 750), randint(50, 550))

class MyFlowerworks(Fireworks):
    def __init__(self):
        super().__init__()

        self.total_particles = randint(300, 500)
        self.size = randint(7, 12)
        self.duration = randint(13, 20)
        self.position = (randint(50, 750), 50)

class MyExplosion(Explosion):
    def __init__(self):
        super().__init__()

        self.total_particles = randint(300, 500)
        self.size = randint(7, 12)
        self.duration = randint(13, 20)
        self.position = (randint(50, 750), randint(50, 550))

# 背景图层类,用来加载和绘制背景图像
class BackgroundLayer(Layer):
    def __init__(self):
        super().__init__()
        try:
            self.images = [resource.image("background1.png"),
                           resource.image("background2.png"),
                           resource.image("background3.png")]
        except:
            print("cannot find background image!")
        else:
            self.image = Animation.from_image_sequence(self.images, 2)

        self.idx = randint(0, 2)

    def draw(self):
        glPushMatrix()
        self.transform()
        self.images[self.idx].blit(0, 0)
        glPopMatrix()

# 菜单图层类,用来创建开始游戏的按钮和倒计时
class MenuLayer(Menu):
    def __init__(self):
        super().__init__("六一快乐")

        self.music = Music()
        music.play()

        self.time = 0

        self.font_title["font_size"] = 64
        self.font_title["color"] = (255, 128, 255, 255)

        self.menu_halign = CENTER
        self.menu_valign = CENTER

        self.items = []
        self.items.append(MenuItem("Start", self.on_stats))

        self.create_menu(self.items, shake(), shake_back())

        self.schedule(self.update)

    def on_stats(self):
        director.push(MainScene())

    def update(self, dt):
        self.time += dt

        if self.time >= 15.0:
            director.push(MainScene())

# 菜单场景类,用来加载菜单图层和背景图层
class MenuScene(Scene):
    def __init__(self):
        super().__init__()

        self.add(MenuLayer(), z=1)
        self.add(BackgroundLayer(), z=-1)

# 游戏图层类,用来实现游戏界面和倒计时
class MainLayer(Layer):
    is_event_handler = True

    def __init__(self):
        super().__init__()

        # 设置文字的初始状态和动画效果
        self.texts = [list("祝各位端午节快乐!"), list("让我们一起欢庆吧!!")]
        self.idx1, self.idx2 = 0, 0
        self.new_text = ["", ""]

        try:
            self.text1 = Label(text=self.new_text[0],
                               font_size=64,
                               font_name="Kristen ITC",
                               color=(255, 128, 255, 255),
                               anchor_x="center",
                               anchor_y="center", )
        except:
            print("cannot find font file!")
        else:
            self.text1.position = (400, 450)
            self.text1.do(reversed(RotateBy(20, 1.5)) +
                          spawn(Repeat(RotateBy(40, 1.5) + reversed(RotateBy(40, 1.5))),
                                ScaleBy(1.25) + reversed(ScaleBy(1.25))))
            self.add(self.text1, z=0)

        try:
            self.text2 = Label(text=self.new_text[1],
                               font_size=64,
                               font_name="Kristen ITC",
                               color=(255, 128, 255, 255),
                               anchor_x="center",
                               anchor_y="center", )
        except:
            print("cannot find font file!")
        else:
            self.text2.position = (400, 300)
            self.text2.do(reversed(RotateBy(20, 1.5)) +
                          spawn(Repeat(RotateBy(40, 1.5) + reversed(RotateBy(40, 1.5))),
                                ScaleBy(1.25) + reversed(ScaleBy(1.25))))
            self.add(self.text2, z=0)

        # 添加背景图片,设置其初始位置
        self.background = Sprite(BackgroundLayer().image)
        self.background.position = (400, 300)
        self.add(self.background, z=-1)

        # 通过循环添加部分粒子效果
        for i in range(randint(15, 21)):
            self.systems = [MyFlower(), MyFlowerworks(), MyExplosion()]
            for j in range(randint(1, 3)):
                self.add(self.systems[randint(0, 2)], z=randint(3, 8))
        self.add(MySpiral())

        # 设置倒计时值,并设置定时器
        self.time1 = 0
        self.time2 = 0
        self.schedule(self.update_systems)
        self.schedule(self.update_text)

    # 更新文字部分的动画效果,实现逐字显示
    def update_text(self, dt):
        self.time1 += dt

        if self.time1 >= 1.0:
            if self.idx1 <= len(self.texts[0]) - 1:
                self.new_text[0] += self.texts[0][self.idx1]
                self.text1.element.text = self.new_text[0]
                self.idx1 += 1

            if self.idx2 <= len(self.texts[1]) - 1 and self.idx1 >= 8:
                self.new_text[1] += self.texts[1][self.idx2]
                self.text2.element.text = self.new_text[1]
                self.idx2 += 1
            self.time1 = 0

    # 更新粒子效果,每隔一段时间添加新的效果
    def update_systems(self, dt):
        self.time2 += dt

        if self.time2 >= randint(15, 20):
            for i in range(randint(15, 21)):
                self.systems = [MyFlower(), MyFlowerworks(), MyExplosion()]
                for j in range(randint(1, 3)):
                    self.add(self.systems[randint(0, 2)], z=randint(3, 8))
                    self.time2 = 0
            self.add(MySpiral())

# 游戏场景类,用来加载游戏图层和背景图层
class MainScene(Scene):
    def __init__(self):
        super().__init__()

        self.add(MainLayer(), z=2)
        self.add(BackgroundLayer(), z=0)

if __name__ == '__main__':
    director.init(resizable=True, caption="六一快乐",
                  width=800, height=600)
    director.run(MenuScene())

4. Conclusión 

En este Festival del Bote Dragón, bañémonos en la atmósfera de la cultura tradicional, probemos las deliciosas albóndigas de arroz, la emoción de las carreras de botes dragón y sintamos el encanto de las costumbres antiguas y el espíritu nacional. ¡Reunámonos estrechamente durante este festival para heredar y proteger este festival tradicional milenario, y deseamos que todos puedan encontrar alegría y felicidad durante el Festival del Bote Dragón! ! !

¡Finalmente, les deseo a todos un feliz Dragon Boat Festival! ! ! adiós

Supongo que te gusta

Origin blog.csdn.net/m0_73552311/article/details/131234329
Recomendado
Clasificación