I finally got the collision down so that when my mouse is hovering over the circles and you click the left mouse button, It fills in. It changes going up, but going down it doesn't.
Here's my code:
# Imports a library of functions!
import pygame
import random
# Initializes the game engine
pygame.init()
# Defines the colors
BLACK = ( 0, 0, 0)
GREEN = ( 3, 255, 3)
# Controls the width of the circle
width_1 = 2
width_2 = 2
width_3 = 2
width_4 = 2
# Un-fills circles
filled_1 = False
filled_2 = False
filled_3 = False
filled_4 = False
# Sets the height and width of the screen
size = [720, 575]
screen = pygame.display.set_mode(size)
# Loops until the user clicks the close button
done = False
clock = pygame.time.Clock()
# While loop
while not done:
# Leaves the fps at 30
clock.tick(30)
for event in pygame.event.get(): # If user did something
if event.type == pygame.QUIT: # If user clicked close
done = True
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
# Finds where you clicked
x, y = event.pos
# Check if mouse was over it
if circle_1.collidepoint(x, y):
# Lets the circle draw
filled_1 = True
width_1 = 0
if filled_1 == True:
circle_1 = pygame.draw.circle(screen, BLACK, [250, 230], 7, width_1)
elif circle_2.collidepoint(x, y):
# Lets the circle draw
filled_2 = True
width_2 = 0
if filled_2 == True:
circle_2 = pygame.draw.circle(screen, BLACK, [250, 260], 7, width_2)
elif circle_3.collidepoint(x, y):
# Lets the circle draw
filled_3 = True
width_3 = 0
if filled_3 == True:
circle_3 = pygame.draw.circle(screen, BLACK, [250, 260], 7, width_3)
elif circle_4.collidepoint(x, y):
# Lets the circle draw
filled_4 = True
width_4 = 0
if filled_4 == True:
circle_4 = pygame.draw.circle(screen, BLACK, [250, 260], 7, width_4)
# Cleans the screen and sets the screen background
screen.fill(GREEN)
# Circles
circle_1 = pygame.draw.circle(screen, BLACK, [250, 230], 7, width_1)
circle_2 = pygame.draw.circle(screen, BLACK, [250, 260], 7, width_2)
circle_3 = pygame.draw.circle(screen, BLACK, [250, 290], 7, width_3)
circle_4 = pygame.draw.circle(screen, BLACK, [250, 320], 7, width_4)
if filled_1 == True:
filled_2 = False
filled_3 = False
filled_4 = False
width_2 = 2
width_3 = 2
width_4 = 2
elif filled_2 == True:
filled_1 = False
filled_3 = False
filled_4 = False
width_1 = 2
width_3 = 2
width_4 = 2
elif filled_3 == True:
filled_1 = False
filled_2 = False
filled_4 = False
width_1 = 2
width_2 = 2
width_4 = 2
elif filled_4 == True:
filled_1 = False
filled_2 = False
filled_3 = False
width_1 = 2
width_2 = 2
width_3 = 2
# Update the screen
pygame.display.flip()
Just run this code and see what happens, its pretty hard to explain.
Let's assume that the second one is clicked, so
filled_1 = False
filled_2 = True
filled_3 = False
filled_4 = False
Then you click the third. Thus,
filled_1 = False
filled_2 = True
filled_3 = True
filled_4 = False
You then have:
screen.fill(GREEN)
circle_1 = pygame.draw.circle(screen, BLACK, [250, 230], 7, width_1)
circle_2 = pygame.draw.circle(screen, BLACK, [250, 260], 7, width_2)
circle_3 = pygame.draw.circle(screen, BLACK, [250, 290], 7, width_3)
circle_4 = pygame.draw.circle(screen, BLACK, [250, 320], 7, width_4)
which will (tempoarily) draw two black circles.
You then do:
if filled_1 == True:
# Not run
and then
elif filled_2 == True:
filled_1 = False
filled_3 = False
filled_4 = False
width_1 = 2
width_3 = 2
width_4 = 2
so now
filled_1 = False
filled_2 = True
filled_3 = False
filled_4 = False
This isn't wanted! Now
elif filled_3 == True:
# Not run
elif filled_4 == True:
# Not run
So clicking the third didn't work! This is because you don't store the order, which is needed.
I suggest moving this setting-to-false into the part inside the click handler:
if circle_1.collidepoint(x, y):
# Lets the circle draw
filled_1 = True
width_1 = 0
filled_2 = False
filled_3 = False
filled_4 = False
width_2 = 2
width_3 = 2
width_4 = 2
if filled_1 == True:
circle_1 = pygame.draw.circle(screen, BLACK, [250, 230], 7, width_1)
# ... etc ...
That works beautifully.
Now, there is still a problem. If on the first iteration there was an event, circle_1
would not be defined. This would crash the program. You should define the circles first.
Some code advice.
Instead of
BLACK = ( 0, 0, 0)
GREEN = ( 3, 255, 3)
use
pygame.Color("black")
pygame.Color(3, 255, 3)
They exist for you!
Instead of having
thing_1 = ...
thing_2 = ...
...
other_thing_1 = ...
other_thing_2 = ...
...
have a list of dictionaries:
circles = [
{
"thing": ...,
"other_thing": ...
}, {
"thing": ...,
"other_thing": ...
},
...
]
where you use circles[1]["thing"]
instead of thing_1
.
This allows you to "simplify" to:
import pygame
import random
pygame.init()
circles = [
{
"width": 2,
"filled": False,
"position": [250, 230]
}, {
"width": 2,
"filled": False,
"position": [250, 260]
}, {
"width": 2,
"filled": False,
"position": [250, 290]
}, {
"width": 2,
"filled": False,
"position": [250, 320]
},
]
size = [720, 575]
screen = pygame.display.set_mode(size)
done = False
clock = pygame.time.Clock()
while not done:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
x, y = event.pos
# Check if mouse was over it
if circles[1]["bounding box"].collidepoint(x, y):
# Lets the circle draw
circles[1]["filled"] = True
circles[1]["width"] = 0
circles[2]["filled"] = False
circles[3]["filled"] = False
circles[4]["filled"] = False
circles[2]["width"] = 2
circles[3]["width"] = 2
circles[4]["width"] = 2
if circles[1]["filled"] == True:
circles[1]["bounding box"] = pygame.draw.circle(screen, pygame.Color("black"), [250, 230], 7, circles[1]["width"])
...
# Cleans the screen and sets the screen background
screen.fill(pygame.Color(3, 255, 3))
# Circles
circles[1]["bounding box"] = pygame.draw.circle(screen, pygame.Color("black"), circles[1]["position"], 7, circles[1]["width"])
circles[2]["bounding box"] = pygame.draw.circle(screen, pygame.Color("black"), circles[2]["position"], 7, circles[2]["width"])
circles[3]["bounding box"] = pygame.draw.circle(screen, pygame.Color("black"), circles[3]["position"], 7, circles[3]["width"])
circles[4]["bounding box"] = pygame.draw.circle(screen, pygame.Color("black"), circles[4]["position"], 7, circles[4]["width"])
# Update the screen
pygame.display.flip()
That might not look simpler, but it allows you to use loops instead of specifying things over and over:
import pygame
import random
pygame.init()
circles = [
{
"width": 2,
"filled": False,
"position": [250, 230]
}, {
"width": 2,
"filled": False,
"position": [250, 260]
}, {
"width": 2,
"filled": False,
"position": [250, 290]
}, {
"width": 2,
"filled": False,
"position": [250, 320]
},
]
size = [720, 575]
screen = pygame.display.set_mode(size)
done = False
clock = pygame.time.Clock()
while not done:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
x, y = event.pos
for circle in circles:
# Check if mouse was over it
if circle["bounding box"].collidepoint(x, y):
# Lets the circle draw
circle["filled"] = True
circle["width"] = 0
for othercircle in circles:
if othercircle is not circle:
othercircle["filled"] = False
othercircle["width"] = 2
if circle["filled"] == True:
circle["bounding box"] = pygame.draw.circle(screen, pygame.Color("black"), circle["position"], 7, circle["width"])
# Cleans the screen and sets the screen background
screen.fill(pygame.Color(3, 255, 3))
# Circles
for circle in circles:
circle["bounding box"] = pygame.draw.circle(screen, pygame.Color("black"), circle["position"], 7, circle["width"])
# Update the screen
pygame.display.flip()
With this design:
Q: What do you do to add another circle?
A: You add it to circles
.
Q: What do you do to make a circle larger?
A: You increase its size
property.
Q: What do you do to change the way collisions are checked for?
A: You change the one place collisions are checked.
See the benefit? :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With