如何在屏幕上显示游戏?

时间:2015-06-19 16:31:46

标签: python kivy

我正在尝试使用启动菜单创建一个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

1 个答案:

答案 0 :(得分:0)

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

首先,请阅读完整的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:

当您点击屏幕游戏的播放乒乓按钮时。你的比赛从球的发球开始。

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