Как вызвать функцию из класса из другого класса в игре с мячом kivy Pong

Я практикую Kivy с кодом PongGame, приведенным в руководстве. Я хочу знать, как вызвать функцию serve_ball2() в классе PongGame из вновь созданного класса PongSample. В приведенном ниже коде я создал класс PongSample для подачи второго мяча после столкновения первого мяча с ракеткой.

Обновление: я могу вызвать serve_ball2() из PongSample, но serve_ball2() не работает должным образом, т. е. не подает мяч.

Я поделился полным кодом ниже. заранее спасибо

Pong.py:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty,\
    ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock, time
from threading import Thread

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
            PongSample().call_game()

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 PongSample(Widget):
    def call_game(self):
        print 'PongSample'
        ponggame=PongGame()
        ponggame.serve_ball2()

class PongGame(Widget):
    ball = ObjectProperty(None)
    ball2 = 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 serve_ball2(self, vel=(3, 0)):  
        print 'Serve_ball2'
        self.ball2.center = self.center
        self.ball2.velocity = vel

    def serve_down(self):
        print 'Inside Serve Down'
        self.ball.center = self.center
        self.ball.velocity = Vector(4,0).rotate(-90)

    def update(self, dt):
        self.ball.move()
        self.ball2.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
        if (self.ball2.y < self.y) or (self.ball2.top > self.top):
            self.ball2.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.ball2.x < self.x:
            self.player2.score += 1
            self.serve_ball2(vel=(3, 0))
        if self.ball2.x > self.width:
            self.player1.score += 1
            self.serve_ball2(vel=(-3, 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 PongApp(App):
    def build(self):
        game = PongGame()
        game.serve_ball()
        Clock.schedule_interval(game.update, 1.0 / 60.0)
        return game

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

понг.кв:

    #:kivy 1.8.0

<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
    ball2: pong_ball2
    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

    PongBall:
        id: pong_ball2
        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

person Newbie7988    schedule 26.06.2014    source источник
comment
В чем именно проблема с тем, что у вас есть до сих пор?   -  person jonrsharpe    schedule 26.06.2014
comment
@jonrsharpe Я могу вызвать serve_ball2() из PongSample, но serve_ball2() не работает должным образом, то есть не подает мяч. P.S. обновил вопрос.   -  person Newbie7988    schedule 26.06.2014
comment
...так что он делает вместо этого?!   -  person jonrsharpe    schedule 26.06.2014
comment
@jonrsharpe мяч должен двигаться как в serve_ball() , но здесь ничего не происходит. Однако функция get вызывается.   -  person Newbie7988    schedule 26.06.2014


Ответы (2)


Чтобы использовать свой класс, добавьте game.serve_ball2() to PongApp

class PongApp(App):
    def build(self):
        game = PongGame()
        game.serve_ball()
        game.serve_ball2()
        Clock.schedule_interval(game.update, 1.0 / 60.0)
        return game

И добавьте self.ball2, чтобы отскочить от весла:

#bounce of paddles
self.player1.bounce_ball(self.ball)
self.player2.bounce_ball(self.ball)
self.player1.bounce_ball(self.ball2)
self.player2.bounce_ball(self.ball2)
person Padraic Cunningham    schedule 26.06.2014
comment
Но я хочу вызвать этот serve_ball из другого класса, это моя проблема. Дайте мне знать, как я могу вызвать serve_ball из другого класса. Вызов с использованием объекта PongGame не работал, как показано в коде выше. - person Newbie7988; 26.06.2014
comment
почему вы хотите добавить еще один класс, вы можете добавить второй мяч в понгейм с другой скоростью с парой простых изменений - person Padraic Cunningham; 26.06.2014
comment
Я хочу добавить еще один класс, чтобы установить таймер через поток для вызова подачи мяча (для моего понимания). Дайте мне знать, если вы можете сказать мне, как добиться этого из другого класса. - person Newbie7988; 26.06.2014
comment
Как вы ожидаете, что что-то произойдет, если у вас нет ничего, что связано с ball2 в PongApp? - person Padraic Cunningham; 26.06.2014

Я подчеркиваю, что это кажется ненужным, и что PongSample кажется, что оно вообще не должно существовать. Однако, чтобы сделать то, что вы просили, я считаю, что должно работать следующее. Однако одна вещь, которая мне действительно не нравится в этом, заключается в том, что экземпляр PongSample создается в файле kv без какой-либо другой цели, кроме как для обслуживания ball2. Однако...

Почему бы вместо этого не определить функцию serve_ball2 в классе PongSample и передать ей ball2?

Пример:

class PongSample(Widget):

    def serve_ball2(self, ball2, vel=(3,0)):
        print 'Serve ball 2'
        ball2.center = self.center
        ball2.velocity = vel

И в классе PongGame:

class PongGame(Widget):
    ball = ObjectProperty(None)
    ball2 = ObjectProperty(None)
    player1 = ObjectProperty(None)
    player2 = ObjectProperty(None)
    # add this
    sample = ObjectProperty(None)

Затем в файле kv:

# add at the top

<PongSample>:
    size: self.size
    pos: self.pos

# add the below in appropriate places within the PongGame definition

PongGame:
    sample: pong_sample

    PongSample:
        id: pong_sample # now it's linked to 'sample' in PongGame

Итак, теперь в PongGame вы можете вызывать self.sample.serve_ball2(ball2) из любого метода.

person Totem    schedule 26.06.2014