Funktion wird nicht aufgerufen

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
Smiley1000
User
Beiträge: 1
Registriert: Mittwoch 25. Januar 2017, 20:29

Code: Alles auswählen

from tkinter import *
lives_player_1 = 3
lives_player_2 = 3
death = 1
HEIGHT = 500
WIDTH = 800
window = Tk()
window.title('Deathly Spikes')
c = Canvas(window, width=WIDTH, height = HEIGHT, bg ='green')
c.pack()
mensch_id2 = c.create_oval(0, 0, 30, 30, fill='yellow')
mensch_id = c.create_oval(5, 20, 25, 25, fill='red')
mensch_id3 = c.create_oval(20, 10, 30, 15, fill='green')
mensch_id4 = c.create_oval(0, 10, 10, 15, fill='green')
mensch_id6 = c.create_oval(0, 0, 30, 30, fill='yellow')
mensch_id5 = c.create_oval(5, 20, 25, 25, fill='red')
mensch_id7 = c.create_oval(20, 10, 30, 15, fill='blue')
mensch_id8 = c.create_oval(0, 10, 10, 15, fill='blue')
MENSCH_R = 20
MID_X = WIDTH / 2
MID_Y = HEIGHT / 2
c.move(mensch_id, MID_X + 25, MID_Y)
c.move(mensch_id2, MID_X + 25, MID_Y)
c.move(mensch_id3, MID_X + 25, MID_Y)
c.move(mensch_id4, MID_X + 25, MID_Y)
c.move(mensch_id5, MID_X - 25, MID_Y)
c.move(mensch_id6, MID_X - 25, MID_Y)
c.move(mensch_id7, MID_X - 25, MID_Y)
c.move(mensch_id8, MID_X - 25, MID_Y)
MENSCH_GESCHW = 10
def menschen_beweg(event):
    if event.keysym == 'Up':
        c.move(mensch_id, 0, -MENSCH_GESCHW)
        c.move(mensch_id2, 0, -MENSCH_GESCHW)
        c.move(mensch_id3, 0, -MENSCH_GESCHW)
        c.move(mensch_id4, 0, -MENSCH_GESCHW)
    elif event.keysym == 'Down':
        c.move(mensch_id, 0, MENSCH_GESCHW)
        c.move(mensch_id2, 0, MENSCH_GESCHW)
        c.move(mensch_id3, 0, MENSCH_GESCHW)
        c.move(mensch_id4, 0, MENSCH_GESCHW)
    elif event.keysym == 'Left':
        c.move(mensch_id, -MENSCH_GESCHW, 0)
        c.move(mensch_id2, -MENSCH_GESCHW, 0)
        c.move(mensch_id3, -MENSCH_GESCHW, 0)
        c.move(mensch_id4, -MENSCH_GESCHW, 0)
    elif event.keysym == 'Right':
        c.move(mensch_id, MENSCH_GESCHW, 0)
        c.move(mensch_id2, MENSCH_GESCHW, 0)
        c.move(mensch_id3, MENSCH_GESCHW, 0)
        c.move(mensch_id4, MENSCH_GESCHW, 0)
    elif event.keysym == 'w':
        c.move(mensch_id5, 0, -MENSCH_GESCHW)
        c.move(mensch_id6, 0, -MENSCH_GESCHW)
        c.move(mensch_id7, 0, -MENSCH_GESCHW)
        c.move(mensch_id8, 0, -MENSCH_GESCHW)
    elif event.keysym == 's':
        c.move(mensch_id5, 0, MENSCH_GESCHW)
        c.move(mensch_id6, 0, MENSCH_GESCHW)
        c.move(mensch_id7, 0, MENSCH_GESCHW)
        c.move(mensch_id8, 0, MENSCH_GESCHW)
    elif event.keysym == 'a':
        c.move(mensch_id5, -MENSCH_GESCHW, 0)
        c.move(mensch_id6, -MENSCH_GESCHW, 0)
        c.move(mensch_id7, -MENSCH_GESCHW, 0)
        c.move(mensch_id8, -MENSCH_GESCHW, 0)
    elif event.keysym == 'd':
        c.move(mensch_id5, MENSCH_GESCHW, 0)
        c.move(mensch_id6, MENSCH_GESCHW, 0)
        c.move(mensch_id7, MENSCH_GESCHW, 0)
        c.move(mensch_id8, MENSCH_GESCHW, 0)
