Search code examples
pythonpygamelag

Pygame window is really laggy


The pygame window gets really laggy when i try to run it. I have 132 lines of code so far and i have loads more stuff to add. While test-running i noticed that the game satrted lagging when i added the following bits of code in

class Game:
        def __init__(self):
            self.win = pygame.display
            self.d = self.win.set_mode((1200, 600))
            self.win.set_caption(" JUMP ")
            self.timee = 0

        def write(self, size, writing, color, x, y):
            font = pygame.font.SysFont("nirmalauisemilight", size)
            text = font.render(writing, True, color)
            self.d.blit(text, (x, y))

        def game_over(self):
            if b.y >= ba.y - b.side and self.timee > 5:
                while True:
                    self.write(200, "GAME OVER", (255, 0, 0), 20, 50)
                    self.write(50, "Press enter to satart a new game", (0, 255, 0), 100, 400)

                    pygame.event.get()
                    keys = pygame.key.get_pressed()
                    if keys[pygame.K_RETURN]:
                        main()

                    g.win.flip()  

AND

def draw(self):
        if g.timee < 5:
            pygame.draw.rect(g.d, (0, 255, 0), (self.x, self.y, self.width, self.height))
        else:
            pygame.draw.rect(g.d, (255, 0, 0), (self.x, self.y, self.width, self.height))

g.timee is a variable i made so i can execute some functions after a cartain time into the game. g.timee is incremented by 0.01 in the main loop. I tried using time module's time.time() fucntion as well but it lagged the game even more. Any advice on how to reduce lagging would be appreciated.

EDIT

while looking through other questions i came across cPrifile and using that i got this data

        ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        0.000    0.000    0.204    0.204 testing.py:10(__init__)
            1    0.000    0.000    0.000    0.000 testing.py:102(platforms)
          401    0.001    0.000    0.001    0.000 testing.py:21(game_over)
            1    0.020    0.020    9.688    9.688 testing.py:3(main)
            1    0.000    0.000    0.000    0.000 testing.py:42(Block)
            1    0.000    0.000    0.000    0.000 testing.py:43(__init__)
          401    0.003    0.000    0.016    0.000 testing.py:53(draw)
          401    0.002    0.000    0.006    0.000 testing.py:56(move)
          401    0.001    0.000    0.001    0.000 testing.py:63(jump_logic)
          401    0.002    0.000    0.002    0.000 testing.py:72(fall)
            1    0.000    0.000    0.000    0.000 testing.py:84(Base)
            1    0.000    0.000    0.000    0.000 testing.py:85(__init__)
            1    0.000    0.000    0.000    0.000 testing.py:9(Game)
          401    0.001    0.000    0.009    0.000 testing.py:91(draw)
          401    0.001    0.000    0.001    0.000 testing.py:97(on_base)

I am not entirely sure what it means though.

EDIT 2

Here is the code i have so far for reference

import pygame, os, random

def main():
    os.environ["SDL_VIDEO_CENTERED"] = "1"
    pygame.init()
    acc_gravity = 0.009
    terminal_vel = 4

    class Game:
        def __init__(self):
            self.win = pygame.display
            self.d = self.win.set_mode((1200, 600), pygame.RESIZABLE)
            self.win.set_caption(" JUMP ")
            self.timee = 0
            self.platlist = []

        def write(self, size, writing, color, x, y):
            font = pygame.font.SysFont("nirmalauisemilight", size)
            text = font.render(writing, True, color)
            self.d.blit(text, (x, y))

        def game_over(self):
            if b.y >= ba.y - b.side and self.timee > 5:
                while True:
                    self.write(200, "GAME OVER", (255, 0, 0), 20, 50)
                    self.write(50, "Press enter to start a new game", (0, 255, 0), 100, 400)

                    pygame.event.get()
                    keys = pygame.key.get_pressed()
                    if keys[pygame.K_RETURN]:
                        main()

                    g.win.flip()

        def control_counter(self):
            if self.timee > 100:
                self.timee = 100





    class Block:
        def __init__(self):
            self.x = 600
            self.y = 0
            self.side = 30
            self.speed = 2
            self.is_jumping = False
            self.gravity = 0.005
            self.jump_force = 10 
            self.jump_strength = 0.05 

        def draw(self):
            pygame.draw.rect(g.d, (0, 99, 99), (self.x, self.y, self.side, self.side))

        def move(self):
            keys = pygame.key.get_pressed()
            if keys[pygame.K_RIGHT]:
                self.x += self.speed
            if keys[pygame.K_LEFT]:
                self.x -= self.speed

        def jump_logic(self):
            for event in events:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        if self.is_jumping == False:
                            b.jump_force = 10
                            self.is_jumping = True


        def fall(self):
            self.y += self.gravity
            self.gravity += acc_gravity
            if self.gravity >= terminal_vel:
                self.gravity = terminal_vel

        def jump(self):
            self.y -= self.jump_force
            self.jump_force -= self.jump_strength
            if self.jump_force <= 0:
                self.jump_force = 0

    class Base:
        def __init__(self):
            self.x = 0
            self.y = 550
            self.width = 1200
            self.height = 20

        def draw(self):
            if g.timee < 5:
                pygame.draw.rect(g.d, (0, 255, 0), (self.x, self.y, self.width, self.height))
            else:
                pygame.draw.rect(g.d, (255, 0, 0), (self.x, self.y, self.width, self.height))

        def on_base(self):
            if b.y >= self.y - b.side:
                b.y = self.y - b.side
                b.is_jumping = False

    class Platforms:
        def __init__(self):
            self.x = random.randint(1, 1100)
            self.y = random.randint(-300, 0)
            self.width = 100
            self.height = 20
            self.speed = random.randint(1, 4)

        def draw(self):
            pygame.draw.rect(g.d, (0, 0, 0), (self.x, self.y, self.width, self.height))

        def move(self):
            self.y += self.speed


    ba = Base()
    b = Block()
    g = Game()

    for  i in range(10):
        g.platlist.append(Platforms())


    game_loop = True
    while game_loop:

        g.timee += 0.01
        events = pygame.event.get()

        g.d.fill((98, 98, 98))

        b.draw()
        b.move()
        b.jump_logic()
        b.fall()

        if b.is_jumping:
            b.jump()

        ba.draw()
        ba.on_base()

        g.game_over()

        for plats in g.platlist:
            plats.draw()
            plats.move()

        g.win.flip()

        pygame.time.Clock().tick(60)

main()

Solution

  • I figured it out. Its because my pygame.time.Clock().tick(60) was in the game loop. Not sure why this was causing lag but for anyone who might be having the same issue, dont put it in the main loop.