#python #python-3.x #kivy #kivy-language
#python #python-3.x #kivy #kivy-language
Вопрос:
Внутри программы можно видеть, что по мере того, как мяч отскакивает, у вас есть возможность открыть страницу настроек из верхнего правого угла. Это приостанавливает движение шара и открывает страницу настроек.
Извините, если это очевидный вопрос, но я снова озадачен странной внутренней работой Kivy, и документы не очень полезны для решения подобных проблем.
Проблема
Мяч всегда начинается с центральной позиции. Хотите, чтобы ball продолжил / возобновил работу с предыдущей позиции перед переключением экрана?
Шаги по воссозданию проблемы
- Нажмите на ярлык, «Нажмите, чтобы начать». Мяч начал отскакивать от центральной позиции
- Нажмите на изображение зубчатого колеса. Отображается экран настроек
- Нажмите «x», чтобы закрыть экран настроек. Мяч начал отскакивать от центральной позиции.
Код:
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
Комментарии:
1. Не уверен, какая именно последовательность вызывает это, но если вы удалите
center: self.parent.center
из своегоBall:
вkv
файле, это исправит это. Кстати, эта строка в любом случае не нужна, поскольку она выполняется вinitBall()
.
Ответ №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()