我如何得到glsl着色器与pymunk物理引擎和相机工作?



以下是我对这个问题的观察:

  • 小行星游戏为发光球武器使用了绘制的纹理精灵。这是在GlowBall类中完成的。武器7使用绘制图像
  • 绘制的精灵是用bullet_list.draw(),但子弹的着色器:在bullet_list: bullet.draw()。
  • 精灵正在被正确绘制,但是着色器没有。
  • 着色器似乎随着船移动,但速度更快。几乎就像被吸引到一个更大的区域。

What I tried:

  • 使用玩家位置减去摄像机位置,这是我
    所做的,使绘制的图像停留在玩家上-在
    船的顶部绘制炮塔。
  • 尝试制作第二个版本的Shadertoy.py,以便我可以使用
  • 用screen_rectangle代替quad_2d_fs。如果我使用pymunk物理引擎,它可以加速着色器,但是使其以上述方式绘制。我如何使用相机与着色器类以及pymunk物理引擎来创建等离子子弹和爆炸?

这些类来自街机示例:https://github.com/pythonarcade/asteroids我正在使用一个边距滚动从例子:https://api.arcade.academy/en/latest/examples/sprite_move_scrolling_box.html#sprite-move-scrolling-box"

class GlowBullet(arcade.Sprite):
def __init__(self, image_file=None, scale=1.0, shadertoy=None, player_no=1):
super().__init__(image_file, scale)
self.type = None
self.shadertoy = shadertoy
self.player_no = player_no
def draw(self):
pass
class GlowBall(GlowBullet):
def __init__(self, shadertoy, glowcolor, radius):
super().__init__(shadertoy=shadertoy)
self.type = None
self.shadertoy = shadertoy
self.glowcolor = glowcolor
self.texture = arcade.make_circle_texture(radius * 2, glowcolor)
self._points = self.texture.hit_box_points
def draw(self):
self.shadertoy.program['pos'] = self.position
self.shadertoy.program['color'] = arcade.get_three_float_color(self.glowcolor)
self.shadertoy.render()

"…在GameView类中:

"

class GameView(arcade.View):
def __init__(self):
super().__init__()
self.glowball_shadertoy = Shadertoy.create_from_file(self.window.get_size(), GLOW_BALL_IMAGE)
def player_blaster(self,x,y,blaster_filename):
self.click_x = self.world_mouse_x 
self.click_y = self.world_mouse_y
r,diff_angle = self.cart_to_polar([self.player.center_x,self.player.center_y],[self.world_mouse_x,self.world_mouse_y])
bullet_sprite = GlowBall(glowcolor=bullet_color,
radius=5,
shadertoy=self.glowball_shadertoy)
glow_bullet = GlowBullet(glowcolor=(1000, 1000, 1000),radius=7,shadertoy=self.glowball_shadertoy)
player_size = max(self.player.width, self.player.height) / 2
bullet_size = max(bullet.width, bullet.height) / 2
glow_bullet_size = bullet_size
radius_start = player_size + bullet_size
glow_radius_start = 0      
glow_bullet_x,glow_bullet_y = self.polar_to_cart(glow_radius_start,diff_angle,[self.player.center_x-self.camera_gui.position[0],self.player.center_y-self.camera_gui.position[1]])  
glow_bullet_x,glow_bullet_y = self.polar_to_cart(glow_radius_start,diff_angle,[self.player.center_x,self.player.center_y])
glow_bullet.center_x=glow_bullet_x
glow_bullet.center_y=glow_bullet_y
glow_bullet.angle=math.degrees(diff_angle) - 90
bullet.damage = self.player.damage_attack
self.bullet_list.append(bullet)
self.glow_bullet_list.append(glow_bullet)
angle = math.pi/2
bullet_force_x = PLASMA_FORCE_1 * math.cos(angle)
bullet_force_y = PLASMA_FORCE_1 * math.sin(angle)       
self.physics_engine.add_sprite(glow_bullet,
mass=0.01,
damping=1,
friction=0.01,
moment_of_intertia=100000,
elasticity=0.9)
self.physics_engine.apply_force(glow_bullet, (bullet_force_x,bullet_force_y)) 
def on_draw(self):
""" Draw everything """
self.clear()
# This controlls the GLSL shader
for bullet in self.glow_bullet_list:
bullet.draw()
# This draws the sprite
self.glow_bullet_list.draw()

"

您是否在HiDPI环境中运行它?

如果是这样,你应该使用shader类与适当的帧缓冲区大小。非window.get_size()

,

shader = ShaderToy(window.get_framebuffer_size())
render_scale = window.get_framebuffer_size()[0] / window.size[0]
shader.program['pos'] = position * render_scale

最新更新