Turtleproblem amateur

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
123gro
User
Beiträge: 23
Registriert: Donnerstag 23. Januar 2014, 18:50

Hallo ich hab ein problem:
ich krieg es nicht nicht hin , dass zwei Turtles unabhängig voneinander per tastendruck
gesteuert werden können!
(ich bin dabei ein kleines spiel zu programmieren, wo man zu
zweit auf einer tastatur mit rittern kämpfen kann) aber wenn ich die taste drücke
die die eine turtle nach links "fahren" lässt, und dann die andere turtle auch bewege hört die erste auf:
also kann man die turtles nur mit ganz vielen tastendrücken nacheineander in kurzem abstand unabhängig voneinander bewegen

Meine Frage ist: kann man zwei Turtles unabhängig voneinander per tastendruck steuern also geht das mit python überhaupt
und wenn ja, wie :?: :?:
Mein Programmcode ist im Moment so:

Code: Alles auswählen

from turtle import*
import sys
sys.setrecursionlimit(20000)

setup(width=0.45, height=0.3)


tracer=False

bgpic("hintergrund.gif")
hideturtle()
pu();fd(500)
screen=Screen()
ritter1=Turtle(visible=False)
ritter2=Turtle(visible=False)
leben1=3
leben2=3 
ritter1.pu()
ritter2.pu()
ritter2.fd(200)
ritter2.lt(90)
ritter2.fd(5)
ritter2.lt(90)
ritter1.bk(200)
ritter1.lt(90)
ritter1.fd(5)
ritter1.rt(90)
ritter1.showturtle()
ritter2.showturtle()
tracer=True
ritter1.speed(1)
def v():
    ritter1.fd(1)
    
def r():
    ritter1.bk(1)
    
def vor():
    ritter2.fd(1)
    
def rück():

    ritter2.bk(1)
     



def schlag1():
    global leben2
    leben2=leben2-1

def schlag2():
    global leben1
    leben1=leben1-1
    
onkeypress(schlag1,"space")
onkeypress(v,"d")
onkeypress(r,"a")
onkeypress(vor,"Left")
onkeypress(rück,"Right")


    
    

screen.listen()
Eine Antwort wäre sehr nett :)
Zuletzt geändert von Anonymous am Donnerstag 23. Januar 2014, 19:41, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Georg :)
BlackJack

@123gro: In Python geht das. Nur mit dem `turtle`-Modul geht das vielleicht. Aber wahrscheinlich nur auf eine Art bei der Programmierer Weinkrämpfe bekommen. :-) Also zum Beispiel wird man wohl nicht ohne ``global`` auskommen, beziehungsweise wenn man gut genug Programmieren kann ohne ``global`` verwenden zu müssen, dann braucht man `turtle` nicht mehr.

Was Du aber auf jeden Fall ganz schnell vergessen solltest ist `sys.setrecursionlimit()`. Das ist gefährlich und total unnötig.
123gro
User
Beiträge: 23
Registriert: Donnerstag 23. Januar 2014, 18:50

ist global ein modul?
Zuletzt geändert von 123gro am Freitag 24. Januar 2014, 14:51, insgesamt 1-mal geändert.
Georg :)
BlackJack

@123gro: Nein das ist ein Schlüsselwort — welches Du zweimal in Deinem Quelltext verwendest. Schlüsselworte der Sprache kann man in Python nicht als Namen verwenden, also auch nicht um ein Modul zu benennen.
123gro
User
Beiträge: 23
Registriert: Donnerstag 23. Januar 2014, 18:50

ah ich hab grad gemerkt das du das global meinst was ich kenne
aber trotzdem... ich hab doch schon global verwendet und außerdem
verstehe ich nicht wo ich global einsetzen soll um zu erzielen das die Turtles
normal gesteuert werden können :(
Georg :)
BlackJack

@123gro: So konkret war das nicht gemeint, sondern eher allegemein das man ohne Klassen so etwas sehr wahrscheinlich nicht ohne den Einsatz von ``global`` hinbekommt. Wenn man aber Objektorientierung lernt, ist man weit über das `turtle`-Modul hinaus.

Letztendlich wird man das mit dem `turtle`-Modul wohl nicht hinbekommen weil die API so wie ich das sehe das *loslassen* von Tasten nicht als Ereignis anbietet auf das man reagieren könnte.
123gro
User
Beiträge: 23
Registriert: Donnerstag 23. Januar 2014, 18:50

