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.
问题:
回答1:
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:
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:
回答2:
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()