在该程序中,您可以看到随着球反弹,人们可以从右上角打开设置页面。这样做会暂停球的运动并打开设置页面。
很抱歉,如果这是一个显而易见的问题,但是我再次被Kivy奇怪的内部运作所困扰,并且文档在这类问题上用处不大。
问题
球始终从中心位置开始。希望球在切换屏幕之前继续/从先前的位置继续吗?
重新创建问题的步骤
代码:
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy import Config
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition,\
SlideTransition
from kivy.uix.widget import Widget
from kivy.animation import Animation
from kivy.properties import NumericProperty, ReferenceListProperty,\
ObjectProperty
from kivy.clock import Clock
from kivy.vector import Vector
from random import randint
Builder.load_string('''
<Ball>:
size_hint: None, None
source: '58-Breakout-Tiles.png'
pos: self.pos
size: 15, 15
<SettingsScreen>:
close: close
AnchorLayout:
anchor_x: 'left'
anchor_y: 'top'
Image:
id: close
size_hint: .03, .03
source: 'grey_crossGrey.png'
GridLayout:
cols: 2
Label:
font_name: 'vgafix.fon'
text: 'Music: '
Switch:
active: True
Label:
font_name: 'vgafix.fon'
text: 'Sounds: '
Switch:
active: True
<MenuScreen>:
cog: cog
AnchorLayout:
anchor_x: 'right'
anchor_y: 'top'
Image:
id: cog
size_hint: .03, .03
source: 'settings-cog.png'
BoxLayout:
orientation: 'vertical'
Image:
source: 'brickbreaker log.png'
Label:
font_name: 'vgafix.fon'
text: 'Tap to start'
<GameScreen>:
ball: ball
cog: cog
AnchorLayout:
anchor_x: 'right'
anchor_y: 'top'
Image:
id: cog
size_hint: .03, .03
source: 'settings-cog.png'
Ball:
id: ball
size_hint: None, None
center: self.parent.center
''')
Config.set('graphics', 'multisamples', '0')
class Ball(Image):
velocityX, velocityY = NumericProperty(0), NumericProperty(0)
velocity = ReferenceListProperty(velocityX, velocityY)
def move(self):
self.pos = Vector(*self.velocity) + self.pos
class Player(Widget):
pass
class Brick(Widget):
pass
class SettingsScreen(Screen):
def __init__(self, **kwargs):
super(SettingsScreen, self).__init__(**kwargs)
self.previous = False
def on_touch_down(self, touch):
if self.close.collide_point(*touch.pos):
sm.transition = SlideTransition(direction = 'right')
if self.previous == 'game':
sm.get_screen('game').interval()
sm.current = self.previous
class MenuScreen(Screen):
def __init__(self, **kwargs):
super(MenuScreen, self).__init__(**kwargs)
def on_touch_down(self, touch):
if self.cog.collide_point(*touch.pos):
sm.transition = SlideTransition(direction = 'left')
sm.get_screen('settings').previous = 'menu'
sm.current = 'settings'
else:
sm.transition = FadeTransition()
sm.current = 'game'
class GameScreen(Screen):
def __init__(self, **kwargs):
super(GameScreen, self).__init__(**kwargs)
self.initBall()
self.interval = Clock.schedule_interval(self.update, 1.0/60.0)
def on_touch_down(self, touch):
if self.cog.collide_point(*touch.pos):
sm.transition = SlideTransition(direction = 'left')
sm.get_screen('settings').previous = 'game'
self.interval.cancel()
sm.current = 'settings'
def initBall(self):
self.ball.center = self.center
self.ball.velocity = Vector(0, 4).rotate(randint(0, 360))
def update(self, dt):
self.ball.move()
if (self.ball.y < 0) or (self.ball.y > self.height-15):
self.ball.velocityY *= -1
# bounce off left and right
if (self.ball.x < 0) or (self.ball.x > self.width-15):
self.ball.velocityX *= -1
sm = ScreenManager(transition = FadeTransition())
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(GameScreen(name='game'))
sm.add_widget(SettingsScreen(name='settings'))
class BrickBreakerInsanityApp(App):
def build(self):
return sm
if __name__ == '__main__':
BrickBreakerInsanityApp().run()
代码资产(必填):
https://drive.google.com/open?id=1GAnv5DfjNUuAXTybmsan90Dm0OuSVOfb
https://i.stack.imgur.com/rR799.png
https://i.stack.imgur.com/ngYvL.png
答案 0 :(得分:1)
SlideTransition
和direction
导致球从中心开始。
删除对SlideTransition
的所有引用。
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.image import Image
from kivy import Config
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition,
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty, StringProperty
from kivy.clock import Clock
from kivy.vector import Vector
from random import randint
Builder.load_string('''
<Ball>:
size_hint: None, None
source: './assets/icons/58-Breakout-Tiles.png'
pos: self.pos
size: 15, 15
<SettingsScreen>:
close: close
AnchorLayout:
anchor_x: 'left'
anchor_y: 'top'
Image:
id: close
size_hint: .03, .03
source: './assets/icons/grey_crossGrey.png'
GridLayout:
cols: 2
Label:
font_name: "./assets/fonts/vgafix.fon"
text: 'Music: '
Switch:
active: True
Label:
font_name: "./assets/fonts/vgafix.fon"
text: 'Sounds: '
Switch:
active: True
<MenuScreen>:
cog: cog
AnchorLayout:
anchor_x: 'right'
anchor_y: 'top'
Image:
id: cog
size_hint: .03, .03
source: './assets/icons/settings-cog.png'
BoxLayout:
orientation: 'vertical'
Image:
source: "./assets/icons/brickbreaker log.png"
Label:
font_name: "./assets/fonts/vgafix.fon"
text: 'Tap to start'
<GameScreen>:
ball: ball
cog: cog
AnchorLayout:
anchor_x: 'right'
anchor_y: 'top'
Image:
id: cog
size_hint: .03, .03
source: './assets/icons/settings-cog.png'
Ball:
id: ball
size_hint: None, None
center: self.parent.center
''')
Config.set('graphics', 'multisamples', '0')
class Ball(Image):
velocityX, velocityY = NumericProperty(0), NumericProperty(0)
velocity = ReferenceListProperty(velocityX, velocityY)
def move(self):
self.pos = Vector(*self.velocity) + self.pos
class Player(Widget):
pass
class Brick(Widget):
pass
class SettingsScreen(Screen):
def __init__(self, **kwargs):
super(SettingsScreen, self).__init__(**kwargs)
self.previous = StringProperty('')
def on_touch_down(self, touch):
if self.close.collide_point(*touch.pos):
self.manager.current = self.previous
class MenuScreen(Screen):
def on_touch_down(self, touch):
if self.cog.collide_point(*touch.pos):
self.manager.get_screen('settings').previous = self.manager.current
self.manager.current = 'settings'
else:
self.manager.transition = FadeTransition()
self.manager.current = 'game'
class GameScreen(Screen):
def __init__(self, **kwargs):
super(GameScreen, self).__init__(**kwargs)
self.initBall()
def on_pre_enter(self, *args):
self.interval = Clock.schedule_interval(self.update, 1.0 / 60.0)
def on_touch_down(self, touch):
if self.cog.collide_point(*touch.pos):
self.manager.get_screen('settings').previous = self.manager.current
self.manager.current = 'settings'
def initBall(self):
self.ball.center = self.center
self.ball.velocity = Vector(0, 4).rotate(randint(0, 360))
def update(self, dt):
self.ball.move()
if (self.ball.y < 0) or (self.ball.y > self.height - 15):
self.ball.velocityY *= -1
# bounce off left and right
if (self.ball.x < 0) or (self.ball.x > self.width - 15):
self.ball.velocityX *= -1
def on_pre_leave(self, *args):
self.interval.cancel()
sm = ScreenManager(transition=FadeTransition())
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(GameScreen(name='game'))
sm.add_widget(SettingsScreen(name='settings'))
class BrickBreakerInsanityApp(App):
def build(self):
return sm
if __name__ == '__main__':
BrickBreakerInsanityApp().run()