简体   繁体   中英

Mouse not drawing in pyglet

My custom mouse image is not showing up in pyglet. It loads normally(When you create the window outside a class), but when i make the window in a class and try yo add the custom mouse cursor nothing happens

class x:
    def __init__(self):
        self.game_window = pyglet.window.Window()
        self.on_mouse_press = self.game_window.event(self.on_mouse_press)

        self.game_cursor = pyglet.image.load('image.png')
        self.cursor = pyglet.window.ImageMouseCursor(self.game_cursor, 50, 70)
        self.game_window.set_mouse_cursor(self.cursor)

I have tried printing every one of the lines of code (for mouse image loading)

When i print - self.game_cursor = pyglet.image.load('image.png') - This is the result: ImageData 85x82

When i print - self.cursor = pyglet.window.ImageMouseCursor(self.game_cursor, 50, 70) - This is the result: pyglet.window.ImageMouseCursor object at 0x7f4dad76b390

When i print - self.game_window.set_mouse_cursor(self.cursor) - This is the result: None

How do I fix make the mouse show?

I strongly suggest you inherit the window class in to your class instead of keeping it as a internal value if possible. So you can use override hooks to replace the on_ functions. Perhaps this is an outdated approach, but for the time I've learned to work with these things - it's reommended.

class x(pyglet.window.Window):
    def __init__(self):
        super(x, self).__init__()
        self.game_cursor = pyglet.image.load('image.png')
        self.cursor = pyglet.window.ImageMouseCursor(self.game_cursor, 50, 70)
        self.set_mouse_cursor(self.cursor)

    def on_mouse_press():
        # Your code handling on_mouse_press

Here's a working example:

在此处输入图像描述

from pyglet import *
from pyglet.gl import *

key = pyglet.window.key

class main(pyglet.window.Window):
    def __init__ (self, width=800, height=600, fps=False, *args, **kwargs):
        super(main, self).__init__(width, height, *args, **kwargs)

        self.game_cursor = pyglet.image.load('image.png')
        self.cursor = pyglet.window.ImageMouseCursor(self.game_cursor, 50, 70)
        self.set_mouse_cursor(self.cursor)

        self.x, self.y = 0, 0

        self.keys = {}

        self.mouse_x = 0
        self.mouse_y = 0

        self.alive = 1

    def on_draw(self):
        self.render()

    def on_close(self):
        self.alive = 0

    def on_mouse_motion(self, x, y, dx, dy):
        self.mouse_x = x

    def on_key_release(self, symbol, modifiers):
        try:
            del self.keys[symbol]
        except:
            pass

    def on_key_press(self, symbol, modifiers):
        if symbol == key.ESCAPE: # [ESC]
            self.alive = 0

        self.keys[symbol] = True

    def render(self):
        self.clear()

        ## Add stuff you want to render here.
        ## Preferably in the form of a batch.

        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()

if __name__ == '__main__':
    x = main()
    x.run()

According to pyglet documentation for ImageMouseCursor class link method draw(x, y) is abstract. So I've tried sub-classing ImageMouseCursor and implementing draw method like this:

    import pyglet
    pyglet.resource.path = ['resources']
    pyglet.resource.reindex()

    # subclass definition
    class GameMouse(pyglet.window.ImageMouseCursor):
        # class initialization
        def __init__(self):
            self.game_cursor = pyglet.resource.image('game_cursor.png')
            super().__init__(self.game_cursor, 0, 34)
        # method override
        def draw(self, x, y):
            self.game_cursor.blit(x, y)

However, this will not work if gl blending is not enabled. gl blending is needed to display alpha channels. I've managed to enable it by sub-classing Window class, and using glEnable / glBlendFunc functions. This is the part of the code that does as described:

    # subclass definition: 
    class GameApp(pyglet.window.Window):
        # class initialization
        def __init__(self):
            super(GameApp, self).__init__()
            pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
            pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,
                                  pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)

Hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM