Pygame icon() function not changing a global variable - python

I have a function that allows for the user to click an icon and set a boolean so that the main loop knows which action to perform. The code is intended to work as click airbrush icon -> set airbrushMode to true -> return airbrushMode so paintScreen() can detect it -> perform the action set by airbrushMode in the while loop. I added in print statements to locate the problem. The variable does change, but the variable is not returned, and the airbrush function does not work. It does work when I set airbrushMode to true inside paintScreen() but setting it to false in the function and outside the function both don't work.
The main function
def paintScreen():
airbrushMode = False
paint = True
gameDisplay.fill(cyan)
message_to_screen('Welcome to PyPaint', black, -300, 'large')
cur = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
pygame.draw.rect(gameDisplay, white, (50, 120, displayWidth - 100, displayHeight - 240))
while paint:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
button('X', 20, 20, 50, 50, red, lightRed, action = 'quit')
icon(airbrushIcon, white, 50, displayHeight - 101, 51, 51, white, grey, 'airbrush')
icon(pencilIcon, white, 140, displayHeight - 101, 51, 51, white, grey, 'pencil')
icon(calligraphyIcon, white, 230, displayHeight - 101, 51, 51, white, grey, 'calligraphy')
pygame.display.update()
if cur[0] >= 50 <= displayWidth - 50 and cur[1] >= 120 <= displayHeight - 120:
if airbrushMode == True:
airbrush()
the function that creates the icons and detects the action, then returns it
def icon(icon, colour, x, y, width, height, inactiveColour, activeColour, action = None):
cur = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + width > cur[0] > x and y + height > cur[1] > y:#if the cursor is over the button
pygame.draw.rect(gameDisplay, activeColour, (x, y, width, height))
gameDisplay.blit(icon, (x, y))
if click[0] == 1 and action != None: #if clicked
print('click')
if action == 'quit':
pygame.quit()
quit()
elif action == 'airbrush':
airbrushMode = True
print('airbrush set')
return airbrushMode
print('airbrush active')

Your problem is that icon does not attempt to change any global variables; it's dealing strictly with its input parameters and local variables. If you want it to change a variable outside its own scope, you need to add
global airbrushMode
at the top of your function.
Also, if you expect paintScreen to recognize the global variable, you must have either a global presence (top-level usage) of that variable, or paintScreen also needs the global declaration.
For full details, look up global variables in Python.

Instead of checking for events in icon(), perhaps the code would flow more smoothly if it posted an event when the button was pressed.
def icon(icon, colour, x, y, width, height, inactiveColour, activeColour, action = None):
cur = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + width > cur[0] > x and y + height > cur[1] > y:#if the cursor is over the button
pygame.draw.rect(gameDisplay, activeColour, (x, y, width, height))
gameDisplay.blit(icon, (x, y))
if click[0] == 1 and action != None: #if clicked
print('click')
pygame.event.post( pygame.USEREVENT + 1, {} )
Then handle these in your main loop:
while paint:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.USEREVENT + 1
airbrushMode = True
If it were me, I would make a set of my own event types:
import enum
...
class MyEvents( enum.Enum ):
AIRBRUSH = pygame.USEREVENT + 1
PEN = pygame.USEREVENT + 2
PENCIL = pygame.USEREVENT + 3
Which allows:
pygame.event.post( MyEvents.AIRBRUSH, {} )
...
elif ( event.type == MyEvents.AIRBRUSH ):
airbrushMode = True

Related

Change colour on area of screen after mouseclick, and stay changed after release Pygame

