I am trying to make a rectangle pop up when middle click is pressed, and stay popped up until I press left click in pygame.
Here is my code:
button1, button2, button3 = pygame.mouse.get_pressed()
if button2 == True:
pygame.draw.rect(screen, ((255, 0, 0)), (0, int(h/2), int(w/6), int(h/2)-40), 0)
pygame.display.update()
The thing is, when I press middle click, the rectangle appears, then disappears instantly.
I have tried putting it as while button2 == 2:, but the program hangs.
Thank you!!
Since you want to react to different mousebutton clicks, it's better to listen for the MOUSEBUTTONUP (or MOUSEBUTTONDOWN) events instead of using pygame.mouse.get_pressed().
You want to change the state of your application when a mousebutton is pressed, so you have to keep track of that state. In this case, a single variable will do.
Here's a minimal complete example:
import pygame, sys
pygame.init()
screen = pygame.display.set_mode((300, 300))
draw_rect = False
rect = pygame.rect.Rect((100, 100, 50, 50))
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
sys.exit()
if e.type == pygame.MOUSEBUTTONUP:
if e.button == 2:
draw_rect = True
elif e.button == 1:
draw_rect = False
screen.fill((255, 255, 255))
if draw_rect:
pygame.draw.rect(screen, (0, 0, 0), rect, 2)
pygame.display.flip()
Change
button1, button2, button3 = pygame.mouse.get_pressed()
if button2 == True:
pygame.draw.rect(screen, ((255, 0, 0)), (0, int(h/2), int(w/6), int(h/2)-40), 0)
pygame.display.update()
to
button1, button2, button3 = pygame.mouse.get_pressed()
if button2 == True:
rect_blit=True
pygame.display.update()
then have
if rect_blit==True:
pygame.draw.rect(screen, ((255, 0, 0)), (0, int(h/2), int(w/6), int(h/2)-40), 0)
somewhere in your main loop (before pygame.display.update).
Another thing is that you do not need to say if some_variable == True:. Instead you can just say if some_variable:. They do the exact same thing.
Related
I an having an error with MOUSEBUTTONDOWN giving an error when used.
Here is the error:
if event.type == MOUSEBUTTONDOWN:
NameError: name 'MOUSEBUTTONDOWN' is not defined
Here is the code that is giving the error:
import pygame
import random
import sys
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
pygame.init()
# Set the width and height of the screen [width, height]
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("game")
# 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 not done:
# --- Main event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# --- Game logic should go here
# --- Screen-clearing code goes here
# Here, we clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
# If you want a background image, replace this clear with blit'ing the
# background image.
screen.fill(WHITE)
# --- Drawing code should go here
monospace = pygame.font.SysFont("Berlin Sans FB", 169)
label = monospace.render("test", 1, (0, 0, 0))
screen.blit(label, (100, 100))
button_rect = pygame.Rect(0, 0, 50, 50) # start button rectangle
abort = False
start = False
while not abort and not start:
for event in pygame.event.get():
if event.type == pygame.QUIT:
abort = True
if event.type == MOUSEBUTTONDOWN:
if button_rect.collidepoint(event.pos):
start = True
# draw title screen
# [...]
done = abort
while not done:
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# --- Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# --- Limit to 60 frames per second
clock.tick(60)
# Close the window and quit.
pygame.quit()
All the other sources on Stack Overflow about this topic that I can find all talk about errors where MOUSEBUTTONDOWN already works.
Also note that I am using Pycharm.
Either pygame.MOUSEBUTTONDOWN instead of MOUSEBUTTONDOWN or from pygame.locals import *
You need only one application loop:
import pygame
from pygame.locals import *
import random
import sys
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
pygame.init()
# Set the width and height of the screen [width, height]
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("game")
clock = pygame.time.Clock()
monospace = pygame.font.SysFont("Berlin Sans FB", 169)
label = monospace.render("test", 1, (0, 0, 0))
button_rect = pygame.Rect(0, 0, 50, 50) # start button rectangle
abort = False
start = False
while not abort:
for event in pygame.event.get():
if event.type == pygame.QUIT:
abort = True
if event.type == MOUSEBUTTONDOWN:
if not start and button_rect.collidepoint(event.pos):
start = True
screen.fill(WHITE)
if not start:
# draw title screen
pygame.draw.rect(screen, "red", button_rect)
else:
# draw game
# [...]
screen.blit(label, (100, 100))
pygame.display.flip()
clock.tick(60)
pygame.quit()
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()
Solution found:
I did not have the needed libraries imported:
For MOUSEBUTTONDOWN to work you need to use:
from pygame.locals import *
Credit to #Rabbid76 for answering in comments.
I'm having issues integrating working buttons into this code. The buttons have been defined and show within pygame but I don't know where to go next. I've attempted to add mouse and click functions but I really don't know where they would be best located or how to use their functions
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
BLACK = (0, 0, 0)
BACKGROUND = (200, 230, 234)
WHITE = (255, 255, 255)
HOVER_COLOUR = (50, 70, 90)
# Text Variables
FONT = pygame.font.SysFont ("Times New Norman", 60)
TEXT = FONT.render ("", True, WHITE)
background_images = pygame.image.load("background.jpg").convert()
screen.blit(background_images, [0,0])
screen.blit(TEXT, (150, 50))
# Text & Rectangles construction
text1 = FONT.render("PlAY", True, WHITE)
text2 = FONT.render("CONTROLS", True, WHITE)
text3 = FONT.render("DIFFICULTY", True, WHITE)
text4 = FONT.render("SCOREBOARD", True, WHITE)
rect1 = pygame.Rect(250,200,300,80)
rect2 = pygame.Rect(250,300,300,80)
rect3 = pygame.Rect(250,400,300,80)
rect4 = pygame.Rect(250,500,300,80)
# The button construction arry. Text and Rectangle
buttons = [
[text1, rect1, BACKGROUND],
[text2, rect2, BACKGROUND],
[text3, rect3, BACKGROUND],
[text4, rect4, BACKGROUND],
]
def game_intro():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.MOUSEMOTION:
for button in buttons:
# Uses collisionpoint to detect mouse position collisions
if button[1].collidepoint(event.pos):
# Set the button's colour to the hover colour.
button[2] = HOVER_COLOUR
else:
# resets the colour to normal.
button[2] = BACKGROUND
# Draws the buttons with their current colours (normal & collisions)
for text, rect, colour in buttons:
pygame.draw.rect(screen, colour, rect)
screen.blit(text, rect)
pygame.display.flip()
clock.tick(15)
#Run Game
game_intro()
scene_change()
pygame.quit()
When integrating this:
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
The program kicks out an error about the mouse position function
Add ids to your buttons:
buttons = [
[text1, rect1, BACKGROUND, 1],
[text2, rect2, BACKGROUND, 2],
[text3, rect3, BACKGROUND, 3],
[text4, rect4, BACKGROUND, 4]
]
Add a function which handles a button event:
def on_button(button):
print(button[3])
Call the function when the button is pressed:
def game_intro():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.MOUSEMOTION:
for button in buttons:
# Uses collisionpoint to detect mouse position collisions
if button[1].collidepoint(event.pos):
# Set the button's colour to the hover colour.
button[2] = HOVER_COLOUR
else:
# resets the colour to normal.
button[2] = BACKGROUND
elif event.type == pygame.MOUSEBUTTONDOWN:
for button in buttons:
# Uses collisionpoint to detect mouse position collisions
if button[1].collidepoint(event.pos):
on_button(button)
# Draws the buttons with their current colours (normal & collisions)
for text, rect, colour, button_id in buttons:
pygame.draw.rect(screen, colour, rect)
screen.blit(text, rect)
pygame.display.flip()
clock.tick(15)
So I'm writing this code for a school assignment, which I'm supposed to use pygame and display some text. I put those text in different pages, and if single click the screen, it will show the next screen.
Here is what I have so far:
import pygame
pygame.init()
pygame.font.init()
# defining the screen
SIZE = (1000, 700)
screen = pygame.display.set_mode(SIZE)
# define time
clock = pygame.time.Clock()
#define button
button = 0
# define font
fontIntro = pygame.font.SysFont("Times New Roman",30)
# define draw scene
def drawIntro(screen):
#start
if button > 0:
screen.fill((0, 0, 0))
text = fontIntro.render("Sigle click to start", 1, (255,255,255))
screen.blit(text, (300, 300, 500, 500))
pygame.display.flip()
#page1
if button == 1:
screen.fill((0, 0, 0))
text = fontIntro.render("page 1", True, (255, 255, 255))
pygame.display.flip()
#page2
if button == 1:
screen.fill((0, 0, 0))
text = fontIntro.render("page 2", True, (255, 255, 255))
screen.blit(text, (300,220,500,200))
pygame.display.flip()
#page3
if button == 1:
screen.fill((0, 0, 0))
text = fontIntro.render("page3", True, (255, 255, 255))
screen.blit(text, (200,190,500,200))
pygame.display.flip()
running = True
while running:
for evnt in pygame.event.get():
if evnt.type == pygame.QUIT:
running = False
if evnt.type == pygame.MOUSEMOTION:
mx,my = evnt.pos
print(evnt.pos)
drawIntro(screen)
pygame.quit()
Though it is not working, can someone please help?! Thanks!
You define button = 0 at the beginning, but never change its value in your main loop. In your drawIntro function, you check if button > 0 or if button == 1
So obviously you never execute any of those if statements.
You need to catch the mouse button by calling pygame.mouse.get_pressed() and figure how to switch correctly to the next page.
By the way, you also have if button == 1 three times, which is not what you want I guess, because the if statements will be immediately executed as they are written, so your page 3 will be shown immediately. You need some counter to keep track of which page you need to show next time the mouse button is pressed.
You need to increment the button counter when the user presses a mouse button.
The drawIntro function shouldn't be called in the event loop once per pygame.MOUSEMOTION event but in the main while loop. Also, change MOUSEMOTION to MOUSEBUTTONDOWN to increment the button once per click.
The conditionals in the drawIntro function are incorrect.
import pygame
pygame.init()
SIZE = (1000, 700)
screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
button = 0
fontIntro = pygame.font.SysFont("Times New Roman",30)
def drawIntro(screen):
#start
if button == 0: # == 0
screen.fill((0, 0, 0))
text = fontIntro.render("Sigle click to start", 1, (255,255,255))
screen.blit(text, (300, 300, 500, 500))
elif button == 1: #page1
screen.fill((0, 0, 0))
text = fontIntro.render("page 1", True, (255, 255, 255))
screen.blit(text, (300,220,500,200))
elif button == 2: #page2
screen.fill((0, 0, 0))
text = fontIntro.render("page 2", True, (255, 255, 255))
screen.blit(text, (300,220,500,200))
elif button == 3: #page3
screen.fill((0, 0, 0))
text = fontIntro.render("page3", True, (255, 255, 255))
screen.blit(text, (200,190,500,200))
running = True
while running:
for evnt in pygame.event.get():
if evnt.type == pygame.QUIT:
running = False
if evnt.type == pygame.MOUSEBUTTONDOWN: # Once per click.
button += 1
drawIntro(screen)
pygame.display.flip()
pygame.quit()
I've been watching a bunch of tutorials and new to pygame and coding in general. None of the tutorials I watched helped me with this. What i'm aiming for is for the buttons to change the button to a different colour when the user hovers over the button. Below is my entire code for the main menu so far.
import pygame
import time
import random
pygame.init()
size = (800, 600)
screen = pygame.display.set_mode(size)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
pygame.display.set_caption("Basketball Shootout")
clock = pygame.time.Clock()
#GAME INTRO
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
#print(event)
if event.type == pygame.QUIT:
pygame.quit()
quit()
#Font's and text
font = pygame.font.SysFont ("Times New Norman", 60)
text = font.render ("", True, WHITE)
#Background Image
background_images = pygame.image.load("greybackground.jpg").convert()
screen.blit(background_images, [0,0])
screen.blit(text, (150, 50))
#Background Music
pygame.mixer.music.load('game.ogg')
pygame.mixer.music.set_endevent(pygame.constants.USEREVENT)
pygame.mixer.music.play()
pygame.display.update()
clock.tick(15)
#BUTTONS
screen.blit(text, (150, 50))
pygame.draw.rect(screen,(0,0,0),(300,300,205,80));
pygame.draw.rect(screen,(0,0,0),(300,400,205,80));
pygame.draw.rect(screen,(0,0,0),(300,500,205,80));
font = pygame.font.SysFont ("Times New Norman, Arial", 30)
text = font.render ("START", True, WHITE)
screen.blit(text, (340, 320))
font = pygame.font.SysFont ("Times New Norman, Arial", 30)
text = font.render ("OPTIONS", True, WHITE)
screen.blit(text, (340, 420))
font = pygame.font.SysFont ("Times New Norman, Arial", 30)
text = font.render ("ABOUT", True, WHITE)
screen.blit(text, (340, 520))
pygame.display.flip();
#Quit Pygame
game_intro()
pygame.quit
I recommend storing the button data (text surface, rect, color) in a list of lists. When the mouse moves, pygame.MOUSEMOTION events get added to the event queue. In the event loop check if the mouse moved and then iterate over your buttons and set the color of colliding buttons to the hover color, reset the others to black. Blit the rects and text surfaces in a for loop as well.
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
HOVER_COLOR = (50, 70, 90)
# Don't define new font objects in your while loop (that's inefficient).
FONT = pygame.font.SysFont ("Times New Norman", 60)
# If the text surfaces and button rects don't change,
# you can define them once outside of the while loop.
text1 = FONT.render("START", True, WHITE)
text2 = FONT.render("OPTIONS", True, WHITE)
text3 = FONT.render("ABOUT", True, WHITE)
rect1 = pygame.Rect(300,300,205,80)
rect2 = pygame.Rect(300,400,205,80)
rect3 = pygame.Rect(300,500,205,80)
# The buttons consist of a text surface, a rect and a color.
buttons = [
[text1, rect1, BLACK],
[text2, rect2, BLACK],
[text3, rect3, BLACK],
]
def game_intro():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.MOUSEMOTION:
for button in buttons:
# button[1] is the rect. Use its collidepoint method with
# the `event.pos` (mouse position) to detect collisions.
if button[1].collidepoint(event.pos):
# Set the button's color to the hover color.
button[2] = HOVER_COLOR
else:
# Otherwise reset the color to black.
button[2] = BLACK
screen.fill((20, 50, 70))
# Draw the buttons with their current colors at their rects.
# You can unpack the button lists directly in the head of the loop.
for text, rect, color in buttons:
pygame.draw.rect(screen, color, rect)
screen.blit(text, rect)
pygame.display.flip()
clock.tick(15)
game_intro()
pygame.quit()
I'd actually recommend defining a Button class, but I'm not sure if you're already familiar with classes/object-oriented programming.
The buttons also need callback functions to actually do something. Take a look at my answer here: https://stackoverflow.com/a/47664205/6220679
I would recommend creating a function for this:
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + w > mouse[0] > x and y + h > mouse[1] > y:
gameDisplay.blit(active, (x, y))
else:
gameDisplay.blit(inactive, (x, y))
and then in you game intro call you function like this:
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
#print(event)
if event.type == pygame.QUIT:
pygame.quit()
quit()
# For example
button(100, 350, 195, 80, startBtn, startBtn_Hover)
This is what each parameter means:
x: x-coordinate of button
y: y-coordinate of button
w: width of button
h: height of button
active: picture when mouse is hovered over button
inactive: picture when button is idle
I have created mouse clicking functions to print (start, options and about) when I click those buttons. I just don't know how to go to the next stage of actually opening a new page once clicking those buttons. I had a go with trying to screen.fill when clicking the button but it would only last a couple of seconds and buttons would appear in front of it.
I am fairly new to pygame.
Here is my code so far,
import pygame
from pygame import *
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
HOVER_COLOR = (50, 70, 90)
#Background Music
pygame.mixer.music.load('game.ogg')
pygame.mixer.music.set_endevent(pygame.constants.USEREVENT)
pygame.mixer.music.play()
pygame.display.update()
clock.tick(15)
#Background
bg = pygame.image.load("greybackground.png")
#Fonts
FONT = pygame.font.SysFont ("Times New Norman", 60)
text1 = FONT.render("START", True, WHITE)
text2 = FONT.render("OPTIONS", True, WHITE)
text3 = FONT.render("ABOUT", True, WHITE)
#Buttons
rect1 = pygame.Rect(300,300,205,80)
rect2 = pygame.Rect(300,400,205,80)
rect3 = pygame.Rect(300,500,205,80)
buttons = [
[text1, rect1, BLACK],
[text2, rect2, BLACK],
[text3, rect3, BLACK],
]
running = False
def game_intro():
while not running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.MOUSEMOTION:
for button in buttons:
if button[1].collidepoint(event.pos):
button[2] = HOVER_COLOR
else:
button[2] = BLACK
screen.blit(bg, (0, 0))
for text, rect, color in buttons:
pygame.draw.rect(screen, color, rect)
screen.blit(text, rect)
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if rect1.collidepoint(event.pos):
screen.fill((0, 0, 0))
elif rect2.collidepoint(event.pos):
print ('options')
elif rect3.collidepoint(event.pos):
print ('about')
if event.type == KEYDOWN:
if (event.key == K_UP):
print ("UP was pressed")
elif (event.key == K_DOWN):
print ("DOWN was pressed")
elif (event.key == K_w):
print ("W was pressed")
elif (event.key == K_s):
print ("S was pressed")
else:
print ("error")
pygame.display.flip()
clock.tick(60)
game_intro()
pygame.quit()
I actually had to do a similar thing myself. This is what you would put at the bottom:
while running:
event = pygame.event.wait()
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
x,y = pygame.mouse.get_pos()
if 300 <= x <= 505 and 300 <= y <= 380:
#change stuff here
running = False
#insert code here \/ for the next screen
This can be used universally for every button. If you need more buttons, just copy and paste the third if statment and change as needed.
Don't forget to do 'pygame.display.update()' to refresh the screen; else, you will see nothing change (which is what happened to me).
I hope this helps!