微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Tkinter 无限生成和移动图像确保每个图像从上到下一直下降

如何解决Tkinter 无限生成和移动图像确保每个图像从上到下一直下降

我正在尝试制作水果忍者游戏。我目前的目标是在我的画布上生成无限的、掉落的果实(总共 4 列,随机速度),并且其中几个同时出现(不像在另一个消失后生成一个)。并跟踪它们中的每一个,以便稍后我可以进行碰撞(如果刀是否击中它们),如果是,则摧毁它们。

之前,我尝试过 root.after 方法,但它显然不适用于我的代码,因为一旦再次调用函数,该变量将被分配给一张新照片,因此之前的水果将消失。

我正在考虑在我展示的这个版本的代码中使用递归。运行不正常:会生成水果,但是和after()方法一样,到了点就会消失,只有前一个消失后才能生成第二个水果。>

这是我的代码

from tkinter import *
import time
from random import randint

score = 0

def create_fruits():
    while score < 21:
        #choose random fruits with different possibilities
        which_fruit = randint(1,11)

        #import fuits and bomb images
        global this_fruit

        if which_fruit == 1 or which_fruit == 10 or which_fruit == 11:
            this_fruit = PhotoImage(file = "bomb.png")
        elif which_fruit == 2:
            this_fruit = PhotoImage(file = "apple.png")
        elif which_fruit == 3:
            this_fruit = PhotoImage(file = "banana.png")
        elif which_fruit == 4:
            this_fruit = PhotoImage(file = "cherry.png")
        elif which_fruit == 5:
            this_fruit = PhotoImage(file = "blueBerry.png")
        elif which_fruit == 6:
            this_fruit = PhotoImage(file = "pear.png")
        elif which_fruit == 7:
            this_fruit = PhotoImage(file = "lemon.png")
        elif which_fruit == 8:
            this_fruit = PhotoImage(file = "watermelon.png")
        elif which_fruit == 9:
            this_fruit = PhotoImage(file = "mango.png")

        #randomly generate which colum (four in total) the fruits will be
        choose_position = randint (1,4)

        global x_position

        if choose_position == 1:
            x_position = 112.5
        elif choose_position == 2:
            x_position = 287.5
        elif choose_position == 3:
            x_position = 462.5
        else:
            x_position = 637.5

        #place the fruit image on the canvas
        global my_photo
        my_photo = canvas.create_image (x_position,image = this_fruit,anchor = 's')

        x_voLocity = 0
        y_voLocity = randint (5,10)

        while True:
            coords = canvas.coords(my_photo) #get coordinates of the fruit picture
            print (coords)
            #move the fruit
            canvas.move (my_photo,x_voLocity,y_voLocity)
            canvas.update()
            time.sleep(0.01)

            if coords [1] >= 400:
                create_fruits()


#create game area
root = Tk ()

canvas = Canvas (root,height = 1200,width = 800,bg = 'black')
#canvas.create_image(0,image = bg_image,anchor = 'nw')
canvas.pack()

create_fruits()

mainloop()

这是我尝试过的另一个版本:(比如将第二个水果分配给一个新变量,然后调用递归)。结果是,一旦第一个水果到达点,程序就会崩溃(就像没有响应)。

from tkinter import *
import time
from random import randint

score = 0

def create_fruits():
    while score < 21:
        #choose random fruits with different possibilities
        which_fruit = randint(1,y_voLocity)
            canvas.update()
            time.sleep(0.01)

            if coords [1] >= 400:
                create_fruits()



                #choose random fruits with different possibilities
                which_fruit2 = randint(1,11)

                #import fuits and bomb images
                global this_fruit2

                if which_fruit2 == 1 or which_fruit2 == 10 or which_fruit2 == 11:
                    this_fruit2 = PhotoImage(file = "bomb.png")
                elif which_fruit == 2:
                    this_fruit2 = PhotoImage(file = "apple.png")
                elif which_fruit == 3:
                    this_fruit2 = PhotoImage(file = "banana.png")
                elif which_fruit == 4:
                    this_fruit2 = PhotoImage(file = "cherry.png")
                elif which_fruit == 5:
                    this_fruit2 = PhotoImage(file = "blueBerry.png")
                elif which_fruit == 6:
                    this_fruit2 = PhotoImage(file = "pear.png")
                elif which_fruit == 7:
                    this_fruit2 = PhotoImage(file = "lemon.png")
                elif which_fruit == 8:
                    this_fruit2 = PhotoImage(file = "watermelon.png")
                elif which_fruit == 9:
                    this_fruit2 = PhotoImage(file = "mango.png")

                #randomly generate which colum (four in total) the fruits will be
                choose_position2 = randint (1,4)

                global x_position2

                if choose_position2 == 1:
                    x_position = 112.5
                elif choose_position2 == 2:
                    x_position2 = 287.5
                elif choose_position2 == 3:
                    x_position2 = 462.5
                else:
                    x_position2 = 637.5

                #place the fruit image on the canvas
                global my_photo2
                my_photo2 = canvas.create_image (x_position2,image = this_fruit2,anchor = 's')

                x_voLocity2 = 0
                y_voLocity2 = randint (5,10)

                while True:
                    coords2 = canvas.coords(my_photo2) #get coordinates of the fruit picture
                    print (coords2)
                    #move the fruit
                    canvas.move (my_photo2,x_voLocity2,y_voLocity2)
                    canvas.update()
                    time.sleep(0.01)

                    if coords2 >= 400:
                        create_fruits()

