gpt4 book ai didi

python - 试图绘制 Sprite 或更改图片pyglet

转载 作者:行者123 更新时间:2023-12-01 03:30:47 24 4
gpt4 key购买 nike

我正在尝试学习pyglet并使用问卷调查的东西练习一些python编码,但是我无法找到一种方法来使背景图片在10秒钟之内被删除或绘制在上面或某物之上。我是新来的,并且缺乏很多我需要的知识,谢谢您的帮助!

import pyglet
from pyglet.window import Window
from pyglet.window import key
from pyglet import image
import time

card1 = False
cat_image = pyglet.image.load("cat.png")
dog_image = pyglet.image.load("dog.png")
image = pyglet.image.load("backg.png")
background_sprite = pyglet.sprite.Sprite(image)
cat = pyglet.sprite.Sprite(cat_image)
dog = pyglet.sprite.Sprite(dog_image)
window = pyglet.window.Window(638, 404, "Life")
mouse_pos_x = 0
mouse_pos_y = 0
catmeme = pyglet.image.load("catmeme.png")
sprite_catmeme = pyglet.sprite.Sprite(catmeme)

@window.event
def on_draw():
window.clear()
background_sprite.draw()
card_draw1(63, 192, 385, 192)
def card1():
while time.time() < (time.time() + 10):
window.clear()
sprite_catmeme.draw()
@window.event
def card_draw1(x1, y1, x2, y2):
cat.set_position(x1, y1)
dog.set_position(x2, y2)
cat.draw()
dog.draw()
def card_draw2():
pass
@window.event
def on_mouse_press(x, y, button, modifiers):
if x > cat.x and x < (cat.x + cat.width):
if y > cat.y and y < (cat.y + cat.height):
card1()
game = True
while game:
on_draw()
pyglet.app.run()

最佳答案

顺序和操作方式中存在一些缺陷。
我将尽力描述它们,并为您提供一段代码,该代码可能会更好地满足您的需求。

我还认为您对问题的描述有点XY Problem,当您认为自己已经接近解决方案时,就复杂问题寻求帮助时,这很常见,因此您正在寻求有关解决方案的帮助。我想出了,不是问题。

我假设您要在10秒钟内显示“启动画面”,这恰好是您的背景?然后在其上方显示cat.pngdog.png,对吗?

如果是这样,您可能需要在这里进行一些更改才能使其正常工作:

draw()功能

它并没有真正更新屏幕,它只是将内容添加到图形内存中。更新屏幕的是您,还是告诉图形库您已完成向屏幕中添加内容的工作,现在该更新所有已更新的内容了。因此,循环中需要的最后一件事是.draw(),以便使您实际绘制的内容显示出来。

如果尝试摆动窗口,您的情况可能会显示出来,由于pyglet的内部机制如何工作,它应该触发场景的重新绘制。

如果您不调用window.flip()-.flip()调用将永远不会发生的可能性-同样,这是Pyglet / GL的内部机制,它告知图形卡某些内容已更新,我们就完成了更新现在该重绘场景了。

一个场景

这是用户所看到的最常用的词。
我可能会在文本中提到很多,所以很高兴知道这是用户所看到的,而不是您redraw()'n或已删除的内容,这是图形的最新显示卡插入显示器。

但是由于图形缓冲区的工作方式,我们可能已经删除了内容或将内容添加到了内存中,而尚未实际绘制。请记住这一点。

.draw()调用

这本身就是一个永无止境的循环,因此在pyglet.app.run()循环中进行循环实际上没有任何意义,因为while game:会“挂起”整个应用程序,您要执行的任何代码都必须位于.run()或从图形代码本身内部生成的def on_draw

为了更好地理解这一点,请看一下我的代码,这些年来,我已经在SO上粘贴了几次,它是两个自定义类的基本模型,继承了Pyglet的行为,但允许您设计自己的类表现稍有不同。

而且大多数功能都在event函数下,该函数几乎总是用于捕获Events的函数。 Pyglet具有很多内置功能,我们将使用自己的功能覆盖它们(但名称必须相同)

import pyglet
from pyglet.gl import *

key = pyglet.window.key

class CustomSprite(pyglet.sprite.Sprite):
def __init__(self, texture_file, x=0, y=0):
## Must load the texture as a image resource before initializing class:Sprite()
self.texture = pyglet.image.load(texture_file)

super(CustomSprite, self).__init__(self.texture)
self.x = x
self.y = y

def _draw(self):
self.draw()

class MainScreen(pyglet.window.Window):
def __init__ (self):
super(MainScreen, self).__init__(800, 600, fullscreen = False)
self.x, self.y = 0, 0

self.bg = CustomSprite('bg.jpg')
self.sprites = {}
self.alive = 1

def on_draw(self):
self.render()

def on_close(self):
self.alive = 0

def on_key_press(self, symbol, modifiers):
if symbol == key.ESCAPE: # [ESC]
self.alive = 0
elif symbol == key.C:
print('Rendering cat')
self.sprites['cat'] = CustomSprite('cat.png', x=10, y=10)
elif symbol == key.D:
self.sprites['dog'] = CustomSprite('dog.png', x=100, y=100)

def render(self):
self.clear()
self.bg.draw()

for sprite_name, sprite_obj in self.sprites.items():
sprite_obj._draw()

self.flip()

def run(self):
while self.alive == 1:
self.render()

# -----------> This is key <----------
# This is what replaces pyglet.app.run()
# but is required for the GUI to not freeze
#
event = self.dispatch_events()

x = MainScreen()
x.run()


现在,此代码故意保持简单,我通常粘贴在SO上的完整代码可以在 Torxed/PygletGui上找到, gui.py是大部分代码的来源,并且是主循环。

我在这里所做的只是通过使用类中的“实际”函数来替换 Decorators。该类本身从传统的 on_???继承函数,并且只要您将函数命名为与继承的一次相同,就将您决定的内容替换为 pyglet.window.Window的核心功能。在这种情况下,我模仿相同的功能,但增加了一些我自己的功能。

on_key_press

这样的示例就是 Window(),它通常只包含一个 on_key_press()调用而没有执行任何操作,在这里,我们检查是否按下了 pass,如果是,则-在 key.C中添加一个项目。因此碰巧在我们的 self.sprites循环中,其中的任何内容都将呈现在背景之上。

这是我使用的图片:

(命名为 self.spritesrender()bg.jpg-注意不同的文件结尾)

bg.jpg
cat.png
dog.png

类别:CustomSprite

cat.png是一个非常简单的类,旨在使您现在的生活更轻松,没有别的。它的功能非常有限,但是做得很少。

其根本目的是获取文件名,将其作为图像加载,然后您可以将对象像传统的 dog.png一样对待,这意味着您可以移动它并以多种方式对其进行操作。

它节省了几行代码,必须加载所需的所有图像,并且如您在 gui_classes_generic.py中所见,您可以为普通的sprite类添加“不可见”且通常不易使用的函数堆。

我一堆用!但是代码变得非常复杂,因此我故意使这篇文章变得简单。

翻转功能

即使在我的课堂上,我仍然需要使用 CustomSprite来更新屏幕内容。这是因为 pyglet.sprite.Sprite会如您所愿地清除窗口,这也会触发场景的重新绘制。

如果数据足够大或发生其他事情(例如,移动窗口),在某些情况下 flip()可能会触发重绘。

但调用 .clear()将告诉GL后端强制重绘。

进一步优化

有一种叫做批处理渲染的东西,基本上,图形卡被设计为可处理大量数据并一次性渲染,因此在多个项目上调用 bg.draw()只会在GPU甚至没有机会发光之前阻塞CPU。阅读有关 Batched rendering and graphics的更多信息!它将为您节省很多帧速率。

另一件事是在 .flip()循环中保留尽可能少的功能,并将事件触发器用作您的主要编码样式来源。
Pyglet在快速方面做得很好,特别是如果您仅在事件驱动的任务上执行操作。

尽量避免使用计时器,但是如果您确实确实需要花费时间,例如在一定时间后删除 .draw(),请使用 clock/time event调用删除猫的函数。除非您知道将代码放在何处以及原因,否则不要尝试使用自己的 render()样式的代码。有一个很好的计时器,我很少使用。。但是,如果您要开始的话,应该这样做。

这一直是一堵墙的地狱,我希望它能教给您一些有关图形和事物生活的知识。继续前进,进入这种东西是一个障碍,但是一旦您掌握了它,这将是非常有意义的(我还没有):)

关于python - 试图绘制 Sprite 或更改图片pyglet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40963164/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com