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()
I am currently starting on python3 in the past few days and started in developing minor projects, but i'm having some trouble, so sorry if i cant use top notch proffessional coders language.
How can I make a pygame.draw.rect rectangle become clickable?
I know about the pygame.mouse. ones, but there might be something wrong in the code.
I want it so that when i press the red rect it will decreese i health and will add a "burn" stat (its just text for now).
Here's the code:
import pygame
import random
import sys
pygame.init()
#Screen Size
screen_width = 600
screen_height = 600
#Screen Settings
screen = pygame.display.set_mode((screen_width, screen_height))
br_color = (0, 0, 0)
pygame.display.set_caption("Type Effect Beta 0.0.1")
#Game Over Bullian
game_over = False
#Other Defenitions
clock = pygame.time.Clock()
myFont = pygame.font.SysFont("arial", 20)
#Basic Recources
health = 50
score = 0
status = "none"
#Colors for the Text
white = (255, 255, 255)
red = (255, 0, 0)
#Mouse Things
mouse_location = pygame.mouse.get_pos()
print(mouse_location)
#Status Text Helpers
burning = "Burning"
#Cards
card_size_x = 45
card_size_y = 60
fire_car_color = (255, 0 ,0)
fire_card_posx = 300
fire_card_posy = 300
card_button_fire = pygame.Rect(fire_card_posx, fire_card_posy, card_size_x, card_size_y)
#Functions
def health_decrease_burn(health, status):
health -= 1
status = "burning"
return health and status
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if pygame.mouse.get_pressed()[0] and card_button_fire.collidepoint(mouse_location):
health_decrease_burn()
if health_decrease_burn(health, status) and health <= 0:
game_over = True
text = "Score:" + str(score)
lable = myFont.render(text, 1, white)
screen.blit(lable, (10, 10))
text = "Health:" + str(health)
lable = myFont.render(text, 1, red)
screen.blit(lable, (10, 30))
text = "Status:" + str(status)
lable = myFont.render(text, 1, white)
screen.blit(lable, (10, 50))
pygame.draw.rect(screen, fire_car_color, (fire_card_posx, fire_card_posy, card_size_x, card_size_y))
clock.tick(30)
pygame.display.update()
You need to grab the mouse_location every iteration of your main loop, as the mouse position/state is constantly changing. The current code is only fetching the mouse position once, on start.
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP: # if mouse button clicked
mouse_location = pygame.mouse.get_pos() # <-- HERE
if pygame.mouse.get_pressed()[0] and card_button_fire.collidepoint(mouse_location):
health_decrease_burn()
#[...etc ]
I'm new to pygame and I'm writing a program that allows the user to click and drag a rectangle around the pygame window, then sends it's coordinates through a socket. I can move the rectangle on mouse click, but I've been messing around with it for a while and still can't figure out how to implement click and drag. Any help would be appreciated. Here's the relevant code:
from pygame.locals import *
import socket, pygame, time
#define variables
x = y = 0
screen = pygame.display.set_mode((430, 410))
targetRectangle = pygame.draw.rect(screen, (255, 0, 0), (176, 134, 7, 7))
pygame.display.flip()
#define smaller functions
#define function to start pygame window
def startPygame():
pygame.display.set_caption(option + " Tracking System")
pygame.mouse.set_visible(True)
screen.fill((255, 255, 255))
targetRectangle = pygame.draw.rect(screen, (255, 0, 0), (176, 134, 7, 7))
pygame.display.flip()
#define function to update pygame window
def updateWindow():
screen.fill((255, 255, 255))
global targetRectangle
global xPosition
global yPosition
targetRectangle = pygame.draw.rect(screen, (255, 0, 0), (xPosition, yPosition, 7, 7))
pygame.display.flip()
#define main functions
def collectMouseData():
startPygame()
print "\n"
print "mouse tracking system"
#wait until a mouse button is clicked
running = 1
while running == 1:
event = pygame.event.poll()
if event.type == pygame.QUIT:
c.send("quit")
pygame.quit()
running = 0
#see if a mousebutton is down
elif event.type == pygame.MOUSEBUTTONDOWN:
xMouse = event.pos[0]
yMouse = event.pos[1]
#see if mouse click collides with targetRectangle
if targetRectangle.collidepoint(xMouse, yMouse):
global xPosition
xPosition = event.pos[0]
global yPosition
yPosition = event.pos[1]
updateWindow()
global targetRectangle
sendData(targetRectangle)
You have to use
MOUSEBUTTONDOWN to check if object was clicked and set drag = True (and remember offset between mouse position and rectangle top-left corner)
MOUSEBUTTONUP to set drag = False
MOUSEMOTION to move object when drag == True using mouse position and offset.
Working example
import pygame
# --- constants --- (UPPER_CASE names)
SCREEN_WIDTH = 430
SCREEN_HEIGHT = 410
#BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
FPS = 30
# --- classses --- (CamelCase names)
# empty
# --- functions --- (lower_case names)
# empty
# --- main ---
# - init -
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
#screen_rect = screen.get_rect()
pygame.display.set_caption("Tracking System")
# - objects -
rectangle = pygame.rect.Rect(176, 134, 17, 17)
rectangle_draging = False
# - mainloop -
clock = pygame.time.Clock()
running = True
while running:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if rectangle.collidepoint(event.pos):
rectangle_draging = True
mouse_x, mouse_y = event.pos
offset_x = rectangle.x - mouse_x
offset_y = rectangle.y - mouse_y
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
rectangle_draging = False
elif event.type == pygame.MOUSEMOTION:
if rectangle_draging:
mouse_x, mouse_y = event.pos
rectangle.x = mouse_x + offset_x
rectangle.y = mouse_y + offset_y
# - updates (without draws) -
# empty
# - draws (without updates) -
screen.fill(WHITE)
pygame.draw.rect(screen, RED, rectangle)
pygame.display.flip()
# - constant game speed / FPS -
clock.tick(FPS)
# - end -
pygame.quit()
EDIT: other examples with many rectangles or circles and buttons on GitHub:
furas/python-examples/pygame/drag-rectangles-circles
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
I would like to keep the screen green for a time and register KEYDOWNS but I cant while the pygame.time.wait function is running
self.screen.fill(self.red)
pygame.time.wait(self.wait)
rect = self.text.get_rect()
rect = rect.move(500,500)
self.screen.blit(self.text, rect)
if event.type == pygame.KEYDOWN:
print "Ouch"
self.lives -= 1
print self.lives
self.screen.fill((255, 255, 255))
self.text = sysfont.render("Lives: %d" % self.lives, True, (255, 255, 255))
self.screen.blit(self.text, (25, 25))
pygame.display.flip()
pygame.display.flip()
You can make something like this: (5 seconds = 5000 milliseconds)
time_to_change_color = pygame.time.get_ticks() + 5000 # 5 seconds
# main loop
while TRUE:
# place for events
if pygame.time.get_ticks() < time_to_change_color:
self.screen.fill(self.GREEN)
else:
self.screen.fill(self.BLACK)
# place for blits
pygame.display.flip()
or like this:
time_to_change_color = pygame.time.get_ticks() + 5000 # 5 seconds
current_background_color = self.GREEN
# main loop
while TRUE:
# place for events
if pygame.time.get_ticks() > time_to_change_color:
current_background_color = self.BLACK
self.screen.fill(current_background_color)
# place for blits
pygame.display.flip()