3

永遠に VB6 を使用して閉じ込められた後、私は Python を学び始めています。Tkinter で GUI を学ぶために、単純なスロット マシンを作成しています。ホイールをアニメーション化するために、使用する予定のすべての写真がストリップとして表示される ~300x2000 の画像があります。現在6枚ほど。画像の一部 (ホイール) を一度に表示して回転させます。とにかく、画像の最後に来て、画像の最後から最初に戻る必要があるコードの部分に問題があります(ホイールがスピンダウンするため、開始は下で終了はトップ)。

何らかの理由で、スクリプトが論理的に理にかなっていると思っていても、画像を正しくトリミングして表示することができません。私のコードは以下に掲載されています。300x2000程度の解像度の画像を作成して、これを使用して、私が抱えている問題を確認できます。私のコードは、表示したい領域の外 (showsize 変数の外) で印刷を開始しますが、その理由がわかりません。

この問題の助けをいただければ幸いです。トリミングによって画像が十分に短くカットされていないようですが、それについて見つけたすべての情報から、スクリプトは問題なく動作するはずだと思います。何が起こっているのかを説明するために、コードに注釈を付けようとしました。

from Tkinter import *
from PIL import Image, ImageTk

def main():
    root = Tk()
    root.title = ("Slot Machine")
    canvas = Canvas(root, width=1500, height=800)
    canvas.pack()

    im = Image.open("colors.png")
    wheelw = im.size[0] #width of source image
    wheelh = im.size[1] #height of source image
    showsize = 400 #amount of source image to show at a time - part of 'wheel' you can see
    speed = 3 #spin speed of wheel
    bx1 = 250 #Box 1 x - where the box will appear on the canvas
    by = 250 #box 1 y
    numberofspins = 100  #spin a few times through before stopping

    cycle_period = 0  #amount of pause between each frame

    for spintimes in range(1,numberofspins):
        for y in range(wheelh,showsize,-speed):  #spin to end of image, from bottom to top

            cropped = im.crop((0, y-showsize, wheelw, y))  #crop which part of wheel is seen
            tk_im = ImageTk.PhotoImage(cropped)
            canvas.create_image(bx1, by, image=tk_im)  #display image

            canvas.update()                 # This refreshes the drawing on the canvas.
            canvas.after(cycle_period)       # This makes execution pause

        for y in range (speed,showsize,speed):  #add 2nd image to make spin loop
            cropped1 = im.crop((0, 0, wheelw, showsize-y)) #img crop 1
            cropped2 = im.crop((0, wheelh - y, wheelw, wheelh)) #img crop 2
            tk_im1 = tk_im2 = None
            tk_im1 = ImageTk.PhotoImage(cropped1)
            tk_im2 = ImageTk.PhotoImage(cropped2)

            #canvas.delete(ALL)
            canvas.create_image(bx1, by, image=tk_im2)  ###THIS IS WHERE THE PROBLEM IS..
            canvas.create_image(bx1, by + y, image=tk_im1)  ###PROBLEM

            #For some reason these 2 lines are overdrawing where they should be.  as y increases, the cropped img size should decrease, but doesn't

            canvas.update()                 # This refreshes the drawing on the canvas
            canvas.after(cycle_period)       # This makes execution pause

    root.mainloop()

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

1 に答える 1

0

サイクルごとに画像を再作成しないと、より簡単になり、はるかに高速でスムーズになります。を使用した私のソリューションは次のとおりcanvas.move()です。canvas.create_image呼び出しを for ループの外に移動したことに注意してください。また、コードをクラスに入れ、「スピン」ボタンを追加し、エラーなしで終了するように何かを追加しました。

from Tkinter import *
from PIL import Image, ImageTk
import sys

class SlotMachine():
    def __init__(self):
        root = Tk()
        root.title = ("Slot Machine")
        self.canvas = Canvas(root, width=1200, height=800)
        self.canvas.grid(column=0,row=0)
        button = Button(root, text="Spin!", width=20, command = self.spin)
        button.grid(column=0,row=1)

        self.alive = True
        root.protocol("WM_DELETE_WINDOW", self.die)
        root.mainloop()

    def spin(self):

        im = Image.open("colors.png")
        wheelw = im.size[0] #width of source image
        wheelh = im.size[1] #height of source image
        showsize = 400 # amount of source image to show at a time -
                       # part of 'wheel' you can see
        speed = 3 #spin speed of wheel
        bx1 = 250 #Box 1 x - where the box will appear on the canvas
        by = 250 #box 1 y
        numberofspins = 100  #spin a few times through before stopping
        cycle_period = 3  #amount of pause between each frame

        tk_im1 = ImageTk.PhotoImage(im)
        tk_im2 = ImageTk.PhotoImage(im)
        im1id = self.canvas.create_image(bx1, by + showsize, image=tk_im1)
        im2id = self.canvas.create_image(bx1, by + showsize + wheelh, 
                                         image=tk_im2)

        for spintimes in range(1,numberofspins):
            for y in range(wheelh,0,-speed): 
                if self.alive:

                    self.canvas.move(im1id, 0, -speed)
                    self.canvas.move(im2id, 0, -speed)

                    self.canvas.update() 
                    self.canvas.after(cycle_period)
                else:
                    sys.exit()

            self.canvas.move(im1id, 0, wheelh)
            self.canvas.move(im2id, 0, wheelh)

    def die(self):
        self.alive = False

if __name__ == '__main__':
    mySlotMachine = SlotMachine()

これにより、ホイールの一部がボックスの外に配置されますが、その上にスロット マシンのテクスチャを配置することができます。

于 2013-02-28T12:26:14.807 に答える