重置游戏,删除画布

时间:2013-09-08 14:43:26

标签: python oop canvas tkinter

我坚持整个游戏,我将创建一个重置按钮。我想将游戏恢复到原始状态。我试图恢复列表等,没有任何积极的结果。

有人可以给我一些好的建议或解决方案吗?

#!/usr/bin/python
# -*- codieren: utf-8 -*-

from Tkinter import *
from PIL import ImageTk, Image
from pygame import mixer


#Skapar fönster och dess inställningar
win = Tk() #Skapar fönster
win.title("Play High or Low Card") #Fönsterrubrik
win.geometry("700x550") #Fönsterstorlek
win.config(bg="#188200")
mixer.init(44100)

turns = int()
score = int(1)

try: #Kontrollerar så att programmet hittar ljudfilerna
    deal = mixer.Sound("Python/projekt/sound/deal.wav")
    shuffle = mixer.Sound("Python/projekt/sound/shuffle.wav")
    winner = mixer.Sound("Python/projekt/sound/win.wav")
    loser = mixer.Sound("Python/projekt/sound/miss.wav")
except: #Felmeddelande skrivs ut om dessa inte hittas
    print ("Kunde inte öppna ljudfilerna")


class Card(object): #Skapar klass innehållande information och metoder för korten

    RANKS = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] #Lista på kortens värde

    SUIT = ["Python/projekt/bilder/hearts.png", "Python/projekt/bilder/spades.png", "Python/projekt/bilder/diamond.png", "Python/projekt/bilder/clubs.png"] #Lista på kortens valörer samt sökväg till bilder på dessa

    def __init__(self, rank, suit): #initierar/gör känt
        self.rank = rank
        self.suit = suit

    def __str__(self):
        rep = self.rank + self.suit
        return rep

    def draw(self): #Metod som ritar upp grafiken/korten

        bg = ImageTk.PhotoImage(Image.open(self.suit).resize((10, 10))) #Öppnar upp bild, bestämmer dess storlek. Tar emot sökväg från SUIT

        cardGraph = Canvas(cardHolder, width=70, height=100, bg="White", bd=1, relief='solid', highlightthickness=2) #Skapar och bestämmer utseende för canvas
        cardGraph.photo=bg #Sätter bilden som öppnas i bg, som bakgrund

        cardGraph.create_image(10,10, image=bg, anchor=CENTER) #left/up
        cardGraph.create_image(53,93, image=bg, anchor=CENTER) #right/down

        cardGraph.create_text(20, 10, text=self.rank, font=("Helvetica", 8, "bold")) #left/up
        cardGraph.create_text(63, 93, text=self.rank, font=("Helvetica", 8, "bold")) #right/down
        cardGraph.create_text(36, 50, text=self.rank, font=("Helvetica", 12, "bold")) #middle

        cardGraph.pack(side=LEFT, anchor=CENTER) #Bestämmer position för canvas

        return cardGraph

class Hand(object):
    def __init__(self):
        self.cards = []
        self.draw_card_stack = [] #Array för ritade kort

    def __str__ (self):
        if self.cards:
            rep = ""
            for card in self.cards:
                rep += str(card) + " "
        else:
            rep = "<empty>"
        return rep

    def add(self, card):
        self.cards.append(card)

class Deck(Hand):

    global CardValueHist
    CardValueHist = []

    def populate(self): #Bygger upp kortleken
        for suit in Card.SUIT:
            for rank in Card.RANKS:
                self.add(Card(rank, suit))

    def shuffle(self): #Blandar och målar upp kort, samt uppdaterar canvas
        import random
        random.shuffle(self.cards)
        DrawCard = self.cards[0]
        card_graph = DrawCard.draw()

        deal.play()

        self.draw_card_stack.append(card_graph)
        if len(self.draw_card_stack) > 3: #Kontrollerar längden på listan. Om listan är större än 3
            self.draw_card_stack[0].destroy() #Tar bort canvas
            del self.draw_card_stack[0] #Snyggar till listan


    def setValue(self): #Sätter värde på korten
        global CardValue
        CardValue = 0
        rank = self.cards[0].rank

        #Kollar upp vilken rank kortet har, sätter därefter värde
        if rank == 'K':
            CardValue += 13
            CardValueHist.append(CardValue)
        elif rank == 'Q':
            CardValue += 12
            CardValueHist.append(CardValue)
        elif rank == 'J':
            CardValue += 11
            CardValueHist.append(CardValue)
        elif rank == 'A':
            CardValue += 1
            CardValueHist.append(CardValue)
        else:
            CardValue += int(rank) #Sätter kortets egna rank som värde (2-10)
            CardValueHist.append(CardValue)

    def reset(self):
            global turns
            global score     

            score = 1
            turns = 0 #Återställer värdet i
            decket = Deck()
            decket.populate()

            turnEnt.delete(0, END) #Tar bort allt ifrån Entry-widgeten
            turnEnt.insert(0, int(turns)) #Fyller den på nytt, men nu med ett nytt värde
            scoreTot.delete(0, END) #Tar bort allt ifrån Entry-widgeten
            scoreTot.insert(0, int(score)) #Fyller den på nytt, men nu med ett nytt värde

            lower.config(state='active')
            higher.config(state='active')
            restart.config(state='disable')