c.bind_all('<Key>', menschen_beweg)
from random import randint
spike_id = list()
spike_r = list()
spike_geschw = list()
MIN_spike_R = 8
MAX_spike_R = 12
MAX_spike_GESCHW = 7
GAP = 100
def erstelle_spike():
    y = -HEIGHT - GAP
    x = randint(0, WIDTH)
    r = randint(MIN_spike_R, MAX_spike_R)
    id1 = c.create_polygon(x + 5, y + 5, x + 30, y + 5, x + 15, y + 30, fill='black')
    spike_id.append(id1)
    spike_r.append(r)
    spike_geschw.append(randint(5, MAX_spike_GESCHW))
def bewege_spikes():
    for i in range(len(spike_id)):
        c.move(spike_id[i], 0, spike_geschw[i])
from time import sleep, time
spike_CHANCE = 7
TIME_LIMIT = 100
BONUS_SCORE = 500
def hole_koord(id_num):
    pos = c.coords(id_num)
    x = (pos[0] + pos[2])/2
    y = (pos[1] + pos[3])/2
    return x, y
def lösche_spike(i):
    del spike_r[i]
    del spike_geschw[i]
    c.delete(spike_id[i])
    del spike_id[i]
def entf_spikes():
    for i in range(len(spike_id)-1, -1, -1):
        x, y = hole_koord(spike_id[i])
        if x < -GAP:
            lösche_spike(i)
from math import sqrt
def distanz(id1, id2):
    x1, y1 = hole_koord(id1)
    x2, y2 = hole_koord(id2)
    return sqrt((x2 - x1)**2 + (y2 - y1)**2)
def kollision():
    points = 0
    for spike in range(len(spike_id)-1, -1, -1):
        if distanz(mensch_id2, spike_id[spike]) < (MENSCH_R + spike_r[spike]):
            global lives_player_1
            lives_player_1 -= 1
            lösche_spike(spike)
        elif distanz(mensch_id6, spike_id[spike]) < (MENSCH_R + spike_r[spike]):
            global lives_player_2
            lives_player_2 -= 1
            lösche_spike(spike)
    return points
c.create_text(50, 30, text='ZEIT', fill='white' )
c.create_text(150, 30, text='LEBEN SPIELER 1', fill='white' )
c.create_text(300, 30, text='LEBEN SPIELER 2', fill='white' )
time_text = c.create_text(50, 50, fill='white' )
lives_text1 = c.create_text(150, 50, fill='white' )
lives_text2 = c.create_text(300, 50, fill='white' )
def zeige_leben1(lives_player_1):
    c.itemconfig(lives_text1, text=str(lives_player_1))
def zeige_leben2(lives_player_2):
    c.itemconfig(lives_text2, text=str(lives_player_2))
def zeige_zeit(time_left):
    c.itemconfig(time_text, text=str(time_left))
score = 0
bonus = 0
ende = time() + TIME_LIMIT
#HAUPTSCHLEIFE
def haupt_schleife():
    global ende
    global score
    global bonus
    while death <= lives_player_1 and death <= lives_player_2 and time() < ende:
        if randint(1, spike_CHANCE) == 1:
            erstelle_spike() 
        bewege_spikes()
        entf_spikes()
        score += kollision()
        if (int(score / BONUS_SCORE)) > bonus:
            bonus += 1
            ende += 5
        zeige_leben1(lives_player_1)
        zeige_leben2(lives_player_2)
        zeige_zeit(int(ende - time()))
        window.update()
        sleep(0.01)
    if death - 1 >= lives_player_1:
        c.create_text(MID_X, MID_Y, \
        text='SPIELER 2 HAT GEWONNEN', fill='white', font=('Helvetica',30))
    elif death - 1 >= lives_player_2:
        c.create_text(MID_X, MID_Y, \
        text='SPIELER 1 HAT GEWONNEN', fill='white', font=('Helvetica',30))
    else:
        c.create_text(MID_X, MID_Y, \
        text='UNENTSCHIEDEN', fill='white', font=('Helvetica',30))
    window.update()
    sleep(5)
    menu_schleife()
