How to make the object move during a while infinite loop? - python

I've been trying to create a game. In the game there is a jet that would fly into the recursive background rectangles. The rectangles are created through an infinite loop so once it enters the loop rest of the functions don't work for example the object. My code is below and the problem arises in the main loop. I want the object to move with the recursive rectangles but it freezes when the rectangles start being drawn in the loop. PS help to fix this as I've tried almost every code sample out there to fix it. Thank you
EDIT: the main function of the game is to make the jet go through what seems like recursive like rectangles (there are two of them and the while loop makes it simultaneously move up and down giving the feeling that the jet is going into the screen.). But since the jet is drawn first, when the program enters the rectangle loop the jet freezes and wont be able to move. I want the jet to move while the background is also moving.
import pygame
import random
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
Blue = (2,55,55)
black=(0,0,0)
end_it=False
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 timer(self):
screen.fill(black)
myfont=pygame.font.SysFont("Britannic Bold", 40)
label2=myfont.render("Ready?", 1, (255, 0, 0))
screen.blit(label2, (350,250))
self =3
nlist=[]
for i in range (2):
score = myfont.render(str(self),1,(255,0,0))
screen.blit((score), (350,250))
self = self - 1
nlist.append(self)
pygame.display.flip()
'''
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()
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
b = 0
flip = 1
a = 0
time = 100
x_speed = 0
y_speed = 0
x_coord = 320
y_coord = 400
image = pygame.image.load("spaceship.gif").convert()
# -------- Main Program Loop -----------
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# User pressed down on key
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x_speed = -10
if event.key == pygame.K_RIGHT:
x_speed = 10
if event.key == pygame.K_UP:
y_speed = -10
if event.key == pygame.K_DOWN:
y_speed = 10
# User let go of key
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
x_speed = 0
if event.key == pygame.K_RIGHT:
x_speed = 0
if event.key == pygame.K_UP:
y_speed = 0
if event.key == pygame.K_DOWN:
y_speed = 0
x_coord += x_speed
y_coord += y_speed
# Set the screen background
screen.fill(BLACK)
screen.blit(image, [x_coord,y_coord])
pygame.display.flip()
clock.tick(60)
# ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
# Go ahead and update the screen with what we've drawn.
# Limit to 60 frames per second
# Be IDLE friendly. If you forget this line, the program will 'hang'
# on exit.
while a == 0 :
if flip == 1 :
recursive_draw(35,25,625,450)
recursive_draw2(0, 0, 700, 500)
flip = flip + 1
pygame.display.flip()
clock.tick(60)
if flip == 2 :
recursive_draw(0, 0, 700, 500)
recursive_draw2(35, 25, 625, 450)
flip = flip - 1
pygame.display.flip()
clock.tick(60)
pygame.quit()

As #Paul Rooney has stated, you'll want to use threads. Here's how you would
import thread
.
.
.
# Instead of calling the function as you are, run it on a new thread
thread.start_new_thread(drawRectanglesFunction, ())

From what I can tell is that you're drawing things in the incorrect order, and I believe that while loop is not needed. (while a == 0). Another thing is that you're flipping the display too often it is hard to keep track of what gets drawn first, and what gets drawn afterwards. My suggestion would be to quickly rewrite your program so that it looks something similar to this:
flip = 1
while not done:
##Catch and handle events()
screen.fill(BLACK)
if flip == 1 :
recursive_draw(35,25,625,450)
recursive_draw2(0, 0, 700, 500)
flip = flip + 1
elif flip == 2 :
recursive_draw(0, 0, 700, 500)
recursive_draw2(35, 25, 625, 450)
flip = flip - 1
screen.blit(image, [x_coord,y_coord])
pygame.display.flip()
clock.tick(60);
I hope this helps out a little.
(Edit: I did this on my own and got the program to run)

Related

Making Flappy Bird but how do I implement the pipes generating offscreen then going across the screen and despawning

So I am a bit stuck on how to implement the pipes spawning offscreen and making them move across the screen so that they can collide the bird and then DE spawning off screen. Do I need to give the pipes acceleration or something else?
I am fairly new to code but I have some ides on how to do it but I don't really know how to implement it or how to make a pipes randomly generate.
#Floppy disk
import sys, pygame
from pygame import mixer
import time
pygame.init()
pygame.mixer.init()
FRAMERATE = 60
clock = pygame.time.Clock()
mixer.music.load('africa-toto.wav')
mixer.music.play(1, 0.0, 3000)
size = width, height = 1000, 1000
speed = [2,2]
power = [0.1, 0.1]
white = 255, 255, 255
black = 0, 0, 0
blue = 0, 255, 200
green = 0, 200, 0
dy = 2
dx =2
screen = pygame.display.set_mode(size)
player1 = pygame.image.load("floppy1.jpg")
pygame.key.set_repeat(1,1)
player = pygame.draw.rect(screen, blue, (500, 500,10, 10))
playerrect = player1.get_rect()
background_image = pygame.image.load("circuit.jpeg").convert()
def obstacles():
obst1 = pygame.draw.rect(screen, green, (500, 600, 100, 450))
obst2 = pygame.draw.rect(screen, green, (500, 0, 100, 450))
obst3 = pygame.draw.rect(screen, green, (700, 0, 100, 400))
obst4 = pygame.draw.rect(screen, green, (700, 550, 100, 500))
obstacles()
while True:
clock.tick(FRAMERATE)
print(dy)
if dy > 0:
dy *= 1.03
if dy < 2:
dy *= 1.03
if dy < 0:
dy *= 0.9
if dy > -1.3:
dy *= 0.95
if dy < 0 and dy > -0.6: #Deceleraiton point
dy *= -1.2
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
## if event.key == pygame.K_LEFT:
## speed[0] -= power[0]
## if event.key == pygame.K_RIGHT:
## speed[0] += power[0]
if event.key == pygame.K_UP:
dy = -10
#speed[1] -= power[1]
if event.key == pygame.K_DOWN:
speed[1] += power[1]
if playerrect.bottom > height:
dy = -20
if playerrect.top < 0:
dy = 15
playerrect = playerrect.move(0, dy)
#screen.fill(white)
screen.blit(background_image, [0,0])
screen.blit(player1, playerrect, obstacles())
pygame.display.flip()
pygame.display.update()
for multiple things that do very similar things i would highly recommend the use of classes: https://docs.python.org/3/tutorial/classes.html
# you don't need to declare those variables globally, it's only one of multiple ways.
# a cleaner way would be to declare those as class variables, you can check out the
# documentation (linked above) for more information.
# random needs to be imported
spawn_timer = 0
movement_speed = 2
x_size = 50
gap_size = 300
pipes = []
# screen, width and height have already been declared
class Pipe:
def __init__(self, x_pos=width):
random_height = random.randint(0, height - gap_size)
self.upper_rect = pygame.Rect(x_pos, 0, x_size, random_height)
self.lower_rect = pygame.Rect(x_pos, random_heigt - gap_size,
x_size, height - random_height - gap_size)
def draw(self):
pygame.draw.rect(screen, green, self.upper_rect)
pygame.draw.rect(screen, green, self.lower_rect)
def collide(self, rect):
return self.lower_rect.colliderect(rect) or self.upper_rect.colliderect(rect)
def update(self)
self.upper_rect.move_ip(-movement_speed, 0)
self.lower_rect.move_ip(-movement_speed, 0)
# in the main loop:
spawn_timer += 1
if spawn_timer >= 200: # use different values for distance between pipes
pipes.append(Pipe())
spawn_timer = 0
for pipe in pipes:
pipe.draw()
pipe.update()
if pipe.collide(playerrect):
print('GAME OVER') # reset the game
if pipes and pipes[0].upper_rect.right < 0: # first pipe will be leftmost pipe.
pipes.pop(0)
also i noticed that the falling was not feeling as clean.
for a more natural movement, i would recommend adding something to the dy value instead of multiplying it.
if you have any questions, please write a comment.
EDIT: fixed list index out of range bug.
EDIT: fixed 'module' object is not callable

Why do i get an error when switching windows?

I tried to build a simple game in python using pygame. At first my problem was to make the movement more smooth, because about every second the movement of the rectangles stuck for a few milliseconds. Then I found an solution by adding "os.environ['SDL_VIDEODRIVER'] = 'directx'" in to my code and changing the display mode to "FULLSCREEN" and "DOUBLEBUFF". The movement is more fluid now, but whenever I Alt + Tab out of the fullscreen game, i get this error:
Traceback (most recent call last):
File "C:\Users\L-Tramp-GAMING\Documents\Python\Game\Main_Game.py", line 64, in <module>
screen.fill(BG_COLOR)
pygame.error: IDirectDrawSurface3::Blt: Surface was lost
I don't know how to bypass this problem. I am also wondering if i can somehow run the game in windowed mode with the directx line added in normal speed. At the moment the game runs in much higher speed when it is in windowed mode. I hope some of you guys can help me. Thank you, Paul
import pygame
import random
import os
#Variables
WIDTH = 1280
HEIGHT = 720
GAME_OVER = False
BG_COLOR = (0, 0, 20)
playerWidth = 50
playerHeight = 50
playerPosX = WIDTH / 2 - playerWidth / 2
playerPosY = HEIGHT - (playerHeight + 75)
playerSpeed = 10
enemieWidth = 75
enemieHeight = 75
enemiePosX = random.randint(0, WIDTH - enemieWidth)
enemiePosY = 0
enemieSpeed = 5
enemieCounter = 1
####################################################################################################
os.environ['SDL_VIDEODRIVER'] = 'directx'
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.FULLSCREEN | pygame.DOUBLEBUF)
pygame.display.set_caption("Game")
pygame.key.set_repeat(1, 10)
clock = pygame.time.Clock()
#GameLoop
while not GAME_OVER:
for e in pygame.event.get():
if e.type == pygame.QUIT:
GAME_OVER = True
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_a:
playerPosX -= playerSpeed
print(hex(screen.get_flags() & 0xFFFFFFFF))
if e.key == pygame.K_d:
playerPosX += playerSpeed
#Graphics
screen.fill(BG_COLOR)
player = pygame.draw.rect(screen, (0, 255, 0), (playerPosX, playerPosY, playerWidth, playerHeight))
if enemiePosY < HEIGHT:
enemie = pygame.draw.rect(screen, (255, 0, 0), (enemiePosX, enemiePosY, enemieWidth, enemieHeight))
enemiePosY += enemieSpeed
else:
enemieCounter += 1
enemiePosY = 0
enemiePosX = random.randint(0, WIDTH - enemieWidth)
if (enemieCounter + 1) % 2 == 0:
pass
#End Graphics
pygame.display.flip()
Your movement lag was caused by pygame.key.set_repeat. To allow the player to hold down a and d to move you can update the players position in your game loop instead of using set_repeat by keeping track of a speed variable. If you wanted to use os.environ for another reason besides fixing the lag then this won't work but otherwise this should be fine.
import pygame
import random
import os
#Variables
WIDTH = 1280
HEIGHT = 720
GAME_OVER = False
BG_COLOR = (0, 0, 20)
playerWidth = 50
playerHeight = 50
playerPosX = WIDTH / 2 - playerWidth / 2
playerPosY = HEIGHT - (playerHeight + 75)
playerSpeed = 10
enemieWidth = 75
enemieHeight = 75
enemiePosX = random.randint(0, WIDTH - enemieWidth)
enemiePosY = 0
enemieSpeed = 5
enemieCounter = 1
####################################################################################################
#os.environ['SDL_VIDEODRIVER'] = 'directx'
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Game")
#pygame.key.set_repeat(1, 10) <----- This line is the problem
clock = pygame.time.Clock()
#GameLoop
speed = 0
while not GAME_OVER:
for e in pygame.event.get():
if e.type == pygame.QUIT:
GAME_OVER = True
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_a:
speed = -playerSpeed
if e.key == pygame.K_d:
speed = +playerSpeed
playerPosX += speed
#Graphics
screen.fill(BG_COLOR)
player = pygame.draw.rect(screen, (0, 255, 0), (playerPosX, playerPosY, playerWidth, playerHeight))
if enemiePosY < HEIGHT:
enemie = pygame.draw.rect(screen, (255, 0, 0), (enemiePosX, enemiePosY, enemieWidth, enemieHeight))
enemiePosY += enemieSpeed
else:
enemieCounter += 1
enemiePosY = 0
enemiePosX = random.randint(0, WIDTH - enemieWidth)
if (enemieCounter + 1) % 2 == 0:
pass
#End Graphics
pygame.display.flip()
Can the code handle the error, and then try re-creating the screen object ?
This is the same sort of process as when switching from full-screen to windowed.
EDIT: Added some code from the PyGame Wiki: https://www.pygame.org/wiki/toggle_fullscreen to hopefully work around further issues from OP's comment.
try:
screen.fill(BG_COLOR)
except pygame.error as e:
# Get the size of the screen
screen_info= pygame.display.Info()
cursor = pygame.mouse.get_cursor() # Duoas 16-04-2007
new_width = screen_info.current_w
new_height = screen_info.current_h
# re-initialise the display, creating a re-sizable window
pygame.display.quit()
pygame.display.init()
screen = pygame.display.set_mode( ( new_width, new_height ), pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE )
pygame.key.set_mods( 0 ) # HACK: work-a-round for a SDL bug??
pygame.mouse.set_cursor( *cursor ) # Duoas 16-04-2007
# did it work?
screen.fill(BG_COLOR)

How can I stop a character in pygame from leaving the edge of the screen?

I have created a small program in pygame where the player controls a blue square moving around the screen, but I want to stop the player from moving past the edge of the screen. Here is the code I have so far, how can I do this?
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
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
is_blue = not is_blue
pressed = pygame.key.get_pressed()
if pressed[pygame.K_UP]: y -= 5
if pressed[pygame.K_DOWN]: y += 5
if pressed[pygame.K_LEFT]: x -= 5
if pressed[pygame.K_RIGHT]: x += 5
screen.fill((0, 0, 0))
color = (0, 128, 255)
pygame.draw.rect(screen, color, pygame.Rect(x, y, 60, 60))
pygame.display.flip()
clock.tick(60)
pygame.Rects have a clamp (and clamp_ip) method which you can use to limit the movement area. So create a rect with the size of the screen (called screen_rect here) and a rect for the player (player_rect) and call the clamp_ip method after each movement to keep it inside of the screen area.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
BG_COLOR = pg.Color(30, 30, 50)
def main():
clock = pg.time.Clock()
image = pg.Surface((50, 30))
image.fill(pg.Color('dodgerblue'))
pg.draw.rect(image, pg.Color(40, 220, 190), (0, 0, 49, 29), 2)
player_rect = image.get_rect(topleft=(200, 200))
# This pygame.Rect has the dimensions of the screen and
# is used to clamp the player_rect to this area.
screen_rect = screen.get_rect()
speed = 5
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
return
pressed = pg.key.get_pressed()
if pressed[pg.K_UP]:
player_rect.y -= speed
if pressed[pg.K_DOWN]:
player_rect.y += speed
if pressed[pg.K_LEFT]:
player_rect.x -= speed
if pressed[pg.K_RIGHT]:
player_rect.x += speed
# Clamp the rect to the dimensions of the screen_rect.
player_rect.clamp_ip(screen_rect)
screen.fill(BG_COLOR)
screen.blit(image, player_rect)
pg.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()
pg.quit()
This should work
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
Where 600 and 800 is the screen size and 60 the size of your rectangle
Something like:
if pressed[pygame.K_UP]:
if not (y > maxwidth or y < 0):
y += 5
And so on for the others. the maxwidth looks like 600 in your code but I'd put it at the top of your code so you dont keep having to change it in different places.
What you are trying to do is called edge detection, as in detect if you are at an edge, in this case you want the edges to be the screen's edges. what you should do, is check if your x or y are at an edge, if so don't go any further.
if pressed[pygame.K_UP]:
if 0 < y-5 < 600: #0 and 600 being the edges of your screen, you can use a variable to change it dynamically later one
y -= 5
Note this will only detect if the top left's square is going out of bounds, since x and y is the top and left coords for the rectangle, meaning the bottom right of the square will be able to still go out of bounds,
If you want to check the whole square, you will have to make adjustment calculations in the if statement, or base your x and y on the center (which you will still have to modify the if statement to something like below. (note I'm altering based on your current code for x and y being top left.
if pressed[pygame.K_UP]:
if (0 < y-5 < 600) or (0< y+60-5 <600) #0 and 600 being the edges of your screen, you can use a variable to change it dynamically later one
y -= 5
This checks the other side of the square. Note for x you will check for the horizontal limits which in this case is 800. Also we are checking including the -5 because we want to see where we are going, not where we are at.

Pong Collision Pygame

I'm writing code for a one paddle pong game in pygame where the ball will bounce off of the 3 walls the paddle is not on, and when it does hit the paddle's wall instead of the paddle, it makes you lose a life. My problem is that I cannot figure out the collision detection to do this. Here is what I've done so far:
import pygame, sys
from pygame.locals import *
pygame.init()
screen_width = 640
screen_height = 480
Display = pygame.display.set_mode((screen_width, screen_height), 0, 32)
pygame.display.set_caption('Lonely Pong')
back = pygame.Surface((screen_width, screen_height))
background = back.convert()
background.fill((255, 255, 255))
paddle = pygame.Surface((80, 20))
_paddle = paddle.convert()
_paddle.fill((128, 0, 0))
ball = pygame.Surface((15, 15))
circle = pygame.draw.circle(ball, (0, 0, 0), (7, 7), 7)
_ball = ball.convert()
_ball.set_colorkey((0, 0, 0))
_paddle_x = (screen_width / 2) - 40
_paddle_y = screen_height - 20
_paddlemove = 0
_ball_x, _ball_y = 8, 8
speed_x, speed_y, speed_circle = 250, 250, 250
Lives = 5
clock = pygame.time.Clock()
font = pygame.font.SysFont("verdana", 20)
paddle_spd = 5
while True:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
if event.type == KEYDOWN:
if event.key == K_RIGHT:
_paddlemove = paddle_spd
elif event.key == K_LEFT:
_paddlemove = -paddle_spd
elif event.type == KEYUP:
if event.key == K_RIGHT:
_paddlemove = 0
elif event.key == K_LEFT:
_paddlemove = 0
Livespr = font.render(str(Lives), True, (0, 0, 0))
Display.blit(background, (0, 0))
Display.blit(_paddle, (_paddle_x, _paddle_y))
Display.blit(_ball, (_ball_x, _ball_y))
Display.blit(Livespr, ((screen_width / 2), 5))
_paddle_x += _paddlemove
passed = clock.tick(30)
sec = passed / 1000
_ball_x += speed_x * sec
_ball_y += speed_y * sec
pygame.display.update()
Another problem I've been having is that when I start it up, the ball doesn't appear at all. Could somebody please point me in the right direction?
first things first, the ball doesn't appear because you are not filling the surface, you are setting the color_key:
_ball.set_colorkey((0, 0, 0))
should be
_ball.fill((0, 0, 0))
Second, for collision detection, pygame offers some functions such as collidepoint and colliderect.
https://www.pygame.org/docs/ref/rect.html#pygame.Rect.collidepoint
which means you will need the rectangles of the surfaces. do this by:
my_surface.get_rect()
https://www.pygame.org/docs/ref/surface.html#pygame.Surface.get_rect
In order to collide with the edges of the screen, you can always do
if _ball_x <= 0 or _ball_y <= 0 or _ball_x >= 640 or _ball_y >= 480:
# collision detected

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

Categories