Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Pygame lag
#1
So my Pygame game has a lag issue its a clicker game and I think the lag is caused by the auto miner and I have tried a few things to fix it but I couldn't fix it so if one of u could please point me in the right direction to fix it I would be happy.

# importing stuff

import pygame
import time

# initializing pygame

pygame.init()

# defining variables

autog = 0
coins = 0
display_width = 800
display_height = 600
white = (255, 255, 255)
black = (0, 0, 0)
grey = (128, 128, 128)
light_grey = (224, 224, 224)

# creating display and caption

gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("clicky clicks")

# defining functions

def autominer():
        global autog
        global coins
        time.sleep(1)
        coins = coins + autog


def DrawText(text, Textcolor, Rectcolor, x, y, fsize):
    font = pygame.font.Font('freesansbold.ttf', fsize)
    text = font.render(text, True, Textcolor, Rectcolor)
    textRect = text.get_rect()
    textRect.center = (x, y)
    gameDisplay.blit(text, textRect)


def rectangle(display, color, x, y, w, h):
    pygame.draw.rect(display, color, (x, y, w, h))


def main_loop():
    global autog
    tc = 0
    mong = 1
    cost = 50
    cost2 = 50
    global coins
    game_running = True
    while game_running:
        autominer()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_running = False

            if event.type == pygame.MOUSEBUTTONDOWN:
                mopos = pygame.mouse.get_pos()
                if mopos >= (350, 0):
                    if mopos <= (450, 0):
                        coins += mong

                if mopos <= (800, 0):
                    if mopos >= (600, 0):
                        if coins >= cost:
                            coins = coins - cost
                            cost = cost * 2
                            mong += 3

                if mopos >= (50, 0):
                    if mopos <= (245, 0):
                        if coins >= cost2:
                            coins = coins - cost2
                            cost2 = cost2 * 2
                            autog = autog + 1

        # drawing stuff

        gameDisplay.fill(white)
        DrawText("Clicky Clicks", black, white, 400, 100, 50)
        DrawText("you have " + str(coins) + " coins", black, white, 100, 50, 20)
        DrawText("upgrade 50*2", black, light_grey, 700, 300, 20)
        DrawText("buy auto miner 50*2", black, light_grey, 150, 370, 20)
        rectangle(gameDisplay, light_grey, 50, 400, 200, 300)
        rectangle(gameDisplay, black, 350, 250, 100, 100)
        rectangle(gameDisplay, light_grey, 600, 317, 200, 300)
        pygame.display.update()

# ending the program


main_loop()
pygame.quit()
quit()
~~ UwU
Reply
#2
Yep! time.sleep will cause game to be unresponsiveness. Use a timer for this. Custom events are limited to 32 events.
Don't forget to pygame.time.Clock to idle your program.
import os
import pygame
import random

class Screen:
    @staticmethod
    def center():
        os.environ['SDL_VIDEO_CENTERED'] = '1'

    def __init__(self, caption, width, height, flags=0):
        pygame.display.set_caption(caption)
        self.surface = pygame.display.set_mode((800, 600), flags)
        self.rect = self.surface.get_rect()
        self.clock = pygame.time.Clock()
        self.delta = 0
        self.fps = 60

    def idle(self):
        self.delta = self.clock.tick(self.fps)

def main():
    pygame.init()
    Screen.center()
    screen = Screen("Basic Screen", 600, 600)
    background = pygame.Color('navy')
    timer_id = pygame.USEREVENT + 1
    pygame.time.set_timer(timer_id, 1000)

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == timer_id:
                rnd = random.randint
                background = pygame.Color(rnd(0, 255), rnd(0, 255), rnd(0, 255))

        screen.surface.fill(background)
        pygame.display.flip()
        screen.idle()

if __name__ == '__main__':
    main()
99 percent of computer problems exists between chair and keyboard.
Reply
#3
(May-08-2020, 09:46 PM)Windspar Wrote: Yep! time.sleep will cause game to be unresponsiveness. Use a timer for this. Custom events are limited to 32 events.
Don't forget to pygame.time.Clock to idle your program.
import os
import pygame
import random

