问题
I have been at this for about 2 hours now and I am getting quite frustrated, I have created a pygame file which doesn't use any external fonts or images (which i know is the main issue on why the game screen usually crashes) however I run mine and in the console I get the usual Hello from pygame community and then my game window pops up for roughly a second ad then disappears again with no error messages in the console.
I even installed OBS just to check if the error message was popping up too fast for me to see however there is no error message in sight. I also tried turning on Debug in the .spec file however everything seemed normal (To be fair this is my first time converting a .py to a .exe so i dont really know what I am looking for when it comes to the debug)
I also tried using cx_freeze but I just kept getting this error when building "TypeError: expected str, bytes or os.PathLike object, not NoneType" and all the fixes I could find were for Pyinstaller not cx_freeze, ideally i would prefer to use cx_freeze but I cant even build an exe with that at least with pyinstaller I have an exe to show (even if it is broken) This is my command window when I run the exe just before it crashes, nothing more is printed after this
My code is as follows :
import random
import pygame
#import matplotlib.pyplot as plt
from pygame.locals import *
import time
import numpy as np
import sys
import os
pygame.init()
# Window details
windowWidth = 1000
windowHeight = 600
pixSize = 2
FPS = 60
numberofcells = 100
screen = pygame.display.set_mode((windowWidth, windowHeight))
pygame.display.set_caption("Infection Game")
class Cell:
def __init__(self):
self.xPos = random.randrange(1, windowWidth)
self.yPos = random.randrange(1, windowHeight)
self.speed = 2
self.isInfected = False
self.infectionRange = 5
self.move = [None, None]
self.direction = None
def cellDraw(self):
if not self.isInfected:
pygame.draw.rect(screen, (255, 255, 255), (self.xPos, self.yPos, pixSize, pixSize), 0)
else:
pygame.draw.rect(screen, (0, 255, 0), (self.xPos, self.yPos, pixSize, pixSize), 0)
def cellMovement(self):
directions = {"S": ((-1, 2), (1, self.speed)), "SW": ((-self.speed, -1), (1, self.speed)),
"W": ((-self.speed, -1), (-1, 2)), "NW": ((-self.speed, -1), (-self.speed, -1)),
"N": ((-1, 2), (-self.speed, -1)), "NE": ((1, self.speed), (-self.speed, -1)),
"E": ((1, self.speed), (-1, 2)),
"SE": ((1, self.speed), (1, self.speed))} # ((min x, max x)(min y, max y))
directionsName = ("S", "SW", "W", "NW", "N", "NE", "E", "SE") # possible directions
if random.randrange(0, 5) == 2: # move about once every 5 frames
if self.direction is None: # if no direction is set, set a random one
self.direction = random.choice(directionsName)
else:
a = directionsName.index(self.direction) # get the index of direction in directions list
b = random.randrange(a - 1,
a + 2) # set the direction to be the same, or one next to the current direction
if b > len(directionsName) - 1: # if direction index is outside the list, move back to the start
b = 0
self.direction = directionsName[b]
self.move[0] = random.randrange(directions[self.direction][0][0], directions[self.direction][0][1]) + 0.35
self.move[1] = random.randrange(directions[self.direction][1][0], directions[self.direction][1][1]) + 0.35
if self.xPos < 5 or self.xPos > windowWidth - 5 or self.yPos < 5 or self.yPos > windowHeight - 5: # if cell is near the border of the screen, change direction
if self.xPos < 5:
self.direction = "E"
elif self.xPos > windowWidth - 5:
self.direction = "W"
elif self.yPos < 5:
self.direction = "S"
elif self.yPos > windowHeight - 5:
self.direction = "N"
self.move[0] = random.randrange(directions[self.direction][0][0], directions[self.direction][0][1]) + 0.35
self.move[1] = random.randrange(directions[self.direction][1][0], directions[self.direction][1][1]) + 0.35
if self.move[0] is not None: # add the relative coordinates to the cells coordinates
self.xPos += self.move[0]
self.yPos += self.move[1]
def Infect(self, uninfected, uninfected_array):
indices = np.greater(uninfected_array[:, 0], self.xPos - self.infectionRange) * \
np.greater(self.xPos + self.infectionRange, uninfected_array[:, 0]) * \
np.greater(uninfected_array[:, 1], self.yPos - self.infectionRange) * \
np.greater(self.yPos + self.infectionRange, uninfected_array[:, 1])
for i in np.where(indices)[0]:
uninfected[i].isInfected = True
font = pygame.font.SysFont(None, 20)
def drawText(text, font ,colour, surface, x, y):
textobj = font.render(text, 1 , colour)
textrect = textobj.get_rect()
textrect.topleft = (x,y)
surface.blit(textobj,textrect)
def main_menu(numberofcells):
while True:
screen.fill((0,0,0))
drawText('main menu', font, (255, 255, 255), screen, 20, 20)
mx, my = pygame.mouse.get_pos()
button_1 = pygame.Rect(50, 100, 200, 50)
button_2 = pygame.Rect(50, 200, 200, 50)
if button_1.collidepoint((mx, my)):
if click:
gameLoop(numberofcells)
if button_2.collidepoint((mx, my)):
if click:
numberofcells = options(numberofcells)
pygame.draw.rect(screen, (255, 0, 0), button_1)
drawText('start sim', font, (0,0,0), screen, 127, 120)
pygame.draw.rect(screen, (255, 0, 0), button_2)
drawText('options', font, (0,0,0), screen, 130, 220)
click = False
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
if event.type == MOUSEBUTTONDOWN:
if event.button == 1:
click = True
pygame.display.update()
pygame.time.Clock().tick(FPS)
def options(numberofcells):
running = True
while running:
screen.fill((0,0,0))
drawText('options - press ESC to return to menu', font, (255, 255, 255), screen, 20, 20)
mx, my = pygame.mouse.get_pos()
button_1 = pygame.Rect(50, 300, 200, 50)
button_2 = pygame.Rect(50, 400, 200, 50)
pygame.draw.rect(screen, (255, 0, 0), button_1)
drawText('100 cells', font, (0,0,0), screen, 127, 320)
pygame.draw.rect(screen, (255, 0, 0), button_2)
drawText('1000 cells', font, (0,0,0), screen, 127, 420)
if button_1.collidepoint((mx, my)):
if optclick:
numberofcells = 100
pygame.draw.rect(screen, (139, 0, 0), button_1)
if button_2.collidepoint((mx, my)):
if optclick:
numberofcells = 1000
pygame.draw.rect(screen, (139, 0, 0), button_2)
optclick = False
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
if event.type == MOUSEBUTTONDOWN:
if event.button == 1:
optclick = True
pygame.display.update()
pygame.time.Clock().tick(FPS)
return(numberofcells)
def gameLoop(numberofcells):
startTime = time.time()
xgraph = []
ygraph = []
cellList = []
for i in range(numberofcells):
cell = Cell()
cellList.append(cell)
cellList[0].isInfected = True
running = True
while running:
infectList = []
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
screen.fill((0, 0, 0))
for i in cellList:
i.cellDraw()
i.cellMovement()
infected = 0
uninfected = [i for i in cellList if not i.isInfected]
uninfected_array = np.array([[i.xPos, i.yPos] for i in uninfected])
if len(uninfected) > 0:
for i in cellList:
if i.isInfected:
i.Infect(uninfected, uninfected_array)
infected += 1
if infected == 0:
infected = len(cellList) - len(uninfected)
xgraph.append(time.time() - startTime)
ygraph.append(infected)
pygame.display.update() # update display
pygame.time.Clock().tick(FPS) # limit FPS
# figured this is what you wanted to do ;)
#plt.plot(xgraph, ygraph)
#plt.xlabel('time (s)')
#plt.ylabel('infected')
#plt.show()
main_menu(numberofcells)
来源:https://stackoverflow.com/questions/62968351/pyinstaller-pygame-window-closes-with-no-error-message