如何在屏幕上显示游戏?

How to display game on the screen?

我正在尝试制作一个带有开始菜单的 kivy 应用程序,但我无法在第二个屏幕上显示我的 Pong 游戏。我应该如何引用游戏以使其可见?我尝试并搜索但找不到任何东西。我 100% 确定 PongGame 可以正常工作,只是无法显示它。如果有人能告诉我如何正确地做到这一点,那就太好了。

Main.py:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, WipeTransition
from kivy.properties import ObjectProperty
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty,\
    ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock
from kivy.uix.popup import Popup
from kivy.uix.label import Label

class PongPaddle(Widget):
    score = NumericProperty(0)

    def bounce_ball(self, ball):
        if self.collide_widget(ball):
            vx, vy = ball.velocity
            offset = (ball.center_y - self.center_y) / (self.height / 2)
            bounced = Vector(-1 * vx, vy)
            vel = bounced * 1.1
            ball.velocity = vel.x, vel.y + offset


class PongBall(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    def move(self):
        self.pos = Vector(*self.velocity) + self.pos


class PongGame(Widget):
    ball = ObjectProperty(None)
    player1 = ObjectProperty(None)
    player2 = ObjectProperty(None)

    def serve_ball(self, vel=(4, 0)):
        self.ball.center = self.center
        self.ball.velocity = vel

    def update(self, dt):
        self.ball.move()

        #bounce of paddles
        self.player1.bounce_ball(self.ball)
        self.player2.bounce_ball(self.ball)

        #bounce ball off bottom or top
        if (self.ball.y < self.y) or (self.ball.top > self.top):
            self.ball.velocity_y *= -1

        #went of to a side to score point?
        if self.ball.x < self.x:
            self.player2.score += 1
            self.serve_ball(vel=(4, 0))

        if self.ball.x > self.width:
            self.player1.score += 1
            self.serve_ball(vel=(-4, 0))
            if self.player1.score == 10:
                popup = Popup(title='Test popup', content=Label(text='Hello world'), auto_dismiss=False)
                return popup
    def on_touch_move(self, touch):
        if touch.x < self.width / 3:
            self.player1.center_y = touch.y
        if touch.x > self.width - self.width / 3:
            self.player2.center_y = touch.y


class ScreenThree(Screen):
    pass

class ScreenTwo(Screen):
    pass

class ScreenOne(Screen):
    pass

class Manager(ScreenManager):

    screen_one = ObjectProperty(None)
    screen_two = ObjectProperty(None)
    screen_three = ObjectProperty(None)

class ScreensApp(App):

    def build(self):
        m = Manager(transition=WipeTransition())
        return m

if __name__ == '__main__':
    ScreensApp().run()

screen.kv:

<PongBall>:
    size: 50, 50
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size

<PongPaddle>:
    size: 25, 200
    canvas:
        Rectangle:
            pos:self.pos
            size:self.size

<PongGame>:
    ball: pong_ball
    player1: player_left
    player2: player_right

    canvas:
        Rectangle:
            pos: self.center_x-5, 0
            size: 10, self.height

    Label:
        font_size: 70
        center_x: root.width / 4
        top: root.top - 50
        text: str(root.player1.score)

    Label:
        font_size: 70
        center_x: root.width * 3 / 4
        top: root.top - 50
        text: str(root.player2.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

<ScreenOne>:
    Button:
        text: "Screen 1 >> Screen 2"
        on_press: root.manager.current = 'screen2'
<ScreenTwo>:
        def build(self):
            game = PongGame()
            game.serve_ball()
            Clock.schedule_interval(game.update, 1.0 / 60.0)
            return game

<ScreenThree>:
    Button:
        text: "Screen 3 >> Screen 1"
        on_press: root.manager.current = 'screen1'


<Manager>:
    id: screen_manager

    screen_one: screen_one
    screen_two: screen_two
    screen_three: screen_three

    ScreenOne:
        id: screen_one
        name: 'screen1'
        manager: screen_manager

    ScreenTwo:
        id: screen_two
        name: 'screen2'
        manager: screen_manager

    ScreenThree:
        id: screen_three
        name: 'screen3'
        manager: screen_manager

嗯!您的程序中有很多错误,我不得不做出大量改进。 (因为你是初学者,我明白了)

首先,请阅读完整的kivy language documentation,我可以清楚地看到你没有掌握基础知识就直接开始编码。 您可能会制作几个好游戏,但在漫长的 运行 中,您将面临这样的问题,如果没有清晰的概念就无法解决这些问题。 不幸的是,您将无法发现 kivy 的真正力量。 :)

您可能还想修改您的 python 概念。

有些改进不值得一提但很重要,您在阅读代码时就会有所了解。

改进 1:

如果你return一个widget on build(),或者你设置self.root,一个应用程序可以被构建。(但是你不能再次创建应用程序) 正如您在此处所做的那样:

<ScreenTwo>:
    def build(self):
        game = PongGame()
        game.serve_ball()
        Clock.schedule_interval(game.update, 1.0 / 60.0)
        return game

改进2:

当你点击按钮时玩乒乓球这是一种屏幕游戏。你的比赛从发球开始。

on_release: root.current = 'game';game.serve_ball()

(求知)

如果您仍然黑屏,您可能需要检查 kivy 文件的名称,为此您可以查看 kivy 文档或 this link

 class PongPaddle(Widget):
    score = NumericProperty(0)

    def bounce_ball(self, ball):
        if self.collide_widget(ball):
            vx, vy = ball.velocity
            offset = (ball.center_y - self.center_y) / (self.height / 2)
            bounced = Vector(-1 * vx, vy)
            vel = bounced * 1.1
            ball.velocity = vel.x, vel.y + offset


class PongBall(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    def move(self):
        self.pos = Vector(*self.velocity) + self.pos


class PongGame(Widget):
    ball = ObjectProperty(None)
    player1 = ObjectProperty(None)
    player2 = ObjectProperty(None)

    def __init__(self, *args, **kwargs):
        super(PongGame, self).__init__(*args, **kwargs)
        Clock.schedule_interval(self.update, 1.0 / 60.0)

    def serve_ball(self, vel=(4, 0)):
        self.ball.center = self.center
        self.ball.velocity = vel

    def update(self, dt):
        self.ball.move()

        #bounce of paddles
        self.player1.bounce_ball(self.ball)
        self.player2.bounce_ball(self.ball)

    #bounce ball off bottom or top
        if (self.ball.y < self.y) or (self.ball.top > self.top):
        self.ball.velocity_y *= -1

    #went of to a side to score point?
        if self.ball.x < self.x:
            self.player2.score += 1
            self.serve_ball(vel=(4, 0))
        if self.ball.x > self.width:
            self.player1.score += 1
            self.serve_ball(vel=(-4, 0))

    def on_touch_move(self, touch):
        if touch.x < self.width / 3:
            self.player1.center_y = touch.y
        if touch.x > self.width - self.width / 3:
            self.player2.center_y = touch.y

class Manager(ScreenManager):
    pass

class ScreensApp(App):
    def build(self):
        self.load_kv('t6.kv')
        return Manager(transition=WipeTransition())

if __name__ == '__main__':
    ScreensApp().run()

这是kv文件。

<PongBall>:
    size: 50, 50
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size

<PongPaddle>:
    size: 25, 200
    canvas:
        Rectangle:
            pos:self.pos
            size:self.size

<PongGame>:
    ball: pong_ball
    player1: player_left
    player2: player_right

    canvas:
        Rectangle:
            pos: self.center_x-5, 0
            size: 10, self.height

    Label:
        font_size: 70
        center_x: root.width / 4
        top: root.top - 50
        text: str(root.player1.score)

    Label:
        font_size: 70
        center_x: root.width * 3 / 4
        top: root.top - 50
        text: str(root.player2.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

<Manager>:
    id: screen_manager


    Screen:
        name: 'home'
        Button:
            text: 'Play Ping Pong'
            halign: 'center'
            valign: 'middle'
            font_size: 100
            text_size: self.size
            on_release: root.current = 'game';game.serve_ball()

    Screen:
        name: 'game'
        PongGame:
            id: game