我目前正在为一个水果忍者项目上课。一切功能正常,但是,当我尝试放入游戏的背景图像时,运行速度非常慢。为了使游戏看起来更优美,我需要在具有游戏背景的同时使所有工作顺利进行。我遇到并试图理解的其他解决方案根本无法正常工作,或者文件永远不会运行。
仅供参考:我正在使用python 2.7。
我尝试了其他一些添加背景的建议,例如使用标签功能,但是,当我尝试实现它时,会遇到各种各样的错误,并且似乎在我的动画框架中不起作用。
def run(width=300, height=300):
def redrawAllWrapper(canvas, data):
canvas.delete(ALL)
canvas.create_rectangle(0, 0, data.width, data.height,
fill='white', width=0)
redrawAll(canvas, data)
canvas.update()
def mousePressedWrapper(event, canvas, data):
mousePressed(event, data)
redrawAllWrapper(canvas, data)
def keyPressedWrapper(event, canvas, data):
keyPressed(event, data)
redrawAllWrapper(canvas, data)
def timerFiredWrapper(canvas, data):
timerFired(data)
redrawAllWrapper(canvas, data)
# pause, then call timerFired again
canvas.after(data.timerDelay, timerFiredWrapper, canvas, data)
# Set up data and call init
class Struct(object): pass
data = Struct()
data.width = width
data.height = height
data.timerDelay = 10 # milliseconds
root = Tk()
root.resizable(width=False, height=False) # prevents resizing window
init(data)
# create the root and the canvas
canvas = Canvas(root, width=data.width, height=data.height)
canvas.configure(bd=0, highlightthickness=0)
canvas.pack()
# set up events
root.bind("<Button-1>", lambda event:
mousePressedWrapper(event, canvas, data))
root.bind("<Key>", lambda event:
keyPressedWrapper(event, canvas, data))
timerFiredWrapper(canvas, data)
# and launch the app
root.mainloop() # blocks until window is closed
print("bye!")
run(1200, 700)
在当前框架下,我在该运行函数上方的init,timerFired,redrawAll,keyPressed和mousePressed函数中编写了所有必需的代码。
以我当前的背景执行。我在1200 x 700 gif文件上使用PhotoImage,并在redrawAll函数(每10毫秒称为一次)中在整个屏幕上绘制图像。没有绘制该图像,我的游戏运行非常平稳,但是,在redrawAll中绘制图像时,游戏明显滞后,所以我知道滞后的原因是绘制背景图像。
这是在redrawAll中绘制它的代码行:
canvas.create_image(data.width // 2,data.height // 2,image = data.background)
这是否仅是因为我在redrawAll中执行此操作,每次调用该函数使其变慢时都会连续绘制图像?在Tkinter中只是拥有如此大的图像会使其变慢吗?来源是什么?
有一种方法可以简单地在背景上绘制一次图像,并且永远不会改变?还是有什么办法可以避免滞后?我只是觉得很奇怪。同样,这是在Mac上的python 2.7中。
谢谢!
答案 0 :(得分:1)
您不必删除并再次添加所有元素即可刷新屏幕。您可以移动元素,画布可以正确绘制
此代码创建了1000个小矩形,并在背景上随机移动它们。
在Python 3.7上进行了测试,但在2.7上也应该可以工作。
使用5_000
矩形会减慢速度,但效果仍然不错(但不是很完美)。使用10_000
会减慢太多速度。
from Tkinter import *
from PIL import Image, ImageTk
import random
IMAGE_PATH = 'background.jpg'
class Struct(object):
pass
def run(width=300, height=300):
def init(data):
# create 1000 rectangles in random position
for _ in range(1000):
x = random.randint(0, data.width)
y = random.randint(0, data.height)
data.data.append(canvas.create_rectangle(x, y, x+10, y+10, fill='red'))
def mousePressedWrapper(event, canvas, data):
#mousePressed(event, data)
pass
def keyPressedWrapper(event, canvas, data):
#keyPressed(event, data)
pass
def timerFiredWrapper(canvas, data):
# move objects
for rect_id in data.data:
x = random.randint(-10, 10)
y = random.randint(-10, 10)
canvas.move(rect_id, x, y)
# pause, then call timerFired again
canvas.after(data.timerDelay, timerFiredWrapper, canvas, data)
# Set up data and call init
data = Struct()
data.width = width
data.height = height
data.timerDelay = 10 # milliseconds
data.data = [] # place for small red rectangles
root = Tk()
root.resizable(width=False, height=False) # prevents resizing window
# create the root and the canvas
canvas = Canvas(root, width=data.width, height=data.height)
canvas.configure(bd=0, highlightthickness=0)
canvas.pack()
#canvas.create_rectangle(0, 0, data.width, data.height, fill='white', width=0)
img = Image.open(IMAGE_PATH)
img = img.resize((data.width, data.height))
photo = ImageTk.PhotoImage(img)
canvas.create_image(0, 0, image=photo, anchor='nw')
init(data) # init after creating canvas because it create rectangles on canvas
# set up events
root.bind("<Button-1>", lambda event:
mousePressedWrapper(event, canvas, data))
root.bind("<Key>", lambda event:
keyPressedWrapper(event, canvas, data))
timerFiredWrapper(canvas, data)
# and launch the app
root.mainloop() # blocks until window is closed
print("bye!")
run(1200, 700)