def menu_schleife():
    lives_player_1 = 3
    lives_player_2 = 3
    haupt_schleife()
haupt_schleife()
Ich weiß nicht wo man sonst schreiben soll also schreibe ich hier. Das ist mein erster Beitrag.
Ich benutze idle 3.5(32bit) Wenn ich das Programm starte funktioniert alles aber wenn haupt_schleife endet setzt menu_schleife die werte nicht zurück. kann mir jemand helfen ?
Zuletzt geändert von Anonymous am Mittwoch 25. Januar 2017, 21:06, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Das lässt sich momentan nicht gut lesen, da du vergessen hast den Code auch als Code zu formatieren.

Vermutlich liegt das Problem aber daran, dass du in `menu_schleife` nur lokale Werte setzt. Die saubere Lösung ist es jetzt übrigens nicht die Werte als `global` zu deklarieren, sondern das gesamte Programm so umzuschreiben, dass du ohne das Keyword `global` auskommst.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Smiley1000: Dein Programm hat eine Länge erreicht, wo es langsam unübersichtlich wird. Bevor Du weiter machst, solltest Du etwas Ordnung reinbringen. Um zu wissen, welche Abhängigkeiten ein Programm hat, sollten alle Import am Anfang stehen. *-importe sind schlecht, da man nicht kontrollieren kann, welche Namen da importiert werden. Danach alle Konstanten. Den Rest des Codes solltest Du in Funktionen packen. Wenn Du anfängst, Variablen durchzunummerieren willst Du eigentlich eine Liste verwenden. Du hast für zwei Menschen zweimal den selben Code. Ein Mensch wäre ein Ideales Beispiel für eine Klasse, mit der Du die Code-Dopplungen vermeiden kannst. Auch für das Fenster brauchst Du eine Klasse, damit Du den Zustand des Spiels nicht in globalen Variablen speichern mußt.
Informationen für ein Objekt in mehrere Listen zu speichern (spike_id, spike_r, spike_gesch) ist schlecht, weil man die immer synchron halten muß und das Iterieren kompliziert macht (so dass man auf die Idee kommt, einen Index zu benutzen). Besser wäre *eine* Liste mit Tupeln, oder gleich ein Spike-Klasse. Statt window.update und sleep solltest Du die window.after-Methode verwenden. Die \ sind überflüssig, weil schon durch die Klammern klar wird, dass die Zeile fortgesetzt wird. Rekursion ist kein Ersatz für eine Schleife.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

So könnte das aussehen:

Code: Alles auswählen

import tkinter as tk
from random import randint

HEIGHT = 500
WIDTH = 800

MID_X = WIDTH / 2
MID_Y = HEIGHT / 2

MENSCH_R = 20
MENSCH_GESCHW = 10
LIVES = 6

MIN_spike_R = 8
MAX_spike_R = 12
MAX_spike_GESCHW = 7
GAP = 100
spike_CHANCE = 7
TIME_LIMIT = 100

class Player:
    def __init__(self, canvas, color, text_position):
        self.lives = LIVES
        self.canvas = canvas
        self.objects = [
            canvas.create_oval(0, 0, 30, 30, fill='yellow'),
            canvas.create_oval(5, 20, 25, 25, fill='red'),
            canvas.create_oval(20, 10, 30, 15, fill=color),
            canvas.create_oval(0, 10, 10, 15, fill=color),
        ]
        self.text = canvas.create_text(text_position, 50, fill='white', text=self.lives)
        
    def move(self, x, y):
        for obj in self.objects:
            self.canvas.move(obj, x, y)

    def get_coordinates(self):
        pos = self.canvas.coords(self.objects[0])
        return (pos[0] + pos[2])/2, (pos[1] + pos[3])/2

    def check_collision(self, spike):
        x1, y1 = self.get_coordinates()
        x2, y2 = spike.get_coordinates()
        distance = ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5
        if distance < MENSCH_R + spike.r:
            self.lives -= 1
            self.canvas.itemconfig(self.text, text=self.lives)
            return True

