my click's counter program wont work - python

After importing the modules and declaring the variables here is how my code starts:
while True:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == MOUSEBUTTONDOWN:
dibujarCirculo()
cont += 1
contador = texto.render("Clicks: " + str(cont), 1, green)
ventana.blit(contador, CONT_POS)
pygame.display.update()
When i run it i get the screen fill with black, and some text "Clicks :0" and when i click the mouse, instead of turning "Clicks: 1" the 1 stacks over the zero and it becomes a mess.
My intention is simply: when you click somewhere in the window it adds 1 to a click's counter. Also it actually draw a circle but that's not important.
i will post the whole code if you want to give it a look.
import sys
import pygame
from pygame.constants import *
pygame.init()
ventana = pygame.display.set_mode((600, 400))
pygame.display.set_caption("Basics")
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
darkBlue = (0, 0, 128)
white = (255, 255, 255)
black = (0, 0, 0)
pink = (255, 200, 200)
cont = 0
CONT_POS = (50, 100)
texto = pygame.font.SysFont("monospace", 15)
def dibujarCirculo():
pos = pygame.mouse.get_pos()
radius = 10
pygame.draw.circle(ventana, white, pos, radius)
cont = 0
while True:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == MOUSEBUTTONDOWN:
dibujarCirculo()
cont += 1
contador = texto.render("Clicks: " + str(cont), 1, green)
ventana.blit(contador, CONT_POS)
pygame.display.update()
note: it is the second time i am posting these because people is voting down for no reason and also tagging the post as off-topic when i try to explain my problem the best way i know...

You need to clear the screen to avoid drawing on top of the old text
while True:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == MOUSEBUTTONDOWN:
dibujarCirculo()
cont += 1
ventana.fill((0,0,0)) # clear the screen
contador = texto.render("Clicks: " + str(cont), 0, green)
ventana.blit(contador, CONT_POS)
pygame.display.update()
You can add the blit using black in your first function to just overwrite the blit each time.
def dibujarCirculo():
pos = pygame.mouse.get_pos()
radius = 10
pygame.draw.circle(ventana, white, pos, radius)
contador = texto.render("Clicks: " + str(cont), 0, black) # set background to black
ventana.blit(contador, CONT_POS)
while True:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == MOUSEBUTTONDOWN:
dibujarCirculo()
cont += 1
contador = texto.render("Clicks: " + str(cont), 1, green)
ventana.blit(contador, CONT_POS)
pygame.display.update()

Related

how to remove square after 2 seconds

