Reputation: 23
I am a beginner python programmer and I am trying to make a tetris game. When I run the game, the block moves down 10 pixels every second. The problem is that randomly the block just stops, the print statements I have also stop printing. I'm not getting an error, according to the task manager, the memory is okay. I have vista 32 bit with a celeron processor, but I also tried it on a windows 7 with an i5 processor and the problem persists so I'm lost.
This is the code:
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()
This is the blocks class: import pygame from 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())))
Upvotes: 2
Views: 934
Reputation: 1189
I think your problem lies in how you use datetime to control when to move the block down.
You should check out the pygame.time module. I recommend you create a variable (for example wanted_fps) containing an integer for how often you want your endless loop to run each second. Your code should then look something like this:
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
You can read about pygame.time here: http://www.pygame.org/docs/ref/time.html
Also, if you want a seemingly no event-processing delay you can set wanted_fps to something like 60 and then make some kind of counter variable (for example mycounter) to handle how often you want something to happen. Lets say you do something like this in your endless loop:
# handle events
if mycounter > 0:
mycounter -= 1
else:
# do something amazing
mycounter = 30
you do something amazing 60/30=2 times each second but you handle events 60 times per second and therefore you can respond to an event seemingly instantly.
Upvotes: 2
Reputation: 896
Because you are setting stopTime by adding 1 to startTime, when startTime becomes 59.xx stopTime will become a value greater than 60. startTime then goes back to 0 because it's a new minute and you are stuck. index = 1 and startTime will never be greater than stopTime. None of the if or elif statements will evaluate to True. If your goal is to incorporate a delay before drawing the box again, consider doing something like this...
pauseLength = 120
and then in the game loop...
pygame.time.delay(pauseLength)
This will also allow you to speed up the game for added difficulty later.
Upvotes: 0