Also ich habe jetzt eine Klasse Ritter definiert.
Aber was für ein Zeichenmodul außer turtle soll ich jetzt nehmen?
Georg :)
BlackJack

@123gro: `turtle` verwendet `Tkinter` (oder `tkinter`, je nach Python-Version).
123gro
User
Beiträge: 23
Registriert: Donnerstag 23. Januar 2014, 18:50

aber wie benutze ich tkinker
Georg :)
BlackJack

@123gro: Was erwartest Du denn jetzt auf diese Frage für eine Antwort? Programmieren lernen und dann die Dokumentation zu den verwendeten Modulen lesen. In der Dokumentation zur Tk-Anbindung gibt es auch Links zu weiterer Dokumentation im Netz.
123gro
User
Beiträge: 23
Registriert: Donnerstag 23. Januar 2014, 18:50

BlackJack hat geschrieben:@123gro: So konkret war das nicht gemeint, sondern eher allegemein das man ohne Klassen so etwas sehr wahrscheinlich nicht ohne den Einsatz von ``global`` hinbekommt. Wenn man aber Objektorientierung lernt, ist man weit über das `turtle`-Modul hinaus.

Letztendlich wird man das mit dem `turtle`-Modul wohl nicht hinbekommen weil die API so wie ich das sehe das *loslassen* von Tasten nicht als Ereignis anbietet auf das man reagieren könnte.
Ich glaube onkeyrelease bemerkt das *loslassen* von Tasten oder? :o
wenn ja , wie muss ich es dann einbauen :?:
Georg :)
BlackJack

@123gro: Ah, die Funktion gibt es in Python 2.7 noch nicht. Die benutzt man genau wie die `onkey()`-Funktion, man kann damit ein Ereignis mit einer Funktion oder Methode verknüpfen. Du musst halt „Buch führen” welche Tasten der Benutzer gedrückt aber noch nicht losgelassen hat und regelmässig auf den aktuellen Zustand reagieren. Dafür kann man eine Funktion oder Methode mit der `ontimer()`-Funktion zeitverzögert ausführen lassen und das halt immer wieder tun, also am Ende der Funktion beispielsweise die Funktion selbst wieder zum Aufrufen nach einer gewissen Zeit. Der Docstring von `ontimer()` hat ein einfaches Beispiel dafür.
123gro
User
Beiträge: 23
Registriert: Donnerstag 23. Januar 2014, 18:50

Also ganz viele if-Anweisungen...
Aber wieso soll man ein Ereignis einprogrammieren, dass erst eintritt wenn eine Taste
losgelassen wird, wenn es auch mit onkeypress geht? Soll ich eigentlich dann vor und nach jedem 'ritter1.bk(1)'-[Code Z.36]
einen 'ontimer(irgendwas)'-Aufruf machen?
Georg :)
BlackJack

@123gro: So wirklich viele ``if``-Anweisungen sollten das nicht werden müssen. Wenn die sich nur vor und zurück bewegen können, dann sehe ich da jetzt erst einmal gar keine ``if``-Anweisung, es sei denn man möchte eine der beiden Tasten dafür priorisieren, was wohl Sinn machen würde.

Es geht ja nicht nur mit `onkeypress()` beziehungsweise nur wenn der Ritter nicht in ständiger Bewegung sein soll und es keinen anderen Tastendruck gibt, der den Ritter anhält.

Dein Ritter hört auch nicht auf sich zu bewegen weil Du eine Taste für den anderen Ritter betätigst, sondern weil ein Tastendruck halt immer nur eine Einheit weit läuft und man dann einen erneuten Tastendruck braucht um wieder eine Einheit zu laufen. So hast Du das programmiert.

Den `ontimer()`-Aufruf würde ich in *eine* Funktion stecken die regelmässig alles nötige Aufruft um einen „Spielschritt” zu machen.
123gro
User
Beiträge: 23
Registriert: Donnerstag 23. Januar 2014, 18:50

Code: Alles auswählen

from turtle import*

title("knightfight")
class Ritter(Turtle):

    def jump(t,distanz,winkel=None):
        t.lt(winkel)
        t.pu()
        t.fd(distanz)
        t.lt(winkel)
    
