Ich mache ein Spiel mit Kivy für Android, die den Spieler durch Berühren bestimmter Bereiche auf dem Bildschirm gesteuert hat. Ich erstelle unsichtbare Buttons (char_controls), die nach dem Antippen den Charakter bewegen. In dem Moment, in dem der Finger losgelassen wird, möchte ich, dass der Charakter aufhört.Clock.unschedule funktioniert nicht, wenn mit bind() in kivy referenziert
Ich habe eine Funktion an jede Schaltfläche gebunden, die Clock.schedule_interval auf eine move_up -Funktion in der Zeichenklasse aufruft (nur mit der Up-Taste im Moment arbeiten). Wenn die Taste losgelassen wird, ruft sie eine andere Funktion auf, die die ursprüngliche Funktion (mit Clock.unschedule) entplanen sollte. Es tut dies jedoch nicht und der Charakter bewegt sich weiter.
Verwende ich die bind() - Funktion von kivy, wenn ich sie verwende, um die on_press- und on_release-Verhalten der Schaltfläche an Funktionen zu binden, die in einer anderen Klasse definiert sind? Ich habe bemerkt, dass ich einen AttributeError bekomme: 'Button' -Objekt hat kein Attribut 'move_up', wenn ich self zur Referenz move_up verwende - ich muss stattdessen auf die move_up-Funktion als character.move_up verweisen, auch wenn ich sie in der Zeichenklasse referenziere . Wenn das Problem nicht mit der bind() - Funktion zu tun hat, wie kann ich das Programm die move_up-Funktion entplanen lassen?
Unten ist mein Code:
from kivy.uix.widget import Widget
from kivy.graphics import Canvas, Rectangle, Color
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.properties import *
from kivy.core.window import Window
from main import *
from render import Layer
class char_controls(FloatLayout):
'''controls where the character moves. There are 4 regions where the player can tap:
the top third to go up, the bottom third to go down, the center left to go left
and the center right to go right. They are buttons.'''
def __init__(self, **kwargs):
super(char_controls, self).__init__(**kwargs)
self.opacity = 0
self.size = (Window.width, Window.height)
anchor_bc = AnchorLayout(anchor_x = 'center', anchor_y = 'bottom')
down_btn = Button(text='', size_hint = (1, 0.3333))
down_btn.bind(on_press=character.move_down, on_release=character.stop)
down_btn.bind(on_press=Layer.move_down, on_release=Layer.stop)
anchor_bc.add_widget(down_btn)
self.add_widget(anchor_bc)
anchor_cl = AnchorLayout(anchor_x = 'left', anchor_y = 'center')
left_btn = Button(text='', size_hint = (0.5, 0.3333))
left_btn.bind(on_press=character.move_left, on_release=character.stop)
left_btn.bind(on_press=Layer.move_left, on_release=Layer.stop)
anchor_cl.add_widget(left_btn)
self.add_widget(anchor_cl)
anchor_cr = AnchorLayout(anchor_x = 'right', anchor_y = 'center')
right_btn = Button(text='', size_hint = (0.5, 0.3333))
right_btn.bind(on_press=character.move_right, on_release=character.stop)
right_btn.bind(on_press=Layer.move_right, on_release=Layer.stop)
anchor_cr.add_widget(right_btn)
self.add_widget(anchor_cr)
#button of interest
anchor_tc = AnchorLayout(anchor_x = 'center', anchor_y = 'top')
up_btn = Button(text='', size_hint = (1, 0.3333))
up_btn.bind(on_press=character.schedule_up, on_release=character.stop)
up_btn.bind(on_press=Layer.move_up, on_release=Layer.stop)
anchor_tc.add_widget(up_btn)
self.add_widget(anchor_tc)
class character(Widget):
'''The character class.'''
x_pos = 0
y_pos = 0
pos = (x_pos, y_pos)
def __init__(self, **kwargs):
super(character, self).__init__(**kwargs)
with self.canvas:
Color(1., 0, 0)
character.sprite = Rectangle(pos=self.pos, size=(32, 32))
#is there a cleaner way to call the movement functions than this? (Eg lambda)
def schedule_up(self):
Clock.schedule_interval(character.move_up, 1/30.)
def move_up(self):
character.y_pos += 1
character.pos = (character.x_pos, character.y_pos)
character.sprite.pos = character.pos
print('run')
def move_down(self):
print('down')
def move_right(self):
print('right')
def move_left(self):
print('left')
def stop(self):
Clock.unschedule(character.move_up) #this is not actually unscheduling the move_up function.
print('stop') #prints, so the function is working
Vielen Dank im Voraus!
Oh dear ... Ich habe einen Tippfehler in meinem Frage. In der Zeile clock.unschedule (character.move_up) habe ich versehentlich clock.unschedule (self.move_up) eingegeben, das wäre natürlich ein entscheidender Fehler im Programm. Die Frage, die ich stelle, ist also, warum die Uhr die Funktion nicht einplant, selbst wenn sie als character.move_up referenziert wird? Ich habe auch keinen Zugriff auf sich selbst aus irgendeinem seltsamen Grund ... – Bam8000
@ Bam8000 nichts wirklich geändert, Sie immer noch verschiedene Funktionen, sehen Sie das Beispiel wieder, ich habe es bearbeitet ^^ – KeyWeeUsr
Danke für das Aufzeigen des Problems! Ich sehe das Problem jetzt. Aber warum sind sie nicht die gleiche Funktion? Ich verweise sie auf die gleiche Weise. Sollte ich einen anderen Ansatz verfolgen? – Bam8000