pythonpygamepygame-surfacepygame-tick

How to provide set of predefined instructions in pygame


I am new to pygame and not a regular coder. I am trying to wright a pygame code which accepts set of instructions from a text box and then move the image accordingly. eg: When you execute the code the pygame window will open with a textbox & primary image. First the user will provide set of directions LEFT, RIGHT, UP, DOWN. After the the primary image should travel LEFT > RIGHT > UP > DOWN.

Below is a try from my end but here the image is directly reaching to last step instead of moving one after the other.

I want the image to move A - B - C - D and not A - D directly. Any help would be appreciated.

import pygame
pygame.init()

# game screen dimensions
screen_width = 1200
screen_height = 800

# Define colors for using it in code
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
dark_red = (138,0,0)
green = (0,128,0)
dark_green = (0,200,0)
silver = (192,192,192)


display_mygame = pygame.display.set_mode((screen_width,screen_height))

# Primary Image
my_img = pygame.image.load('kid.png')

def game_loop():
    x = (screen_width * 0.25)
    y = (screen_height * 0.8)
    font = pygame.font.Font(None, 32)
    clock = pygame.time.Clock()
    input_box = pygame.Rect(100, 100, 240, 62)
    color_inactive = pygame.Color('lightskyblue3')
    color_active = pygame.Color('dodgerblue2')
    color = color_inactive
    active = False
    text = ''
    list = []
    count = 0
    start_width = 50
    start_height = 50
    sy = 0
    crashed = False
    while not crashed:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

            display_mygame.fill(white)
            if event.type == pygame.MOUSEBUTTONDOWN:
                if input_box.collidepoint(event.pos):
                    active = not active
                else:
                    active = False
            if event.type == pygame.KEYDOWN:
                if active:
                    if event.key == pygame.K_RETURN:
                        # Capturing the 4 instructions provided
                        list.append(str(text))
                        text = ""
                        count += 1
                        # Want the primary image to act accordingly to the instructions
                        if int(count) == 4:
                            for text in list:
                                if text == 'left':
                                    x += -300
                                elif text == 'right':
                                    x += 450
                                elif text == 'up':
                                    y += -300
                                elif text == 'down':
                                    y += 300

                    elif event.key == pygame.K_BACKSPACE:
                        text = text[:-1]
                    else:
                        text += event.unicode
        display_mygame.blit(my_img, (x,y))
        txt_surface = font.render(text, True, color)
        width = max(200, txt_surface.get_width()+10)
        input_box.w = width
        display_mygame.blit(txt_surface, (input_box.x+5, input_box.y+5))
        pygame.draw.rect(display_mygame, color, input_box, 2)

        pygame.display.update()
        clock.tick(60)

game_loop()
pygame.quit()
quit()

Solution

  • Please do not name a variable list. For instance use the name move_list rather than list.

    Add 2 new states, walking and move:

    walking = False
    move = [0, 0]
    

    Do not accept any input if walking == True. Set walking = True if the number of inputs is 4:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    
        if not walking:
            if event.type == pygame.MOUSEBUTTONDOWN:
                if input_box.collidepoint(event.pos):
                    active = not active
                else:
                    active = False
            if event.type == pygame.KEYDOWN:
                if active:
                    if event.key == pygame.K_RETURN:
                        # Capturing the 4 instructions provided
                        move_list.append(str(text))
                        text = ""
                        count += 1
                        walking = count == 4
                    elif event.key == pygame.K_BACKSPACE:
                        text = text[:-1]
                    else:
                        text += event.unicode
    

    Move the player in the main application loop, if walking == True. Remove the first element from move_list and set the moving direct move accordingly. If move is set move the player by 1 in every frame and appropriate decrease move:

    if walking:
        if move[0] != 0 or move[1] != 0:
            if move[0] < 0:
                x -= 1
                move[0] += 1
            if  move[0] > 0:
                x += 1
                move[0] -= 1
            if move[1] < 0:
                y -= 1
                move[1] += 1
            if  move[1] > 0:
                y += 1
                move[1] -= 1
        elif len(move_list) > 0:
            if move_list[0] == 'left':
                move = [-300, 0]
            elif move_list[0] == 'right':
                move = [300, 0]
            elif move_list[0] == 'up':
                move = [0, -300]
            elif move_list[0] == 'down':
                move = [0, 300]
            del move_list[0]
        else:
            walking = False
            count = 0
    

    See the example:

    import pygame
    pygame.init()
    
    # game screen dimensions
    screen_width = 1200
    screen_height = 800
    
    # Define colors for using it in code
    black = (0,0,0)
    white = (255,255,255)
    red = (255,0,0)
    dark_red = (138,0,0)
    green = (0,128,0)
    dark_green = (0,200,0)
    silver = (192,192,192)
    
    
    display_mygame = pygame.display.set_mode((screen_width,screen_height))
    
    # Primary Image
    #my_img = pygame.image.load('kid.png')
    my_img = pygame.Surface((20, 20))
    my_img.fill((0, 255, 0))
    
    def game_loop():
        x = (screen_width * 0.25)
        y = (screen_height * 0.8)
        font = pygame.font.Font(None, 32)
        clock = pygame.time.Clock()
        input_box = pygame.Rect(100, 100, 240, 62)
        color_inactive = pygame.Color('lightskyblue3')
        color_active = pygame.Color('dodgerblue2')
        color = color_inactive
        active = False
        text = ''
        move_list = []
        count = 0
        start_width = 50
        start_height = 50
        sy = 0
        crashed = False
        walking = False
        move = [0, 0]
        while not crashed:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
    
                if not walking:
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        if input_box.collidepoint(event.pos):
                            active = not active
                        else:
                            active = False
                    if event.type == pygame.KEYDOWN:
                        if active:
                            if event.key == pygame.K_RETURN:
                                # Capturing the 4 instructions provided
                                move_list.append(str(text))
                                text = ""
                                count += 1
                                walking = count == 4
                            elif event.key == pygame.K_BACKSPACE:
                                text = text[:-1]
                            else:
                                text += event.unicode
    
            if walking:
                if move[0] != 0 or move[1] != 0:
                    if move[0] < 0:
                        x -= 1
                        move[0] += 1
                    if  move[0] > 0:
                        x += 1
                        move[0] -= 1
                    if move[1] < 0:
                        y -= 1
                        move[1] += 1
                    if  move[1] > 0:
                        y += 1
                        move[1] -= 1
                elif len(move_list) > 0:
                    if move_list[0] == 'left':
                        move = [-300, 0]
                    elif move_list[0] == 'right':
                        move = [300, 0]
                    elif move_list[0] == 'up':
                        move = [0, -300]
                    elif move_list[0] == 'down':
                        move = [0, 300]
                    del move_list[0]
                else:
                    walking = False
                    count = 0
    
    
            display_mygame.fill(white)
            display_mygame.blit(my_img, (x,y))
            txt_surface = font.render(text, True, color)
            width = max(200, txt_surface.get_width()+10)
            input_box.w = width
            display_mygame.blit(txt_surface, (input_box.x+5, input_box.y+5))
            pygame.draw.rect(display_mygame, color, input_box, 2)
    
            pygame.display.update()
            clock.tick(60)
    
    game_loop()
    pygame.quit()
    quit()