我无法按正确的顺序显示正确的屏幕。我首先想要的是标题屏幕,它是红色的。然后,如果我单击“播放”按钮,我想切换到“难度”屏幕,该屏幕具有“简单”和“硬按钮”。如果我单击简单按钮,我希望我的游戏进入主游戏,我认为我已经通过将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_game()时是否存在问题,或者如果点击它,将main()传递到我的按钮的其中一个参数更多的问题是什么?感谢
答案 0 :(得分:1)
大多数框架中的按钮都需要callback
- 它表示没有()
和参数的函数名称 - 因此您需要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
创建非名称功能
Button("Play", (60, 30), lambda:self.SwitchToScene(DifficultyScene()) )