class Spike:
    def __init__(self, canvas):
        self.canvas = canvas
        y = 0
        x = randint(0, WIDTH)
        self.r = randint(MIN_spike_R, MAX_spike_R)
        self.geschw = randint(5, MAX_spike_GESCHW)
        self.id = canvas.create_polygon(x + 5, y + 5, x + 30, y + 5, x + 15, y + 30, fill='black')

    def move(self):
        self.canvas.move(self.id, 0, self.geschw)

    def get_coordinates(self):
        pos = self.canvas.coords(self.id)
        return (pos[0] + pos[2])/2, (pos[1] + pos[3])/2

    def is_visible(self):
        return self.get_coordinates()[1] < HEIGHT
    
    def remove(self):
        self.canvas.delete(self.id)

class Game(tk.Canvas):
    def __init__(self, window):
        super().__init__(window, width=WIDTH, height=HEIGHT, bg='green')
        self.time_left = TIME_LIMIT
        self.spikes = []
        self.players = [
            Player(self, 'green', 150),
            Player(self, 'blue', 300)
        ]
        self.players[0].move(MID_X + 25, MID_Y)
        self.players[1].move(MID_X - 25, MID_Y)
        self.bind_all('<Key>', self.menschen_beweg)
        self.create_text(50, 30, text='ZEIT', fill='white')
        self.create_text(150, 30, text='LEBEN SPIELER 1', fill='white')
        self.create_text(300, 30, text='LEBEN SPIELER 2', fill='white')
        self.time_text = self.create_text(50, 50, fill='white', text='%.2f' % self.time_left)

    def menschen_beweg(self, event):
        if event.keysym == 'Up':
            self.players[0].move(0, -MENSCH_GESCHW)
        elif event.keysym == 'Down':
            self.players[0].move(0, MENSCH_GESCHW)
        elif event.keysym == 'Left':
            self.players[0].move(-MENSCH_GESCHW, 0)
        elif event.keysym == 'Right':
            self.players[0].move(MENSCH_GESCHW, 0)
        elif event.keysym == 'w':
            self.players[1].move(0, -MENSCH_GESCHW)
        elif event.keysym == 's':
            self.players[1].move(0, MENSCH_GESCHW)
        elif event.keysym == 'a':
            self.players[1].move(-MENSCH_GESCHW, 0)
        elif event.keysym == 'd':
            self.players[1].move(MENSCH_GESCHW, 0)

    def move_spikes(self):
        spikes = []
        if randint(1, spike_CHANCE) == 1:
            spikes.append(Spike(self))
        for spike in self.spikes:
            spike.move()
            collided = [p.check_collision(spike) for p in self.players]
            if any(collided) or not spike.is_visible():
                spike.remove()
            else:
                spikes.append(spike)
        self.spikes = spikes

    def haupt_schleife(self):
        self.move_spikes()
        self.time_left -= 0.01
        self.itemconfig(self.time_text, text='%.2f' % self.time_left)
        if any(p.lives == 0 for p in self.players) or self.time_left < 0:
            self.finish_screen()
        else:
            self.after(10, self.haupt_schleife)

    def finish_screen(self):
        if self.players[0].lives:
            text = "Spieler 1 hat gewonnen"
        elif self.players[1].lives:
            text = "Spieler 2 hat gewonnen"
        else:
            text = "Unentschieden"        
        self.create_text(MID_X, MID_Y, text=text, fill='white', font=('Helvetica',30))

def main():
    window = tk.Tk()
    window.title('Deathly Spikes')
    game = Game(window)
    game.pack()
    game.haupt_schleife()
    window.mainloop()

if __name__ == '__main__':
    main()
Antworten