Python 屏幕模式未按正确顺序运行

Python 屏幕模式未按正确顺序运行,python,object,pygame,Python,Object,Pygame,我无法以正确的顺序显示正确的屏幕。我首先想要标题屏幕,它是红色的。然后,如果我点击播放按钮,我想切换到难度屏幕,它有简单和硬按钮。如果我单击easy按钮,我希望我的游戏转到main游戏,我想我已经通过将pong4.main传递到按钮的动作参数中完成了 我的问题是,我首先运行的是主游戏,而不是标题屏幕。我从来没有点击过标题屏幕。然后,一旦乒乓球游戏结束,我也会得到一个字体 import pygame import os import pongtry4 WHITE = (255, 255, 2

我无法以正确的顺序显示正确的屏幕。我首先想要标题屏幕,它是红色的。然后,如果我点击播放按钮,我想切换到难度屏幕,它有简单和硬按钮。如果我单击easy按钮,我希望我的游戏转到main游戏,我想我已经通过将pong4.main传递到按钮的动作参数中完成了

我的问题是,我首先运行的是主游戏,而不是标题屏幕。我从来没有点击过标题屏幕。然后,一旦乒乓球游戏结束,我也会得到一个字体

import pygame
import os 
import pongtry4


WHITE = (255, 255, 255)
GREY = (200, 200, 200)
BLACK = (0, 0, 0)

screen = pygame.display.set_mode((800, 400))
pygame.init()

###############################
class Button():
    def __init__(self, txt, location, action, bg=WHITE, fg=BLACK, size=(80, 30), font_name="Segoe Print", font_size=16):
        self.color = bg  # the static (normal) color
        self.bg = bg  # actual background color, can change on mouseover
        self.fg = fg  # text color
        self.size = size

        self.font = pygame.font.SysFont(font_name, font_size)
        self.txt = txt
        self.txt_surf = self.font.render(self.txt, 1, self.fg)
        self.txt_rect = self.txt_surf.get_rect(center=[s//2 for s in self.size])

        self.surface = pygame.surface.Surface(size)
        self.rect = self.surface.get_rect(center=location)

        self.call_back_ = action

    def draw(self):
        self.mouseover()

        self.surface.fill(self.bg)
        self.surface.blit(self.txt_surf, self.txt_rect)
        screen.blit(self.surface, self.rect)

    def mouseover(self):
        self.bg = self.color
        pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(pos):
            self.bg = GREY  # mouseover color

    def call_back(self):
        self.call_back_()


def my_great_function():
    print("Great! " * 5)


def my_fantastic_function():
    print("Fantastic! " * 4)


def mousebuttondown(button):
    pos = pygame.mouse.get_pos()

    if button.rect.collidepoint(pos):
        button.call_back()
#########################


class SceneBase:
    def __init__(self):
        self.next = self

    def ProcessInput(self, events, pressed_keys):
        print("uh-oh, you didn't override this in the child class")

    def Update(self):
        print("uh-oh, you didn't override this in the child class")

    def Render(self, screen):
        print("uh-oh, you didn't override this in the child class")

    def SwitchToScene(self, next_scene):
        self.next = next_scene

    def Terminate(self):
        self.SwitchToScene(None)

def run_game(width, height, fps, starting_scene):

    screen = pygame.display.set_mode((width, height))
    clock = pygame.time.Clock()

    active_scene = starting_scene


    while active_scene != None:
        pressed_keys = pygame.key.get_pressed()

        # Event filtering 
        filtered_events = []
        for event in pygame.event.get():
            quit_attempt = False
            if event.type == pygame.QUIT:
                quit_attempt = True
            elif event.type == pygame.KEYDOWN:
                alt_pressed = pressed_keys[pygame.K_LALT] or \
                              pressed_keys[pygame.K_RALT]
                if event.key == pygame.K_ESCAPE:
                    quit_attempt = True
                elif event.key == pygame.K_F4 and alt_pressed:
                    quit_attempt = True

            if quit_attempt:
                active_scene.Terminate()
            else:
                filtered_events.append(event)

        active_scene.ProcessInput(filtered_events, pressed_keys)
        active_scene.Update()
        active_scene.Render(screen)

        active_scene = active_scene.next

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

# The rest is code where you implement your game using the Scenes model 

class TitleScene(SceneBase):
    def __init__(self):
        SceneBase.__init__(self)
        #Create buttons and font instances here 
        self.play_button = Button("Play", (60, 30), self.SwitchToScene(DifficultyScene()))
        self.my_font = pygame.font.SysFont("Moyko", 50)

    def ProcessInput(self, events, pressed_keys):
        for event in events:
            if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
                # Move to the next scene when the user pressed Enter 
                self.SwitchToScene(DifficultyScene())

            if event.type == pygame.KEYUP:
                print("You are hitting up!") 
                print(self.next)

            if event.type == pygame.MOUSEBUTTONDOWN:
                mousebuttondown(self.play_button)

    def Update(self):
        pass

    def Render(self, screen):
        # For the sake of brevity, the title scene is a blank red screen 
        screen.fill((255, 0, 0))

        #Just Draw the Text Here 
        #myfont = pygame.font.SysFont(("Moyko"), 50)
        textImage = self.my_font.render("Anime Pong", True, (0, 255, 0))
        screen.blit(textImage, (100,100))

        #Just draw the button here 
        self.play_button.draw()


def my_great_function():
    print("Great! " * 5)


def my_fantastic_function():
    print("Fantastic! " * 4)


class DifficultyScene(SceneBase):
    def __init__(self):
        SceneBase.__init__(self)

        self.easy_button = Button("Easy", (60, 30), pongtry4.main())
        self.hard_button = Button("Hard", (120, 60), my_fantastic_function)


    def ProcessInput(self, events, pressed_keys):

        for event in events:
            if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
                # Move to the next scene when the user pressed Enter 
                self.SwitchToScene(GameScene())

            if event.type == pygame.KEYUP:
                print("You are hitting up!") 
                print(self.next)

            if event.type == pygame.MOUSEBUTTONDOWN:
                mousebuttondown(self.easy_button)
                mousebuttondown(self.hard_button)

    def Update(self):
        pass

    def Render(self, screen):
        # The game scene is just a blank blue screen 
        screen.fill((255, 0, 255))

        self.easy_button.draw()
        self.hard_button.draw()

class GameScene(SceneBase):
    def __init__(self):
        SceneBase.__init__(self)

    def ProcessInput(self, events, pressed_keys):
        for event in events:
            if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
                # Move to the next scene when the user pressed Enter 
                self.SwitchToScene(DifficultyScene())

            if event.type == pygame.KEYUP:
                print("You are hitting up!") 
                print(self.next)

            if event.type == pygame.MOUSEBUTTONDOWN:
                mousebuttondown(self.play_button)

    def Update(self):
        pass

    def Render(self, screen):
        # The game scene is just a blank blue screen 
        screen.fill((0, 0, 255))

run_game(800, 400, 60, TitleScene())
下面也是我的pongTry4主要游戏模型

import pygame
from pygame.locals import * 
import math 
import random


########Colors######
RED = (255,0,0)
WHITE = (255, 255, 255)
GREEN = (0,255,0)
BLACK = (0, 0 , 0)
####################

game_mode = "Easy"

class Pong(object):

    def __init__(self, screen_size):
        #screenSize is a tuple (XLen, YLen)
        self.screen_size = screen_size  

        self.XCenter = screen_size[0] // 2
        self.YCenter = screen_size[1] // 2

        self.rad = 10 

        #Create the surface for the Pong. #Drawn from top left corner 
        self.rect = pygame.Rect(self.XCenter-self.rad,
                                self.YCenter-self.rad,
                                self.rad*2,
                                self.rad*2)
        self.color = GREEN

        #direction and speed 
        self.direction = [-1, -1]
        self.speedX = 4
        self.speedY = 2


        #Pong Hitting left edge results in a loss
        #Pong Hitting right edge results in a win
        self.hit_left_edge = False 
        self.hit_right_edge = False 


    def update(self, player_paddle, ai_paddle):

        self.XCenter += self.speedX * self.direction[0]
        self.YCenter += self.speedY * self.direction[1]

        #update the center of the rectangle 
        self.rect.center = (self.XCenter, self.YCenter)

        #Make sure the ball does not go past the bottom/top of screen
        if self.rect.top <= 0:
            self.direction[1] = 1
        elif self.rect.bottom >= self.screen_size[1] - 1:
            self.direction[1] = -1 

        #Tells us if the right or left edge has been hit
        #This will tell us if someone has scored or not 
        if self.rect.left <= 0:
            self.hit_left_edge = True 
        elif self.rect.right >= self.screen_size[0] - 1:
            self.hit_right_edge = True 

        #Change the direction of pong based on where it hits player paddle

        if self.rect.colliderect(player_paddle.rect):

            relative_IntersectionY = player_paddle.YCenter - self.YCenter
            normal_IntersectionY = relative_IntersectionY // (player_paddle.height //2)
            bounce_angle = normal_IntersectionY * (math.pi * 5 // 12)   

            #constrains the speed of the ball
            if self.speedX >= 10 or self.speedY >= 10:
                self.speedX -= random.randint(4, 7)
                self.speedY -= random.randint(4, 7)

            self.speedX += random.randint(1, 3)
            self.speedY += random.randint(1, 3)
            print(self.speedX, self.speedY)
            self.direction[0] = math.cos(bounce_angle)
            self.direction[1] = -1*math.sin(bounce_angle)

        #Change the direction of pong baesd on where it hits AI Paddle 
        if self.rect.colliderect(ai_paddle.rect):
            relative_IntersectionY = ai_paddle.YCenter - self.YCenter
            normal_IntersectionY = relative_IntersectionY // (ai_paddle.height // 2)
            bounce_angle = normal_IntersectionY * (math.pi * 5 //12)

            if self.speedX >= 10 or self.speedY >= 10:
                self.speedX -= random.randint(4, 7)
                self.speedY -= random.randint(4, 7)

            self.speedX += random.randint(1,2)
            self.speedY += random.randint(1,2)
            print(self.speedX, self.speedY)

            self.direction[0] = -1 * math.cos(bounce_angle)
            self.direction[1] = -1 * math.sin(bounce_angle)


    def draw(self, screen):

        pygame.draw.circle(screen, self.color, self.rect.center, self.rad, 0)
        pygame.draw.circle(screen, BLACK, self.rect.center, self.rad, 1)

class Paddle(object):

    def __init__(self, screen_size, XCenter, YCenter, height, width, color):

        self.screen_size = screen_size
        self.XCenter = XCenter
        self.YCenter = YCenter
        self.height = height
        self.width = width 
        self.color = color 


        #Create the paddle surface on the sides of the screen
        self.rect = pygame.Rect(0, self.YCenter - self.height//2, self.width, self.height)


    def draw(self, screen):
        pygame.draw.rect(screen, self.color, self.rect, 0)
        pygame.draw.rect(screen, BLACK, self.rect, 1)


class PlayerPaddle(Paddle):

    def __init__(self, screen_size, XCenter, YCenter, height, width, color):

        super().__init__(screen_size, XCenter, YCenter, height, width, color)

        self.speed = 5
        self.direction = 0

    def draw(self, screen):

        super().draw(screen)

    def update(self):

        self.YCenter += self.direction * self.speed 

        self.rect.center = (self.XCenter, self.YCenter)

        #ensures the paddle doesn't go off the screen 
        if self.rect.top <= 0:
            self.rect.top = 0
        if self.rect.bottom > self.screen_size[1]:
            self.rect.bottom = self.screen_size[1]

class AIPaddle(Paddle):

    def __init__(self, screen_size, XCenter, YCenter, height, width, color):

        super().__init__(screen_size, XCenter, YCenter, height, width, color)

        self.speed = 4

    def draw(self, screen):

        super().draw(screen)

    def update(self, pong):

        #If the pong is above the paddle, move the paddle towards it
        #If the pong is below the paddle, move the paddle towards it 
        if pong.rect.top < self.rect.top:
            self.YCenter -= self.speed 
        elif pong.rect.bottom > self.rect.bottom:
            self.YCenter += self.speed  

        #update the AI Paddle's center coordinates 
        self.rect.center = (self.XCenter, self.YCenter)

################################################

def main():

    pygame.init()
    screen_size = (1200, 800)
    screen = pygame.display.set_mode(screen_size)
    clock = pygame.time.Clock()

    pong = Pong(screen_size)
    ai_paddle = AIPaddle(screen_size, screen_size[0] - 5, screen_size[1]//2, 100, 10, WHITE)
    player_paddle = PlayerPaddle(screen_size, 5, screen_size[1]//2, 100, 10, WHITE)

    running = True

    while running:
        #fps limiting/reporting phase
        clock.tick(64)

        #event handling phase
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False

            if event.type == KEYDOWN:
                if event.key == K_UP:
                    player_paddle.direction = -1
                elif event.key == K_DOWN:
                    player_paddle.direction = 1
            if event.type == KEYUP:
                if event.key == K_UP and player_paddle.direction == -1:
                    player_paddle.direction = 0
                elif event.key == K_DOWN and player_paddle.direction == 1:
                    player_paddle.direction = 0

        #object updating phase
        ai_paddle.update(pong)
        player_paddle.update()
        pong.update(player_paddle, ai_paddle)

        #CODE TASK: make some text on the screen over everything else saying you lost/won, and then exit on keypress
        #CODE BONUS: allow restarting of the game (hint: you can recreate the Pong/Paddle objects the same way we made them initially)
        if pong.hit_left_edge:
            print("You Won")
            running = False
        elif pong.hit_right_edge:
            print("you lose")
            running = False

        #rendering phase
        screen.fill((100,100,100))

        ai_paddle.draw(screen)
        player_paddle.draw(screen)
        pong.draw(screen)

        pygame.display.flip()

    pygame.quit()

当我运行main或运行run_游戏时是否有问题,或者如果单击按钮,是否更像是将main传递到我的按钮的一个参数中的问题?感谢大多数框架中的按钮期望回调-它意味着没有参数和参数的函数名-因此您需要pong4.main而不是pong4.main

如果您使用pong4.main,那么您会得到

result = pong4.main()
Button(..., result)
因此它首先执行pong4.main

编辑:您在中有相同的问题

Button("Play", (60, 30), self.SwitchToScene(DifficultyScene()))
您必须创建函数并使用它按钮

def function():
    self.SwitchToScene(DifficultyScene())

Button("Play", (60, 30), function)
或者可以使用lambda创建noname函数

Button("Play", (60, 30), lambda:self.SwitchToScene(DifficultyScene()) )

始终使用标记python—它突出显示代码并使其更具可读性。我的部分问题已经解决,当我单击“轻松模式”时,pong游戏将运行。然而,弹出的第一件事仍然是乒乓球游戏,标题屏幕从未进入。可能您使用了其他按钮。您在ButtonPlay,60,30,self.switchtoscenedifficlescenesee lambda中遇到了相同的问题。这修复了标题场景错误。然而,我还有两个错误。首先,此场景代码始终运行我的pongTry4文件的旧版本,而从不运行我的pongTry4的编辑版本。我的第二个问题是,主乒乓球游戏仍然在标题屏幕前运行。