Pygame Error: Display surface quit (Why does this happen?) - python

Over the summer I decided to make a version of pong using the pygame module in Python. I already have the game logic and now I am just working on a title screen for some added touch. My main goal for this specific function is to be able to select an option on the screen and have it become highlighted orange. However, I keep getting this weird error error every time I try to scroll down via downward button the program ends and displays this error:
error: display Surface quit
From what I've read this comes from declaring things after pygame.quit() has been initiated so I took it out of my code temporarily, yet the same thing happened without it. WTF?
My code (It has a few unused variable due to the fact that I just copied and pasted it to another python doc):
import pygame,random, time
pygame.init()
#GLOBAL VARIABLES
mode='normal'#Sets game theme
playerx=0 #Paddle x for gamer
playery=0 #paddle y for gamer
aix=0 #paddle x for computer
aiy=0 #paddle y form computer
x=400 #ball x coord
y=300 #ball y coord
speed_ballx=0 #xball pixel change during post blit
speed_bally=0 #yball pixel change during post blit
r=0 #redval
g=0 #greval
b=0 #blueval
#GRAPHIC ART
paddle=pygame.image.load('paddle.PNG')
ball=pygame.image.load('ball.PNG')
logo=pygame.image.load('logo.PNG')
comicsans = pygame.font.SysFont("comicsansms", 22) #comicsans font initialization
startoption = comicsans.render("START", True, (255,255,255))
instructionoption = comicsans.render("HELP", True, (255,255,255))
select=pygame.image.load('optionselect.PNG')
def pong():
main_surface.blit(ball, (x,y))#prints ball
def intsructions():
pygame.quit()
def menu():
end=False #will end while loop and end menu
opt=1 #used to decide what option the player is selecting
main_surface = pygame.display.set_mode((815,615))#creates new window
while end==False:
main_surface.blit(logo, (15,15))
pygame.display.flip()#renders all blitted objects
#The following if statements blit orange highlight on to the selected option
if opt==1:
main_surface.blit(select,(12,140))
if opt==2:
main_surface.blit(select,(12,170))
main_surface.blit(startoption, (15,140))
main_surface.blit(instructionoption, (15,170))
pygame.display.flip()#renders all blitted objects
for ev in pygame.event.get():
if ev.type == pygame.QUIT: # Window close button clicked?
end=True
if ev.type == pygame.KEYDOWN:
if ev.key == pygame.K_DOWN and opt==1: #moving down an option
opt=opt+1
print 2
if ev.key == pygame.K_DOWN and opt==2: #moving from last option (selection restarts at top)
opt=1
if ev.key == pygame.K_KP_ENTER and opt==1: #selecting START
pong()
if ev.key == pygame.K_DOWN and opt==1: #selecting INSTRUCTIONS
intsructions()
pygame.quit()
menu()

I don't see you defining your surface anywhere.
Just define it.

Related

Problem with making Circle properly appear on screen in Pygame

