box around cursor pygame

2019-06-18 06:40发布

In the little games I made in pygame there's always a box around my cursor in which all colours are reversed (e.g. if I hold my cursor over a black and red background the square around the cursor will be white and cyan). This initially wasn't a problem, since the first few projects only required keyboard inputs, but now I want to make a game where you have to click a lot, so it would look very ugly. How do I remove this box? I am using macOS High Sierra, python3 and pygame 1.9.3.

标签: python pygame
2条回答
祖国的老花朵
2楼-- · 2019-06-18 07:22

I'm putting this as an answer, because it's too much for a comment. Also, I don't have a Mac, so this answer is supposition.

Looking at the github issue @Keno posted:
bad cursor

There's an image of a white cursor (black filled outline), on a black background.

It looks to me, that with the latest OS upgrade, MacOS is no longer working correctly with whatever mouse-cursor-image functions PyGame is using. Obviously the pixels outside the cursor should be transparent.

Anecdotal evidence (i.e.: a google search) suggests that other software has cursor issues with macOS High Sierra too.

Maybe it's possible to work around the problem.

If the PyGame application is not using the mouse, it may be useful to just hide the cursor.

 pygame.mouse.set_visible()  # Perhaps this just gives a black-box though

However if PyGame is "hiding" the mouse by setting a fully-transparent cursor, the result may still be a completely black square. So the mouse can be moved outside the window (or at least to the bottom-right corner):

w, h = pygame.display.get_surface().get_size() # get window size
pygame.mouse.set_pos( [w, h] )  # move cursor outside window

I got a bit carried away with this problem, and ended up writing a bunch of test cases.

import sys
import time
import pygame
from pygame.locals import *

WHITE = 255,255,255
BLUE  = 0,0,60

WINDOW_WIDTH=600
WINDOW_HEIGHT=500

pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.font.init()
clock = pygame.time.Clock()
text_font = pygame.font.Font(None,60)

STARTUP_MS = int(time.time() * 1000.0)  # Epoch time programme started
MANUAL_CURSOR = pygame.image.load('finger_cursor_16.png').convert_alpha()

cursor_test    = 0
time_last_test = 0

while (True):
    NOW_MS = int(time.time() * 1000.0) - STARTUP_MS  # current time in milliseconds-since-start

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    # Try different cursor styles
    if ( cursor_test == 4 ):
        text_image  = text_font.render( 'Off-Screen-Cursor', True, WHITE )
        pygame.mouse.set_pos( [ WINDOW_WIDTH, WINDOW_HEIGHT ])
        pygame.mouse.set_visible(True)

    elif ( cursor_test == 3 ):
        text_image  = text_font.render( 'Manual-Cursor', True, WHITE )
        pygame.mouse.set_visible(False)
        # cursor drawn as part of the screen, see below

    elif ( cursor_test == 2 ):
        text_image  = text_font.render( 'Transparent-Cursor', True, WHITE )
        pygame.mouse.set_cursor((8,8),(0,0),(0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0))
        pygame.mouse.set_visible(True)

    elif ( cursor_test == 1 ):
        text_image  = text_font.render( 'Hidden-Cursor', True, WHITE )
        pygame.mouse.set_visible(False)

    elif ( cursor_test == 0 ):
        text_image  = text_font.render( 'Default-Arrow-Cursor', True, WHITE )
        pygame.mouse.set_visible(True)
        pygame.mouse.set_cursor(*pygame.cursors.arrow)

    # test for 3-seconds each
    if ( NOW_MS - time_last_test > 3000 ):
        pygame.mouse.set_pos( [ WINDOW_WIDTH//2, WINDOW_HEIGHT//2 ])
        time_last_test = NOW_MS
        cursor_test += 1
        if ( cursor_test > 4 ):
            cursor_test = 0

    # Paint the screen
    screen.fill(BLUE)
    # Write the mode
    screen.blit(text_image, ( 0, 0 ))
    # if we're in manual-cursor mode, paint a cursor too
    if (cursor_test == 3):
        screen.blit( MANUAL_CURSOR, ( pygame.mouse.get_pos() ) )

    pygame.display.update()
    clock.tick_busy_loop(60)

EDIT: I forgot to upload the finger_cursor_16.png image:

finger_cursor_16.png

查看更多
劳资没心,怎么记你
3楼-- · 2019-06-18 07:28

Just adding to @Kingsley answer without the tests and out of window cursor detection, still super hacky and probably more trouble than it's worth but might help you while there's a fix.

import sys, pygame, os
from pygame.locals import *

def main():
    pygame.init()
    screen = pygame.display.set_mode((600,600))
    screen.fill((100, 100, 100))

    # http://tobiasahlin.com/blog/common-mac-os-x-lion-cursors/
    custom_cursor = pygame.image.load(os.path.join('yourPath', 'pointer.png')).convert_alpha()      

    # MAIN LOOP:
    while True:
        # EVENTS :
        for event in pygame.event.get():
            if event.type == pygame.QUIT: sys.exit()
             # Press Q to quit
            elif event.type == KEYDOWN and event.key == K_q:
                sys.exit()

        pygame.mouse.set_visible(False)
        screen.fill((100,100,100))
        if pygame.mouse.get_focused():
            screen.blit( custom_cursor, ( pygame.mouse.get_pos() ) )
        pygame.display.flip()


if __name__ == '__main__': main()

enter image description here

查看更多
登录 后发表回答