I have this code and I don't know how to make the red cube disappear after 2 seconds.
import pygame
import sys
from pygame.locals import *
pygame.init()
a=0
#display
prozor = pygame.display.set_mode((800,800))
FPS = pygame.time.Clock()
FPS.tick(60)
#boje
green=pygame.Color(0 ,255 , 0)
red=pygame.Color(255, 0, 0)
yellow=pygame.Color(255, 255, 0)
blue=pygame.Color(0, 0, 255)
black=pygame.Color(0, 0, 0)
white=pygame.Color(255, 255, 255)
#class
class Cube:
def update(self):
self.cx, self.cy = pygame.mouse.get_pos()
self.square = pygame.Rect(self.cx, self.cy, 50, 50)
def draw(self):
pygame.draw.rect(prozor, (255, 0, 0), self.square)
cube = Cube()
drawing_cube = False
#objekt
for j in range(16):
for i in range(800):
if i%50 == 0:
pygame.draw.rect(prozor, green, ((0+i, a), (50, 50),),1)
a=a+50
#gameloop
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit
if event.type == pygame.MOUSEBUTTONDOWN:
cube.update()
drawing_cube = True
if drawing_cube:
cube.draw()
pygame.display.flip()
pygame.display.update()
Adding it to the draw class will just freeze the game and shut it.
def draw(self):
pygame.draw.rect(prozor, red, self.square)
time.sleep(3)
pygame.draw.rect(prozor, black, self.square
I tried making another class called delete which would delete the cube after 3 seconds using the time module.
def delete(self):
time.sleep(3)
pygame.draw.rect(prozor, black, self.square)
and added it here
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit
if event.type == pygame.MOUSEBUTTONDOWN:
cube.update()
drawing_cube = True
if drawing_cube:
cube.draw()
pygame.display.flip()
**cube.delete**
pygame.display.flip()
pygame.display.update()
but the cube is not disappearing.
Use pygame.time.get_ticks to measure the time in milliseconds. Calculate the time when the cube must disappear again and hide the cube if the current time is greater than the calculated time. You also need to clear the display (prozor.fill(0)) and redraw the scene in each frame:
drawing_cube = False
hide_cube_time = 0
clock = pygame.time.Clock()
run = True
while run:
clock.tick(100)
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
cube.update()
drawing_cube = True
hide_cube_time = current_time + 2000 # 2000 milliseconds == 2 sconds
if current_time > hide_cube_time:
drawing_cube = False
prozor.fill(0)
a=0
for j in range(16):
for i in range(800):
if i%50 == 0:
pygame.draw.rect(prozor, green, (0+i, a, 50, 50), 1)
a=a+50
if drawing_cube:
cube.draw()
pygame.display.update()
pygame.quit()
sys.exit()
Note, 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()

why this code is not letting me draw using the rectangle but just moving the rectangle?

import pygame
pygame.init()
win = pygame.display.set_mode((800, 600))
Listing all pixels in pygame window in an array
pts = pygame.PixelArray(win)
Creating some color constants
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
GREY = (128, 128, 128)
clicked = False
clock = pygame.time.Clock()
# GAME LOOP
while True:
win.fill(BLACK)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
Checking if left mousebutton if clicked and held
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
clicked = True
Checking if mousebutton released
elif event.type == pygame.MOUSEBUTTONUP:
clicked = False
I don't know if something is wrong down here.
if clicked:
mouse_X, mouse_Y = pygame.mouse.get_pos()
for a in range(mouse_X, mouse_X + 79):
pts[a][mouse_Y:mouse_Y + 60] = GREEN
pygame.display.update()
clock.tick(250)
This is a problem of your logic. The rectangle is not drawn permanently.
pts[a][mouse_Y:mouse_Y + 60] = GREEN changes a pixel in the win Surface.
However win.fill(BLACK) turns all the pixel in win into BLACK.
Copy the "win" surface as soon as a rectangle has been placed on a permanant_win Surface. blit the Surface as the background of the window at the beginning of the application loop:
import pygame
pygame.init()
win = pygame.display.set_mode((800, 600))
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
clicked = False
clock = pygame.time.Clock()
permanant_win = win.copy()
while True:
win.blit(permanant_win, (0, 0))
make_permanent = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
clicked = True
elif event.type == pygame.MOUSEBUTTONUP:
make_permanent = True
if clicked:
mouse_X, mouse_Y = pygame.mouse.get_pos()
pts = pygame.PixelArray(win)
for a in range(mouse_X, mouse_X + 79):
pts[a][mouse_Y:mouse_Y + 60] = GREEN
pts = None
if make_permanent:
permanant_win = win.copy()
pygame.display.update()
clock.tick(250)

How to draw a continuous line in Pygame?

I want to draw a line when mouse clicked and moving in Pygame framework, it will be a line if I move the mouse very slowly. However, if I move the mouse quickly, it's just incontinuous dots. The question is how to draw a continuous line when mouse move? Thanks in advance.
import pygame, sys
from pygame.locals import *
def main():
pygame.init()
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
mouse_position = (0, 0)
drawing = False
screen = pygame.display.set_mode((600, 800), 0, 32)
screen.fill(WHITE)
pygame.display.set_caption("ScratchBoard")
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == MOUSEMOTION:
if (drawing):
mouse_position = pygame.mouse.get_pos()
pygame.draw.line(screen, BLACK, mouse_position, mouse_position, 1)
elif event.type == MOUSEBUTTONUP:
mouse_position = (0, 0)
drawing = False
elif event.type == MOUSEBUTTONDOWN:
drawing = True
pygame.display.update()
if __name__ == "__main__":
main()
By calling pygame.draw.line with the same argument (mouse_position) twice, you're not drawing a line, you're drawing a single pixel, because start_pos and end_pos are the same.
To get a contiguous line, you need to save the last position and draw a line between it and the next position, like this (changes are the lines with last_pos):
import pygame, sys
from pygame.locals import *
def main():
pygame.init()
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
mouse_position = (0, 0)
drawing = False
screen = pygame.display.set_mode((600, 800), 0, 32)
screen.fill(WHITE)
pygame.display.set_caption("ScratchBoard")
last_pos = None
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == MOUSEMOTION:
if (drawing):
mouse_position = pygame.mouse.get_pos()
if last_pos is not None:
pygame.draw.line(screen, BLACK, last_pos, mouse_position, 1)
last_pos = mouse_position
elif event.type == MOUSEBUTTONUP:
mouse_position = (0, 0)
drawing = False
elif event.type == MOUSEBUTTONDOWN:
drawing = True
pygame.display.update()
if __name__ == "__main__":
main()
vgel is right, you need to pass the previous position and the current position to pygame.draw.line. You can also calculate the previous position by subtracting the event.rel attribute of the event from the event.pos attribute.
It's also possible get rid of the drawing variable by using the event.buttons attribute. If event.buttons[0] is True then the left mouse button is being pressed.
import pygame
def main():
pygame.init()
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
screen = pygame.display.set_mode((600, 800), 0, 32)
screen.fill(WHITE)
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
elif event.type == pygame.MOUSEMOTION:
if event.buttons[0]: # Left mouse button down.
last = (event.pos[0]-event.rel[0], event.pos[1]-event.rel[1])
pygame.draw.line(screen, BLACK, last, event.pos, 1)
pygame.display.update()
clock.tick(30) # Limit the frame rate to 30 FPS.
if __name__ == "__main__":
main()

How to create a pause button in Pygame?

I've been trying to make a game, and everything in there works so far except that the pause button , that when pressed the button P should pause and when pressed S should continue. I kinda understand the problem such that once in enters the while loop in the main code it wont get out. I tried putting the pause function inside the while loop. Please do help or provide tips to fix if possible thank you.
import pygame
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
Blue = (2,55,55)
def recursive_draw(x, y, width, height):
""" Recursive rectangle function. """
pygame.draw.rect(screen, WHITE,
[x, y, width, height],
1)
speed = [10,0]
rect_change_x = 10
rect_change_y = 10
# Is the rectangle wide enough to draw again?
if (width > 25):
# Scale down
x += width * .1
y += height * .1
width *= .8
height *= .8
# Recursively draw again
recursive_draw(x, y, width, height)
def recursive_draw2(x, y, width, height):
""" Recursive rectangle function. """
pygame.draw.rect(screen, Blue,
[x, y, width, height],
1)
speed = [10,0]
rect_change_x = 10
rect_change_y = 10
# Is the rectangle wide enough to draw again?
if (width > 25):
x += width * .1
y += height * .1
width *= .8
height *= .8
# Recursively draw again
recursive_draw2(x, y, width, height)
def paused():
screen.fill(black)
largeText = pygame.font.SysFont("comicsansms",115)
TextSurf, TextRect = text_objects("Paused", largeText)
TextRect.center = ((display_width/2),(display_height/2))
gameDisplay.blit(TextSurf, TextRect)
while pause:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
#gameDisplay.fill(white)
button("Continue",150,450,100,50,green,bright_green,unpause)
button("Quit",550,450,100,50,red,bright_red,quitgame)
pygame.display.update()
clock.tick(15)
pygame.init()
#rectanglelist = [big()]
# Set the height and width of the screen
size = [700, 500]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("My Game")
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
black=(0,0,0)
end_it=False
time = 100
USEREVENT = 0
pygame.time.set_timer(USEREVENT+1, 10)
milliseconds = 0
seconds = 0
start_it = False
while (end_it==False):
screen.fill(black)
myfont=pygame.font.SysFont("Britannic Bold", 40)
nlabel=myfont.render("Welcome to "+ " Jet shooter ", 1, (255, 0, 0))
label=myfont.render("Click on the mouse to start ", 1, (255, 0, 0))
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
end_it=True
screen.blit(nlabel,(200, 100))
screen.blit(label, (170,300))
pygame.display.flip()
while (start_it==False):
screen.fill(black)
myfont2=pygame.font.SysFont("Britannic Bold", 40)
label2=myfont2.render("Ready?", 1, (255, 0, 0))
screen.blit(label2, (300,250))
pygame.display.flip()
pygame.time.wait(3000)
start_it = True
fall = False
while (fall==False):
nlist = [3,2,1]
for i in (nlist):
screen.fill(black)
n = str(i)
myfont3=pygame.font.SysFont("Britannic Bold", 40)
score = myfont3.render(n,1,(255,0,0))
screen.blit((score), (350,250))
pygame.display.flip()
pygame.time.wait(1000)
screen.fill(black)
myfont4=pygame.font.SysFont("Britannic Bold", 40)
label4=myfont3.render("GOOO!!!", 1, (255, 0, 0))
screen.blit(label4, (300,250))
pygame.display.flip()
pygame.time.wait (1000)
fall = True
pause = 0
b = 0
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.KEYUP:
if event.key==K_p:
pause=True
if pause == True:
screen.fill(black)
font=pygame.font.SysFont("Britannic Bold", 40)
nlabelBB=myfont.render("Pause", 1, (255, 0, 0))
screen.blit(nlabelBB,(200, 100))
pygame.display.flip()
# Set the screen background
screen.fill(BLACK)
flip = 1
a = 0
# ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
recursive_draw(0, 0, 700, 500)
recursive_draw2(35,25, 625, 450)
**###I TRIED TO PUT THE PAUSE GAME HERE AND IF PRESSED P PAUSE AND S CONTINUE
while a == 0 :
if flip == 1 :
recursive_draw(35,25,625,450)
recursive_draw2(0, 0, 700, 500)
flip = flip + 1
pygame.display.flip()
if event.type == pygame.KEYUP:
if event.key==K_p:
a = 1
screen.fill(black)
font=pygame.font.SysFont("Britannic Bold", 40)
nlabelBB=myfont.render("Pause", 1, (255, 0, 0))
screen.blit(nlabelBB,(200, 100))
pygame.display.flip()
if event.key==K_s:
a = 0
if flip == 2 :
recursive_draw(0, 0, 700, 500)
recursive_draw2(35, 25, 625, 450)
flip = flip - 1
pygame.display.flip()
if event.type == pygame.KEYUP:
if event.key==K_p:
a = 1
screen.fill(black)
font=pygame.font.SysFont("Britannic Bold", 40)
nlabelBB=myfont.render("Pause", 1, (255, 0, 0))
screen.blit(nlabelBB,(200, 100))
pygame.display.flip()
if event.key==K_s:
a = 0**
if event.type == pygame.QUIT:
done = True
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 60 frames per second
clock.tick(20)
# Be IDLE friendly. If you forget this line, the program will 'hang'
# on exit.
pygame.quit()
Just use a single game loop for everything and keep track of the current state (e.g. main menu, pause screen, game scene) of your game..
Here's an example where we keep track of the state by a simple variable called state and act in our game loop accordingly:
import pygame, math, itertools
def magnitude(v):
return math.sqrt(sum(v[i]*v[i] for i in range(len(v))))
def sub(u, v):
return [u[i]-v[i] for i in range(len(u))]
def normalize(v):
return [v[i]/magnitude(v) for i in range(len(v))]
pygame.init()
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
path = itertools.cycle([(26, 43), (105, 110), (45, 225), (145, 295), (266, 211), (178, 134), (250, 56), (147, 12)])
target = next(path)
ball, speed = pygame.rect.Rect(target[0], target[1], 10, 10), 3.6
pause_text = pygame.font.SysFont('Consolas', 32).render('Pause', True, pygame.color.Color('White'))
RUNNING, PAUSE = 0, 1
state = RUNNING
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT: break
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_p: state = PAUSE
if e.key == pygame.K_s: state = RUNNING
else:
screen.fill((0, 0, 0))
if state == RUNNING:
target_vector = sub(target, ball.center)
if magnitude(target_vector) < 2:
target = next(path)
else:
ball.move_ip([c * speed for c in normalize(target_vector)])
pygame.draw.rect(screen, pygame.color.Color('Yellow'), ball)
elif state == PAUSE:
screen.blit(pause_text, (100, 100))
pygame.display.flip()
clock.tick(60)
continue
break
As you can see, the rectangle keeps moving until you press P, which will change the state to PAUSE; and a simple message will now be displayed instead of drawing/moving the rectangle further.
If you press S the state switches back to the normal mode; all done in a single game loop.
Further reading:
Pygame level/menu states
Mulitple Displays in Pygame
Trying to figure out how to track Pygame events and organize the game's functions

Why do the circles not disappear after being drawn?

When I run this code it just make a trail of circles instead of one circle moving. The code is as follows:
import pygame, sys, random
from pygame.locals import *
pygame.init()
windowSurface = pygame.display.set_mode((500, 400), 0, 32)
WHITE = (255, 255, 255)
circX = 250
circY= 250
diffX= 0
diffY=0
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
diffX += random.randint(-1,1)
diffY += random.randint(-1,1)
circX += diffX
circY += diffY
circLocate = (circX,circY)
pygame.draw.circle(windowSurface, WHITE, circLocate, 10, 0)
pygame.display.flip()
You have to clear the screen so it appears like the object is moving.
windowSurface.fill(WHITE)
As such:
import pygame, sys, random
from pygame.locals import *
pygame.init()
windowSurface = pygame.display.set_mode((500, 400), 0, 32)
WHITE = (255, 255, 255)
circX = 250
circY= 250
diffX= 0
diffY=0
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
diffX += random.randint(-1,1)
diffY += random.randint(-1,1)
circX += diffX
circY += diffY
circLocate = (circX,circY)
windowSurface.fill(WHITE)
pygame.draw.circle(windowSurface, WHITE, circLocate, 10, 0)
pygame.display.flip()
However, make sure that the windowSurface.fill() is before the pygame.draw.circle(), else, it will only show a white screen.
This addition should clear your screen each time you want the circle to move
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
windowSurface.fill(WHITE) //add this line to clear the screen
diffX += random.randint(-1,1)
diffY += random.randint(-1,1)
circX += diffX
circY += diffY
circLocate = (circX,circY)
pygame.draw.circle(windowSurface, WHITE, circLocate, 10, 0)
pygame.display.flip()

Categories