I think my understanding of Pygame is a little bit weak. I would appreciate any help in general about the intricacies of the code (since this was given by the teacher) or simply how I can at least make the obstacle visible.
def draw(screen, background, boids, obstaclearray):
#redrawing the whole window
boids.clear(screen, background)
dirty = boids.draw(screen)
for element in obstaclearray:
pygame.draw.circle(screen, (255,255,255), (element.x, element.y), element.radius)
pygame.display.update(dirty)
Above is where I actually do the drawing and attempt to draw the circle.
The CircularObstacle class is a very simple class that looks like this:
import pygame
class CircularObstacle():
def __init__(self, x, y, radius): #MAYBE ADD A SIZE
self.x = x
self.y = y
self.radius = radius
The problem is that the circle only draws itself when the boids have went over it, which is really weird. I think it has to do with the way the pygame has been setup with and the Surfaces and everything, so below is all the code in main. Of course the obstacle does not work as intended, but I plan to fix that later, first I want to at least get a circle to show.
Below is my full code because I believe it is crucial to solving the issue:
import pygame
from pygame.locals import *
import argparse
import sys
from boid import Boid
from Obstacle import CircularObstacle
def add_boids(boids,num_boids):
for boid in range (num_boids):
boids.add(Boid())
def update(dt, boids):
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit(0)
elif event.type == KEYDOWN:
mods = pygame.key.get_mods()
if event.key == pygame.K_q:
# quit
pygame.quit()
sys.exit(0)
elif event.key == pygame.K_UP:
# add boids
if mods & pygame.KMOD_SHIFT:
add_boids(boids, 100)
else:
add_boids(boids, 10)
elif event.key == pygame.K_DOWN:
# remove boids
if mods & pygame.KMOD_SHIFT:
boids.remove(boids.sprites()[:100])
else:
boids.remove(boids.sprites()[:10])
#ADD STUFF LIKE THE SLIDER AND STUFF
for b in boids:
b.update(dt, boids)
def draw(screen, background, boids, obstaclearray):
#redrawing the whole window
boids.clear(screen, background)
dirty = boids.draw(screen)
for element in obstaclearray:
pygame.draw.circle(screen, (255,255,255), (element.x, element.y), element.radius)
pygame.display.update(dirty)
default_boids = 0
default_geometry = "1000x1000"
# Initialise pygame.
pygame.init()
pygame.event.set_allowed([pygame.QUIT, pygame.KEYDOWN, pygame.KEYUP])
# keep a good framerate so the graphics are better
fps = 60.0
fpsClock = pygame.time.Clock()
# Set up pygamme window
window_width, window_height = 800,600
flags = DOUBLEBUF
screen = pygame.display.set_mode((window_width, window_height), flags)
screen.set_alpha(None)
background = pygame.Surface(screen.get_size()).convert()
background.fill(pygame.Color('black'))
boids = pygame.sprite.RenderUpdates()
add_boids(boids, default_boids)
obstaclearray = []
defaultcircleobstacle = CircularObstacle(200,200,13)
obstaclearray.append(defaultcircleobstacle)
#The "game loop"
dt = 1/fps # here dt means the amount of time elapsed since the last frame
#it seems like thie is a forever loop but in reality this is not since in the update method we provide functinality to quit the program
while True:
update(dt, boids)
draw(screen, background, boids, obstaclearray)
dt = fpsClock.tick(fps)
When you call pygame.display.update() you have 2 options. You can call it without any parameter. In this case the complete screen is updated.
pygame.display.update()
Or call it with a list of rectangular regions that need to be updated. In this case, only the rectangular areas will be updated.
pygame.display.update(rect_list)
You do the 2nd option, but the areas where the circles are drawn are not in the dirty list, therefore this regions are not updated.
pygame.display.update(dirty)
Either update the whole screen with pygame.display.update() or add the regions of the circles to the dirty list:
def draw(screen, background, boids, obstaclearray):
boids.clear(screen, background)
dirty = boids.draw(screen)
for element in obstaclearray:
dirty_rect = pygame.draw.circle(screen, (255,255,255), (element.x, element.y), element.radius)
dirty.append(dirty_rect)
pygame.display.update(dirty)

Why are there black lines appearing between the red and green squares whenever they "move" [duplicate]

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.

Can't click on image again, what's wrong with my pygame code?

