- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在为我的第一个深度Pyglet项目开发2D Minecraft克隆,但遇到了一个问题。每当我在屏幕上有相当数量的块时,帧速率都会急剧下降。
这是我的渲染方法:
我使用字典,键是元组(代表块的坐标),项是纹理。
我遍历整个字典并渲染每个块:
for key in self.blocks:
self.blocks[key].blit(key[0] * 40 + sx,key[1] * 40+ sy)
最佳答案
我将尽力解释为什么以及如何在不真正了解代码外观的情况下优化代码。
我将假设您具有以下特点:
self.blocks['monster001'] = pyglet.image.load('./roar.png')
sprite = pyglet.sprite.Sprite(pyglet.image.load('./roar.png'))
sprite.draw() # This is instead of blit. Position is done via sprite.x = ...
.blit()
快得多,但是我们暂时跳过为什么,只坚持极速的升级。
main_batch = pyglet.graphics.Batch()
background = pyglet.graphics.OrderedGroup(0)
# stuff_above_background = pyglet.graphics.OrderedGroup(1)
# ...
monster_image = pyglet.image.load('./roar.png')
for i in range(100): # We'll create 100 test monsters
self.blocks['monster'+str(i)] = pyglet.sprite.Sprite(imgage=monster_image, x=0, y=0, batch=main_batch, group=background)
monster_image
个怪物,并将它们添加到了批次
100
的子组
main_batch
中。简单如馅饼。
background
而不是调用
self.blocks[key].blit()
或
.draw()
,它将把每个怪兽发射到图形卡上并产生奇迹。
main_batch.draw()
中进行调用。
baseSprite
对象尝试设置
Sprite
时,使用这些东西时会引起各种各样的故障和错误,因此我们将设置
class baseSprite(pyglet.sprite.Sprite):
def __init__(self, texture, x, y, batch, subgroup):
self.texture = texture
super(baseSprite, self).__init__(self.texture, batch=batch, group=subgroup)
self.x = x
self.y = y
def move(self, x, y):
""" This function is just to show you
how you could improve your base class
even further """
self.x += x
self.y += y
def _draw(self):
"""
Normally we call _draw() instead of .draw() on sprites
because _draw() will contains so much more than simply
drawing the object, it might check for interactions or
update inline data (and most likely positioning objects).
"""
self.draw()
main_batch = pyglet.graphics.Batch()
background = pyglet.graphics.OrderedGroup(0)
monster_image = pyglet.image.load('./roar.png')
self.blocks['monster001'] = baseSprite(monster_image, 10, 50, main_batch, background)
self.blocks['monster002'] = baseSprite(monster_image, 70, 20, main_batch, background)
...
main_batch.draw()
image
示例,这很好,但是从长远来看,我发现它很慢,很丑,而且不切实际。您想进行面向对象的编程吗?
self.texture
,并依次调用它的后续函数并轮询事件处理程序,否则sh **会卡住,请相信我。和瓶颈很容易创建。
@on_window_draw()
类,该类使用基于轮询的事件处理,从而将刷新率限制在您的编程中,而不是在Pyglet中内置行为。
class main(pyglet.window.Window):
def __init__ (self):
super(main, self).__init__(800, 800, fullscreen = False)
self.x, self.y = 0, 0
self.sprites = {}
self.batches = {}
self.subgroups = {}
self.alive = 1
def on_draw(self):
self.render()
def on_close(self):
self.alive = 0
def render(self):
self.clear()
for batch_name, batch in self.batches.items():
batch.draw()
for sprite_name, sprite in self.sprites.items():
sprite._draw()
self.flip() # This updates the screen, very much important.
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.
# Basically it flushes the event pool that otherwise
# fill up and block the buffers and hangs stuff.
event = self.dispatch_events()
x = main()
x.run()
class
类,除了渲染黑色背景以及放置在
main
和
main
中的所有内容外,什么也不做。
self.sprites
是因为我们之前创建了自己的Sprite类?是的,这是很棒的基本Sprite类,您可以在每个单独的Sprite上完成
self.batches
之前,将自己挂接到自己的东西中。
import pyglet
from pyglet.gl import *
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_LINE_SMOOTH)
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE)
pyglet.clock.set_fps_limit(60)
class baseSprite(pyglet.sprite.Sprite):
def __init__(self, texture, x, y, batch, subgroup):
self.texture = texture
super(baseSprite, self).__init__(self.texture, batch=batch, group=subgroup)
self.x = x
self.y = y
def move(self, x, y):
""" This function is just to show you
how you could improve your base class
even further """
self.x += x
self.y += y
def _draw(self):
"""
Normally we call _draw() instead of .draw() on sprites
because _draw() will contains so much more than simply
drawing the object, it might check for interactions or
update inline data (and most likely positioning objects).
"""
self.draw()
class main(pyglet.window.Window):
def __init__ (self):
super(main, self).__init__(800, 800, fullscreen = False)
self.x, self.y = 0, 0
self.sprites = {}
self.batches = {}
self.subgroups = {}
self._handles = {}
self.batches['main'] = pyglet.graphics.Batch()
self.subgroups['base'] = pyglet.graphics.OrderedGroup(0)
monster_image = pyglet.image.load('./roar.png')
for i in range(100):
self._handles['monster'+str(i)] = baseSprite(monster_image, randint(0, 50), randint(0, 50), self.batches['main'], self.subgroups['base'])
# Note: We put the sprites in `_handles` because they will be rendered via
# the `self.batches['main']` batch, and placing them in `self.sprites` will render
# them twice. But we need to keep the handle so we can use `.move` and stuff
# on the items later on in the game making process ;)
self.alive = 1
def on_draw(self):
self.render()
def on_close(self):
self.alive = 0
def render(self):
self.clear()
for batch_name, batch in self.batches.items():
batch.draw()
for sprite_name, sprite in self.sprites.items():
sprite._draw()
self.flip() # This updates the screen, very much important.
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.
# Basically it flushes the event pool that otherwise
# fill up and block the buffers and hangs stuff.
event = self.dispatch_events()
# Fun fact:
# If you want to limit your FPS, this is where you do it
# For a good example check out this SO link:
# http://stackoverflow.com/questions/16548833/pyglet-not-running-properly-on-amd-hd4250/16548990#16548990
x = main()
x.run()
global_settings = {'player position' : (50, 50)}
# The player is at X cord 50 and Y cord 50.
class baseSprite(pyglet.sprite.Sprite):
def __init__(self, texture, x, y, batch, subgroup):
self.texture = texture
super(baseSprite, self).__init__(self.texture, batch=batch, group=subgroup)
self.x = x + global_settings['player position'][0]#X
self.y = y + global_settings['player position'][1]#Y
._draw()
(注意,不是
draw()
,因为批处理渲染将调用
draw()
而不是
_draw()
)功能来遵循和更新每个渲染序列的位置更新。那或者您可以创建一个继承
draw
的新类,并且只更新那些类型的sprite:
class monster(baseSprite):
def __init__(self, monster_image, main_batch, background):
super(monster, self).__init__(imgage=monster_image, x=0, y=0, batch=main_batch, group=background)
def update(self):
self.x = x + global_settings['player position'][0]#X
self.y = y + global_settings['player position'][1]#Y
_draw
类型的类/子画面上调用
baseSprite
。
关于python - Pyglet图像渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34846635/
我正在使用Python 2.6.6和pyglet 1.1.4。在我的“Erosion”文件夹中,有“Erosion.py”和一个名为“Images”的文件夹。在图像内部,有.png图像。一幅图像被命名
我有一个奇怪的问题。当 pyglet 应用程序启动时,它只绘制 1-2 帧然后卡住。 on_draw 事件刚刚停止发生。但是每次我移动鼠标或按键时,on_draw 事件也会调度。简而言之,我必须移动鼠
我有一个应用程序正在创建名为 Pizza Clicker 的 Cookie Clicker 的替代版本。它非常基本,但运行速度非常慢,我不明白为什么。 import pyglet window = p
因此,在我们的游戏中使用 Tkinter 后,我们决定转向 Pyglet。但我遇到的问题之一是运动,在 Tkinter 中我能够制作一个平滑的运动系统,但在 pyglet 中我所能做的就是让角色以一种
我正在使用 pyglet 的 Player 类在 python 中编写一个音频播放器。该模块只是对 Player 和 Source 类的测试,它不会产生任何结果。没有声音,没有错误,只有一个关于垂直同
我正在尝试使用 pyglet 制作一个简单的 GUI。 这是我的代码: button_texture = pyglet.image.load('button.png') button = pyglet
考虑以下示例: import pyglet def foo(): print("I'm in a loop...") def main(): w = pyglet.window.Win
我正在使用 pyglet (OpenGL) 库,我希望能够在不改变窗口大小的情况下改变虚拟分辨率。例如,一个 2x2 的框将在屏幕上绘制为 4x4 像素。我知道我可以找到正在绘制的所有内容并单独对其进
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我非常喜欢 pyglet,但是抽象的基本单位是坐标向量,这很笨拙,而且不是我在设计复杂场景时想要的抽象级别。 是否有任何库“通常”与 pyglet 一起使用来管理形状并将它们组合到场景中?每个人都从头
我有一个用于在屏幕上显示文本的标签元素: nameLabel = pyglet.text.Label(name, font_name='Tahoma', x=50, y=50, font_size=1
我正在使用 pyglet 编写心理物理学实验。我使用的电脑有两个显示器。它们被配置为两个独立的 Xscreens,0 和 1,分别对应于我的工作站监视器和实验屏幕。我想让 pyglet 绘制到实验屏幕
在我使用 Python 和 pyglet 的游戏中,我有将事件向下传播到其成员的组: class Group(EventDispatcher): def __init__(self):
我制作了两个立方体视口(viewport),但它们都是正面正交投影,我需要其中一个来自侧面。这是绘图代码draw_small 正在绘制小型静态立方体dwar_big是大立方体的绘制,可以移动、缩放和旋
我目前正在开发一个项目,我一直在尝试将 pyglet 库中的标签字体更改为我在网上找到的字体,但我无法让它工作。我尝试在网上搜索一个小时,但似乎没有任何效果。添加了一些代码供引用: font.add_
所以我是一名 Python 初学者程序员,我一直在使用 pyglet,如果您运行此代码,我发现了一个问题: from pyglet.gl import * window = pyglet.window
我已经阅读了我能找到的所有内容,并查看了 pyglet 上游戏循环的许多示例,但我仍然不确定它是如何工作的或到底发生了什么。 (这些是我读过的文章...) http://www.pyglet.org/
我正在使用 Pyglet,并且我有一个包含在背景上移动的对象的小东西。它们都由图像(png 和 jpg)表示。 我创建了一个大小为 800x600 的非全屏窗口,它工作正常,但是当我切换到全屏时...
好吧,所以我对 pyglet 和 OpenGL 来说都是个新手,我想知道为什么这不起作用: def DrawCircle(cx, cy, r, segments): theta = 2*3.14159
我正在尝试使用 Pyglet 通过 OpenGL 渲染图像。到目前为止,我已经能够设置帧缓冲区和纹理、渲染到其中并将其保存为 PNG 图像。但我不知道如何使用 Pyglets 字体渲染。 import
我是一名优秀的程序员,十分优秀!