Python-kivy implementa un juego de pinball simple (que incluye mejoras en las reglas comunes y un embellecimiento simple de la interfaz)

Tabla de contenido

 Prefacio:

1. Una breve descripción de las reglas

(1) Acerca de la colisión

(2) Acerca de la puntuación

2. Mejoras a las reglas

(1) Sobre el funcionamiento de la pelota

(2) Sobre la adición de IA para personas con discapacidades mentales

(3) Embellecimiento de la interfaz

 (4) Agregue efectos de sonido de fondo y música

3. Énfasis en otros detalles

(1) componente de widget

(2) Lonas y etiquetas en kv

4. Código completo

5. Resumen de deficiencias


 Prefacio:

        Este sigue siendo un proyecto en el plan de estudios de mi escuela, porque también tengo que tomar el examen de ingreso de posgrado, por lo que no dediqué demasiado tiempo a hacer buenos proyectos. Entonces hice algunas mejoras simples basadas en un juego de tenis de mesa en Internet. Los siguientes son los documentos y las direcciones de descarga del código fuente a los que me refiero, y puede recogerlos si los necesita:

GitHub - attreyabhatt/Kivy-Pong-Game: juego de Pong creado con Kivy https://github.com/attreyabhatt/Kivy-Pong-Game

        Si quieres entender el proyecto que estoy haciendo, finalmente puedes leer el siguiente documento, que introduce su lógica de funcionamiento más básica: 

Tutorial del juego Pong: documentación de Kivy 2.1.0 https://kivy.org/doc/stable/tutorials/pong.html


1. Una breve descripción de las reglas

(1) Acerca de la colisión

        Como todos sabemos, la lógica de colisión del juego de pinball: cuando la bola golpea el tablero o el límite, rebota, la velocidad vertical se invierte cuando golpea los límites superior e inferior, y la velocidad horizontal se invierte cuando golpea los límites izquierdo y derecho.

(2) Acerca de la puntuación

        Hay varias reglas de puntuación. En primer lugar, puede definir agregar puntos cuando toca el tablero, o puede agregar puntos al oponente cuando toca el borde de su propio lado, etc. También se pueden establecer puntos.

2. Mejoras a las reglas

(1) Sobre el funcionamiento de la pelota

        El proceso de carrera de la pelota es lógico, lo que hará que el jugador prediga la dirección de la pelota al jugar, lo que reduce en gran medida la dificultad, por lo que configuré una lógica de carrera irregular aquí, y la velocidad de la pelota y el tamaño cambiarán. aleatoriamente a lo largo del tiempo. Vamos a explicarlo con código:

        Primero definí algunos parámetros para facilitar los cambios posteriores en la velocidad y el tamaño:

speed_x = NumericProperty(0)  # 球的水平速度属性
speed_y = NumericProperty(0)  # 球的垂直速度属性
speed = ReferenceListProperty(speed_x, speed_y)  # 球的速度向量属性
r =  NumericProperty(0)   #球的大小属性
max_speed = 5  # 球的最大速度

        A continuación, la función de movimiento actualiza la posición de la pelota en tiempo real. La función aleatoria significa que la velocidad de la pelota cambia constantemente. Los números positivos de vel_y y vel_x representan las velocidades hacia arriba y hacia la derecha, y los números negativos son viceversa. La función daxiao hace que la bola cambie aleatoriamente entre 20*20 y 80*80.

 def move(self):
        self.pos = Vector(*self.speed) + self.pos  # 根据速度更新球的位置

 def randomize(self):
        # 随机化速度
        vel_x = uniform(-5, 5)  # 在[-5, 10]范围内生成一个随机数作为水平速度
        vel_y = uniform(-5, 5)  # 垂直速度
        self.speed = Vector(vel_x, vel_y).normalize() * self.max_speed  # 设置球的速度向量,并将其归一化后乘以最大速度


 def daxiao(self):
        # 随机化大小
        r = uniform(20, 80)
        self.size = r , r # 在[20, 80]范围内生成一个随机数作为球的大小
        print(self.size)

        Luego llámalo en la clase subsiguiente.

def serve_ball(self):
     self.ball.center = self.center  # 将球的中心位置设置为窗口的中心位置
     self.ball.randomize()  # 随机化球的速度
     self.ball.daxiao()     # 随机化球的大小
     self.timer = 0  # 计时器初始化为0

(2) Sobre la adición de IA para personas con discapacidades mentales

        ¿Por qué se llama IA para discapacitados mentales? Como sugiere el nombre, su lógica de implementación es demasiado simple. Solo necesitamos dejar que el centro de uno de los tableros se mueva con el centro de la pelota y establecer la velocidad de carrera. ¿No es así? muy simple Ababa (• • )~