class Screen:
    @staticmethod
    def center():
        os.environ['SDL_VIDEO_CENTERED'] = '1'

    def __init__(self, caption, width, height, flags=0):
        pygame.display.set_caption(caption)
        self.surface = pygame.display.set_mode((800, 600), flags)
        self.rect = self.surface.get_rect()
        self.clock = pygame.time.Clock()
        self.delta = 0
        self.fps = 60

    def idle(self):
        self.delta = self.clock.tick(self.fps)

def main():
    pygame.init()
    Screen.center()
    screen = Screen("Basic Screen", 600, 600)
    background = pygame.Color('navy')
    timer_id = pygame.USEREVENT + 1
    pygame.time.set_timer(timer_id, 1000)

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == timer_id:
                rnd = random.randint
                background = pygame.Color(rnd(0, 255), rnd(0, 255), rnd(0, 255))

        screen.surface.fill(background)
        pygame.display.flip()
        screen.idle()

if __name__ == '__main__':
    main()
So I am having problems implementing this into my program because I still don't know object-oriented programming do you know any other ways Edit: for now I found a way around it by just shortening the time that the auto miner makes money
~~ UwU
Reply
#4
TIMER_ID = pygame.USEREVENT + 1
pygame.time.set_timer(TIMER_ID, 1000)
# Then in event loop
    elif event.type == TIMER_ID:
        autominer()
Object oriented program is not much difference. Then what you are doing now. Except class object is store in a namespace. Classes help organize code and reduces globals variables. Classes are a container.
Example. Showing code in non object. Move timer_id.
import os
import pygame
import random

TIMER_ID = pygame.USEREVENT + 1

def center_screen():
    os.environ['SDL_VIDEO_CENTERED'] = '1'

def screen_setup(caption, width, height, flags=0):
    global surface, rect, clock, delta, fps
    pygame.display.set_caption(caption)
    surface = pygame.display.set_mode((800, 600), flags)
    rect = surface.get_rect()
    clock = pygame.time.Clock()
    delta = 0
    fps = 60

def idle():
    global delta
    delta = clock.tick(fps)

def main():
    pygame.init()
    center_screen()
    screen_setup("Basic Screen", 600, 600)
    background = pygame.Color('navy')
    pygame.time.set_timer(TIMER_ID, 1000)

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == TIMER_ID:
                rnd = random.randint
                background = pygame.Color(rnd(0, 255), rnd(0, 255), rnd(0, 255))

        surface.fill(background)
        pygame.display.flip()
        idle()

if __name__ == '__main__':
    main()
99 percent of computer problems exists between chair and keyboard.
Reply
#5
(May-09-2020, 04:00 AM)Windspar Wrote:
TIMER_ID = pygame.USEREVENT + 1
pygame.time.set_timer(TIMER_ID, 1000)
# Then in event loop
    elif event.type == TIMER_ID:
        autominer()
Object oriented program is not much difference. Then what you are doing now. Except class object is store in a namespace. Classes help organize code and reduces globals variables. Classes are a container.
Example. Showing code in non object. Move timer_id.
import os
import pygame
import random

TIMER_ID = pygame.USEREVENT + 1

def center_screen():
    os.environ['SDL_VIDEO_CENTERED'] = '1'

def screen_setup(caption, width, height, flags=0):
    global surface, rect, clock, delta, fps
    pygame.display.set_caption(caption)
    surface = pygame.display.set_mode((800, 600), flags)
    rect = surface.get_rect()
    clock = pygame.time.Clock()
    delta = 0
    fps = 60

def idle():
    global delta
    delta = clock.tick(fps)

def main():
    pygame.init()
    center_screen()
    screen_setup("Basic Screen", 600, 600)
    background = pygame.Color('navy')
    pygame.time.set_timer(TIMER_ID, 1000)

    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == TIMER_ID:
                rnd = random.randint
                background = pygame.Color(rnd(0, 255), rnd(0, 255), rnd(0, 255))

        surface.fill(background)
        pygame.display.flip()
        idle()