Okay, I'am trying to create a Tom and Jerry game with the pygame library.
The game focuses on catching mice by clicking on them as they appear in their holes. The problem
is that sometimes a cat appears instead of a mouse and should the player erroneously click on the
cat (s)he looses all earned points, but the game continues.
The mouse is an image of a mouse and the cat is an image of an cat.
If you click on the mouse, you get mouse, otherwise the cat gets the points.
The code is a mess, that's because I don't know what I'am doing and just set an another event loop because then it works, because it runs after I create the mouse. It works to click on the mouse but then you click somewhere else and after that it's like you did not clicked on the mouse.
The mouse is created in a loop and is supposed to wait for 5 seconds and if you click on the mouse within these seconds then an appropriate message prints out in the console ,,Jerry clicked!" else "1 click". If you don't click on the mouse within 5 seconds a image covers the mouse so she disappears.
Now, what I'am trying to do right now is to print the message 1 click when the player does not click on anything but print 1 click jerry clicked when the player clicks on the mouse. I have a image of the mousehole and then I put the mouse on the mousehole, that is, on an another image.
This code works with one image at least:
pygame.init()
width=350;
height=400
screen = pygame.display.set_mode( (width, height ) )
pygame.display.set_caption('clicked on image')
redSquare = pygame.image.load("images/red-square.png").convert()
x = 20; # x coordnate of image
y = 30; # y coordinate of image
screen.blit(redSquare , ( x,y)) # paint to screen
pygame.display.flip() # paint screen one time
running = True
while (running):
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
# Set the x, y postions of the mouse click
x, y = event.pos
if redSquare.get_rect().collidepoint(x, y):
print('clicked on image')
#loop over, quite pygame
pygame.quit()
My problem is that, when I click on the mouse and then I don't click on the mouse I can't click on the mouse again at another position.
So what's wrong? What I'am doing wrong here?
Here is my code:
import pygame
from pygame import *
from random import *
init()
run = True
screen = (800,800)
screen = display.set_mode(screen)
xpos = 0
ypos = 0
mouseorcatxpos = 5
mouseorcatypos = 0
mousehole = image.load("mousehole.png").convert()
cat = image.load("tom.png")
jerry = image.load("jerry.png")
def makeholes():
global ypos
global xpos
for holey in range(1,9):
for holex in range(1,9):
screen.blit(mousehole,(xpos,ypos))
display.flip()
xpos += 100
ypos += 100
xpos = 0
def mouseorcat():
global xpos
mouseorcatxpos = 5
ypos = 0
for mousecaty in range(1,9):
pygame.event.pump()
for mousecatx in range(1,9):
randommouse = randint(1, 3)
randomcat = randint(1, 10)
if(randommouse == 2):
screen.blit(jerry, (mouseorcatxpos, ypos))
display.flip()
for event in pygame.event.get():
if (event.type == MOUSEBUTTONDOWN):
if jerry.get_rect().collidepoint(xpos, ypos) == False:
print("l clicked!")
x, y = event.pos
if jerry.get_rect().collidepoint(xpos, y):
print("JERRY CLICKED!!")
x, y = event.pos
print(x, y)
time.wait(5000)
#screen.blit(mousehole, (mouseorcatxpos - 5, ypos))
display.flip()
elif(randomcat == 2):
screen.blit(cat, (mouseorcatxpos, ypos))
display.flip()
time.wait(1500)
screen.blit(mousehole, (mouseorcatxpos-5, ypos))
display.flip()
mouseorcatxpos += 100
mouseorcatxpos = 0
ypos += 100
makeholes()
while run == True:
for event in pygame.event.get():
mouseorcat()
if event.type == QUIT:
run = False
I rewrote your game to show you how I would do it.
To keep track of the time and to limit the framerate I used a pygame.time.Clock and a timer variable. The clock returns the time in milliseconds since clock.tick was called the last time, which is used to increase the timer variable. The cat just replaces the mouse after two seconds and the mouse is set to a new position. I use pygame.Rects to store the positions, but you could also use lists or tuples.
import sys
import random
import pygame
pygame.init()
size = (800, 800)
screen = pygame.display.set_mode(size)
# Images replaced by pygame.Surface. Do that too
# in the future before you post your code.
mousehole = pygame.Surface((40, 40)).convert()
mousehole.fill(pygame.Color(30, 30, 30))
cat = pygame.Surface((40, 40)).convert()
cat.fill(pygame.Color(110, 110, 130))
jerry = pygame.Surface((40, 40)).convert()
jerry.fill(pygame.Color(190, 130, 0))
# Create the background image and blit the holes.
background = pygame.Surface(size).convert()
for holey in range(8):
for holex in range(8):
background.blit(mousehole, (holex*100, holey*100))
def new_position():
"""Return a random position between 0-700 in steps of 100."""
return (random.randrange(0, 701, 100), random.randrange(0, 701, 100))
def main():
fps = 30
clock = pygame.time.Clock()
jerry_rect = jerry.get_rect() # Stores jerry's position and size.
jerry_rect.topleft = new_position() # New random position.
# The cat is outside of the screen first.
cat_rect = cat.get_rect(topleft=(-100, -100))
points = 0
timer = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
if jerry_rect.collidepoint(event.pos):
points += 1
print('Jerry caught! Points:', points)
timer = 0
jerry_rect.topleft = new_position()
else:
print('Missed. Points:', points)
# Run logic.
timer += clock.tick(fps) / 1000 # timer + seconds since last tick.
if timer > 2: # Cat catches mouse after 2 seconds.
cat_rect.topleft = jerry_rect.topleft
jerry_rect.topleft = new_position()
timer = 0
points = 0
print('Tom caught Jerry.')
# Draw.
# Clear the screen by blitting the bg.
screen.blit(background, (0, 0))
screen.blit(jerry, jerry_rect)
screen.blit(cat, cat_rect)
pygame.display.flip()
if __name__ == '__main__':
main()
pygame.quit()
sys.exit()
Side notes:
Don't use star imports (from module import *), because that can make code harder to read. If you want you can use from pygame.locals import *, if it's the only star import.
Don't use global variables, because they can make code harder to read, understand and maintain. Pass variables to functions as arguments and then return the result.
Update: Some notes about your program:
The first big problem is that your game has two event loops and the important one is deeply nested inside of two other for loops and a if. The event loop should be directly under the main while loop (one indentation level (when you have more experience you can put it into a function or class method)).
The two for loops seem to have the purpose to let the code run until randommouse or randomcat are 2. To run code until a condition is met is the purpose of a while loop. But in this case you should better just pick a random number and write the if/elif conditions so that they always apply. For example, you want a 2/3 chance for mouse and 1/3 for a cat,
random_number = random.randint(1, 3)
if random_number < 3:
print("2/3 probability. It's a mouse")
else:
print("1/3 probability. It's a cat")
Or use random.choice with a list:
>>> random.choice(['mouse', 'mouse', 'cat'])
'mouse'
time.wait(5000) shouldn't be used because the game just hangs in this time. You can't even close the window. Limit the framerate and get the time since the last tick with a pygame.time.Clock.
pygame.event.pump() is not needed.
If you call get_rect() without an argument, the rect is positioned at (0, 0).
if jerry.get_rect().collidepoint(xpos, y):
That's the reason why clicking on jerry only works in the top row, and because you use the global xpos here. Since xpos is 0, the whole top row counts as Jerry.
You can pass coordinates to get_rect like so (you can also use center or other args instead of topleft):
jerry_rect = jerry.get_rect(topleft=(50, 100))
I'm sorry but I don't think I can simply fix your code. I've tried it several times, but I always end up re-writing it completely.
I begin by extracting the event loop out of the two nested for loops, then remove these loops, create rects for the mouse and cat, fix the collision detection, add a timer and so on. Take a close look at my example and try to rewrite your game in a similar way, and keep asking questions if you don't understand something.

