Python 为什么在单击“开始”按钮后,主循环中(“在此代码中运行”)没有响应?

Python 为什么在单击“开始”按钮后,主循环中(“在此代码中运行”)没有响应?,python,python-3.x,pygame,Python,Python 3.x,Pygame,我正在创建一个基本的游戏。我主要有两个代码:I菜单ii基本游戏。我想在点击“开始”按钮后运行“whilegame_over”循环。但我单击“开始”按钮后,代码没有响应 import pygame import random import sys pygame.init() w=800 h=600 yellow=(255,255,0) player_size=25 player_pos=[w/2,h-(2*player_size)] enemy_size=25 enemy_pos=[random.

我正在创建一个基本的游戏。我主要有两个代码:I菜单ii基本游戏。我想在点击“开始”按钮后运行“whilegame_over”循环。但我单击“开始”按钮后,代码没有响应

import pygame
import random
import sys
pygame.init()
w=800
h=600
yellow=(255,255,0)
player_size=25
player_pos=[w/2,h-(2*player_size)]
enemy_size=25
enemy_pos=[random.randint(0,w-enemy_size),0]
enemy_list=[ ]
Menu_bg_color=(34,139,34)
red=(255,0,0)
blue=(0,0,125)
bright_blue=(0,0,255)
font_size=35
b1_pos=[w/2-50,h/2]
b1_size=[105,50]
bg_color=(0,0,0)
screen=pygame.display.set_mode((w,h))
speed=10
score=0
clock=pygame.time.Clock()
myFont=pygame.font.SysFont("monospace",font_size)
Menu_myFont=pygame.font.SysFont("freesansbold.tff",font_size)
running=True
Menu_running=True

#GAME CODE
def GameCode():
    global game_over
    global score
    global speed
    global player_pos
    def set_level(score,speed):
        if score<10:
            speed=5
        elif score<20:
            speed=6
        elif score<30:
            speed=8
        elif score<40:
            speed=10
        elif score<50:
            speed=13
        elif score<200:
            speed=15
        else:
            speed=20
        return speed
    def drop_enemies(enemy_list):
        delay=random.random()
        if len(enemy_list)<6 and delay<0.1:
            x_pos=random.randint(0,w-enemy_size)
            y_pos=0
            enemy_list.append([x_pos,y_pos])
    def draw_enemies(enemy_list):
        for enemy_pos in enemy_list:
            pygame.draw.rect(screen,blue,     (enemy_pos[0],enemy_pos[1],enemy_size,enemy_size))
    def update_enemy_pos(enemy_list,score):
        for idx,enemy_pos in enumerate(enemy_list):
           if enemy_pos[1]>=0 and enemy_pos[1]<h:
            enemy_pos[1]+=speed
           else:
               enemy_list.pop(idx)
               score+=1
        return score
    def detect_collision(player_pos,enemy_pos):
        p_x=player_pos[0]
        p_y=player_pos[1]
        e_x=enemy_pos[0]
        e_y=enemy_pos[1]
        if (e_x>=p_x and e_x<(p_x+player_size)) or (p_x>=e_x and p_x<(e_x+enemy_size)):
            if (e_y>=p_y and e_y<(p_y+player_size)) or (p_y>=e_y and p_y<(e_y+enemy_size)):
                return True
        return False
    def collision_check(enemy_list,player_pos):
        for enemy_pos in enemy_list:
            if detect_collision(enemy_pos,player_pos):
                return True
        return False
    while game_over==False:
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                sys.exit()
            if event.type==pygame.KEYDOWN:
                x=player_pos[0]
                y=player_pos[1]
                if event.key==pygame.K_LEFT:
                    x-=player_size
                elif event.key==pygame.K_UP:
                    y-=player_size
                elif event.key==pygame.K_RIGHT:
                    x+=player_size
                elif event.key==pygame.K_DOWN:
                    y+=player_size
                player_pos=[x,y]
        screen.fill(bg_color)
        #screen.blit(road,(0,0))
        drop_enemies(enemy_list)
        score=update_enemy_pos(enemy_list,score)
        speed=set_level(score,speed)
        text='Your Score is:' + str(score)
        label=myFont.render(text,1,yellow)
        screen.blit(label,(w/2,h-40))
        if collision_check(enemy_list,player_pos):
            game_over=True
            break
        draw_enemies(enemy_list)
        pygame.draw.rect(screen,red,(player_pos[0],player_pos[1],player_size,player_size))
        clock.tick(30)
        pygame.display.update()
        pygame.display.flip()
#MENU CODE
def MenuCode():
    global game_over
    def button(b1_pos,b1_size):
        mouse_pos=pygame.mouse.get_pos()
        click=pygame.mouse.get_pressed()
        if (b1_pos[0]<mouse_pos[0]<(b1_pos[0]+b1_size[0])) and (b1_pos[1]<mouse_pos[1]<(b1_pos[1]+b1_size[1])):
            pygame.draw.rect(screen,bright_blue,(b1_pos[0],b1_pos[1],b1_size[0],b1_size[1]))
            if click[0]==1:
                     game_over=False
        else:
            pygame.draw.rect(screen,blue,(b1_pos[0],b1_pos[1],b1_size[0],b1_size[1]))
        text='START'
        label=Menu_myFont.render(text,1,red)
        screen.blit(label,(w/2-38,h/2+5))
        Menu_running=True
    while Menu_running:
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                sys.exit()
        screen.fill(Menu_bg_color)
        button(b1_pos,b1_size)
        #button(b1_pos,b1_size,'quit')
        pygame.display.update()
        clock.tick(30)
while running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            break;
    screen.fill(bg_color)
    if MenuCode():
            if game_over==False:
                    GameCode()
    clock.tick(30)
    pygame.display.update()

这里有一个经过大量修改的代码版本,没有问题。我已经对代码进行了修改,使其严格遵守指导原则,并通过使它们位于使用它们的函数的局部,消除了许多全局变量

我做的一件主要的装饰性的事情是确定哪些全局变量是不变的常数,哪些变量的值实际上发生了变化。之后,根据PEP 8,我将常量的名称改为全大写,并将具有不同值的名称移到实际使用它们的函数中

对菜单处理函数进行了最广泛的更改-现在命名为menu_code-这可能是问题的主要根源。为了便于重写,我添加了一个MenuButton类来在很大程度上封装它们的行为,并减少重复代码

请注意,game_code函数可能存在问题,因为我没有尝试对其进行优化、测试或调试

希望这将为你提供一个良好的基础,在此基础上进一步发展游戏。我强烈建议你阅读并开始遵循政治公众人物第8版

import random
import pygame as pyg

W, H = 800, 600
RED = (255, 0, 0)
BLUE = (0, 0, 125)
BRIGHT_BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
PLAYER_SIZE = 25
ENEMY_SIZE = 25
FONT_SIZE = 35
BG_COLOR = BLACK
FPS = 30
START, QUIT = 0, 1  # Button selection codes returned by menu_code()

pyg.init()
screen = pyg.display.set_mode((W, H))
pyg.display.set_caption('Basic Game')
clock = pyg.time.Clock()
game_font = pyg.font.SysFont("monospace", FONT_SIZE)
menu_font = pyg.font.SysFont("freesansbold.ttf", FONT_SIZE)

def game_code():
    enemy_pos = [random.randint(0, W-ENEMY_SIZE), 0]
    enemy_list = []
    game_over = False
    player_pos = [W/2, H - 2*PLAYER_SIZE]
    score = 0
    speed = 10

    def get_speed(score):
        if score < 10:
            speed = 5
        elif score < 20:
            speed = 6
        elif score < 30:
            speed = 8
        elif score < 40:
            speed = 10
        elif score < 50:
            speed = 13
        elif score < 200:
            speed = 15
        else:
            speed = 20
        return speed

    def drop_enemies(enemy_list):
        delay = random.random()
        if len(enemy_list) < 6 and delay < 0.1:
            x_pos = random.randint(0, W-ENEMY_SIZE)
            y_pos = 0
            enemy_list.append([x_pos, y_pos])

    def draw_enemies(enemy_list):
        for enemy_pos in enemy_list:
            pyg.draw.rect(screen, BLUE,
                          (enemy_pos[0], enemy_pos[1], ENEMY_SIZE, ENEMY_SIZE))

    def update_enemy_pos(enemy_list, score):
        for idx, enemy_pos in enumerate(enemy_list):
            if enemy_pos[1] >= 0 and enemy_pos[1] < H:
                enemy_pos[1] += speed
            else:
                enemy_list.pop(idx)
                score += 1
        return score

    def detect_collision(player_pos, enemy_pos):
        p_x, p_y = player_pos
        e_x, e_y = enemy_pos
        if ((e_x >= p_x and e_x < (p_x + PLAYER_SIZE))
            or (p_x >= e_x and p_x < (e_x + ENEMY_SIZE))):
            if ((e_y >= p_y and e_y < (p_y+PLAYER_SIZE))
                or (p_y >= e_y and p_y < (e_y + ENEMY_SIZE))):
                return True
        return False

    def collision_check(enemy_list, player_pos):
        for enemy_pos in enemy_list:
            if detect_collision(enemy_pos, player_pos):
                return True
        return False

    while not game_over:
        for event in pyg.event.get():
            if event.type == pyg.QUIT:
                game_over = True
                break
            if event.type == pyg.KEYDOWN:
                x = player_pos[0]
                y = player_pos[1]
                if event.key == pyg.K_LEFT:
                    x -= PLAYER_SIZE
                elif event.key == pyg.K_UP:
                    y -= PLAYER_SIZE
                elif event.key == pyg.K_RIGHT:
                    x += PLAYER_SIZE
                elif event.key == pyg.K_DOWN:
                    y += PLAYER_SIZE
                player_pos = [x, y]

        screen.fill(BG_COLOR)
        drop_enemies(enemy_list)
        score = update_enemy_pos(enemy_list, score)
        speed = get_speed(score)
        text = 'Your Score is:' + str(score)
        label = game_font.render(text, 1, YELLOW)
        screen.blit(label, (W/2, H-40))
        if collision_check(enemy_list, player_pos):
            game_over = True
            break
        draw_enemies(enemy_list)
        pyg.draw.rect(screen, RED,
                      (player_pos[0], player_pos[1], PLAYER_SIZE, PLAYER_SIZE))
        clock.tick(FPS)
        pyg.display.update()
#        pyg.display.flip()  # Don't do both update() and flip().


class MenuButton:
    def __init__(self, text, value, rect):
        self.text = text
        self.value = value
        self.rect = rect

    def draw(self):
        # Background color determined by whether mouse is positioned over label.
        mouse_pos = pyg.mouse.get_pos()
        fg_color = RED
        bg_color = BRIGHT_BLUE if self.rect.collidepoint(mouse_pos) else BLUE
        pyg.draw.rect(screen, bg_color, self.rect)
        pyg.draw.rect(screen, YELLOW, self.rect, 1)  # Draw a border.

        label = menu_font.render(self.text, 1, fg_color)
        # Center lable text inside its rectangle.
        txw, txh = menu_font.size(self.text)
        screen.blit(label, (self.rect.left + txw/2, self.rect.top + txh/2))


def menu_code():
    MENU_BG_COLOR = (34, 139, 34)
    LABEL_SIZE = LABEL_WIDTH, LABEL_HEIGHT = (105, 50)
    B1_RECT = pyg.Rect((W/2 - LABEL_WIDTH/2, H/2 - LABEL_HEIGHT/2), LABEL_SIZE)
    B2_RECT = pyg.Rect((W/2 - LABEL_WIDTH/2, H/2 + LABEL_HEIGHT/2), LABEL_SIZE)
    MENU_BUTTONS = [MenuButton('Start', START, B1_RECT),
                    MenuButton('Quit', QUIT, B2_RECT)]

    choice = None
    while choice is None:
        screen.fill(MENU_BG_COLOR)
        for button in MENU_BUTTONS:
            button.draw()

        for event in pyg.event.get():
            if event.type == pyg.QUIT:
                choice = QUIT
            # Handle left mouse button clicks.
            if event.type == pyg.MOUSEBUTTONDOWN and event.button == 1:
                for button in MENU_BUTTONS:
                    if button.rect.collidepoint(event.pos):
                        choice = button.value
                        break

        pyg.display.update()
        clock.tick(FPS)

    return choice

# Main loop.
running = True
while running:
    for event in pyg.event.get():
        if event.type == pyg.QUIT:
            running = False
            break;

    screen.fill(BG_COLOR)
    choice = menu_code()
    if choice == START:
        game_code()
    if choice == QUIT:
        running = False
    pyg.display.update()
    clock.tick(FPS)

freesansbold.tff应为freesansbold.ttf TrueType字体。您需要在顶层代码中引用game_,仅在函数中使用全局函数引用它并不能使其成为全局变量。然后再试一次……除其他外,您的MenuCode函数从不返回任何内容,因此if MenuCode:永远不会为true,游戏代码永远不会被调用。全局博弈变量从未初始化。@martineau应该有什么变化?我只是一个初学者,所以它会很有帮助。Supreme:我开始尝试修复它,但在取得一些进展之后,放弃是因为我无法破译逻辑-主要是因为你使用了这么多全局标志变量,再加上嵌套的函数定义和事件处理循环。@martineau非常感谢你的帮助。非常感谢你,先生。我感谢你花这么多时间在这方面。我最不需要的是像你这样的人来指导我。不太需要确定你最后一句话的意思是什么,因为一个人需要的最后一件事通常是一个人绝对不想要或没有用的东西。忽略这一点……请注意,我已经更新并改进了我的答案。我当然不是pygame专家,但我一直对计算机图形学感兴趣,并发现它的许多应用程序都很有趣——所以它并没有那么麻烦。