#create game area
root = Tk ()

canvas = Canvas (root,anchor = 'nw')
canvas.pack()

create_fruits()

mainloop()

这是我的代码的第三个版本(使用 after 方法)。在代码中,我还尝试使用 list 来跟踪水果并在之后删除它们,但它似乎不起作用(我不知道为什么)。

#make the fruits appear on the screen
def create_fruits():
    #choose random fruits with different possibilities
    which_fruit = randint(1,11)
    
    #import fuits and bomb images
    global this_fruit
    
    if which_fruit == 1 or which_fruit == 10 or which_fruit == 11:
        this_fruit = PhotoImage(file = "bomb.png")
    elif which_fruit == 2:
        this_fruit = PhotoImage(file = "apple.png")
    elif which_fruit == 3:
        this_fruit = PhotoImage(file = "banana.png")
    elif which_fruit == 4:
        this_fruit = PhotoImage(file = "cherry.png")
    elif which_fruit == 5:
        this_fruit = PhotoImage(file = "blueBerry.png")
    elif which_fruit == 6:
        this_fruit = PhotoImage(file = "pear.png")
    elif which_fruit == 7:
        this_fruit = PhotoImage(file = "lemon.png")
    elif which_fruit == 8:
        this_fruit = PhotoImage(file = "watermelon.png")
    elif which_fruit == 9:
        this_fruit = PhotoImage(file = "mango.png")

    #randomly generate which colum (four in total) the fruits will be
    choose_position = randint (1,4)
    
    global x_position
    
    if choose_position == 1:
        x_position = 112.5
    elif choose_position == 2:
        x_position = 287.5
    elif choose_position == 3:
        x_position = 462.5
    else:
        x_position = 637.5

    #create a list to store fruit images
    global fruits_list
    fruits_list = []
    
    
    
    #append it to the list
    fruits_list.append(this_fruit)
   
    
    #place the fruit image on the canvas
    global my_photo
    my_photo = canvas.create_image (x_position,anchor = 's')
    #global root
    #repeatedly generate fruit images every 3 second
    root.after(3000,create_fruits)
    
    
    
    

#nake fruits' animation  
#let one fruit keep moving while the second fruit pears  
def move_fruits():
    
    #set the moving speed
    x_voLocity = 0
    y_voLocity = randint (5,10)
    
    #try to make two fruits moving at the same time on the screen
    for i in range (0,len(fruits_list)-1):
        while True:
            coords = canvas.coords(fruits_list[i]) #get coordinates of the fruit picture
            print (coords)
            #move the fruit
            canvas.move (fruits_list[i],y_voLocity)
            canvas.update()
            time.sleep(0.01)
            #assign this fruit to finished fruit to delete it from the list later
            finished_fruit = fruits_list[i]
            #check is the fruit is outside of the boarder,if so,delete if from the list and countinue on the second fruit
            if coords [i] >= 1400:
                fruits_list.remove(finished_fruit)

解决方法

我对您的代码进行了一些更改,包括删除不必要的 if 语句(而是将其存储在 dict 中)和删除无限 while 循环。

from tkinter import *
from random import randint
from PIL import Image,ImageTk

#make the fruits appear on the screen
def create_fruits():
    
    global fruits_list

    #choose random fruits with different possibilities
    which_fruit = randint(1,3)

    this_fruit = ImageTk.PhotoImage(Image.open(fruit_dic[which_fruit]))
    #randomly generate which colum (four in total) the fruits will be
    choose_position = randint (1,4)
    
    x_position = x_positions_dic[choose_position]  # choose the position from dict

    my_photo = canvas.create_image(x_position,80,image = this_fruit,anchor = 's')

    #append it to the list(image_id,x position,image)
    fruits_list.append([my_photo,randint(5,10),this_fruit])

    #repeatedly generate fruit images every 3 second
    root.after(3000,create_fruits)
    

def move_fruits():
    
    for fruit in fruits_list:
        
        canvas.move(fruit[0],fruit[1])

        if canvas.bbox(fruit[0])[3] >= canvas.winfo_height()+100:
            canvas.delete(fruit[0])
            fruits_list.remove(fruit)

    root.after(10,move_fruits)  # calls the move_fruits after every 10 seconds
    
root = Tk()

canvas = Canvas (root,height = 1200,width = 800,bg = 'black')
canvas.pack()

fruits_list = []

x_positions_dic = {1: 112.5,2: 287.5,3: 462.5,4:637.5}
fruit_dic = {1: r"imag\fruit1",2: r"img\fruit2",3: r"img\fruit3"} # your path here

create_fruits()
move_fruits()

root.mainloop()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。