Seite 1 von 1

Tkinter Animationen

Verfasst: Sonntag 27. Mai 2018, 18:43
von Crafter_07
Hi Leute,
ich bin gerade dabei, ein kleines Spiel mit tkinter zu programmieren.
In dem Spiel soll man quasi eine Kanone sein, und von oben, unten, links und rechts sollen Kanonenkugeln kommen. Wenn man klickt, sollte man schießen(ich habe die feindlichen Kanonenkugel noch nicht programmiert):

Code: Alles auswählen

#Imports
from tkinter import *
from time import *

#window
W_WIDTH = 1600
W_HEIGHT = 900
window = Tk()
window.title("SimpleGame")

#canvas
c = Canvas(window, width=W_WIDTH, height=W_HEIGHT, bg="lightgrey")
c.pack()

#Player

#player1
player1_size = 100
player1_posX = W_WIDTH/2 - player1_size/2
player1_posY = W_HEIGHT/2 - player1_size/2
player_1 = c.create_oval(0, 0, player1_size, player1_size, fill="red")
c.move(player_1, player1_posX, player1_posY)

#player2
player2_sizeX = player1_size*2
player2_sizeY = player1_size/2
player2_posX = player1_posX + player1_size/2
player2_posY = player1_posY + player1_size/4
player_2 = c.create_rectangle(0, 0, player2_sizeX, player2_sizeY, fill="black")
c.move(player_2, player2_posX, player2_posY)


#Schuss

def shoot(event):
    shoot_size = 50
    shoot_posX = player2_posX +  player2_sizeX/2 + shoot_size*2
    shoot_posY = player2_posY
    shoot = c.create_oval(0, 0, shoot_size, shoot_size, fill="black")
    c.move(shoot, shoot_posX, shoot_posY)
    for i in range(80):
        shoot_posX += 10
        shoot_posY += 10
        c.move(shoot, shoot_posX, shoot_posY)
        window.update()
        sleep(0.5)
c.bind_all("<Button-1>", shoot)
Aber immer wenn ich klicke, stürzt das Programm ab. Kann mir da jemand helfen?
LG,
Crafter_07

Re: Tkinter Animationen

Verfasst: Sonntag 27. Mai 2018, 19:08
von Sirius3
Das Programm macht gar nichts, weil `mainloop` fehlt. Was ist denn die Fehlermeldung, die Du bekommst? Schleifen und sleep dürfen in GUIs nicht vorkommen, weil sie die Abarbeitung von Events stoppt. Für "Animationen" gibt es ›after‹. `move` beweget Objekte relativ zu ihrer aktuellen Position. Sternchenimporte vermeiden, weil man nicht kontrollieren kann, was da alles in den eigenen Namensraum geladen wird.

Re: Tkinter Animationen

Verfasst: Sonntag 27. Mai 2018, 19:20
von ThomasL
du definierst eine Funktion shoot mit Parameter event, wo wird die aufgerufen?
in dieser Funktion erzeugst du eine Variable shoot = c.create..... die Namensgebung solltest du überdenken, dass sind zuviele shoots :lol:

Re: Tkinter Animationen

Verfasst: Sonntag 27. Mai 2018, 19:40
von Sirius3
Die Funktion `shoot` wird an das Button-Event gebunden. Die muß man also nicht direkt aufrufen. Und solange man sich nicht selbst aufrufen will, ist es egal, ob eine lokale Variable auch `shoot` heißt.

Re: Tkinter Animationen

Verfasst: Montag 28. Mai 2018, 07:11
von wuf
Hi Crafter_07

Hier meine primitiver Lösungsansatz:

Code: Alles auswählen

#Imports
from tkinter import *
from time import *

#window
W_WIDTH = 1600
W_HEIGHT = 900
window = Tk()
window.title("SimpleGame")

#canvas
c = Canvas(window, width=W_WIDTH, height=W_HEIGHT, bg="lightgrey")
c.pack()

#Player

#player1
player1_size = 100
player1_posX = W_WIDTH/2 - player1_size/2
player1_posY = W_HEIGHT/2 - player1_size/2

player_1 = c.create_oval(0, 0, player1_size, player1_size, fill="red")
c.move(player_1, player1_posX, player1_posY)

#player2
player2_sizeX = player1_size*2
player2_sizeY = player1_size/2
player2_posX = player1_posX + player1_size/2
player2_posY = player1_posY + player1_size/4

player_2 = c.create_rectangle(0, 0, player2_sizeX, player2_sizeY, fill="black")
c.move(player_2, player2_posX, player2_posY)


#Schuss

def shoot(event):
    shoot_size = 50
    shoot_posX = player2_posX +  player2_sizeX/2 + shoot_size*2
    shoot_posY = player2_posY
    c.create_oval(0, 0, shoot_size, shoot_size, fill="black", tags="bullet")
    c.move(shoot, shoot_posX, shoot_posY)
    move_bullet()
    
def move_bullet(cycle=0):
    x0, y0, x1, y1 = c.coords("bullet")
    x0 += 10
    y0 += 10
    x1 += 10
    y1 += 10
    print(x0, y0)
    c.coords("bullet", x0, y0, x1, y1)
    cycle -= 1
    if cycle == 0:return
    window.after(100, move_bullet, cycle)
            
c.bind_all("<Button-1>", shoot)

window.mainloop()
Gruss wuf ;-)

Re: Tkinter Animationen

Verfasst: Montag 28. Mai 2018, 07:58
von Sirius3
@wuf: Sternchenimporte vermeiden, da man nicht kontrollieren kann, was da in den eigenen Namensraum geladen wird. Aus dem Modul `time` wird nichts verwendet, also kann der Import weg. In `shoot` ist das erste Argument von `move` falsch. `move_bullet` wird genau einmal durchlaufen, weil das `cycle`-Argument null ist. `shoot` und `move_bullet` könnten besser so aussehen:

Code: Alles auswählen

def shoot(event):
    shoot_size = 50
    shoot_posX = player2_posX +  player2_sizeX/2 + shoot_size*2
    shoot_posY = player2_posY
    shoot_id = c.create_oval(0, 0, shoot_size, shoot_size, fill="black")
    c.move(shoot_id, shoot_posX, shoot_posY)
    move_bullet(shoot_id, 100)

def move_bullet(shoot_id, turn):
    c.move(shoot_id, 10, 10)
    if turn > 0:
        window.after(100, move_bullet, shoot_id, turn - 1)