Erasing screen with button - python

#Imported Pygame
import pygame
#The Colors
BLACK = ( 0, 0, 0)
GREEN = ( 0, 255, 0)
WHITE = ( 255, 255, 255)
RED = ( 255, 0, 0)
ORANGE = ( 255, 115, 0)
YELLOW = ( 242, 255, 0)
BROWN = ( 115, 87, 39)
PURPLE = ( 298, 0, 247)
GRAY = ( 168, 168, 168)
PINK = ( 255, 0, 234)
pygame.init()
#The Screen
screen = pygame.display.set_mode([1000,500])
#Name of the window
pygame.display.set_caption("My first game")
clock = pygame.time.Clock()
#The sounds
# Positions of graphics
background_position = [0,0]
singleplayer_position = [350, 200]
tutorial_position = [350,300]
sorry_position = [0,0]
developer_position = [0,450]
rules_position = [0,0]
#The graphics
background_image = pygame.image.load("Castle.png").convert()
singleplayer_image = pygame.image.load("SinglePlayer.png").convert()
singleplayer_image.set_colorkey(WHITE)
tutorial_button = pygame.image.load("Tutorial_button.png").convert()
sorry_message = pygame.image.load("Sorry.png").convert()
sorry_message.set_colorkey(WHITE)
developer_message = pygame.image.load("Developer.png").convert()
developer_message.set_colorkey(WHITE)
Rules_image = pygame.image.load("Rules.png").convert()
#Main Loop __________________________
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Copy of background or main menu
screen.blit(background_image, background_position)
#Copy of other images
mouse_pos = pygame.mouse.get_pos()
my_rect = pygame.Rect(350,200,393,75)
tutorial_rect = pygame.Rect(350,300,393,75)
screen.blit(singleplayer_image, singleplayer_position)
screen.blit(tutorial_button, tutorial_position)
screen.blit(developer_message, developer_position)
if pygame.mouse.get_pressed()[0] and my_rect.collidepoint(mouse_pos):
screen.blit(sorry_message, sorry_position)
correct = False
if pygame.mouse.get_pressed()[0] and my_rect.collidepoint(mouse_pos):
#Here I make the screen fill white
if python.mouse.get_pressed()[0]tutorial_rect.collidepoint(mouse.pos):
correct = True
if correct == True:
screen.blit(Rules_image, rules_position)
pygame.display.flip()
clock.tick(60)
#To quit game
pygame.quit()
This is basically my code... When I hit the single player button I have it making the area white but it doesn't stay there. Like when I hit it once and hold the singleplayer button it stays white but when i unclick the screens back to what it was. Is there anyway I can just erase everything I did before and start a new screen when I hit the Singleplayer button?'
Ok back to the answer you gave me..
I structured my code like you said.
if pygame.mouse.get_pressed()[0] and my_rect.collidepoint(mouse_pos):
color_white = True
if color_white = True
screen.fill(WHITE)
This isn't working because It still doesn't make the screen stay white.
I tried this.
if pygame.mouse.get_pressed()[0] and my_rect.collidepoint(mouse_pos):
color_white = True
if color_white = True
screen.fill(WHITE)
This also doesn't seem to work because it keeps saying color_white is undefined.