class game(Deck):

    def helper(self): #Funktion för att öppna hjälptextfilen
        try:
            textFile = open("helper.txt", "r") #Öppnar och läser fil
            data = textFile.read() #Ger variabel data från filen
            textFile.close() #Stänger filen
        except IOError:
            print ("Filen finns inte") #Skriver ut om filen inte hittas
            return 0

        helper = Toplevel() #Fönster, längst fram
        helper.geometry("700x250") #Fönsterstorlek
        helper.title("Hjälpavsnitt") #Fönsterrubrik

        helpText = Label(helper, text=data, wraplength=680) #Bestämmer hur lång texten får vara/rad
        helpText.pack()        


    def higher(self):
        global turns
        global score
        decket.shuffle()
        decket.setValue()

        turns += 1 #Ökar värde i variabeln med 1, för varje gång användaren klickar på Gissa
        turnEnt.delete(0, END) #Tar bort allt ifrån Entry-widgeten
        turnEnt.insert(0, int(turns)) #Fyller den på nytt, men nu med ett nytt värde

        rank = CardValue
        compare = CardValueHist[-2]

        if (compare <= rank):
            mode.set("Bra jobbat! Fortsätt!")
            infoText.config(bg="Green")
            lower.config(state='active')
            score *= turns #Ökar värde i variabeln med 1, för varje gång användaren klickar på Gissa
            scoreTot.delete(0, END) #Tar bort allt ifrån Entry-widgeten
            scoreTot.insert(0, int(score)) #Fyller den på nytt, men nu med ett nytt värde


        else:
            mode.set("Tyvärr, du gissade fel") #Skriver meddelande
            infoText.config(bg="Red") #Bestämmer backgrund för meddelande
            higher.config(state='disable') #Ställer knappen som inaktiv
            lower.config(state='disable') #Ställer knappen om inaktiv
            restart.config(state='active') #Ställer knappen som aktiv
            loser.play()

    def lower(self):
        global turns
        global score
        decket.shuffle()
        decket.setValue()

        turns += 1 #Ökar värde i variabeln med 1, för varje gång användaren klickar på Gissa
        turnEnt.delete(0, END) #Tar bort allt ifrån Entry-widgeten
        turnEnt.insert(0, int(turns)) #Fyller den på nytt, men nu med ett nytt värde

        rank = CardValue
        compare = CardValueHist[-2]

        if (compare >= rank):
            mode.set("Bra jobbat! Fortsätt!")
            infoText.config(bg="Green")
            score *= turns #Ökar värde i variabeln med 1, för varje gång användaren klickar på Gissa
            scoreTot.delete(0, END) #Tar bort allt ifrån Entry-widgeten
            scoreTot.insert(0, int(score)) #Fyller den på nytt, men nu med ett nytt värde
        else:
            mode.set("Tyvärr, du gissade fel")
            infoText.config(bg="Red")
            higher.config(state='disable') #Ställer knappen som inaktiv
            lower.config(state='disable') #Ställer knappen om inaktiv
            restart.config(state='active') #Ställer knappen som aktiv
            turns += 1
            loser.play()

#Top-bakgrund
BannerBg = ImageTk.PhotoImage(Image.open("Python/projekt/bilder/card_bg.jpg"))
Banner = Label(win, text="This is a game", image=BannerBg)
Banner.pack(fill=BOTH)