def move_player2(self):
        # 根据球的位置移动玩家2的挡板
        if self.ball.center_y < self.player2.center_y:
            self.player2.center_y -= 5  # 将玩家2的挡板向下移动5个单位
        elif self.ball.center_y > self.player2.center_y:
            self.player2.center_y += 5

        Entonces recuerda llamarlo al frente, para que el tablero se mueva con nuestra bola, para que no tengas que controlar a dos jugadores tú solo. Por supuesto, también puede configurar el tablero del jugador 1 en automático, para que pueda ver los dos tableros y jugar solo.

(3) Embellecimiento de la interfaz

        Con respecto al embellecimiento de la interfaz, modificamos principalmente el archivo kv. El siguiente es mi archivo kv completo. Podemos configurar el tamaño, el color, etc. Para los parámetros específicos, puede consultarlo en línea.

<PongBall>:
    canvas:
        Color:
            rgba: .9,.9,.1 ,9
        Ellipse:
            pos: self.pos
            size: self.size
            source: "出生.jpg"

<PongPaddle>:
    size: 25, 150
    canvas:
        Color:
            rgba: 1, 1, 1, .9
        Rectangle:
            pos: self.pos
            size: self.size
            source: "无标题.png"

<PongGame>:
    ball: pong_ball
    player1: player_left
    player2: player_right
    canvas:
        Color:
            rgba:1, 1, 1, .9
        Rectangle:
            size:self.size
            source:"233.jpg"
        Color:
            rgba: .2, 1, 1, .9
        Rectangle:
            pos: self.center_x - 5, 0
            size: 10, self.height

    Label:
        color: .9,.6,.1 ,9
        font_size: 70
        center_x: root.width / 4
        top: root.top - 50
        text: str(root.player2.score)

    Label:
        color: .8,.1,.1 ,9
        font_size: 70
        center_x: root.width * 3/4
        top: root.top - 50
        text: str(root.player1.score)

    PongBall:
        id: pong_ball
        center: self.parent.center

    PongPaddle:
        id: player_left
        x: root.x
        center_y: root.center_y

    PongPaddle:
        id: player_right
        x: root.width - self.width
        center_y: root.center_y

         Aquí hay algunas fotos que usé:

         El efecto final de la interfaz es el siguiente:

 (4) Agregue efectos de sonido de fondo y música

        Para agregar efectos de sonido y música, usaremos una biblioteca de kivy:

from kivy.core.audio import SoundLoader

        Solo necesitamos las siguientes líneas de código:

sound = SoundLoader.load('away.mp3')
        if sound:
            sound.loop = True  # 设置循环播放
            sound.play()

3. Énfasis en otros detalles

(1) componente de widget

1. Widget no es un diseño y Widget no cambiará la posición y el tamaño de sus subcomponentes.
2. El tamaño predeterminado de Widget es 100*100.
3. Por defecto, el size_hint del Widget es 1 * 1. Si su componente principal es un componente de diseño, su tamaño es el tamaño requerido por el diseño en el componente principal.
4. Las funciones como on_touch_down(), on_touch_move(), on_touch_up() no realizan juicios de rango de límites de componentes (juicios de colisión) y necesitan llamar a collide_point().

(2) Lonas y etiquetas en kv

Canvas: Cree un lienzo, las siguientes son algunas propiedades de Canvas:

        1 .add(): agrega un objeto gráfico al lienzo, que puede ser un gráfico o un grupo.

        2. insert(): inserta un objeto gráfico antes de la posición especificada en el lienzo.

        3. remove(): Elimina el objeto gráfico especificado del lienzo.

        4. clear(): elimina todos los objetos gráficos del lienzo.

        5. tamaño: El tamaño del lienzo, su valor determina el tamaño del lienzo.

        6. pos: la posición del lienzo, su valor determina la posición del lienzo en relación con el control principal.

        7. opacidad: La opacidad del lienzo, su valor está entre 0-1.

        8. canvas.before: Objetos gráficos dibujados antes de todos los elementos en el lienzo.

        9. canvas.after: objetos gráficos dibujados después de todos los elementos del lienzo.

        10. canvas.clear(): Limpia todo el lienzo.

        11. canvas.ask_update(): Actualiza a la fuerza el contenido del lienzo.

        12. canvas.export_to_png(): guarde el lienzo en un archivo PNG.