def tot1():
    onkeypress(None,"w")
    onkeypress(None,"a")
    onkeypress(None,"d")
    screen.listen()
def tot2():
    onkeypress(None,"Up")
    onkeypress(None,"Left")
    onkeypress(None,"Right")
    screen.listen()    
def jump(t,distanz,winkel=None):
        t.lt(winkel)
        t.pu()
        t.fd(distanz)
        t.lt(winkel)    

    


tracer=False
screen=Screen()
setup(width=0.45, height=0.3)
bgpic("hintergrund.gif")
ritter1=Ritter()
ritter2=Ritter()
l1=Turtle()
l2=Turtle()
leb1=3
leb2=3

for bn in("r1s0.gif","r1s1.gif","r1s2.gif","r1s3.gif",
          "r2s0.gif","r2s1.gif","r2s2.gif","r2s3.gif","herz3.gif",
          "herz2.gif","herz1.gif"):
    screen.register_shape(bn)

ritter1.pu()
ritter2.pu()
ritter1.hideturtle()
ritter2.fd(200)
ritter2.lt(90)
ritter2.fd(18)
ritter2.lt(90)
ritter1.bk(200)
ritter1.lt(90)
ritter1.fd(18)
ritter1.rt(90)
l1.speed(0)
l2.speed(0)
jump(l1,200,135)
jump(l2,200,45)
ritter1.showturtle()
for i in((ritter1,"r1s0.gif"),(ritter2,"r2s0.gif"),
         (l1,"herz3.gif"),(l2,"herz3.gif")):
    objekt,bild=i
    objekt.shape(bild)
tracer=True

def schlag1():
    global leb2
    leb2=leb2-1

    if leb2==3:
        l2.shape("herz3.gif")
    if leb2==2:
        l2.shape("herz2.gif")
    if leb2==1:
        l2.shape("herz1.gif")
    if leb2==0:
        l2.hideturtle()
        tot2()
def schlag2():
    global leb1
    leb1=leb1-1

    if leb1==3:
        l1.shape("herz3.gif")
    if leb1==2:
        l1.shape("herz2.gif")
    if leb1==1:
        l1.shape("herz1.gif")
    if leb1==0:
        l1.hideturtle()
        tot1()
ritter1.speed(1)
ritter2.speed(0)
z=0
def v():
    for i in range(4):
        global z
        ritter1.fd(5)
        ontimer(None,200)
        if z<4:
            z=z+1
        if z>=4:
            z=0
        ritter1.shape("r1s{0}.gif".format(z))
        
def r():
    tracer=False
    ritter1.bk(3)
    
y=0
def vor():
    for i in range(4):
        global y
        
        ritter2.fd(5)
        ontimer(None,200)
        if z<4:
            y=y+1
        if y>=4:
            y=0
        ritter2.shape("r2s{0}.gif".format(y))
    
def rück():
    tracer=False
    ritter2.bk(3)
    tracer=True  

onkeypress(schlag1,"w")
onkeypress(v,"d")
onkeypress(r,"a")
onkeypress(vor,"Left")
onkeypress(rück,"Right")
onkeypress(schlag2,"Up")

screen.listen()
(r1s0 z.B. bedeutet ritter1_schritt0 usw.)
bei einem tastendruck läuft der ritter jetzt einen schritt)

So...das ist der Code den ich zum Teil ohne deine Tipps erweitert habe
aber wenn ich jetzt den einen Ritter bewege und kurz nach dem 1. Tastendruck den 2.Ritter bewege stoppt erst der ritter1 dann läuft ritter2 und dann beendet riiter1 seinen schritt

das heißt ja dann schon , dass Ritter1 von Ritter2 bei der Fortbewegung aufgehalten wird oder? :roll:
Zuletzt geändert von 123gro am Freitag 31. Januar 2014, 15:11, insgesamt 2-mal geändert.
Georg :)
123gro
User
Beiträge: 23
Registriert: Donnerstag 23. Januar 2014, 18:50

außerdem hab ich eine andere frage zu meinem ritterspiel :
wie kann man festellen wie weit zwei turtles (die ritter) voneinander entfernt sind?
Georg :)
123gro
User
Beiträge: 23
Registriert: Donnerstag 23. Januar 2014, 18:50

PS: kann man den abstand zwischen zwei turtles mit python feststellen?
Georg :)
Antworten