I am attempting to use Kivy to modify the example Pong game to have a main menu. It took me ages, but I finally got the menu system to work and start the game object itself in a new screen. However, this has broken the graphics, and I cannot for the life of me figure out how to restore them. The collision between the ball and paddles still works, but it is badly offset. I understand that this has something to do with the fact that the ScreenManager uses a relative layout, where the default widget I was using before introducing screens was absolute. However, this page describes the exact problem I'm having, where the paddles and ball are offset from their intended center, but the proposed solution of setting pos: 0,0 or just removing pos altogether doesn't help, it just puts everything in the bottom left corner of the screen, and now nothing moves. I've tried many solutions involving size and position hinting, but in the end, they all break my game completely. The code provided below is my initial starting code, which is still the most functional of everything I've tried. Please keep in mind that I'm relatively new to Python and still experimenting with Kivy. Edit: I nearly forgot to include a gif of the offset collision. GIF to incorrect play main.py from kivy.app import App from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty from kivy.uix.screenmanager import Screen, ScreenManager, NoTransition from kivy.uix.widget import Widget from kivy.vector import Vector from kivy.clock import Clock 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() self.player1.bounce_ball(self.ball) self.player2.bounce_ball(self.ball) if (self.ball.y < 0) or (self.ball.top > self.height): self.ball.velocity_y *= -1 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 PongScreen(Screen): def on_enter(self, *args): game = PongGame() self.add_widget(game) game.serve_ball() Clock.schedule_interval(game.update, 1 / 60) return game class PongMenu(Screen): pass class PongApp(App): def build(self): sm = ScreenManager(transition=NoTransition()) sm.add_widget(PongMenu(name="menu")) sm.add_widget(PongScreen(name="game")) return sm if __name__ == "__main__": PongApp().run() pong.kv #:kivy 2.3.1 <PongBall>: canvas: Ellipse: pos: self.pos size: 50, 50 <PongPaddle>: canvas: Rectangle: pos: self.pos size: 25, 200 <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: self.parent.x center_y: self.parent.center_y PongPaddle: id: player_right x: self.parent.width - self.width center_y: self.parent.center_y <PongMenu>: start_btn: button_start BoxLayout: orientation: 'vertical' Button: id: button_start text: "Start Game" markup: True width: 200 height: 200 on_press: root.manager.current = "game" Continue reading...