1

I've been set a challenge to make a game using pygame ( I am making snake so it should be easy... but I've never used pygame) so using a more efficient language isn't an option.So my question is that I updating the snake grid is too slow and I'm not experienced enough in pygame to fix this, can anyone who is help.Also as a note if I only fill the grid it doesn't clear behind the Snake. Using python 3.8

import pygame
import time
import random

pygame.init()

display_width = 800
display_height = 600
display = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Snake")

pureblue = (0,0,255)
purered = (255,0,0)
puregreen = (0,255,0)
white = (255,255,255)
black = (1,1,1)
grey = (50,50,50)
darkgrey = (25,25,25)


clock = pygame.time.Clock()

snake_block = 10
snake_speed = 30

font_style = pygame.font.SysFont(None, 50)

def drawGrid():
    blockSize = 10 
    for x in range(display_width):
        for y in range(display_height):
            rect = pygame.Rect(x*blockSize, y*blockSize,blockSize, blockSize)
            pygame.draw.rect(display, darkgrey, rect, 1)

def message(msg, colour):
    text = font_style.render(msg, True, colour)
    display.blit(text, [display_width/2, display_height/2])

def SnakeGameLoop():
    game_over = False

    X = display_width/2
    Y = display_height/2

    X_change = 0
    Y_change = 0

    while not game_over:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_over = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    X_change = -10
                    Y_change = 0
                elif event.key == pygame.K_RIGHT:
                    X_change = 10
                    Y_change = 0
                elif event.key == pygame.K_UP:
                    X_change = 0
                    Y_change = -10
                elif event.key == pygame.K_DOWN:
                    X_change = 0
                    Y_change = 10

        if X >= display_width or X < 0 or Y >= display_height or Y < 0:
            game_over = True

        X += X_change
        Y += Y_change
        display.fill(grey)
        drawGrid()
        pygame.draw.rect(display,puregreen,[X,Y,10,10])

        pygame.display.update()
        clock.tick(15)

    message("You lost", purered)
    pygame.display.update()
    time.sleep(2)

    pygame.quit()
    quit()

SnakeGameLoop()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Are you sure it's `drawGrid` that is making your game low? the frames per seconds are limited by `clock.tick(15)` (15 frames per second) – Rabbid76 Dec 20 '20 at 20:49
  • I tried upping that and all it did was make it load slow then speed the snake into the wall. –  Dec 20 '20 at 23:59

1 Answers1

1

To improve the game's performance, draw the grid on a pygame.Surface object with the size of the screen, before the application loop:

def drawGrid(surf):
    surf.fill(grey)
    blockSize = 10 
    for x in range(display_width):
        for y in range(display_height):
            rect = pygame.Rect(x*blockSize, y*blockSize,blockSize, blockSize)
            pygame.draw.rect(surf, darkgrey, rect, 1)

grid_surf = pygame.Surface(display.get_size())
drawGrid(grid_surf)

blit the surface once per frame on the display instead of drawing the grid once per frame, in the application loop:

def SnakeGameLoop():
    # [...]

    while not game_over:
        # [...]

        display.blit(grid_surf, (0, 0))
        
        pygame.draw.rect(display,puregreen,[X,Y,10,10])

        pygame.display.update()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thank you so much this helps a lot, I feel realllly stupid asking this but I cant change the colour of actual blocks in the grid it is just constantly black, how do I change this I optimally want inbetween the grids at a RGB value of (50,50,50) and the grid lines to be (75,75,75) –  Dec 20 '20 at 23:51
  • Also as a side note I've been messing around with this is there anyway place the snake on the grid when the block isnt 10. (I have changed it so the grid blocks are always the same SIZE as the snake but it doesnt allign with it and I dont know how I would do that) –  Dec 21 '20 at 00:12
  • @D.CMorgan 1. I've changed the answer. Fill (`surf.fill(grey)`) the gird surface before drawing the grid. 2. This is a bug in your application. However it is a new question. – Rabbid76 Dec 21 '20 at 07:30