Pygame 问题 user_input 总是出现在下一次迭代中

问题描述 投票:0回答:1

事实上,我是一名刚学完 Python 课程的软件新学生。我正在学习如何使用 pygame。事实上,我正在尝试实现一个数学游戏,它提出随机数学方程来求解并等待用户输入,然后再转到下一个方程。就我而言,每次我写下我的答案时(它出现在 while 循环的下一次迭代中和另一个数学方程(不是原始问题)。我部分理解为什么会发生这种情况,但我真的无法解决问题

这是我目前的代码,但仍然缺少一些元素

import pygame
from sys import exit
import operations
import re

# Constants
SKYBLUE = (152, 195, 195)
BEIGE = (210, 190, 150)
YELLOW = (255, 255, 204)
KEYBOARD_NUMBERS = [pygame.K_0, pygame.K_1, pygame.K_2, pygame.K_3, pygame.K_4, pygame.K_5,
                    pygame.K_6, pygame.K_7, pygame.K_8, pygame.K_9, pygame.K_MINUS]

# Globals
final_state = False
start_the_game = False
choose_level = False
start_playing = False

user_answer = ''
color = BEIGE
equations_list = []
answers_list = []
score = 0


class Operations:

    def __init__(self, x, y, operation, name):
        font = pygame.font.Font('font/Pixeltype.ttf', 60)
        self.surface = font.render(operation, False, (64, 64, 64))
        self.rect = self.surface.get_rect(center=(x, y))
        self.name = name

    def draw(self, color=BEIGE):
        pygame.draw.circle(screen, color, self.rect.center, 50)
        screen.blit(self.surface, self.rect)


class Levels:
    def __init__(self, x, y, niveau, name):
        font = pygame.font.Font('font/Pixeltype.ttf', 60)
        self.surface = font.render(name, False, (64, 64, 64))
        self.rect = self.surface.get_rect(center=(x, y))
        self.niveau = niveau
        self.name = name

    def draw(self, color=BEIGE):
        pygame.draw.circle(screen, color, self.rect.center, 50)
        screen.blit(self.surface, self.rect)


class Display_Operation:
    def __init__(self, operation=None):
        font = pygame.font.Font('font/Pixeltype.ttf', 40)
        self.operation_surf = font.render(f'{operation}', False, (64, 64, 64))
        self.rect = self.operation_surf.get_rect(topleft=(50, 130))
        self.rect.h += 5

    def draw(self):
        self.rect = pygame.draw.rect(screen, BEIGE, self.rect)
        self.rect = pygame.draw.rect(screen, BEIGE, self.rect, 10)
        screen.blit(self.operation_surf, self.rect)


def display_operation(details_list):
    if details_list[0] == 'Addition':
        return operations.addition(details_list[1])
    elif details_list[0] == 'Substraction':
        return operations.substraction(details_list[1])
    elif details_list[0] == 'Multiplication':
        return operations.multiplication(details_list[1])
    else:
        return operations.division(details_list[1])


def correct_answer(math_equation, answer):
    math_equation = math_equation.replace('=', '')
    num1, num2 = re.split(r'[+\-x/]', math_equation)
    if '+' in math_equation:
        return int(num1) + int(num2) == int(answer)
    elif '-' in math_equation:
        return int(num1) - int(num2) == int(answer)
    elif 'x' in math_equation:
        return int(num1) * int(num2) == int(answer)
    else:
        return int(num1) / int(num2) == int(answer)


def image_surface(image):
    return pygame.image.load(image).convert_alpha()


def image_rect(image_surf, x, y):
    return image_surf.get_rect(center=(x, y))


def phrase_rect(sentence, x, y, color=(64, 64, 64)):
    global text_font
    surf = text_font.render(sentence, False, color)
    rect = surf.get_rect(center=(x, y))
    return (surf, rect)


def events_loop():
    global start_the_game, choose_level, start_playing, user_answer, final_state, num
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

        if start_the_game:
            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                operationes = [addition, substracction, multiplication, division]
                for op in operationes:
                    if op.rect.collidepoint(pygame.mouse.get_pos()):
                        choose_level = True
                        game_algo.append(op.name)
                if choose_level:
                    levelos = [level_1, level_2, level_3]
                    for level in levelos:
                        if level.rect.collidepoint(pygame.mouse.get_pos()):
                            start_playing = True
                            game_algo.append(level.niveau)

            if start_playing:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_BACKSPACE:
                        user_answer = user_answer[:-1]

                    else:
                        user_answer += event.unicode
        elif final_state:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    num = 0
                    final_state = False
                    start_the_game = False
                    choose_level = False
                    start_playing = False


        else:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    start_the_game = True


pygame.init()
screen = pygame.display.set_mode((600, 400))
pygame.display.set_caption('Little Professor')
clock = pygame.time.Clock()

# Images
little_professor_surf = image_surface('Graphics/start_screen_little_professo.png')
little_professor_surf = pygame.transform.smoothscale_by(little_professor_surf, 0.4)
little_professor_rect = image_rect(little_professor_surf, 300, 200)

# Font
text_font = pygame.font.Font('font/Pixeltype.ttf', 50)
# Game title
title_surf, title_rect = phrase_rect('Little Professor', 300, 60)
# start message
start_message_surf, start_message_rect = phrase_rect('Press space to start', 300, 350)

# Operations
sentence_surf, sentence_rect = phrase_rect('Choose a Mathematical Operation: ', 300, 50)

addition = Operations(80, 200, '+', 'Addition')
substracction = Operations(230, 200, '-', 'Substraction')
multiplication = Operations(380, 200, 'x', 'Multiplication')
division = Operations(530, 200, '/', 'Division')

command_surf, command_rect = phrase_rect('Put your mouse on the operation', 300, 300)
command1_surf, command1_rect = phrase_rect('and press space ', 300, 330)

# Levels:
level_surf, level_rect = phrase_rect('Select a level: ', 300, 50)
level_1 = Levels(150, 200, 1, '1')
level_2 = Levels(300, 200, 2, '2')
level_3 = Levels(450, 200, 3, '3')

# Operation to use in game
game_algo = []

# Game In Playing
play_surface = text_font.render('Let\'s Play !', False, (64, 64, 64))
play_surface_rect = play_surface.get_rect(topleft=(50, 50))
user_rect = Display_Operation().rect
user_rect.x = 180
user_rect.y = 200
user_rect.w = Display_Operation().rect.w + 5
answer_prompt_surf = text_font.render('Answer: ', False, (64, 64, 64))
answer_prompt_rect = answer_prompt_surf.get_rect(topleft=(50, 200))

click_surf, click_rect = phrase_rect('Press Enter to continue ', 230, 300)

# Final State
score_surf, score_rect = phrase_rect(f'Your score: {score} out of 10', 300, 100)
restart_surf, restart_rect = phrase_rect('Press Space to play again', 300, 200)
mathgame_surf = image_surface('Graphics/mathgame.webp')
mathgame_surf = pygame.transform.smoothscale_by(mathgame_surf, 0.05)
mathgame_rect = image_rect(mathgame_surf, 300, 300)

num = 0
while True:
    # for loop
    events_loop()
    # Game screen
    # Operations Screen
    if num == 10:
        start_the_game = False
        final_state = True
    else:
        pass
    if start_the_game:
        screen.fill(SKYBLUE)
        screen.blit(sentence_surf, sentence_rect)
        addition.draw()
        substracction.draw()
        multiplication.draw()
        division.draw()
        screen.blit(command_surf, command_rect)
        screen.blit(command1_surf, command1_rect)
        # Levels screen
        if choose_level:
            pygame.time.wait(300)
            screen.fill(SKYBLUE)
            screen.blit(level_surf, level_rect)
            level_1.draw()
            level_2.draw()
            level_3.draw()
            screen.blit(command_surf, command_rect)
            screen.blit(command1_surf, command1_rect)
        # Real Game Screen
        if start_playing:
            screen.fill(SKYBLUE)
            screen.blit(play_surface, play_surface_rect)
            screen.blit(answer_prompt_surf, answer_prompt_rect)
            screen.blit(click_surf, click_rect)

            user_rect = pygame.draw.rect(screen, color, user_rect)
            user_text_surf = text_font.render(user_answer, True, (64, 64, 64))
            user_rect.w = max(Display_Operation().rect.w, user_text_surf.get_width() + 10)
            screen.blit(user_text_surf, user_rect)

            equation = display_operation(game_algo)
            question_surf = Display_Operation(equation).operation_surf
            question_rect = Display_Operation(equation).rect
            screen.blit(question_surf, question_rect)

            equations_list.append(equation)

            while True:
                event = pygame.event.poll()
                if event.type == pygame.QUIT:
                    pygame.quit()
                    exit()

                if num == 0 and start_playing:
                    num += 1
                    break

                else:
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_RETURN:
                            if user_answer.strip().replace('-', '').isdigit():
                                x = user_answer
                                answers_list.append(x)
                                print(equation, x)
                                user_answer = ''
                                num += 1
                                break  # Exit the inner loop when the user presses enter

                        elif event.key == pygame.K_BACKSPACE:
                            user_answer = user_answer[:-1]
                        else:
                            user_answer += event.unicode
                            user_rect = pygame.draw.rect(screen, color, user_rect)
                            user_text_surf = text_font.render(user_answer, True, (64, 64, 64))
                            user_rect.w = max(Display_Operation().rect.w, user_text_surf.get_width() + 10)
                            screen.blit(user_text_surf, user_rect)

    elif final_state:
        screen.fill(YELLOW)
        screen.blit(score_surf, score_rect)
        screen.blit(restart_surf, restart_rect)
        screen.blit(mathgame_surf, mathgame_rect)
    # Starting screen
    else:
        screen.fill(YELLOW)
        screen.blit(little_professor_surf, little_professor_rect)
        screen.blit(title_surf, title_rect)
        screen.blit(start_message_surf, start_message_rect)

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

如果有人可以帮助我解决这个问题,我将非常感激

python pygame
1个回答
0
投票

您游戏中的主要问题是玩家的答案和新问题在游戏循环中更新不顺畅。现在,当玩家输入答案时,它只会出现在下一个循环迭代中,同时还会出现一个新问题。这可能会让玩家感到困惑。

要解决此问题,您需要做三件事:

分别处理输入和更新:将游戏循环分为两部分。一部分应该处理玩家输入(例如输入答案),另一部分应该更新游戏状态(例如检查答案并生成新问题)。

立即反馈:一旦玩家按下 Enter,您就应该处理他们的答案,更新显示以显示该答案,然后生成下一个问题。这样,玩家可以立即看到他们的输入,并且游戏感觉更加灵敏。

简化游戏状态:确保您的游戏在不同状态之间高效转换(例如回答问题并转到下一个),而不会出现不必要的延迟。

本质上,它是为了让游戏对玩家输入做出更快的反应,并确保游戏的响应(例如显示答案和提出下一个问题)是即时且无缝的。

简单来说,可以这样想:循环的一部分是游戏的耳朵和手——倾听玩家的行为并相应地更新内容。另一部分是大脑——思考下一步该做什么,比如产生新问题。在整个过程中,游戏需要不断向玩家展示正在发生的事情,而无需等待。

我希望这能让它更清楚!如果您需要有关具体代码的更多帮助来执行此操作,请告诉我!

© www.soinside.com 2019 - 2024. All rights reserved.