Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

box around cursor pygame

Tags:

python

pygame

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.

like image 338
Jonathan Haar Avatar asked Apr 15 '18 12:04

Jonathan Haar


1 Answers

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

like image 191
Kingsley Avatar answered Oct 21 '22 16:10

Kingsley