Pygame responds incorrectly to button clicks

I'm having an issue with pygame. I've set up a window that randomly places circles across the screen very quickly, just for testing purposes. There are also three buttons: play/pause (switches back and forth, stops circles from appearing) and an increase speed and decrease speed button. I'm not very experienced with python or pygame, but I've come up with this function to create a clickable button on the screen:
def makeButton(rect, color, hovercolor, text, textsize, textcolor):
clicked = False
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
clicked = True
mouse = pygame.mouse.get_pos()
rect = pygame.Rect(rect)
displaycolor = color
if rect.collidepoint(mouse):
displaycolor = hovercolor
buttonSurface = pygame.draw.rect(gameDisplay, displaycolor, rect, 0)
font = pygame.font.Font('freesansbold.ttf',textsize)
TextSurf = font.render(text, True, textcolor)
TextRect = TextSurf.get_rect()
TextRect.center = rect.center
gameDisplay.blit(TextSurf, TextRect)
if clicked:
return True
else:
return False
This function can definitely be shortened and simplified, but it has worked for me, up until now. I took out a big chunk of code that I realized was useless (having a completely different block of code to render the button when hovered, instead of just changing the display color). Now, whenever I click any of the three previously-mentioned buttons, it seems to pick a random one and return True, messing up the rest of the program. For example, the play button will increase the speed one time, pressing decrease speed will pause, etc. Sometimes it does do what it is supposed to, but it seems to be random.
Some extra info, if it's useful:
-This function is called three times every tick. It's inside a loop, and if it returns true, its corresponding actions are supposed to be performed (pause or play the game, increase/decrease speed)
-The play/pause button is one button that toggles between green with an 'play' arrow, and red with a pause symbol. They are two separate buttons and functions, and only one of them is executed at a time.
-I have almost zero experience with classes, so they may be way better at handling this situation.
-The only explanation I can think of for this problem is that the returned booleans are getting mixed up between the different places this function is used. I'm pretty sure the problem is within this chunk of code, but ask me and I will post the places it is called too.
"pygame.event.get()" takes one event at a time, and *clears it** from the list of events that need to be processed.
So, more specifically, pygame.event.get() returns each event only once.
Take a look at the following code:
clicked = False
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
clicked = True
After this is called, all of the events are removed. Here is an analysis of the code. Assume that there are currently two events that haven't been processed, the first being a key pressed down and the other being a mouse button that's been pressed down.
The first event, event.KEYDOWN, is put into the variable "event".
The program checks whether "event" (currently equal to event.KEYDOWN) is equal to event.MOUSEBUTTONDOWN. They are obviously not the same thing, so the next line is skipped.
The second event, event.MOUSEBUTTONDOWN, is put into variable "event". This removes what was previously in the variable "event", removing the first event from existence.
The program checks whether "event" (currently equal to event.MOUSEBUTTONDOWN) is equal to event.MOUSEBUTTONDOWN. It is, so it proceeds to the next line...
"clicked" is set to True, and the for loop exits, because there are no event remaining.
You should now have a better understanding of how Pygame processes events.
There are also many problems with the function you gave (makeButton). You should find a python tutorial to learn the rest. I suggest a book called "Hello World", by Carter and Warren Sande. The book is kind of out of date (teaches Python 2.5), but its code still works with Python 2.7, and it is one of the few decent Python books I've been able to find.
I have included the code to do what you are trying to do. I don't use Rect objects, but if you want them you can change the code to include them. I also didn't include the text, because I am short on time. Instead of placing random circles, this prints text (to the shell) when buttons are clicked.
import pygame, sys
pygame.init()
screen = pygame.display.set_mode([640,480])
clock = pygame.time.Clock()
buttons = []
#buttons = [[rect, color, hovercolor, hovering, clicked, msg]]
def makeButton(rect, color, hovercolor, text):
global buttons
buttons.append([rect, color, hovercolor, False, False, text])
makeButton([0,0,50,50], [0,127,0], [0,255,0], "Clicked Green")
makeButton([50,0,50,50], [190,190,0], [255,255,0], "Clicked Yellow")
makeButton([100,0,50,50], [0,0,127], [0,0,255], "Clicked Blue")
while 1:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.MOUSEMOTION:
mousepos = event.pos
for a in range(len(buttons)):
if mousepos[0] >= buttons[a][0][0] and mousepos[0] <= buttons[a][0][0]+buttons[a][0][2] and mousepos[1] >= buttons[a][0][1] and mousepos[1] <= buttons[a][0][1]+buttons[a][0][3]:
buttons[3] = True
else:
buttons[3] = False
if event.type == pygame.MOUSEBUTTONDOWN:
mousepos = event.pos
for a in range(len(buttons)):
if mousepos[0] >= buttons[a][0][0] and mousepos[0] <= buttons[a][0][0]+buttons[a][0][2] and mousepos[1] >= buttons[a][0][1] and mousepos[1] <= buttons[a][0][1]+buttons[a][0][3]:
buttons[4] = True
else:
buttons[4] = False
for a in range(len(buttons)):
if buttons[3] == 0:
pygame.draw.rect(screen, buttons[1], buttons[0])
else:
pygame.draw.rect(screen, buttons[2], buttons[0])
if buttons[4] == 1:
buttons[4] = 0
print buttons[5]
pygame.display.flip()
I haven't had the opportunity to test out the code I just typed (using school computer), but it should work. If there are any problems with the code, just leave a comment and I'll fix it.
Also leave a comment if you don't understand something. Don't give up, you can do it!