if __name__ == '__main__':
    main()
so I messed around with the timer program that you had and I found that it would pause the auto miner whenever you clicked and when you stopped clicking it would continue again. I think that it could be where I placed so I am going to work on it a bit more
~~ UwU
Reply
#6
# importing stuff

import pygame
import time


# initializing pygame

pygame.init()

# defining variables

clock = pygame.time.Clock()
ver = "Beta 0.1.0.3"
autog = 0
coins = 0
display_width = 800
display_height = 600
white = (255, 255, 255)
black = (0, 0, 0)
grey = (128, 128, 128)
light_grey = (224, 224, 224)

# creating display and caption

gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("clicky clicks")

# defining functions

def autominer():
    global coins
    global autog
    coins = coins + autog


def DrawText(text, Textcolor, Rectcolor, x, y, fsize):
    font = pygame.font.Font('freesansbold.ttf', fsize)
    text = font.render(text, True, Textcolor, Rectcolor)
    textRect = text.get_rect()
    textRect.center = (x, y)
    gameDisplay.blit(text, textRect)


def rectangle(display, color, x, y, w, h):
    pygame.draw.rect(display, color, (x, y, w, h))


def main_loop():
    global clock
    global autog
    global ver
    mong = 1
    cost = 50
    cost2 = 50
    global coins
    game_running = True
    while game_running:
        for event in pygame.event.get():
            TIMER_ID = pygame.USEREVENT + 1
            pygame.time.set_timer(TIMER_ID, 1000)
            if event.type == TIMER_ID:
                autominer()

            if event.type == pygame.QUIT:
                game_running = False

            if event.type == pygame.MOUSEBUTTONDOWN:
                mopos = pygame.mouse.get_pos()
                if mopos >= (350, 0):
                    if mopos <= (450, 0):
                        coins += mong

                if mopos <= (800, 0):
                    if mopos >= (600, 0):
                        if coins >= cost:
                            coins = coins - cost
                            cost = cost * 1.5
                            mong += 1
                            cost = round(cost, 0)
                            print(f'{cost:.2f}')

                if mopos >= (50, 0):
                    if mopos <= (245, 0):
                        if coins >= cost2:
                            coins = coins - cost2
                            cost2 = cost2 * 1.5
                            autog = autog + 0.25
                            cost2 = round(cost2, 0)
                            print(f'{cost2:.2f}')


        # drawing stuff

        gameDisplay.fill(white)
        DrawText("Clicky Clicks", black, white, 400, 100, 50)
        DrawText("you have " + str(f'{coins:.2f}') + " coins", black, white, 100, 50, 20)
        DrawText("upgrade 50*1.2", black, white, 700, 300, 20)
        DrawText("buy auto miner 50*1.2", black, white, 150, 370, 20)
        DrawText("Version: " + ver, black, white, 650, 50, 20)
        rectangle(gameDisplay, light_grey, 50, 400, 200, 300)
        rectangle(gameDisplay, black, 350, 250, 100, 100)
        rectangle(gameDisplay, light_grey, 600, 317, 200, 300)
        pygame.display.update()
        clock.tick(30)

# ending the program

main_loop()
pygame.quit()
quit()
So I haven't yet been able to fix the problem where whenever I click it pauses the auto miner but when I stop licking it resumes I have tried moving the timer around to other spots but this spot is the only spot that won't bring out an error
~~ UwU
Reply
#7
This does not belong in event loop or main loop.
TIMER_ID = pygame.USEREVENT + 1
pygame.time.set_timer(TIMER_ID, 1000)
You want TIMER_ID as a constant. You want this before you define your variables.
When you want to start the timer. Then you use pygame.time.set_timer(TIMER_ID, 1000) to start your timer.
When you want to stop the timer. pygame.time.set_timer(TIMER_ID, 0) will stop the timer.
# define constant
TIMER_ID = pygame.USEREVENT + 1

# defining variables
99 percent of computer problems exists between chair and keyboard.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020