so I have a background to my game. If an event (click) occurs, an area of the background changes colour. When I release the mouseclick, the screen updates and returns to the original colour which I don't want to happen.
The issue is clearly that the background updates after every iteration of the game loop, returning it to its original state, however, I believe I need the background to keep updating, but also for the clicks change to stay in permanent effect? So I need to find a way so that after a mouseclick, the
clicked area changes color, while the game continues to loop.
class Game(object):
def __init__(self):
self.squares = []
self.occupied = []
for x in range(0,8,1):
for y in range(0,8,1):
if (x + y) % 2 !=0:
pygame.draw.rect(screen, white, [x*100, y*100, 100, 100])
elif(x + y) % 2 ==0:
pygame.draw.rect(screen, aqua, [x*100, y*100, 100, 100])
self.squares.append([x,y])
if event.type == pygame.MOUSEBUTTONDOWN:
mx, my = pygame.mouse.get_pos()
mx = mx//100
my = my//100
pygame.draw.rect(screen, green, [mx*100, my*100, 100, 100])
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
game = Game()
pygame.display.update()
clock.tick(30)
pygame.quit()
quit()
Do not create a new instance of Game() each iteration. Create one instance only before the main loop, and add a method to Game class to update the color of the square.
Better to catch all the events in the main loop and not in the classes. When you catch an event, call the correlated class method to perform the intended action.
Below a working code:
import pygame
white = (255, 255, 255)
aqua = (0, 0, 100) #or whatever it really is, it's just a constant
green = (0, 255, 0)
class Game(object):
def __init__(self):
self.squares = []
self.occupied = []
for x in range(0,8,1):
for y in range(0,8,1):
if (x + y) % 2 !=0:
pygame.draw.rect(screen, white, [x*100, y*100, 100, 100])
elif(x + y) % 2 ==0:
pygame.draw.rect(screen, aqua, [x*100, y*100, 100, 100])
self.squares.append([x,y])
def colorsquare(self):
mx, my = pygame.mouse.get_pos()
mx = mx//100
my = my//100
pygame.draw.rect(screen, green, [mx*100, my*100, 100, 100])
game_over = False
pygame.init()
screen = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
game = Game()
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
elif event.type == pygame.MOUSEBUTTONDOWN:
game.colorsquare()
pygame.display.update()
clock.tick(30)

How to make a function activated when over a region, stay active outside the limiting region

I am writing a code for a paint app, and I want to have multiple brushes. Only issue right now is that with this code here, the brush works fine, but it only works when the cursor is above the actual icon. Here is the code:
def paintScreen():
intro = True
gameDisplay.fill(cyan)
message_to_screen('Welcome to PyPaint', black, -300, 'large')
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
pygame.draw.rect(gameDisplay, white, (50, 120, displayWidth - 100, displayHeight - 240))
button('X', 20, 20, 50, 50, red, lightRed, action = 'quit')
icon(airbrushIcon, white, 50, displayHeight - 101, 51, 51, white, grey, 'airbrush')
pygame.display.update()
def icon(icon, colour, x, y, width, height, inactiveColour, activeColour, action = None):
cur = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + width > cur[0] > x and y + height > cur[1] > y:#if the cursor is over the button
pygame.draw.rect(gameDisplay, activeColour, (x, y, width, height))
gameDisplay.blit(icon, (x, y))
if click[0] == 1 and action != None:
if action == 'quit':
pygame.quit()
quit()
if action == 'pencil':
pencil()
if action == 'airbrush':
airbrush()
if action == 'calligraphy':
calligraphy()
if action == 'erase':
pencil()
else:
pygame.draw.rect(gameDisplay, inactiveColour, (x, y, width, height))
gameDisplay.blit(icon, (x, y))
def airbrush(brushSize = 3):
airbrush = True
cur = pygame.mouse.get_pos() #cur[0] is x location, cur[1] is y location
click = pygame.mouse.get_pressed()
if click[0] == True:
if cur[0] > 50 < displayWidth - 50 and cur[1] > 120 < displayHeight - 120:
#the area of the canvas is x(50, width-50) y(120, width-120)
pygame.draw.circle(gameDisplay, black, (cur[0] + random.randrange(brushSize), cur[1] + random.randrange(brushSize)), random.randrange(1, 5))
clock.tick(60)
I recognise that the issue is with the function only being called when the cursor is above the icon, but I don't know where to move the action statements, or how to change them.
You want to make it so when the user clicks on the paint icon a variable is set. So instead of:
def icon(icon, colour, x, y, width, height, inactiveColour, activeColour, action = None):
cur = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + width > cur[0] > x and y + height > cur[1] > y:#if the cursor is over the button
pygame.draw.rect(gameDisplay, activeColour, (x, y, width, height))
gameDisplay.blit(icon, (x, y))
if click[0] == 1 and action != None:
if action == 'quit':
pygame.quit()
quit()
if action == 'pencil':
pencil()
if action == 'airbrush':
airbrush()
if action == 'calligraphy':
calligraphy()
if action == 'erase':
pencil()
else:
pygame.draw.rect(gameDisplay, inactiveColour, (x, y, width, height))
gameDisplay.blit(icon, (x, y))
You can change this code to simply toggle paint on and off for:
def icon(icon, colour, x, y, width, height, inactiveColour, activeColour, paint_on, action = None):
cur = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + width > cur[0] > x and y + height > cur[1] > y and click[0] == 1: # if the cursor is over the button and they clicked
if paint_on == True:
paint_on = False
else:
paint_on = True
return paint_on
Obviously in your case since you have multiple tools you would have to create different toggles for each tool inside this function, but I'm trying to keep it simple and show an example for just a single paint tool.
Now that you have a toggle that will change the variable "paint_on" upon clicking the icon, you can check for just a regular mouse click
def regular_click(colour, x, y, width, height, inactiveColour, activeColour, action = None):
cur = pygame.mouse.get_pos()
click = pygame.get_pressed()
if cur[1] > y and click[0] == 1 and paint_on == True: # if cursor is beneath the tool bar (I'm assuming your tool bar is at the top)
pygame.draw.rect(gameDisplay, activeColour, (x, y, width, height))
Then adding this function to your main while True loop:
def paintScreen():
intro = True
gameDisplay.fill(cyan)
message_to_screen('Welcome to PyPaint', black, -300, 'large')
paint_on = False
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
pygame.draw.rect(gameDisplay, white, (50, 120, displayWidth - 100, displayHeight - 240))
button('X', 20, 20, 50, 50, red, lightRed, action = 'quit')
paint_on = icon(airbrushIcon, white, 50, displayHeight - 101, 51, 51, white, grey, paint_on, 'airbrush')
regular_click(paint_on)
pygame.display.update()
So all up this code works as follows:
Upon user clicking the icon, it changes the variable "paint_on" to it's opposite (so on if off or off if on), then when they click anywhere, it checks whether this variable is on, and if the curso is not in the tool bar, and if both of these are met, then it draws.
This is how you would do this. I can not guarantee that this code works as I have never used pygame myself, but I know this is the best way of doing this kind of thing, unless there is some sort of in built function.

