So I'm trying to make this button change color when I hover over it, but pygame.mouse.get_pos() is not updating after I open the program.
I'm a novice to both python and program so any assistance would be a appreciated greatly.
import pygame
pygame.init()
gameDisplay = pygame.display.set_mode((800,600))
pygame.display.set_caption('Click to Adventure')
clock = pygame.time.Clock()
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
green = (0,255,0)
gameDisplay.fill(white)
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def button(msg,x,y,w,h,ic,ac,action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
ycrd = int((y+(h/2)))
r = int(h/2)
print(mouse)
if x+(w+(h/2)) > mouse[0] > x-(h/2) and y+h > mouse[1] > y:
pygame.draw.rect(gameDisplay,ac,(x,y,w,h))
pygame.draw.circle(gameDisplay,ac,(x,ycrd),r,0)
pygame.draw.circle(gameDisplay,ac,(x+w,ycrd),r,0)
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(gameDisplay,ic,(x,y,w,h))
pygame.draw.circle(gameDisplay,ic,(x,ycrd),r,0)
pygame.draw.circle(gameDisplay,ic,(x+w,ycrd),r,0)
smallText = pygame.font.SysFont("comicsansms",20)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x+(w/2)),(y+(h/2)))
gameDisplay.blit(textSurf, textRect)
button("Hi",300,200,100,50,red,green,None)
gameExit = False
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
#print(event)
pygame.display.update()
clock.tick(60)
pygame.quit()
quit()
I'm not really sure why pygame.mouse.get_pos() isn't updating as I have both pygame.time.Clock() and clock.tick(60).
I'm not a pygame expert myself but what i can see is that you're calling the button() function only once when the game is starting. You need to make a function that will be called in every frame which will wait for an event to happen, in your case, changing the button's color.
Make a normal button on the screen. Then, make a function which will be called when the mouse is on top of the button and change color.
Something like,
Button = MakeButton(); #This function will create a button and show on the screen
In while not gameExit:
if Button.get_rect().collidepoint(pygame.mouse.get_pos()): #This line will wait for the mouse to hover over the button
ChangeButtonColor(); #This function will change the button color
These are pseudo codes to get you started.
pygame uses the "update/draw loop" pattern, commonly found in game development frameworks. This pattern consists of a loop that is mostly non-terminating, and you have it in your code as while not gameExit:. Inside this loop, you must handle all of the user input, through the usage of event flags. For example, your code deals with the QUIT event.
However, your button code is not particularly tailored for this pattern. Instead, it hopes to create a "button" as some sort of static object on the screen, like event-based GUIs.
First, you should separate the update step and the draw step. The update changes the game state, and the draw step simply checks the state and draw things on screen. In your case, the update step should check if the mouse is over the button or not, and define which color is used.
Let's do that separation:
# to be used in the draw step
def draw_button(msg, x, y, width, height, color):
ycrd = int((y + (h / 2)))
r = int(h / 2)
pygame.draw.rect(gameDisplay, color, (x, y, width, height))
pygame.draw.circle(gameDisplay, color, (x, ycrd), r, 0)
pygame.draw.circle(gameDisplay, color, (x + w, ycrd), r, 0)
smallText = pygame.font.SysFont("comicsansms",20)
textSurf, textRect = text_objects(msg, smallText)
textRect.center = ((x + (w / 2)), (y + (h / 2)))
# to be used in the update step
def check_mouse_state_over_box(x, y, width, height):
# I'm returning strings here, but you should use something else like an enum
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + (w + (h / 2)) > mouse[0] > x - (h / 2) and y + h > mouse[1] > y:
if click[0] == 1:
return 'click'
else:
return 'hover'
else:
return 'no-relation'
Now that the button() function separates the update and draw steps, you can properly use it in the game loop:
while not game_exit:
# UPDATE STEP
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit() # this function is undefined it seems?
# you can also use 'elif event.type == pygame.MOUSEMOTION:' if you wish, but then the logic is a bit different
button_state = check_mouse_over_box(300, 200, 100, 50)
if button_state = 'no-relation':
button_color = red
else:
button_color = green
if button_state = 'click':
action() # define whatever action you want
# DRAW STEP
draw_button('Hi', 300, 200, 100, 50, button_color)
gameDisplay.blit() # I think this is mandatory in pygame
Now, this should work. But if you know object-oriented programming (OOP), you could define a class Button that holds its position and color, an update method that checks the mouse and change the button state properly, and a draw method that draws the button. If you don't know OOP, this is a great opportunity to learn it :)
Related
I have some code that creates a button and code creating some text that is displayed on-screen. The goal is to have the button when clicked add 1 to the variable and have the changed reflected on screen (ie button is clicked the value on screen goes from 0 to 1 and then 1 to 2 and so on).
The button function:
def button(message, x, y, w, h, activeRGB, inactiveRGB, action=None): #example of color param for line 61/63
mouse = pygame.mouse.get_pos() #get location of mouse recorded by pygame
click = pygame.mouse.get_pressed()
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(gameDisplay, activeRGB, (x, y, w, h))
if click[0] ==1 and action != None:
if action == "countUP":
clickCounter+= 1
print(str(clickCounter)) # print to check that the button actually changes the value
pygame.display.update()
else:
pygame.draw.rect(gameDisplay, inactiveRGB, (x, y, w, h))
smallText = pygame.font.Font("freesansbold.ttf", 20)
textSurf, textRect = textBox(message, mediumText)
textRect.center = ( (x + (w/2)), y+(h/2))
gameDisplay.blit(textSurf, textRect)
The logic I have so far
gameDisplay.fill(white)
pygame.display.update()
clickCounter = str(clickCounter)
textObject(clickCounter, black, mediumText, 200, 200)
closeGame = False
while not closeGame: # this keeps the window from shutting down
for thing in pygame.event.get():
if thing.type == pygame.QUIT:
closeGame = True
print(thing)
button("Click me!", 300, 300, 100, 100, blue, brightBlue, "countUP")
pygame.display.update()
clock.tick(20)
gameDisplay.fill(white)
pygame.display.update()
#logicloop()
The button function does appear to be changing the value of clickCounter but it is not reflected on screen. My guess was that there is a missing blit command or screen update, though nothing i've tried has worked.
For whatever reason when I had this block of code set up as a function that is then called, it ran without the gameDisplay.fill(white) or any of the other on screen elements appearing, how would I go about setting it up as a function to make adding more to the logic easier?
All of the code:
import pygame
pygame.init()
displayWidth = 700
displayHeight = displayWidth
gameDisplay = pygame.display.set_mode((700,700))
clock = pygame.time.Clock()
black = (0, 0, 0)
brightBlue = (0, 0, 225)
blue = (0, 0, 255)
white = (255, 255, 255) #predef colors to make temp rgb value coding easier
closeGame = False
mediumText = pygame.font.Font("freesansbold.ttf", 70) #initalize font
clickCounter = 0
#def fontSize (pxsize):
#pygame.font.Font("freesandsbold.ttf", pxsize)
def textObject (text, color, font, x, y):
storedGenerate = font.render(text, 1, ((color)))
gameDisplay.blit(storedGenerate, (x,y))
def textBox(text, font): #purely for returning rectangle around font// used for btn function only, tObject for displaying text
textSurface = font.render(text, True, black) #swap black for rgb later
return textSurface, textSurface.get_rect()
def button(message, x, y, w, h, activeRGB, inactiveRGB, action=None): #example of color param for line 61/63
mouse = pygame.mouse.get_pos() #get location of mouse recorded by pygame
click = pygame.mouse.get_pressed()
global clickCounter
clickCounter = 0
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(gameDisplay, activeRGB, (x, y, w, h))
if click[0] ==1 and action != None:
if action == "countUP":
clickCounter+= 1
print(str(clickCounter))
pygame.display.update()
else:
pygame.draw.rect(gameDisplay, inactiveRGB, (x, y, w, h))
#smallText = pygame.font.Font("freesansbold.ttf", 20) # constant has been declared, try deleting line when done w/ proj
smallText = pygame.font.SysFont('Times New Roman', 20)
textSurf, textRect = textBox(message, smallText)
textRect.center = ( (x + (w/2)), y+(h/2))
gameDisplay.blit(textSurf, textRect)
gameDisplay.fill(white)
pygame.display.update()
clickCounter = str(clickCounter)
textObject(clickCounter, black, mediumText, 200, 200)
closeGame = False
while not closeGame: # this keeps the window from shutting down
for thing in pygame.event.get():
if thing.type == pygame.QUIT:
closeGame = True
print(thing)
button("Click me!", 300, 300, 100, 100, blue, brightBlue, "countUP")
pygame.display.update()
clock.tick(20)
gameDisplay.fill(white)
pygame.display.update()
#logicloop()
pygame.quit()
quit()
The first issue is, that the number value stored in clickCounter is converted to a string.
Delete:
lickCounter = str(clickCounter)
In the function button, the value of clickCounter is continuously set 0. Delete this, too:
def button(message, x, y, w, h, activeRGB, inactiveRGB, action=None):
mouse = pygame.mouse.get_pos() #get location of mouse recorded by pygame
click = pygame.mouse.get_pressed()
global clickCounter
# clickCounter = 0 <------ delete
# [...]
You missed to draw the changed text in the main loop. Before the text is drawn the "old" text has to be cleared. Continuously redraw the entire scene in the main loop of the application.
This means the display has to be filled by the background color and the text and the button have to be redrawn:
while not closeGame: # this keeps the window from shutting down
for thing in pygame.event.get():
if thing.type == pygame.QUIT:
closeGame = True
print(thing)
gameDisplay.fill(white)
button("Click me!", 300, 300, 100, 100, blue, brightBlue, "countUP")
textObject(str(clickCounter), black, mediumText, 200, 200)
pygame.display.update()
clock.tick(20)
I want to click these 2 circle balls and drag them to mouse current mouse position but it is not working.
I just want to click and drag the balls with mouse.
some codes was not added(import pygame,draw a display, colors etc.)
import pygame
window = pygame.display.set_mode((800,400))
clock = pygame.time.Clock()
##bg = pygame.image.load("bgpool.png")
##window.blit(bg,(0,0))
black = (0,0,0)
yellow = (255,255,0)
class Circle:
def __init__(self,x,y,color,radius):
self.x = x
self.y = y
self.color = color
self.radius = radius
pygame.draw.circle(window, color,(x,y),radius)
def quitgame():
pygame.quit()
quit()
def loop():
cikis = False
while not cikis:
for event in pygame.event.get():
if event.type == pygame.QUIT:
cikis = True
pygame.quit()
quit()
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
bas = pygame.MOUSEBUTTONDOWN
window.fill((255,255,255))
main_circle = Circle(75,175,black,10)
aim_circle = Circle(375,175,yellow,10)
if click[0] == 1:
if mouse[0] >= main_circle.x and mouse[0] <= main_circle.x + main_circle.radius:
if mouse[1] >= main_circle.y and mouse[1] <= main_circle.y + main_circle.radius:
if click[0] == 1:
main_circle.x == mouse[0]
main_circle.y == mouse[1]
clock.tick(120)
pygame.display.update()
loop()
pygame.quit()
quit()
While click = pygame.mouse.get_pressed() works, it's very much recommended to use Pygame's events, like you have done for pygame.QUIT.
Because you didn't provide much code, I added the bare minimum to make the code runnable, and I commented every modification:
import pygame
pygame.init()
window = pygame.display.set_mode((700, 500))
class Circle:
def __init__(self, x, y, color, radius):
# Changed pos to contain both coordinates
self.pos = (x, y)
# Where the radius ends
self.x_boundary = (x - radius, x + radius)
self.y_boundary = (y - radius, y + radius)
self.color = color
self.radius = radius
def recalc_boundary(self):
# Recalculate the boundaries of the circle,
# this is needed whenever the circle is moved
self.x_boundary = (
self.pos[0] - self.radius, self.pos[0] + self.radius
)
self.y_boundary = (
self.pos[1] - self.radius, self.pos[1] + self.radius
)
# Single instantiation of our circle
# didn't add aim_circle because it is irrelevant
# in my answer
main_circle = Circle(75, 175, (255, 0, 0), 10)
# Small lambda function that'll take care of
# checking whether or not a point x is
# within two boundaries.
# This replaces your
# `if mouse[0] >= main_circle.x and mouse[0]
# <= main_circle.x + main_circle.radius:`
# lines
within = lambda x, low, high: low <= x <= high
# Boolean that attests to whether or not the
# user is clicking on our circle
selected = False
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
# Test for MOUSEBUTTONDOWN events
elif event.type == pygame.MOUSEBUTTONDOWN:
# Left mouse button
if event.button == 1:
pos = pygame.mouse.get_pos()
# Check if the mouse is within
# our circle's limits, to see if the
# user is trying to click on it
if (
within(pos[0], *main_circle.x_boundary)
and within(pos[1], *main_circle.y_boundary)
):
selected = True
elif event.type == pygame.MOUSEBUTTONUP:
# User released mouse buttons
selected = False
if selected:
# Move to mouse position when selected,
# the circle 'follows' the mouse
main_circle.pos = pygame.mouse.get_pos()
main_circle.recalc_boundary()
window.fill((0, 0, 0))
# Moved this draw call to outside
# your class definition
pygame.draw.circle(
window, main_circle.color,
main_circle.pos,
main_circle.radius
)
pygame.display.update()
Note: it's a bad idea to instantiate a new Circle object each game loop iteration, this'll consume lots of CPU for nothing. I believe you've done that because you placed your circle draw calls inside it, but you should really just move it out into the loop.
Edit: added a longer example code.
I'm having trouble with coding buttons in pygame. I'm a newbie to the pygame module, so be gentle.
Basically, the goal is to make a point-and-click telltale kind of game. The player gets presented with two choices each gameloop, ie "go left" or "go right". Accordingly, there are two buttons in each gameloop, all located at the same coordinates.
Here is the function:
import pygame
import os
import time
pygame.init()
display_width= 1280
display_height = 720
gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()
def button(msg,x, y, w, h, ic, ac, action=None): #message, x y location, width, height, inactive and active colour
if action ==None:
pygame.display.update()
clock.tick(15)
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(gameDisplay, ac,(x,y,w,h))
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
pygame.display.update()
clock.tick(15)
if action == "left1":
game_loop("loop1-1.png",0,0,"left2","left2","","")
else:
pygame.draw.rect(gameDisplay, ic,(x,y,w,h))
smallText = pygame.font.SysFont('timesnewroman',20)
textSurf, textRect = text_objects(msg, smallText, silver)
textRect.center = ( (x+(w/2)), (y+(h/2)) )
gameDisplay.blit(textSurf, textRect)
def game_loop(pic,width,heigth,act1,act2,left,right):
intro = True
while intro:
for event in pygame.event.get():
print(event)
if event.type == pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white)
gameDisplay.blit(get_image(pic), (0, 0)) #MAIN MENU PIC
button(left,440,450,width,heigth, dark_gray, gray, action=act1)#start nupp
button(right,740,450,width,heigth, dark_gray, gray, action=act2)#exit nupp
pygame.display.update()
clock.tick(15)
The problem occurs when I click the button carelessly, meaning if I don't purposefully click on the left mouse button as fast as I can. Once game_loop1 is called and if I click for a bit longer, the program will read the first click again in this game_loop1 and run the next game_loop and then the next etc. This means the player can accidentally skip through gameloops.
Is there a way to delay the program after the first click(however long it is)? Or maybe a way to include keyup in the function, so it won't count the click in the next gameloop?
Thanks!
I think your original code is a bit too convoluted to fix it and I'll rather show you some better ways to do what you want. You need a finite-state machine to transition between different states/scenes. You can find a simple example with functions as scenes here.
If the logic in your scenes is mostly the same, you could also try to just swap out the data for the scene, for example the background image. Each state/scene needs to know to which new states it can switch, so I put the data into a dictionary of dictionaries. The nested dicts contain the background image of the scene and the connected left and right scenes. When the user presses a button/rect I check if it was the left or right button and then switch to the corresponding scene (subdict) in the states dictionary.
import pygame
pygame.init()
display_width= 1280
display_height = 720
gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()
# Use uppercase names for constants that should never be changed.
DARK_GRAY = pygame.Color('gray13')
BACKGROUND1 = pygame.Surface((display_width, display_height))
BACKGROUND1.fill((30, 150, 90))
BACKGROUND2 = pygame.Surface((display_width, display_height))
BACKGROUND2.fill((140, 50, 0))
BACKGROUND3 = pygame.Surface((display_width, display_height))
BACKGROUND3.fill((0, 80, 170))
states = {
'scene1': {'background': BACKGROUND1, 'left_scene': 'scene2', 'right_scene': 'scene3'},
'scene2': {'background': BACKGROUND2, 'left_scene': 'scene1', 'right_scene': 'scene3'},
'scene3': {'background': BACKGROUND3, 'left_scene': 'scene1', 'right_scene': 'scene2'},
}
def game_loop():
# The buttons are just pygame.Rects.
left_button = pygame.Rect(440, 450, 60, 40)
right_button = pygame.Rect(740, 450, 60, 40)
# The current_scene is a dictionary with the relevant data.
current_scene = states['scene1']
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.MOUSEBUTTONDOWN:
# If the left button is clicked we switch to the 'left_scene'
# in the `current_scene` dictionary.
if left_button.collidepoint(event.pos):
current_scene = states[current_scene['left_scene']]
print(current_scene)
# If the right button is clicked we switch to the 'right_scene'.
elif right_button.collidepoint(event.pos):
current_scene = states[current_scene['right_scene']]
print(current_scene)
# Blit the current background.
gameDisplay.blit(current_scene['background'], (0, 0))
# Always draw the button rects.
pygame.draw.rect(gameDisplay, DARK_GRAY, left_button)
pygame.draw.rect(gameDisplay, DARK_GRAY, right_button)
pygame.display.update()
clock.tick(30) # 30 FPS feels more responsive.
game_loop()
pygame.quit()
This question already has answers here:
Pygame mouse clicking detection
(4 answers)
Closed 1 year ago.
I am trying to make buttons using rect in Pygame. I started with the red quit button and checked if a click was inside the boundingbox of the button.
import pygame
"""import nemesis.py;"""
pygame.init();
screen = pygame.display.set_mode((400,300));
pygame.display.set_caption("menu");
menuAtivo = True;
start_button = pygame.draw.rect(screen,(0,0,240),(150,90,100,50));
continue_button = pygame.draw.rect(screen,(0,244,0),(150,160,100,50));
quit_button = pygame.draw.rect(screen,(244,0,0),(150,230,100,50));
pygame.display.flip();
while menuAtivo:
for evento in pygame.event.get():
print(evento);
if evento.type == pygame.MOUSEBUTTONDOWN:
if pygame.mouse.get_pos() >= (150,230):
if pygame.mouse.get_pos() <= (250,280):
pygame.quit();
When using rects in pygame, it's best to use the in built collision detection.
here is an example code on how to do it hope it helps you solve your problem.
Before that though i'd like to mention you should render/draw your objects withing the while loop or the wont show up.
import pygame
import sys
def main():
pygame.init()
clock = pygame.time.Clock()
fps = 60
size = [200, 200]
bg = [255, 255, 255]
screen = pygame.display.set_mode(size)
button = pygame.Rect(100, 100, 50, 50) # creates a rect object
# The rect method is similar to a list but with a few added perks
# for example if you want the position of the button you can simpy type
# button.x or button.y or if you want size you can type button.width or
# height. you can also get the top, left, right and bottom of an object
# with button.right, left, top, and bottom
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = event.pos # gets mouse position
# checks if mouse position is over the button
if button.collidepoint(mouse_pos):
# prints current location of mouse
print('button was pressed at {0}'.format(mouse_pos))
screen.fill(bg)
pygame.draw.rect(screen, [255, 0, 0], button) # draw button
pygame.display.update()
clock.tick(fps)
pygame.quit()
sys.exit
if __name__ == '__main__':
main()
Another good way to create buttons on pygame (in python) is by installing the package called pygame_widgets (pip3 install pygame_widgets) on Mac or Linux and (pip install pygame_widgets) on Windows. And also make sure you have pip installed otherwise, it is not going to work.
# Importing Modules
import pygame as pg
import pygame_widgets as pw
# creating screen
pg.init()
screen = pg.display.set_mode((800, 600))
running = True
button = pw.Button(
screen, 100, 100, 300, 150, text='Hello',
fontSize=50, margin=20,
inactiveColour=(255, 0, 0),
pressedColour=(0, 255, 0), radius=20,
onClick=lambda: print('Click')
)
while running:
events = pg.event.get()
for event in events:
if event.type == pg.QUIT:
running = False
button.listen(events)
button.draw()
pg.display.update()
Hope this helps you.
TKS GUYS,
Here is my answer :
import pygame
pygame.init();
screen = pygame.display.set_mode((400,300));
pygame.display.set_caption("menu");
menuAtivo = True;
start_button = pygame.draw.rect(screen,(0,0,240),(150,90,100,50));
continue_button = pygame.draw.rect(screen,(0,244,0),(150,160,100,50));
quit_button = pygame.draw.rect(screen,(244,0,0),(150,230,100,50));
pygame.display.flip();
def startGame():
screen.fill((0,0,0));
pygame.display.flip();
import nemesis.py;
while menuAtivo:
for evento in pygame.event.get():
print(evento);
if evento.type == pygame.MOUSEBUTTONDOWN:
if pygame.mouse.get_pos()[0] >= 150 and pygame.mouse.get_pos()[1] >= 230:
if pygame.mouse.get_pos()[0] <= 250 and pygame.mouse.get_pos()[1] <= 280:
pygame.quit();
if pygame.mouse.get_pos()[0] >= 150 and pygame.mouse.get_pos()[1] >= 90:
if pygame.mouse.get_pos()[0] <= 250 and pygame.mouse.get_pos()[1] <= 140:
startGame();
I think the main problem in your code is that you compare pygame.mouse.get_pos() directly with a Tuple, which is ambiguous. You should try testing x then y separately:
while menuAtivo:
for evento in pygame.event.get():
print(evento);
if evento.type == pygame.MOUSEBUTTONDOWN:
if pygame.mouse.get_pos()[0] >= 150 and pygame.mouse.get_pos()[1] >= 230:
if pygame.mouse.get_pos()[0] <= 250 and pygame.mouse.get_pos()[1] <= 280:
pygame.quit();
I have already provided an answer on the above. Here is my another answer without the module pygame_widgets:
import pygame
import sys
# initializing the constructor
pygame.init()
# screen resolution
res = (720,720)
# opens up a window
screen = pygame.display.set_mode(res)
# white color
color = (255,255,255)
# light shade of the button
color_light = (170,170,170)
# dark shade of the button
color_dark = (100,100,100)
# stores the width of the
# screen into a variable
width = screen.get_width()
# stores the height of the
# screen into a variable
height = screen.get_height()
# defining a font
smallfont = pygame.font.SysFont('Corbel',35)
# rendering a text written in
# this font
text = smallfont.render('quit' , True , color)
while True:
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
#checks if a mouse is clicked
if ev.type == pygame.MOUSEBUTTONDOWN:
#if the mouse is clicked on the
# button the game is terminated
if width/2 <= mouse[0] <= width/2+140 and height/2 <= mouse[1] <= height/2+40:
pygame.quit()
# fills the screen with a color
screen.fill((60,25,60))
# stores the (x,y) coordinates into
# the variable as a tuple
mouse = pygame.mouse.get_pos()
# if mouse is hovered on a button it
# changes to lighter shade
if width/2 <= mouse[0] <= width/2+140 and height/2 <= mouse[1] <= height/2+40:
pygame.draw.rect(screen,color_light,[width/2,height/2,140,40])
else:
pygame.draw.rect(screen,color_dark,[width/2,height/2,140,40])
# superimposing the text onto our button
screen.blit(text , (width/2+50,height/2))
# updates the frames of the game
pygame.display.update()
Hope This Helps if pygame_widgets (pip install pygame_widgets) module could not be installed in your python version.
this is my solution
class button():
def __init__(self, color, x,y,width,height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self,win,outline=None):
#Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x-2,self.y-2,self.width+4,self.height+4),0)
pygame.draw.rect(win, self.color, (self.x,self.y,self.width,self.height),0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 60)
text = font.render(self.text, 1, (0,0,0))
win.blit(text, (self.x + (self.width/2 - text.get_width()/2), self.y + (self.height/2 - text.get_height()/2)))
def isOver(self, pos):
#Pos is the mouse position or a tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
I have no idea why when the button is pressed it doesnt just go to the next function. It goes back to the other one its really weird and annoying.
It should go to the whattodo function but it does for like half a second then goes to the other. Anyone know why?
#!/usr/bin/python
import pygame
pygame.init()
screen = pygame.display.set_mode((1400,700))
pygame.display.set_caption("Anti-Docter")
titlescreen = pygame.image.load('titleframe.bmp')
boxinfo = pygame.image.load('boxinfo.bmp')
black = (0,0,0)
white = (255,255,255)
randommommycolor = (255,139,12)
Brown = (102,51,0)
Lighter_Brown = (120,59,5)
def mts(text, textcolor, x, y, fs):
font = pygame.font.Font(None,fs)
text = font.render(text, True, textcolor)
screen.blit(text, [x,y])
def buttonPlay(x,y,w,h,ic,ac):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(screen, ac,(x,y,w,h))
if click[0] == 1:
whattodo()
else:
pygame.draw.rect(screen, ic,(x,y,w,h))
def whattodo():
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.blit(boxinfo, (0,0))
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.blit(titlescreen, (0,0))
buttonPlay(580, 350, 200, 90, Brown, Lighter_Brown)
mts("Play", black, 620, 365, 80)
pygame.display.update()
Every time your main loop repeats, it calls 'buttonPlay'. There is nothing inside 'whattodo' that changes this behaviour, so 'whattodo' runs once then control flow passes back to the main loop, which just repeats 'buttonPlay'.