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 回答