#Textfält för spelstatus och välkomsttext
mode = StringVar()
mode.set("Welcome to High or Low Game")
infoText = Label(win, textvariable=mode, font=("Helvetica", 12, "bold"), bg="Yellow", bd=0.5, relief='solid')
infoText.pack(fill=BOTH)

decket = Deck()
game = game()
decket.populate()
decket.setValue()
game.higher
game.lower
decket.reset
game.helper

#Poäng och rundor
label = Label(win, bg="#188200", height=800)
label.pack(side=RIGHT,fill=BOTH)


#Korthållare
cardHolder = LabelFrame(win)
cardHolder.pack(anchor=N)

#Poäng och rundor
turnText = Label(label, text="Antal gissningar:", bg="#188200", font=("verdana", 10, "bold"))
turnText.pack(fill=BOTH, anchor=E)
turnEnt = Entry(label, bg="#188200", bd=0, font=("verdana", 15, "bold"), width=10, justify=CENTER)
turnEnt.pack(anchor=E)
scoreText = Label(label, text="Poäng:", bg="#188200", font=("verdana", 10, "bold"))
scoreText.pack(fill=BOTH, anchor=E)
scoreTot = Entry(label, bg="#188200", bd=0, font=("verdana", 15, "bold"), width=10, justify=CENTER)
scoreTot.pack(anchor=E)

#Knappar
buttonHolder = LabelFrame(win)
buttonHolder.pack(side=BOTTOM, anchor=S)

higher = Button(buttonHolder, text="+Högre", width=50, highlightthickness=5, command=lambda: game.higher())
higher.config(state='active')
higher.pack()

lower = Button(buttonHolder, text="-Lägre", width=50, highlightthickness=5, command=lambda: game.lower())
lower.config(state='disable')
lower.pack()

restart = Button(buttonHolder, text="=Börja om", width=50, highlightthickness=5, command=lambda: game.reset())
restart.config(state='disable')
restart.pack()

helpBg = ImageTk.PhotoImage(Image.open("Python/projekt/bilder/help.jpg").resize((85, 75)))
helpBtn = Button(label, text="?Hjälp", bg="#188200", image = helpBg, bd=0, highlightthickness=0, command=lambda: game.helper())
helpBtn.config(state='active')
helpBtn.pack(side=RIGHT, anchor=SE)

win.mainloop()

这是我为恢复游戏而制作的方法的代码:

def reset(self):
    global turns
    global score     

    score = 1
    turns = 0 #Återställer värdet i
    decket = Deck()
    decket.populate()

    turnEnt.delete(0, END) #Tar bort allt ifrån Entry-widgeten
    turnEnt.insert(0, int(turns)) #Fyller den på nytt, men nu med ett nytt värde
    scoreTot.delete(0, END) #Tar bort allt ifrån Entry-widgeten
    scoreTot.insert(0, int(score)) #Fyller den på nytt, men nu med ett nytt värde

    lower.config(state='active')
    higher.config(state='active')
    restart.config(state='disable')

1 个答案:

答案 0 :(得分:0)

您的代码过于依赖于许多全局变量,这使得真正的重置函数非常困难。

你应该有一个代表游戏逻辑的类,一个代表gui的类。在启动时,您的GUI类可以创建游戏类的实例。然后,重置按钮可以删除旧游戏对象并创建新游戏对象,从而在单个语句中有效地重置所有游戏逻辑。唯一剩下的就是在GUI类中有一个函数,它根据当前的游戏状态更新屏幕。

为了使它更容易一些,GUI应该将自己传递给游戏类,以便游戏类可以调用GUI中的方法。由于GUI创建了游戏类,因此它可以调用游戏中的方法。例如,每当游戏逻辑中发生某些事情时,它可能想要调用self.gui.refresh()来刷新显示。

粗略地说,它看起来像这样:

class Game:
    def __init__(self, gui):
        self.gui = gui
        self.turns = 0
        self.score = 0 
        ...

class GUI:
    def __init__(self):
        # create the GUI here...
        ...
        self.reset_button = tk.Button(..., command=self.reset)
        ...

        # last step is to create a new game (optional; you
        # could make the user click a "New Game" button)
        self.new_game()

    def new_game(self):
        # create new game instance, passing in a reference to this object
        self.game = Game(self)
        # reset the GUI
        self.refresh()

    def refresh(self):
        ...
        self.scoreText.configure(self.game.get_score())
        ...