0

I'm trying to program a game. If I press the "new game" button, the game starts. But because the game uses "while 1", the Tkinter never refreshes after the game starts. I tried to it using threading but it writes:

Unhandled exception in thread started by <function refresh at 0xb7465c6c>
Traceback (most recent call last):
File "Alchymist_lab.py", line 22, in refresh
okno.mainloop()
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1035, in mainloop
self.tk.mainloop(n)
RuntimeError: Calling Tcl from different appartment

Here is the code:

    #importace modulů
import thread
from Tkinter import *
import base64
from pygame import *
import os

okno=Tk() #incializace okna pro tlačítka
okno.title("alchymist lab") #titul okna



def refresh():
    okno.mainloop()

def first_time():
    gamesave = [base64.b64encode("10000"), base64.b64encode("0"), base64.b64encode("0")]  #zakódovávání počátečních hodnot (peníze, bankovky, skóre) 
    file = open(os.path.dirname(os.path.abspath(__file__))+"/gamesave.txt", "w") #otevíraní + vytváření souboru s gamesavem
    file.write(str(gamesave)) #zapisování zakódovaných hodnot
    file.close #zavírání souboru 
    hra(10000,0,0) #otevírání hry s následujícími hodnotami: peníze 10000 , bankovky 0, skóre 0

def hra(p,b,s):
    start_panel=okno.winfo_screenwidth()-2*okno.winfo_screenheight()/5 #výpočet začátku panelu tak "aby to dobře vypadalo"
    base_width=start_panel+219-1 # výpočet šířky od které se dopočítává
    base_start_panel=800 #výpočet základního začátku panelu od kterého se pak dopočítává
    real_width=okno.winfo_screenwidth() #opravdpvá šířka obrazovky
    add_width=real_width-base_width #výpočet čísla ketré bude připočteno k šířce panelu 

    effect_bottle=os.path.dirname(os.path.abspath(__file__)) + "/efektova_lahev.png" #hledání obrázku efektové lahve
    effect_bottle_obr=image.load(effect_bottle) #nahrávání obrázku efektové lahve
    water_bottle=os.path.dirname(os.path.abspath(__file__))+ "/vodni_lahev.png" # hledání obrázku vodní lahve 
    water_bottle_obr=image.load(water_bottle) #nahrávání obrázku vodní lahve
    explosive_bottle=os.path.dirname(os.path.abspath(__file__))+ "/vybusna_lahev.png" #hledání obrázku výbušné lahve
    explosive_bottle_obr=image.load(explosive_bottle) #nahrávání obrázku výbušné lahve
    explosive_bottle_blue=os.path.dirname(os.path.abspath(__file__))+"/vybusna_lahev_blue.png" # hledání obrázku výbušné lahve s modrým pozadím
    explosive_bottle_blue_obr=image.load(explosive_bottle_blue) #nahrávání obrázku

    width = okno.winfo_screenwidth()  # šířka obrazovky
    height= okno.winfo_screenheight() # výška obrazovky



    while 1:   #hlavní smyčka
        clicked="no" #přednastavení proměné o kliknutí
        screen = display.set_mode((width, height)) #incializace obrazovky
        game = screen.subsurface (0,0,start_panel,okno.winfo_screenheight())
        panel = screen.subsurface (start_panel,0,219+add_width-4,okno.winfo_screenheight()) #incializace panelu
        game.fill([0,0,255]) #vybarvení obrazovky
        panel.fill([0,255,0]) #vybarvení panelu
        mouse_position=mouse.get_pos() #pozice myši
        panel.blit(effect_bottle_obr,(0,0)) #vykreslení obrázku efektové lahve na panel
        panel.blit(water_bottle_obr,(0,160)) #vykreslení obrázku vodní lahve na panel
        panel.blit(explosive_bottle_obr,(0,320))#vykreslení obrázku výbušné lahve na panel
        screen.blit(explosive_bottle_blue_obr,(120,50))#vykreslení obrázku výbušné lahve na obrazovku hry
        if mouse.get_pressed()[0]==1: #pokud je levé tlačítko myši zmáčknuto:
            clicked = "yes" # nastav proměnou kliknuto na ano

        if clicked=="yes": # pokud je proměná kliknuto na ano:
            while 1: # smyčka jako ta hlavní vylepšená o myš pronásledovanou obrázken výbušné lahve na obrazovce hry
                screen = display.set_mode((width, height))
                game = screen.subsurface (0,0,start_panel,okno.winfo_screenheight())
                panel = screen.subsurface (start_panel,0,219+add_width-4,okno.winfo_screenheight())
                game.fill([0,0,255])
                panel.fill([0,255,0])
                mouse_position=mouse.get_pos()
                panel.blit(effect_bottle_obr,(0,0))
                panel.blit(water_bottle_obr,(0,160))
                panel.blit(explosive_bottle_obr,(0,320))
                game.blit(explosive_bottle_blue_obr,(mouse_position))
                display.flip()

                if mouse.get_pressed()[0]==1: # pokud je znova zmáčknuto levé tlačítko myši:
                    break # zastav smyčku

        display.flip() # obnovení obrazovky pro znovunačtení dat, tím se pohybují obrázky pohybují

def continue_game():
    print "nacist do 3 proměných peníze , super peníze , skóre"

start=Button(okno, text="new game", command=first_time) #tlačítko pro novou hru
start.pack() #zarovnání tlačítka

continue_game=Button(okno, text=" continue ", command=continue_game) #tlačítko pro pokračování ve hře
continue_game.pack() #zarovnání tlačítka

end=Button(okno, text="     end     ", command=exit) #tlačítko pro  konec hry
end.pack() #zarovnání tlačítka
thread.start_new_thread(refresh,())
okno.mainloop() #konečné zobrazení

`

Disregard the comments, I write them in Czech because I'm Czech.

3

1 Answer 1

0

I use a loop like this in a similar program

root = Tk()

while True:
    canvas.delete(ALL)
    game_loop()
    draw(canvas)
    canvas.update()
    canvas.after(100)

root.mainloop()

This sorted out the issue with Tkinter not refreshing because an update is called each time. The canvas.after(100) acts to pause the refreshing - you can use this to control frame rate

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.