【问题标题】:How to display game on the screen?如何在屏幕上显示游戏?
【发布时间】:2015-06-19 16:31:45
【问题描述】:

我正在尝试制作带有开始菜单的 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

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    好吧!你的程序有很多错误,我不得不做出很多改进。 (我理解为你是初学者)

    首先,请阅读完整的kivy language documentation,因为我可以清楚地看到您直接从编码开始而没有掌握基础知识。 你可能会做出一些不错的游戏,但从长远来看,你会面临这样的问题,如果没有明确的概念,这些问题就无法解决。 不幸的是,您将无法发现 kivy 的真正力量。 :)

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

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

    改进 1:

    如果您在 build() 上返回一个小部件,或者您设置 self.root,则可以构建应用程序。(但您不能再次创建应用程序) 就像你在这里所做的那样:

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

    改进 2:

    当你点击按钮 play ping pong 这是屏幕游戏。你的比赛从发球开始。

    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
    

    【讨论】:

    • 非常感谢!我想我不仅仅是初学者,你的建议很有帮助。现在一切正常,很容易理解为什么。再次非常感谢您! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多