Reputation: 2487
In Pygame, I have wrote a Minesweeper clone. However, when I blit the final image stating YOU LOSE or YOU WIN, I get this result:
I'm sure you notice the thick black line surrounding the text. Here is the function in which the image is blitted onto the window:
def play():
SIZE = (WIDTH, HEIGHT) = (16, 16)
MINES = 40
PIXELS_PER_CELL = 30
pygame.init()
screen = pygame.display.set_mode((WIDTH * PIXELS_PER_CELL,
HEIGHT * PIXELS_PER_CELL))
pygame.display.set_caption("PyMines")
board = create_board(SIZE, MINES)
board.draw(screen)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif (event.type == pygame.MOUSEBUTTONDOWN and board.is_playing and
not board.is_solved):
board.mouse_handler(event, screen)
message = None
if not board.is_playing:
board.show_mines(screen)
message = pygame.image.load("images/lose.png").convert_alpha()
elif board.is_solved:
message = pygame.image.load("images/win.png").convert_alpha()
if message:
message = pygame.transform.scale(message, (screen.get_width(),
screen.get_height() //
5))
screen.blit(message, (0, 0))
pygame.display.update()
As I am not sure which part of the code you should be looking at, here is the full code.
Another reason why I think this behaviour is so bizarre, is that when I first created PyMines, the image blitted perfectly like so (as you can see, there is a very slight shadow to the text):
This however, is not a optimized version, as after each cycle, the whole board is redrawn (so it takes a very long time on a 16x16 board as shown in the first image, so I used a 9x9 - but the results are the same). Here is the play()
function of the original version:
def play():
SIZE = (WIDTH, HEIGHT) = (9, 9)
MINES = 10
PIXELS_PER_CELL = 30
pygame.init()
screen = pygame.display.set_mode((WIDTH * PIXELS_PER_CELL,
HEIGHT * PIXELS_PER_CELL))
pygame.display.set_caption("PyMines")
board = create_board(SIZE, MINES)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif (event.type == pygame.MOUSEBUTTONDOWN and board.is_playing and
not board.is_solved):
board.mouse_handler(event, screen)
message = None
if not board.is_playing:
board.show_mines()
message = pygame.image.load("lose.png").convert_alpha()
elif board.is_solved:
message = pygame.image.load("win.png").convert_alpha()
board.draw(screen)
if message:
message = pygame.transform.scale(message, (screen.get_width(),
screen.get_height() //
5))
screen.blit(message, (0, 0))
pygame.display.update()
I would attach a link to the full code, but pastebin is down, so here is the full code for the original game without the strange black line.
EDIT: I have already tried dropping the convert_alpha()
and adding convert()
or even nothing at all.
.convert()
:
NOTHING:
Why are all these black lines there, how do I get rid of them and which version (convert
/convert_alpha
/NOTHING) should I use (and how to decide which one to use).
Upvotes: 3
Views: 432
Reputation: 19057
The text has a black shadow with an alpha channel. In your original version, you render the board, then render the text, and the shadow gets blended with the board.
In the revised version, you render the board, then repeatedly render the text over it. On the first pass, it renders correctly, with the shadow blending with the board. On the second pass, the shadow blends with the shadow you've already rendered, making a slightly darker shadow. On the next pass, the shadow gets slightly darker, and so on.
You can't use alpha blending without keeping tight control over what you're blending over. Each time you render the text, you'll need to render at least the section of the board behind the text, if not the full board.
Upvotes: 2