Etiqueta de etiqueta: en Kivy, el widget de etiqueta se usa para presentar texto. Solo admite cadenas codificadas en ASCII y Unicode (no se admite el chino). En Etiqueta, puede configurar el contenido del texto, la fuente, el tamaño, el color, la alineación y el salto de línea. , citas y texto etiquetado

        1. texto: el texto que muestra la etiqueta

        2. text_size: tamaño del texto de la etiqueta

        3. font_name: el nombre de archivo de la fuente que se utilizará

        4. font_size: el tamaño de fuente del texto

        5. negrita: la fuente usa negrita

        6. cursiva: la fuente usa cursiva

        7. color: color de fuente, el formato es rgba, el valor predeterminado es blanco [1, 1, 1, 1]

        8. halign: la alineación horizontal del texto, los parámetros opcionales son: izquierda, centro, derecha, justificar

        9. valign: la alineación vertical del texto, los parámetros opcionales son: inferior, medio (o centro), superior

        10. marcado: si dividir todo el texto marcado

        11. subrayar: añade un subrayado al texto

        12. padding_x: el relleno horizontal del texto dentro del cuadro del widget

        13. padding_y: el relleno vertical del texto dentro del cuadro del widget

        14. textura: el objeto de textura del texto, el texto se representará automáticamente cuando cambie la propiedad

        15. Tamaño de textura del texto textura_tamaño, determinado por el tamaño de fuente y el texto

        16. tachado: agrega un tachado al texto

        17. strip: Ya sea para eliminar espacios y saltos de línea

        18. outline_color: el color del contorno del texto

        19. outline_width: el ancho del contorno alrededor del texto, en píxeles

        20. max_line: el número máximo de líneas a usar, el valor predeterminado es 0, lo que significa ilimitado

        21. acortar: si el contenido del texto debe acortarse tanto como sea posible, el valor predeterminado es Falso

        22. shorten_from: en qué lado acortar el texto, el valor predeterminado es el centro, los parámetros opcionales son: izquierda, derecha y centro

        23. is_shortend: si renderizar de forma abreviada

        24. line_height: la altura de línea del texto, el valor predeterminado es 1.0

4. Código completo

        Tenga en cuenta que lo he escrito en detalle para todos, si tiene alguna pregunta, puede dejar un mensaje en cualquier momento para hacer preguntas o chatear conmigo en privado.

        codigo py:

from random import randint, uniform  # 导入randint和uniform函数用于生成随机数
from kivy.app import App  # 导入App类,用于创建应用
from kivy.clock import Clock  # 导入Clock类,用于调度函数的定时器
from kivy.core.audio import SoundLoader
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty  # 导入各种属性类,用于定义属性
from kivy.uix.widget import Widget  # 导入Widget类,用于创建控件
from kivy.vector import Vector  # 导入Vector类,用于处理向量运算
from kivy.core.window import Window

class PongPaddle(Widget):
    score = NumericProperty(0) # 分数属性,用于记录得分

    def bounce_ball(self, ball):
        if self.collide_widget(ball): # 如果球与挡板相撞
            ball.speed_x *= -1.1 # 改变球的水平速度,反弹出去


class PongBall(Widget):
    speed_x = NumericProperty(0)  # 球的水平速度属性
    speed_y = NumericProperty(0)  # 球的垂直速度属性
    speed = ReferenceListProperty(speed_x, speed_y)  # 球的速度向量属性
    r =  NumericProperty(0)   #球的大小属性
    max_speed = 5  # 球的最大速度

    def move(self):
        self.pos = Vector(*self.speed) + self.pos  # 根据速度更新球的位置

    def randomize(self):
        # 随机化速度
        vel_x = uniform(-5, 5)  # 在[-5, 10]范围内生成一个随机数作为水平速度
        vel_y = uniform(-5, 5)  # 垂直速度
        self.speed = Vector(vel_x, vel_y).normalize() * self.max_speed  # 设置球的速度向量,并将其归一化后乘以最大速度


    def daxiao(self):
        # 随机化大小
        r = uniform(20, 80)
        self.size = r , r # 在[20, 80]范围内生成一个随机数作为球的大小
        print(self.size)


