您可以在不打开 pygame window 的情况下导入 pygame 脚本吗(直到您想要为止?)
Can you import a pygame script without opening a pygame window (until you want to?)
所以,我有一个名为 run.py 的游戏,是我用 pygame 制作的,在大多数情况下,它运行良好。我正在尝试为我所有的 pygame 制作一个启动器。但是当我导入它时,它立即打开一个空白window。在我调用 run.main()
之前,我什么都不想发生
import tkinter as tk
import run
WIN = tk.Tk()
WIN.mainloop()
run.main()
我知道发生这种情况是因为在我的 pygame 脚本中我将 window 设置在一个函数之外,当我打开一个 tkinter window 它离开 pygame window 打开直到我关闭 tkinter 一个。但是我希望原始游戏在没有这个启动器的情况下也能正常工作。
这是我的 pygame:
的代码
import pygame , random
pygame.init()
# This is where it opens the window
WIDTH , HEIGHT = 900 , 500
WIN = pygame.display.set_mode((WIDTH , HEIGHT))
pygame.display.set_caption('game')
BLOCK_MOVEMENT_TIMER_EVENT = pygame.USEREVENT + 1
BLOCK_MOVEMENT_TIME_DELAY = 15
pygame.time.set_timer(BLOCK_MOVEMENT_TIMER_EVENT , BLOCK_MOVEMENT_TIME_DELAY)
BLOCK_CREATE_TIMER_EVENT = pygame.USEREVENT + 2
BLOCK_CREATE_TIME_DELAY = 1500
pygame.time.set_timer(BLOCK_CREATE_TIMER_EVENT, BLOCK_CREATE_TIME_DELAY)
FPS = 60
#colors
WHITE = (255 , 255 ,255)
BLACK = (0 , 0 , 0)
RED = (255 , 0 , 0)
BIGFONT = pygame.font.Font('Retro.ttf' , 65)
SMALLFONT = pygame.font.Font('Retro.ttf' , 20)
FLOOR = pygame.Rect(0 , 400 , 900 , 5)
class Player:
def __init__(self):
self.size = 20
self.x = 75
self.y = 380
self.jumping = False
self.fall = False
self.update_rect()
self.score = 0
def update_rect(self):
self.rect = pygame.Rect(self.x , self.y , self.size , self.size)
def jump(self):
pressed = pygame.key.get_pressed()
if pressed[pygame.K_SPACE] and not self.fall:
self.jumping = True
if self.jumping:
self.y -= 3
if self.y < 300:
self.y = 300
self.fall = True
self.jumping = False
if self.fall:
self.y += 3
if self.y > 380:
self.y = 380
self.fall = False
self.update_rect()
player = Player()
class Obstacles:
def __init__(self , width , height):
self.x = 900
self.y = HEIGHT - height - 100
self.width = width
self.height = height
self.update_rect()
def update_rect(self):
self.rect = pygame.Rect(self.x , self.y , self.width , self.height)
def move_obstacles(obstacle_list):
for obstacle in obstacle_list:
obstacle.x -= 3
if obstacle.x < -100:
obstacle_list.pop(0)
player.score += 1
obstacle.update_rect()
def add_obstacle(obstacle_list):
obstacle1 = Obstacles(20 , 40)
obstacle2 = Obstacles(75 , 20)
obstacle3 = Obstacles(35 , 35)
obstacle4 = Obstacles(50 , 25)
obstacle5 = Obstacles(80 , 10)
obstacle6 = Obstacles(40 , 20)
obstacle7 = Obstacles(20 , 30)
obstacle_options = [obstacle1 , obstacle2 , obstacle3 , obstacle4 , obstacle5 , obstacle6 , obstacle7]
obstacle_list.append(obstacle_options[random.randint(0,6)])
def is_game_over(obstacle_list):
for obstacle in obstacle_list:
if player.rect.colliderect(obstacle):
return True
def game_over():
running = False
while not running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = True
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
player.score = 0
main()
break
if event.key == pygame.K_e:
running = True
quit()
WIN.fill(BLACK)
game_over = BIGFONT.render('GAME OVER', False, WHITE)
WIN.blit(game_over , (200 , 175))
instructions = SMALLFONT.render(f'You scored {player.score}. Press R to restart or E to exit' , False , WHITE)
WIN.blit(instructions , (145 , 290))
pygame.display.flip()
def draw_window(obstacle_list , is_game_over):
WIN.fill(BLACK)
pygame.draw.rect(WIN , WHITE , FLOOR)
pygame.draw.rect(WIN , WHITE , player.rect)
for obstacle in obstacle_list:
pygame.draw.rect(WIN , RED , obstacle.rect)
score_counter = BIGFONT.render(f'SCORE {player.score}', False, (255, 255, 255))
WIN.blit(score_counter , (240 , 100))
pygame.display.flip()
def main():
clock = pygame.time.Clock()
obstacle_list = []
done = False
while not done:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_e:
done = True
quit()
if event.type == BLOCK_MOVEMENT_TIMER_EVENT:
move_obstacles(obstacle_list)
if event.type == BLOCK_CREATE_TIMER_EVENT:
add_obstacle(obstacle_list)
draw_window(obstacle_list , is_game_over(obstacle_list))
player.jump()
is_game_over(obstacle_list)
if is_game_over(obstacle_list):
game_over()
done = True
pygame.display.flip()
if __name__ == '__main__':
main()
如果这个问题没有意义,我很抱歉,但我们将不胜感激。
是的。首先 pygame 不会初始化游戏 window 直到你调用 pygame.display.set_mode((width, height))
.
因此您可以将 run.py
内的所有游戏逻辑移动到一个函数中,例如...
def my_game_name():
pygame.init()
WIDTH , HEIGHT = 900 , 500
WIN = pygame.display.set_mode((WIDTH , HEIGHT))
...
class Player:
...
def move_obstacles(obstacle_list):
...
def main():
...
然后在你的内心main.py
你可以做到这一点。
import run
# When you're ready to run the game
run.my_game_name()
我建议您 不 做的第二个选择是...
里面main.py
#TK button clicked to start game
def start_my_game():
import run # Window is shown here
run.main() # Game logic begins
我不会推荐这个,因为你依赖 import
在后台设置东西,这就是你现在遇到问题的原因。
所以,我有一个名为 run.py 的游戏,是我用 pygame 制作的,在大多数情况下,它运行良好。我正在尝试为我所有的 pygame 制作一个启动器。但是当我导入它时,它立即打开一个空白window。在我调用 run.main()
import tkinter as tk
import run
WIN = tk.Tk()
WIN.mainloop()
run.main()
我知道发生这种情况是因为在我的 pygame 脚本中我将 window 设置在一个函数之外,当我打开一个 tkinter window 它离开 pygame window 打开直到我关闭 tkinter 一个。但是我希望原始游戏在没有这个启动器的情况下也能正常工作。
这是我的 pygame:
的代码import pygame , random
pygame.init()
# This is where it opens the window
WIDTH , HEIGHT = 900 , 500
WIN = pygame.display.set_mode((WIDTH , HEIGHT))
pygame.display.set_caption('game')
BLOCK_MOVEMENT_TIMER_EVENT = pygame.USEREVENT + 1
BLOCK_MOVEMENT_TIME_DELAY = 15
pygame.time.set_timer(BLOCK_MOVEMENT_TIMER_EVENT , BLOCK_MOVEMENT_TIME_DELAY)
BLOCK_CREATE_TIMER_EVENT = pygame.USEREVENT + 2
BLOCK_CREATE_TIME_DELAY = 1500
pygame.time.set_timer(BLOCK_CREATE_TIMER_EVENT, BLOCK_CREATE_TIME_DELAY)
FPS = 60
#colors
WHITE = (255 , 255 ,255)
BLACK = (0 , 0 , 0)
RED = (255 , 0 , 0)
BIGFONT = pygame.font.Font('Retro.ttf' , 65)
SMALLFONT = pygame.font.Font('Retro.ttf' , 20)
FLOOR = pygame.Rect(0 , 400 , 900 , 5)
class Player:
def __init__(self):
self.size = 20
self.x = 75
self.y = 380
self.jumping = False
self.fall = False
self.update_rect()
self.score = 0
def update_rect(self):
self.rect = pygame.Rect(self.x , self.y , self.size , self.size)
def jump(self):
pressed = pygame.key.get_pressed()
if pressed[pygame.K_SPACE] and not self.fall:
self.jumping = True
if self.jumping:
self.y -= 3
if self.y < 300:
self.y = 300
self.fall = True
self.jumping = False
if self.fall:
self.y += 3
if self.y > 380:
self.y = 380
self.fall = False
self.update_rect()
player = Player()
class Obstacles:
def __init__(self , width , height):
self.x = 900
self.y = HEIGHT - height - 100
self.width = width
self.height = height
self.update_rect()
def update_rect(self):
self.rect = pygame.Rect(self.x , self.y , self.width , self.height)
def move_obstacles(obstacle_list):
for obstacle in obstacle_list:
obstacle.x -= 3
if obstacle.x < -100:
obstacle_list.pop(0)
player.score += 1
obstacle.update_rect()
def add_obstacle(obstacle_list):
obstacle1 = Obstacles(20 , 40)
obstacle2 = Obstacles(75 , 20)
obstacle3 = Obstacles(35 , 35)
obstacle4 = Obstacles(50 , 25)
obstacle5 = Obstacles(80 , 10)
obstacle6 = Obstacles(40 , 20)
obstacle7 = Obstacles(20 , 30)
obstacle_options = [obstacle1 , obstacle2 , obstacle3 , obstacle4 , obstacle5 , obstacle6 , obstacle7]
obstacle_list.append(obstacle_options[random.randint(0,6)])
def is_game_over(obstacle_list):
for obstacle in obstacle_list:
if player.rect.colliderect(obstacle):
return True
def game_over():
running = False
while not running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = True
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
player.score = 0
main()
break
if event.key == pygame.K_e:
running = True
quit()
WIN.fill(BLACK)
game_over = BIGFONT.render('GAME OVER', False, WHITE)
WIN.blit(game_over , (200 , 175))
instructions = SMALLFONT.render(f'You scored {player.score}. Press R to restart or E to exit' , False , WHITE)
WIN.blit(instructions , (145 , 290))
pygame.display.flip()
def draw_window(obstacle_list , is_game_over):
WIN.fill(BLACK)
pygame.draw.rect(WIN , WHITE , FLOOR)
pygame.draw.rect(WIN , WHITE , player.rect)
for obstacle in obstacle_list:
pygame.draw.rect(WIN , RED , obstacle.rect)
score_counter = BIGFONT.render(f'SCORE {player.score}', False, (255, 255, 255))
WIN.blit(score_counter , (240 , 100))
pygame.display.flip()
def main():
clock = pygame.time.Clock()
obstacle_list = []
done = False
while not done:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_e:
done = True
quit()
if event.type == BLOCK_MOVEMENT_TIMER_EVENT:
move_obstacles(obstacle_list)
if event.type == BLOCK_CREATE_TIMER_EVENT:
add_obstacle(obstacle_list)
draw_window(obstacle_list , is_game_over(obstacle_list))
player.jump()
is_game_over(obstacle_list)
if is_game_over(obstacle_list):
game_over()
done = True
pygame.display.flip()
if __name__ == '__main__':
main()
如果这个问题没有意义,我很抱歉,但我们将不胜感激。
是的。首先 pygame 不会初始化游戏 window 直到你调用 pygame.display.set_mode((width, height))
.
因此您可以将 run.py
内的所有游戏逻辑移动到一个函数中,例如...
def my_game_name():
pygame.init()
WIDTH , HEIGHT = 900 , 500
WIN = pygame.display.set_mode((WIDTH , HEIGHT))
...
class Player:
...
def move_obstacles(obstacle_list):
...
def main():
...
然后在你的内心main.py
你可以做到这一点。
import run
# When you're ready to run the game
run.my_game_name()
我建议您 不 做的第二个选择是...
里面main.py
#TK button clicked to start game
def start_my_game():
import run # Window is shown here
run.main() # Game logic begins
我不会推荐这个,因为你依赖 import
在后台设置东西,这就是你现在遇到问题的原因。