Pyglet 中的 Sprite 没有做我想做的事
Sprite in Pyglet not doing what I want
我正在尝试创建一个圆圈,当单击该圆圈时,它会移动到屏幕上的其他位置。但是,当我点击圆圈时,没有任何反应。
#IMPORT STUFF
import pyglet as pg
from random import randint
mouse = pg.window.mouse
#VARS
window = pg.window.Window(width = 640, height = 480)
score = 0
circleImg = pg.image.load("circle.png")
circle = pg.sprite.Sprite(circleImg, randint(1, window.width), randint(1, window.height))
text = pg.text.Label("Click red!", font_name = "Times New Roman", font_size = 18, x = 260, y = 10)
#DETECT MOUSE PRESS ON CIRCLE
@window.event
def on_mouse_press(x, y, button, modifiers):
if x == circle.x and y == circle.y:
circle.x = randint(1, window.width)
circle.y = randint(1, window.height)
@window.event
def on_draw():
window.clear()
text.draw()
circle.draw()
pg.app.run()
我不熟悉 pyglet,但我猜问题是你正在检查是否 x == circle.x
等,这意味着它只有在你单击正中心的单个像素时才会移动圈子。尝试与中心的某种最大距离(例如斜边 math.sqrt( (x-circle.x)**2 + (y-circle.y)**2) < circle.radius
import pyglet
from pyglet.gl import *
from random import randint
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
class Circle(pyglet.sprite.Sprite):
def __init__(self, radiance=5, x=0, y=0):
self.texture = pyglet.image.load('circle.png')
super(Circle, self).__init__(self.texture)
def click(self, x, y):
if x >= self.x and y >= self.y:
if x <= self.x + self.texture.width and y <= self.y + self.texture.height:
return self
mouse = pyglet.window.mouse
#VARS
window = pyglet.window.Window(width = 640, height = 480)
score = 0
#circleImg = pyglet.image.load("circle.png")
#circle = pyglet.sprite.Sprite(circleImg, randint(1, window.width), randint(1, window.height))
circle = Circle(x=50, y=50)
text = pyglet.text.Label("Click red!", font_name = "Times New Roman", font_size = 18, x = 260, y = 10)
#DETECT MOUSE PRESS ON CIRCLE
@window.event
def on_mouse_press(x, y, button, modifiers):
if circle.click(x, y):
print('Clicked in circle')
circle.x = randint(0, window.width - 10)
circle.y = randint(0, window.height - 10)
@window.event
def on_draw():
window.clear()
text.draw()
circle.draw()
pyglet.app.run()
对其作用的简短描述是它创建了一个名为 Circle
的自定义 class,它继承了 Sprite
class。它将 circle.png
作为纹理加载,并带有由 GL 库混合的 alpha 通道。
我们添加一个名为 click
的自定义函数,用于检查最低 x,y
坐标是否高于圆圈最低 x,y
,然后我们检查光标是否低于 [=18] =] 和图像区域的 y
相同。
如果是这样,我们 return 圆形精灵 class 作为 True
值,以防我们想要使用精灵。
未来的改进:
您应该使用 gl functions 绘制圆,因此我在 class 定义中定义了 radiance
。然而,此处的 radiance 从未使用过,它是未来的占位符。
这样一来,如果您确实在圆圈内单击,就可以使用数学来定义,但这超出了我快速回答的范围。我必须自己进行大量调试才能使数学相加(这不是我坚强的一面)。
现在它起作用的原因是我们使用图像宽度、高度、x 和 y 数据来粗略地检查我们是否在图像内,也就是 "the circle"。
作为奖励,我会将此答案添加到增强列表中,因为它包含一些可能有用的内容。一种是用自定义 pyglet.window.Window
class 替换 90% 的代码,以替换全局变量和装饰器等。
它看起来像这样:
import pyglet
from pyglet.gl import *
from random import randint
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
key = pyglet.window.key
class Circle(pyglet.sprite.Sprite):
def __init__(self, radiance=5, x=0, y=0):
self.texture = pyglet.image.load('circle.png')
super(Circle, self).__init__(self.texture)
def click(self, x, y):
if x >= self.x and y >= self.y:
if x <= self.x + self.texture.width and y <= self.y + self.texture.height:
return self
class MainScreen(pyglet.window.Window):
def __init__ (self):
super(MainScreen, self).__init__(800, 600, fullscreen = False)
self.x, self.y = 0, 0
self.bg = pyglet.sprite.Sprite(pyglet.image.load('background.jpg'))
self.sprites = {}
self.sprites['circle'] = Circle(x=50, y=50)
self.sprites['label'] = pyglet.text.Label("Click red!", font_name = "Times New Roman", font_size = 18, x = 260, y = 10)
self.alive = 1
def on_draw(self):
self.render()
def on_close(self):
self.alive = 0
def on_mouse_press(self, x, y, button, modifiers):
if self.sprites['circle'].click(x, y):
print('Clicked in circle')
self.sprites['circle'].x = randint(0, self.width - 10)
self.sprites['circle'].y = randint(0, self.height - 10)
def on_key_press(self, symbol, modifiers):
if symbol == key.ESCAPE: # [ESC]
self.alive = 0
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()
我正在尝试创建一个圆圈,当单击该圆圈时,它会移动到屏幕上的其他位置。但是,当我点击圆圈时,没有任何反应。
#IMPORT STUFF
import pyglet as pg
from random import randint
mouse = pg.window.mouse
#VARS
window = pg.window.Window(width = 640, height = 480)
score = 0
circleImg = pg.image.load("circle.png")
circle = pg.sprite.Sprite(circleImg, randint(1, window.width), randint(1, window.height))
text = pg.text.Label("Click red!", font_name = "Times New Roman", font_size = 18, x = 260, y = 10)
#DETECT MOUSE PRESS ON CIRCLE
@window.event
def on_mouse_press(x, y, button, modifiers):
if x == circle.x and y == circle.y:
circle.x = randint(1, window.width)
circle.y = randint(1, window.height)
@window.event
def on_draw():
window.clear()
text.draw()
circle.draw()
pg.app.run()
我不熟悉 pyglet,但我猜问题是你正在检查是否 x == circle.x
等,这意味着它只有在你单击正中心的单个像素时才会移动圈子。尝试与中心的某种最大距离(例如斜边 math.sqrt( (x-circle.x)**2 + (y-circle.y)**2) < circle.radius
import pyglet
from pyglet.gl import *
from random import randint
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
class Circle(pyglet.sprite.Sprite):
def __init__(self, radiance=5, x=0, y=0):
self.texture = pyglet.image.load('circle.png')
super(Circle, self).__init__(self.texture)
def click(self, x, y):
if x >= self.x and y >= self.y:
if x <= self.x + self.texture.width and y <= self.y + self.texture.height:
return self
mouse = pyglet.window.mouse
#VARS
window = pyglet.window.Window(width = 640, height = 480)
score = 0
#circleImg = pyglet.image.load("circle.png")
#circle = pyglet.sprite.Sprite(circleImg, randint(1, window.width), randint(1, window.height))
circle = Circle(x=50, y=50)
text = pyglet.text.Label("Click red!", font_name = "Times New Roman", font_size = 18, x = 260, y = 10)
#DETECT MOUSE PRESS ON CIRCLE
@window.event
def on_mouse_press(x, y, button, modifiers):
if circle.click(x, y):
print('Clicked in circle')
circle.x = randint(0, window.width - 10)
circle.y = randint(0, window.height - 10)
@window.event
def on_draw():
window.clear()
text.draw()
circle.draw()
pyglet.app.run()
对其作用的简短描述是它创建了一个名为 Circle
的自定义 class,它继承了 Sprite
class。它将 circle.png
作为纹理加载,并带有由 GL 库混合的 alpha 通道。
我们添加一个名为 click
的自定义函数,用于检查最低 x,y
坐标是否高于圆圈最低 x,y
,然后我们检查光标是否低于 [=18] =] 和图像区域的 y
相同。
如果是这样,我们 return 圆形精灵 class 作为 True
值,以防我们想要使用精灵。
未来的改进:
您应该使用 gl functions 绘制圆,因此我在 class 定义中定义了 radiance
。然而,此处的 radiance 从未使用过,它是未来的占位符。
这样一来,如果您确实在圆圈内单击,就可以使用数学来定义,但这超出了我快速回答的范围。我必须自己进行大量调试才能使数学相加(这不是我坚强的一面)。
现在它起作用的原因是我们使用图像宽度、高度、x 和 y 数据来粗略地检查我们是否在图像内,也就是 "the circle"。
作为奖励,我会将此答案添加到增强列表中,因为它包含一些可能有用的内容。一种是用自定义 pyglet.window.Window
class 替换 90% 的代码,以替换全局变量和装饰器等。
它看起来像这样:
import pyglet
from pyglet.gl import *
from random import randint
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
key = pyglet.window.key
class Circle(pyglet.sprite.Sprite):
def __init__(self, radiance=5, x=0, y=0):
self.texture = pyglet.image.load('circle.png')
super(Circle, self).__init__(self.texture)
def click(self, x, y):
if x >= self.x and y >= self.y:
if x <= self.x + self.texture.width and y <= self.y + self.texture.height:
return self
class MainScreen(pyglet.window.Window):
def __init__ (self):
super(MainScreen, self).__init__(800, 600, fullscreen = False)
self.x, self.y = 0, 0
self.bg = pyglet.sprite.Sprite(pyglet.image.load('background.jpg'))
self.sprites = {}
self.sprites['circle'] = Circle(x=50, y=50)
self.sprites['label'] = pyglet.text.Label("Click red!", font_name = "Times New Roman", font_size = 18, x = 260, y = 10)
self.alive = 1
def on_draw(self):
self.render()
def on_close(self):
self.alive = 0
def on_mouse_press(self, x, y, button, modifiers):
if self.sprites['circle'].click(x, y):
print('Clicked in circle')
self.sprites['circle'].x = randint(0, self.width - 10)
self.sprites['circle'].y = randint(0, self.height - 10)
def on_key_press(self, symbol, modifiers):
if symbol == key.ESCAPE: # [ESC]
self.alive = 0
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()