class PongGame(Widget):
    ball = ObjectProperty(None)  # 球的实例对象属性
    player1 = ObjectProperty(None)  # 玩家1挡板的实例对象属性
    player2 = ObjectProperty(None)  # 玩家2挡板的实例对象属性
    music = None


    def serve_ball(self):
        self.ball.center = self.center  # 将球的中心位置设置为窗口的中心位置
        self.ball.randomize()  # 随机化球的速度
        self.ball.daxiao()     # 随机化球的大小
        self.timer = 0  # 计时器初始化为0

    def update(self, dt):
        self.ball.move()
        if self.timer >= 3:   # 如果计时器大于等于3秒
            self.ball.randomize()  # 随机化球的速度和大小
            self.ball.daxiao()
            self.timer = 0 # 重置计时器为0
        else:
            self.timer += dt  # 更新计时器的值,增加经过的时间
        # 球与上下边界的碰撞检测,如果球的底部超出窗口底部或者球的顶部超出窗口顶部
        if (self.ball.y < 0) or (self.ball.top > self.height):
            self.ball.speed_y *= -1   # 反转球的垂直速度,使其向相反的方向运动
        # 球与左边界的碰撞检测,如果球的左边超出窗口左边界
        if self.ball.x < 0:
            self.ball.speed_x *= -1  # 反转球的水平速度,使其向相反的方向运动
            sound1 = SoundLoader.load('你好.mp3')
            if sound1:
                #sound1.loop = True
                sound1.play()
            self.player2.score += 1       # 2 + 1
        # 球与右边界的碰撞检测,如果球的右边超出窗口右边界
        if self.ball.right > self.width:
            self.ball.speed_x *= -1  # 反转球的水平速度,使其向相反的方向运动
            sound2 = SoundLoader.load('村民叫.mp3')
            if sound2:
                #sound2.loop = True  # 设置循环播放
                sound2.play()
            self.player1.score += 1      # 1 + 1
        self.player1.bounce_ball(self.ball)
        self.player2.bounce_ball(self.ball)
        self.move_player2()

    def move_player2(self):
        # 根据球的位置移动玩家2的挡板
        if self.ball.center_y < self.player2.center_y:
            self.player2.center_y -= 5  # 将玩家2的挡板向上移动5个单位
        elif self.ball.center_y > self.player2.center_y:
            self.player2.center_y += 5

    def on_touch_move(self, touch):
        if touch.x < self.width / 1 / 4:
            self.player1.center_y = touch.y   # 根据触摸点的y坐标移动玩家1的挡板的中心位置



class PongApp(App):
    def build(self):
        self.title = '一个弹球游戏嘿嘿嘿'
        game = PongGame()
        game.serve_ball()  # 开始游戏,将球放在中心位置并随机化速度和大小
        sound = SoundLoader.load('qsbl.mp3')
        if sound:
            sound.loop = True  # 设置循环播放
            sound.play()
        Clock.schedule_interval(game.update, 1.0 / 60.0)  # 使用Clock类的schedule_interval方法以1/60秒的间隔调用game.update函数

        return game

PongApp().run()  # 创建PongApp的实例对象并运行应用程序

        codigo kv:

<PongBall>:
    canvas:
        Color:
            rgba: .9,.9,.1 ,9
        Ellipse:
            pos: self.pos
            size: self.size
            source: "出生.jpg"

<PongPaddle>:
    size: 25, 150
    canvas:
        Color:
            rgba: 1, 1, 1, .9
        Rectangle:
            pos: self.pos
            size: self.size
            source: "无标题.png"

<PongGame>:
    ball: pong_ball
    player1: player_left
    player2: player_right
    canvas:
        Color:
            rgba:1, 1, 1, .9
        Rectangle:
            size:self.size
            source:"233.jpg"
        Color:
            rgba: .2, 1, 1, .9
        Rectangle:
            pos: self.center_x - 5, 0
            size: 10, self.height

    Label:
        color: .9,.6,.1 ,9
        font_size: 70
        center_x: root.width / 4
        top: root.top - 50
        text: str(root.player2.score)

    Label:
        color: .8,.1,.1 ,9
        font_size: 70
        center_x: root.width * 3/4
        top: root.top - 50
        text: str(root.player1.score)

    PongBall:
        id: pong_ball
        center: self.parent.center

    PongPaddle:
        id: player_left
        x: root.x
        center_y: root.center_y

    PongPaddle:
        id: player_right
        x: root.width - self.width
        center_y: root.center_y

5. Resumen de deficiencias

        Todavía hay algunos errores, por ejemplo, si la velocidad es demasiado rápida, siempre se atascará en el borde. Para la configuración de dificultad, puede crear una interfaz de selección de dificultad, de modo que la velocidad se pueda ajustar de acuerdo con la dificultad.

        Espero que esto pueda ayudar a todos ~ Si crees que te ayuda, por favor déjame un me gusta ~

Supongo que te gusta

Origin blog.csdn.net/m0_51440939/article/details/130782670
Recomendado
Clasificación