Your confusion results from the while loop and how it behaves, so I'll explain that to answer your question.
Quick note: if you are not using a pygame clock object with tick at end of code, comment and I'll explain that at end, its important you do this.(http://www.pygame.org/docs/ref/time.html)
Okay, the problem: your picture is not remaining white after you click it. It stays white if you hold the mouse down, but it goes away once you lift up. I assume you want it to remain white even once you lift the mouse click.
Currently, your code colors the picture white inside of an if statement.
if pygame.mouse.get_pressed()[0] and my_rect.collidepoint(mouse_pos):
Review the docs on what .get_pressed() does. It returns True if the mouse button is pressed. So, when you click it, it says True, if you are holding it down, it says True. If you are not clicking or holding, its False. So it only colors it white when the mouse is clicked or held down, since thats when its told to do so. What makes it turn back to normal are your blits earlier in the loop. Each loop, pygame makes the image normal (via blit) and colors the picture white if your statement evaluates to True. This means whenever your if statement is False, the picture remains normal.
To make it remain painted white, use a boolean.
if pygame.mouse.get_pressed()[0] and my_rect.collidepoint(mouse_pos):
color_white = True
And then instead of putting the code to color the white inside the if statement that now sets the boolean to true, make a new if statement before your loop ends.
if color_white:
# Code to make the screen white.
This way, it can remain white even while not holding it down. If you want to make it back to normal with another click. You can expand your first if statement.
if pygame.mouse.get_pressed()[0] and my_rect.collidepoint(mouse_pos):
if color_white is True:
color_white = False
else:
color_white = True
Which can be coded in a shorter fashion...
color_white = False if color_white == True else True
Edit: I wrote the previous code considering events. This code would work if you were using the MOUSEBUTTONDOWN event to change the color. However, if you want to use get_pressed(), you'll have to use a different mouse button. If you only use left click, how should the program know whether to turn it off or on with so many loops going by?
I'll rewrite the code with get_pressed in mind.
if pygame.mouse.get_pressed()[0] and my_rect.collidepoint(mouse_pos):
color_white = True
if pygame.mouse.get_pressed()[1] and my_rect.collidepoint(mouse_pos): # Not sure if it should be 1 or 2 in get_pressed, but I'm assuming they represent the right click and middle mouse button. So you can use these to turn the screen back to normal.
color_white = False
Edit2: Your color_white is undefined, because it doesn't get defined until after the if statements in your code. So before you get a chance to click (and define it), a loop runs and gets to
if color_white:
But color_white doesn't exist to the computer yet. To solve, define color_white before your while loop.
color_white = False # Default to not color the screen white.

Related

Why does my Pygame label not show up even though I copied from my other one that worked?

I am making a Pygame game and I have a label that every time you lose it should make the screen black and say GAME OVER. This is my code and the Label won't show up even though I copied it from my other label code and just changed it to label2. What is wrong?
if self.rect.colliderect(obstacle2.rect) or self.rect.colliderect(obstacle1.rect):
obstacle2.kill()
obstacle1.kill()
player.kill()
screenColor = BLACK
default_font2 = pygame.font.get_default_font()
font_renderer2 = pygame.font.Font(default_font2, 100)
label2 = font_renderer2.render('GAME OVER', True, WHITE)
label2_rect = label2.get_rect()
label2_rect.center = screen_rect.center
screen.blit(label2, label2_rect)
You need to draw the label in the application loop. The condition self.rect.colliderect(obstacle2.rect) or self.rect.colliderect(obstacle1.rect) is just fulfilled in a single frame. Hence the label is just visible for a single frame and not noticeable.
Before the application loop, add a game_over variable:
game_over = False
Set the variable when the collision is detected:
if self.rect.colliderect(obstacle2.rect) or self.rect.colliderect(obstacle1.rect):
obstacle2.kill()
obstacle1.kill()
player.kill()
screenColor = BLACK
# [...]
game_over = True
Draw the text in the application loop depending on game_over:
# application loop
while True:
# [...]
if game_over
# [...]
screen.blit(label2, label2_rect)
pygame.display.update()

Redrawing image isn't working?

So, i have a pygame.circle that i would like to move. I have it moving etc, but it just duplicated the image and doesn't remove the previous. I understand the concept of "Blit" and understand it copies an array of pixels over. So i thought i would try redrawing my whole game, here's what i have:
if event.type == pygame.KEYDOWN and event.key == pygame.K_a:
diceRoll = random.randint(1, 4)
diceRollLabel = myFont.render(str(diceRoll), 1, black)
window.blit(diceRollLabel, (750, 40))
window.fill(black)
game()
count1 = pygame.draw.circle(window, (black),(150, countY - 72 * diceRoll), 25, 0)
game = False
game2 = True
print("Test")
player1Text = myFont.render(("Player twos turn!"), 1, black)
window.blit(player1Text, (650, 750))
pygame.display.update()
break
When it calls "game()" it should recall the function that contains all of the game screen, so the texture etc. but for some reason, it doesn't do anything? The screen just goes black?
it says "Bool object not callable" but my function isn't a boolean?
Fill the screen at the start of the loop.
def draw():
screen.fill(Color('black'))
# draw
pygame.display.flip()
You've set game as a Boolean
game = False
So when you call "game()" it's the same as "False()" which is the reason for your error.
You also fill the screen black after blitting the diceRollLabel (in black), and you then seem to draw a black circle on a black screen.
Full code would be helpful.

