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

1.5k Views Asked by At

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()
2

There are 2 best solutions below

4
On

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, ())
0
On

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)