Kivy — удаление объектов при нажатии кнопки

#python #kivy

#python #kivy

Вопрос:

Я недавно начал играть с Kivy и хотел бы создать простую игру-стрелялку.

Это мой код:

 import kivy
kivy.require('1.9.0')

from kivy.config import Config
Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '600')

from kivy.app import App
from kivy.clock import Clock
from kivy.core.text import LabelBase
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Rectangle
from kivy.lang import Builder
from kivy.config import Config
import random, time

a = Builder.load_string('''
<BattleField>
    BoxLayout:
        orientation: 'vertical'

<Target>
    canvas:
        Rectangle:
            pos: self.pos
            size: self.size
            source: 'target.jpg'    

''')

class BattleField(Widget):

    #to destroy target
    def on_touch_down(self,touch):
        #if self.collide_point(*touch.pos):
        if self.collide_widget(self.target):
            self.remove_widget(self.target)

    def appear_target(self, *args):

        random_pos = tuple([random.randint(0, 600) for i in range(2)])
        self.target = Target()
        self.target.pos = (random_pos)
        self.add_widget(self.target)


class Target(Widget):

    pass

class ClockApp(App):

    def build(self):
        g = BattleField()
        Clock.schedule_interval(g.appear_target, 1)
        return g

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

Так что на данный момент он добавляет новую цель каждые 1 секунду. Однако здесь у меня есть несколько проблем:

  1. можно удалить только недавно добавленный виджет
  2. недавно добавленный виджет удаляется независимо от того, где я нажимаю.

Может ли кто-нибудь, пожалуйста, помочь мне исправить это? Спасибо!

Ответ №1:

Вот и все (никаких особых изменений в вашем исходном сообщении). Вам следует взглянуть на эту страницу официальной документации

 from kivy.config import Config
Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '600')
from kivy.app import App
from kivy.clock import Clock
from kivy.core.text import LabelBase
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Rectangle
from kivy.lang import Builder
from kivy.config import Config
import random, time

a = Builder.load_string('''
<BattleField>
    BoxLayout:
        orientation: 'vertical'

<Target>
    canvas:
        Rectangle:
            pos: self.pos
            size: self.size
            source: 'target.jpg'    

''')

class BattleField(Widget):

    def __init__(self, **kwargs):
        super(BattleField, self).__init__(**kwargs)
        Clock.schedule_interval(self.appear_target, 1)


    def appear_target(self, *args):
        random_pos = tuple([random.randint(0, 600) for i in range(2)])
        target = Target()
        target.pos = random_pos
        self.add_widget(target)


class Target(Widget):

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            self.parent.remove_widget(self)


class ClockApp(App):

    def build(self):
        return BattleField()

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

Комментарии:

1. Работает как шарм, спасибо! Я немного поиграл с кодом и обнаружил, что если не создавать инициализацию в BattleField, а вместо этого вставлять часы в приложение, как раньше, это тоже работает. Есть ли какая-то особая причина, по которой вы это сделали? Я обязательно прочитаю предоставленную вами ссылку. Еще раз спасибо!

Ответ №2:

Вы пробовали «self.parent.remove_widget (self.target)» вместо «self.remove_widget (self.target)»? Чтобы удалить виджет, ваш код должен действовать с более высокой точки в дереве виджетов (я бы хотел протестировать ваш, но у меня сейчас нет компьютера).

Комментарии:

1. Я попробовал это, но даже самый последний виджет после этого не удаляется. Я чувствую, что мне не хватает какой-то важной концепции здесь, чтобы удалить старые объекты,