why can i not click and drag circles on Python?

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.

How can I create an interactive object in pygame?

In a pygame program I am creating, I have need for an interactive object on the screen that will call a function when the player character moves onto it and presses the enter key. Here is the code I have so far:
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
done = False
x = 30
y = 30
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pressed = pygame.key.get_pressed()
if pressed[pygame.K_UP] and y > 0: y -= 5
if pressed[pygame.K_DOWN] and y < 600 - 60: y += 5
if pressed[pygame.K_LEFT] and x > 0: x -= 5
if pressed[pygame.K_RIGHT] and x < 800 - 60: x += 5
screen.fill((0, 0, 0))
color = (0, 128, 255)
pygame.draw.rect(screen, color, pygame.Rect(x, y, 60, 60))
myfont = pygame.font.SysFont("monospace", 15)
label = myfont.render("Start the experiment simulator", 1, (255,255,255))
screen.blit(label, (100, 100))
label2 = myfont.render("Start the quiz", 1, (255,255,255))
screen.blit(label2, (550, 100))
label3 = myfont.render("Quit game", 1, (255,255,255))
screen.blit(label3, (350, 400))
pygame.draw.rect(screen, red, pygame.Rect(600, 125, 30, 30))
pygame.draw.rect(screen, red, pygame.Rect(225, 125, 30, 30))
pygame.draw.rect(screen, red, pygame.Rect(375, 425, 30, 30))
pygame.display.flip()
clock.tick(60)
At the moment, the object is just a test so would be best to be a small red rectangle, about half the size of the player, that I can replace with an icon later on. This rectangle should be placed below the 'quit game' label on the pygame window and quit the game when interacted with. This is one method that I have tried so far:
if pressed[pygame.K_RETURN] and x >= 375 or x <= 405 and y >=425 or y <= 455:
pygame.display.quit()
pygame.quit()
sys.exit()
Where theoretically the system checks if the user is in a specific area and has pressed the enter key before performing the command.
You can check for collision, using pygame's colliderect
First, create three rects that will represent your three option rects :
simulator_rect = pygame.Rect(600, 125, 30, 30)
quiz_rect = pygame.Rect(225, 125, 30, 30)
quit_rect = pygame.Rect(375, 425, 30, 30)
Next, we'll create a rect that will represent the blue selector rect :
selector_rect = pygame.Rect(50, 50, 60, 60)
So now you've got rects that are created only once, instead of unnamed rects that are created every time
Now, for the actual collision detection :
# Check to see if the user presses the enter key
if pressed[pygame.K_RETURN]:
# Check to see if the selection rect
# collides with any other rect
for rect in option_rects:
if selector_rect.colliderect(rect):
if rect == simulator_rect:
# Do simulations stuff!
print('Simulating!')
elif rect == quiz_rect:
# Do quizzing stuff!
print('Quizzing!')
elif rect == quit_rect:
# Quit!
done = True
Final code :
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
done = False
x = 30
y = 30
clock = pygame.time.Clock()
# RGB values for red
red = (255, 0 ,0)
# Your three button rects :
simulator_rect = pygame.Rect(225, 125, 30, 30)
quiz_rect = pygame.Rect(600, 125, 30, 30)
quit_rect = pygame.Rect(375, 425, 30, 30)
# These represent your three option rects
option_rects = [simulator_rect, quiz_rect, quit_rect]
# Your blue selector rect
selector_rect = pygame.Rect(50, 50, 60, 60)
# The 50, 50 xy coords are temporary
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pressed = pygame.key.get_pressed()
if pressed[pygame.K_UP] and y > 0: y -= 5
if pressed[pygame.K_DOWN] and y < 600 - 60: y += 5
if pressed[pygame.K_LEFT] and x > 0: x -= 5
if pressed[pygame.K_RIGHT] and x < 800 - 60: x += 5
# Set the slector rect's coords to x/y
selector_rect.x, selector_rect.y = x, y
screen.fill((0, 0, 0))
color = (0, 128, 255)
pygame.draw.rect(screen, color, selector_rect)
myfont = pygame.font.SysFont("monospace", 15)
label = myfont.render("Start the experiment simulator", 1, (255,255,255))
screen.blit(label, (100, 100))
label2 = myfont.render("Start the quiz", 1, (255,255,255))
screen.blit(label2, (550, 100))
label3 = myfont.render("Quit game", 1, (255,255,255))
screen.blit(label3, (350, 400))
# Use our created rects
pygame.draw.rect(screen, red, simulator_rect)
pygame.draw.rect(screen, red, quiz_rect)
pygame.draw.rect(screen, red, quit_rect)
# Check to see if the user presses the enter key
if pressed[pygame.K_RETURN]:
# Check to see if the selection rect
# collides with any other rect
for rect in option_rects:
# Add rects as needed
if selector_rect.colliderect(rect):
if rect == simulator_rect:
# Do simulations stuff!
print('Simulating!')
elif rect == quiz_rect:
# Do quizzing stuff!
print('Quizzing!')
elif rect == quit_rect:
# Quit!
done = True
pygame.display.flip()
clock.tick(60)
This does add some complication to your program, but at least it's a rock solid method that you can add features too, and that will remain robust.
Answer to my own question, I managed to make my first attempt work by adding brackets around the x and y checks in this section:
and x >= 375 or x <= 405 and y >=425 or y <= 455:
So that it now reads:
and (x >= 375 and x <= 405) and (y >= 425 and y <= 455):
I just create a system for interactable object and it easy to scale.
listBox = [] # this list used to store all object inside
listBox.append(("text", pos, size, bgColor, textColor, InteractAction))
# add dumy object to the list, "text" can be empty if you dont want.
def InteractAction(mousePos): # sample action used to tie to object
print("do somehthing")
def newDrawBox(IableO):
pygame.draw.rect(gameDisplay, IableO[3],(IableO[1][0], IableO[1][1], IableO[2][0], IableO[2][1]))
text = basicfont.render(str(IableO[0]), True,IableO[4], None)
textrect = text.get_rect()
textrect.centerx = IableO[1][0] + IableO[2][0] / 2
textrect.centery = IableO[1][1] + IableO[2][1] / 2
gameDisplay.blit(text, textrect)
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
gameExit = True
elif event.type == pygame.MOUSEBUTTONDOWN:
Mouse[event.button] = 1
Mouse[0] = (event.pos[0], event.pos[1])
elif event.type == pygame.MOUSEBUTTONUP:
Mouse[event.button] = 0
Mouse[0] = (event.pos[0], event.pos[1])
#-------- check if mouse is click on any object in the list of Interatable object
if Mouse[1] == 1:
for x in listBox:
if x[1][0] < Mouse[0][0] < x[1][0] + x[2][0] and x[1][1] < Mouse[0][1] < x[1][1] + x[2][1]:
x[5](Mouse[0])
#---- draw all object -----
for x in listBox:
newDrawBox(x)