Inserting text into pygame upon key input

When I run the program everything works except when I press the s key the text is not printed to the screen, here is the part of my code which is not working:
elif event.key == K_s:
fontObj = pygame.font.Font("freesansbold.ttf", 32)
textSurfaceObj = fontObj.render("Roar!!!", True, WHITE)
textRectObj = textSurfaceObj.get_rect()
textRectObj.center = (200,100)
DISPLAYSURF.blit(textSurfaceObj,textRectObj)
DISPLAYSURF.fill(GREEN)
DISPLAYSURF.blit(LionCubImg,(LionCubX,LionCubY))
pygame.display.update()
You're filling the Surface with green after you just printed some text to it, thus covering up the text you just added to the Surface.
Order matters when drawing on Surfaces in Pygame.

Why does my image have a thick black line around?

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

How do I display text in a grid-like structure in Pygame?

I'm new to pygame and currently I'm working on creating a memory game where the computer displays boxes at random positions for like a second and then the user has to click on where he/she thinks those boxes are. It's kind of like this game:
However I'm not really sure how to make the computer display the boxes with like a letter or symbol e.g. 'T' or '%'. (I've already made the grid).
Could anyone please help? It would be really appreciated.
import pygame
size=[500,500]
pygame.init()
screen=pygame.display.set_mode(size)
# Colours
LIME = (0,255,0)
RED = (255, 0, 0)
BLACK = (0,0,0)
PINK = (255,102,178)
SALMON = (255,192,203)
WHITE = (255,255,255)
LIGHT_PINK = (255, 181, 197)
SKY_BLUE = (176, 226, 255)
screen.fill(BLACK)
# Width and Height of game box
width=50
height=50
# Margin between each cell
margin = 5
# Create a 2 dimensional array. A two dimesional
# array is simply a list of lists.
grid=[]
for row in range(20):
# Add an empty array that will hold each cell
# in this row
grid.append([])
for column in range(20):
grid[row].append(0) # Append a cell
# Set row 1, cell 5 to one. (Remember rows and
# column numbers start at zero.)
grid[1][5] = 1
# Set title of screen
pygame.display.set_caption("Spatial Recall")
#Loop until the user clicks the close button.
done=False
# Used to manage how fast the screen updates
clock=pygame.time.Clock()
# -------- Main Program Loop -----------
while done==False:
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
if event.type == pygame.MOUSEBUTTONDOWN:
# User clicks the mouse. Get the position
pos = pygame.mouse.get_pos()
# Change the x/y screen coordinates to grid coordinates
column=pos[0] // (width+margin)
row=pos[1] // (height+margin)
# Sete t hat location to zero
grid[row][column]=1
print("Click ",pos,"Grid coordinates: ",row,column)
# Draw the grid
for row in range(10):
for column in range(10):
color = LIGHT_PINK
if grid[row][column] == 1:
color = RED
pygame.draw.rect(screen,color,[(margin+width)*column+margin,(margin+height)*row+margin,width,height])
# Limit to 20 frames per second
clock.tick(20)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
pygame.quit ()
In order to display text, you have to go through a series of steps. First you will want to get a font by using the command `pygame.font.Font(font name, size). For example:
arialfont=pygame.font.Font('arial', 12)
All available fonts can be gotten from the command pygame.font.get_fonts(). Remember to initialize pygame (pygame.init()) before any of this.
Next, you will have to use the Font.render(text, antialias, color, background=None). For example:
text=arialfont.render('Hello World!', True, (0, 0, 0))
This will return a surface. You can use it just like you would any other surface. Use text.get_rect() to get its rect, then reposition the rect to put it where you want it to be, and blit it to the window. If you don't know anything about surface objects, just ask me.
Here is a working code.
import pygame, sys
pygame.init()#never forget this line
window=pygame.display.set_mode((100, 100))
font=pygame.font.SysFont('arial', 40)
text=font.render('#', True, (0, 0, 0))
rect=text.get_rect()
window.fill((255, 255, 255))
window.blit(text, rect)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
sys.exit()

Categories

Resources