Моя игра в тетрадь пигамей застревает
Я начинающий программист на Python и пытаюсь сделать игру в тетрис. Когда я запускаю игру, блок перемещается вниз на 10 пикселей каждую секунду. Проблема в том, что случайным образом блок просто останавливается, у меня также перестают печататься операторы print. Я не получаю ошибку, по словам диспетчера задач, память в порядке. У меня Vista 32-разрядная с процессором Celeron, но я также попробовал его на Windows 7 с процессором i5, и проблема остается, поэтому я потерян.
Это код:
import pygame
from pygame.locals import *
from datetime import datetime
import Blocks
def Gravity(Box, rate):
# Gravity effect
Box.set_yCoor(Box.get_yCoor()+ rate)
Box.Edge.set_yCoor(Box.Edge.get_yCoor()+ rate)
return Box
def main():
# initailize all pygame modules
pygame.init()
windowWidth,windowHeight= 640,700
screen_color= (255,255,255)
# Determines how many pixels per time the box will fall
gravity= 10
# Create screen/window and change color to white
screen= pygame.display.set_mode((windowWidth,windowHeight),0,32)
screen.fill(screen_color)
# Used to determine whether to draw box and apply gravity
index =0
# Put box and border info in list
# Args: (x,y) (len, width) (color)
boxInfo= [10,10, 20,50, (0,0,0)]
borderInfo= [5,5, 30,60, (154,24,214)]
# Create instance of box and pass info
Box= Blocks.Box(boxInfo, borderInfo)
#Create an endless loop that the game will run inside of
while True:
for event in pygame.event.get():
if event.type== QUIT:
pygame.quit()
return
# Get second and millisecond time and convert to string
startTime= str(datetime.now())
# Splice time string and convert to float
startTime= float(startTime[17:23])
if index== 0:
# Pull the box down by gravity
Box= Gravity(Box, gravity)
# Move box back to the top of window
if Box.Edge.get_yCoor() > windowHeight - Box.Edge.get_boxWid():
Box.Edge.set_yCoor(5)
Box.set_yCoor(10)
# Clear screen
screen.fill(screen_color)
# Display Screen
Box.display(screen)
# Set the stop time used to determine when to call gravity and display
stopTime= startTime+ 1
index= 1
# Get second and millisecond time and convert to string
bug= str(datetime.now())
# Splice time string and convert to float
bug= bug[17:23]
print("\nDisplayed at:")
print('Start:', startTime)
print('Stop:', stopTime)
print('Bug:', bug)
elif startTime >= stopTime:
index= 0
# Get second and millisecond time and convert to string
bug= str(datetime.now())
# Splice time string and convert to float
bug= bug[17:26]
print("\nNot displaying at:")
print('Start:', startTime)
print('Stop:', stopTime)
print('Bug:', bug)
# Call main
main()
Это класс блоков: импорт pygame из pygame.locals import *
class Box():
def __init__(self, boxInfo, edgeInfo):
# Pixel location of the box
self.__xCoor= boxInfo[0]
self.__yCoor= boxInfo[1]
# Pixel length and width of the box
self.__boxLen= boxInfo[2]
self.__boxWid= boxInfo[3]
# Pixel color is white by default
self.__color= boxInfo[4]
self.Edge= Border(edgeInfo)
# ---- ACCESSORS -- and -- MUTATORS ----
def set_xCoor(self,Coordx):
self.__xCoor= Coordx
def get_xCoor(self):
return self.__xCoor
def set_yCoor(self,Coordy):
self.__yCoor= Coordy
def get_yCoor(self):
return self.__yCoor
def set_boxLen(self,Length):
self.__boxLen= Length
def get_boxLen(self):
return self.__boxLen
def set_boxWid(self,Width):
self.__boxWid= Width
def get_boxWid(self):
return self.__boxWid
def set_color(self,color):
self.__color= color
def get_color(self):
return self.__color
# ---- METHODS ----
def boxStatCheck(self):
# Prints all the attributes in the shell for debug
print("x-Coordinate=", self.get_xCoor())
print("y-Coordinate=", self.get_yCoor())
print("Box Length=", self.get_boxLen())
print("Box Width=", self.get_boxWid())
print("Color Value=", self.get_color())
def display(self, screen):
screen.lock()
pygame.draw.rect(screen, self.Edge.get_color(), Rect((self.Edge.get_xCoor(),self.Edge.get_yCoor()),
(self.Edge.get_boxLen(),self.Edge.get_boxWid())))
pygame.draw.rect(screen, self.get_color(), Rect((self.get_xCoor(),self.get_yCoor()),
(self.get_boxLen(),self.get_boxWid())))
screen.unlock()
pygame.display.update()
class Border():
def __init__(self, listInfo):
# Pixel location of the box
self.__xCoor= listInfo[0]
self.__yCoor= listInfo[1]
# Pixel length and width of the box
self.__boxLen= listInfo[2]
self.__boxWid= listInfo[3]
# Pixel color is white by default
self.__color= listInfo[4]
# ---- ACCESSORS -- and -- MUTATORS ----
def set_xCoor(self,Coordx):
self.__xCoor= Coordx
def get_xCoor(self):
return self.__xCoor
def set_yCoor(self,Coordy):
self.__yCoor= Coordy
def get_yCoor(self):
return self.__yCoor
def set_boxLen(self,Length):
self.__boxLen= Length
def get_boxLen(self):
return self.__boxLen
def set_boxWid(self,Width):
self.__boxWid= Width
def get_boxWid(self):
return self.__boxWid
def set_color(self,color):
self.__color= color
def get_color(self):
return self.__color
# ---- METHODS ----
def boxStatCheck(self):
# Prints all the attributes in the shell for debug
print("x-Coordinate=", self.get_xCoor())
print("y-Coordinate=", self.get_yCoor())
print("Box Length=", self.get_boxLen())
print("Box Width=", self.get_boxWid())
print("Color Value=", self.get_color())
def display(self, screen):
pygame.draw.rect(screen, self.get_color(), Rect((self.get_xCoor(),self.get_yCoor()),
(self.get_boxLen(),self.get_boxWid())))
2 ответа
Я думаю, что ваша проблема заключается в том, как вы используете datetime для контроля, когда перемещать блок вниз.
Вы должны проверить модуль pygame.time. Я рекомендую вам создать переменную (например, wanted_fps), содержащую целое число для того, как часто вы хотите, чтобы ваш бесконечный цикл выполнялся каждую секунду. Ваш код должен выглядеть примерно так:
wanted_fps = 1 # how often I want the endless loop to run per second
fpsHandler = pygame.time.Clock() # fpsHandler created to handle fps
while(True): # our endless loop
# do something awesome
fpsHandler.tick(wanted_fps) # makes sure fps isn't higher than wanted_fps
Вы можете прочитать о pygame.time здесь: http://www.pygame.org/docs/ref/time.html
Кроме того, если вы хотите, по-видимому, никакой задержки при обработке событий, вы можете установить значение wanted_fps, например, равное 60, а затем создать некоторую переменную счетчика (например, mycounter) для обработки того, как часто вы хотите, чтобы что-то происходило. Допустим, вы делаете что-то подобное в своем бесконечном цикле:
# handle events
if mycounter > 0:
mycounter -= 1
else:
# do something amazing
mycounter = 30
вы делаете что-то удивительное 60/30=2 раза в секунду, но вы обрабатываете события 60 раз в секунду, и, следовательно, вы можете реагировать на событие, казалось бы, мгновенно.
Поскольку вы устанавливаете stopTime, добавляя 1 к startTime, когда startTime становится 59.xx, stopTime становится значением больше 60. startTime затем возвращается к 0, потому что это новая минута, и вы застряли. index = 1 и startTime никогда не будет больше, чем stopTime. Ни одно из утверждений if или elif не оценивается как True. Если ваша цель - включить задержку перед тем, как снова нарисовать прямоугольник, подумайте над тем, чтобы сделать что-то вроде этого...
pauseLength = 120
а потом в игровой цикл...
pygame.time.delay(pauseLength)
Это также позволит вам ускорить игру для дополнительной сложности позже.