Pygame click is too sensitive

I'm making a game and the game has a shop which you can buy tokens and if you click the button to buy them the mouse goes crazy..
This is a function which waits for the mouse click.
def button(text, x, y, width, height, inactive_color, active_color, action):
cur = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if x + width > cur[0] > x and y + height > cur[1] > y:
pygame.draw.rect(gameDisplay, active_color, (x, y, width, height))
if click[0] == 1:
if action == "buy_slowdown":
slowdown_powerup += 1
else:
pygame.draw.rect(gameDisplay, inactive_color, (x, y, width, height))
text_to_button(text, black, x, y, width, height)
Here is where the function is called:
def shop():
shop = True
while shop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
gameDisplay.fill(white)
# BUY SLOWDOWN TOKENS
buyslowdownlabel = shopfont.render("Slowdown Tokens", 1, blue)
slowdown_string_label = smallfont.render(str(slowdown_powerup), 1, black)
gameDisplay.blit(buyslowdownlabel, [340, 190])
pygame.draw.rect(gameDisplay, grey, [380, 235, 75, 75])
gameDisplay.blit(slowdown_string_label, [410.5, 255.5])
button("Buy", 380, 320, 100, 70, dark_yellow, yellow, "buy_slowdown")
pygame.display.update()
Use event.MOUSEBUTTONDOWN instead of pygame.mouse.get_pressed() because event.MOUSEBUTTONDOWN is created only once when button changes state from not-pressed into pressed. pygame.mouse.get_pressed() is True all the time when you keep pressed - and because computer is faster than you then it can check pygame.mouse.get_pressed() thousands time when you click button.
#!/usr/bin/env python3
import pygame
# --- constants --- (UPPER_CASE names)
WHITE = (255,255,255)
BLACK = ( 0, 0, 0)
DARK_YELLOW = (200,200, 0)
YELLOW = (255,255, 0)
# --- functions ---
def button_create(text, rect, inactive_color, active_color, action):
font = pygame.font.Font(None, 40)
button_rect = pygame.Rect(rect)
text_buy = font.render(text, True, BLACK)
text_buy_rect = text_buy.get_rect(center=button_rect.center)
return [text_buy, text_buy_rect, button_rect, inactive_color, active_color, action, False]
def button_check(info, event):
text, text_rect, rect, inactive_color, active_color, action, hover = info
if event.type == pygame.MOUSEMOTION:
# hover = True/False
info[-1] = rect.collidepoint(event.pos)
elif event.type == pygame.MOUSEBUTTONDOWN:
if hover and action:
action()
def button_draw(screen, info):
text, text_rect, rect, inactive_color, active_color, action, hover = info
if hover:
color = active_color
else:
color = inactive_color
pygame.draw.rect(screen, color, rect)
screen.blit(text, text_rect)
# ---
def buy_slowdown(number=1):
global slowdown_powerup
slowdown_powerup += number
print('slowdown_powerup:', slowdown_powerup)
def buy_1():
buy_slowdown(1)
def buy_10():
buy_slowdown(10)
def buy_100():
buy_slowdown(100)
# --- main ---
# - init -
pygame.init()
screen = pygame.display.set_mode((800,600))
screen_rect = screen.get_rect()
# - objects -
slowdown_powerup = 0
button_1 = button_create("+1", (380, 235, 75, 75), DARK_YELLOW, YELLOW, buy_1)
button_2 = button_create("+10", (480, 235, 75, 75), DARK_YELLOW, YELLOW, buy_10)
button_3 = button_create("+100", (580, 235, 75, 75), DARK_YELLOW, YELLOW, buy_100)
# - mainloop -
shop = True
while shop:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
shop = False
button_check(button_1, event)
button_check(button_2, event)
button_check(button_3, event)
# --- draws ---
screen.fill(WHITE)
button_draw(screen, button_1)
button_draw(screen, button_2)
button_draw(screen, button_3)
pygame.display.update()
# - end -
pygame.quit()

Categories

Resources