Menu problem with PyGame MOUSEBUTTONDOWN event

Yes, that title wasn't worded very properly at all.
Ok, here's what we've got - a Python program using the pyGame library, and we're making a game. We start in a menu environment main.py. When the user clicks on one of the menu buttons, an action is performed. The program checks for clicks on menu items using the following code:
if event.type == pygame.MOUSEBUTTONDOWN:
mousePos = pygame.mouse.get_pos()
for item in buttons: # For each button
X = item.getXPos() # Check if the mouse click was...
Y = item.getYPos() # ...inside the button
if X[0] < mousePos[0] < X[1] and Y[0] < mousePos[1] < Y [1]:
# If it was
item.action(screen) # Do something
When the user clicks on the "Play Game" button, it opens a sub-module, playGame.py. In this sub-module is another pyGame loop etc.
Part of the game is to hold the left mouse button to 'grow' circles out of the current position (It's a puzzle game, and it makes sense in context). Here is my code for doing this:
mouseIsDown == False
r = 10
circleCentre = (0,0)
[...other code...]
if mouseIsDown == True:
# This grown the circle's radius by 1 each frame, and redraws the circle
pygame.draw.circle(screen, setColour(currentColourID), circleCentre, r, 2)
r += 1
for event in pygame.event.get():
if event.type == pygame.QUIT:
runningLevel = False
elif event.type == pygame.MOUSEBUTTONDOWN:
# User has pressed mouse button, wants to draw new circle
circleCentre = pygame.mouse.get_pos()
mouseIsDown = True
elif event.type == pygame.MOUSEBUTTONUP:
# Stop drawing the circle and store it in the circles list
mouseIsDown = False
newCircle = Circle(circleCentre, r, currentColourID)
circles.append(newCircle)
circleCount += 1
r = 10 # Reset radius
The problem I have is that the user's left mouse click from the main menu is persisting into the playGame.py module, and causing it to create and store a new circle, of radius 10 and at position (0,0). Both of these are the default values.
This only happens for the one frame after the menu.
Is there any way to prevent this, or is it a flaw in my code?
All help greatly appreciated, as always. If you need more code or explanation of these snippets, let me know.
If you'd like the full code, it's on GitHub.
You could use MOUSEBUTTONUP instead of MOUSBUTTONDOWN in the menu.
Does adding pygame.event.clear() to the top of Play fix it?

Categories