Reputation: 687
I am making an arkanoid game and having a problem: after collision I am using remove_widget
method to remove a widget from layout. So it disappears from the screen but it is still in there, it is available by ids
and if the ball enters that point again it still collides with a widget.
Here is some code:
gemsgrid.kv
<Brick@Widget>:
canvas:
Rectangle:
size: self.size
pos: self.pos
<GemsGrid@FloatLayout>:
size_hint: None, None
Brick:
pos: 300, 100
id: 1
Brick:
pos: 300,200
id: 2
main.py
from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.relativelayout import RelativeLayout
from kivy.properties import NumericProperty
Builder.load_file('paddle.kv')
Builder.load_file('ball.kv')
Builder.load_file('gemsgrid.kv')
class Game(RelativeLayout):
lives = NumericProperty(5)
def __init__(self, **kwargs):
super(Game, self).__init__(**kwargs)
self.game_started = False
def on_touch_move(self, touch):
if touch.y < self.height / 3:
self.ids.paddle_widget.center_x = touch.x
if not self.game_started:
self.ids.ball_widget.serve_ball()
self.game_started = True
def update(self, dt):
if self.game_started:
self.ids.ball_widget.move()
self.ids.paddle_widget.bounce_ball(self.ids.ball_widget)
for id, gem in self.gemsgrid.ids.iteritems():
if self.ids.ball_widget.collide_widget(gem):
self.gemsgrid.remove_widget(gem)
self.right_left_collissioned(self.ids.ball_widget, gem)
self.top_bottom_collissioned(self.ids.ball_widget, gem)
# bounce off top and bottom
if (self.ids.ball_widget.top > self.height):
self.ids.ball_widget.velocity_y *= -1
# bounce off left and right
if (self.ids.ball_widget.x < 0) or (self.ids.ball_widget.right > self.width):
self.ids.ball_widget.velocity_x *= -1
# subtract one life if hit the bottom but not the paddle
if (self.ids.ball_widget.y < self.y):
self.lives -= 1
self.ids.ball_widget.reset()
self.game_started = False
def right_left_collissioned(self, ball, gem):
if ball.y > gem.y and ball.y < (gem.y + gem.height):
ball.velocity_x *= -1
def top_bottom_collissioned(self, ball, gem):
if ball.x > gem.x and ball.x < gem.x + gem.width:
ball.velocity_y *= -1
class MainApp(App):
def on_pause(self):
return True
def build(self):
game = Game()
Clock.schedule_interval(game.update, 1/60)
return game
if __name__ == '__main__':
MainApp().run()
What am I missing?
Upvotes: 0
Views: 264
Reputation: 3769
The ids
is generated when the .kv
has been parsed.
So it will stay that way.
Use self.children
instead to check if it is still there.
Upvotes: 1
Reputation: 29458
The ids dict is static and is not intended to update like this (although I don't see why it couldn't be changed if people really want the feature). It sounds like it just isn't a good fit for your problem, I would manage the object references manually.
Upvotes: 1