Question

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())))
Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top