I made a quick version of the snake game, it unfinished with some bugs, but it's just an example to show different ways to shorten code and prevent it from becoming spaghetti code. Dictionaries are a big way to shorten code. Especially in the main loop, there are dictionaries that I used to shorten the amount of if statements that could have been there.
import random, pygame, sys, time #Start up pygame.init() screen = pygame.display.set_mode((500, 500)) #Constants fps = 60 clock = pygame.time.Clock() #ScreenDisplay def TextDisplay(screen, text, size, color, centerX, centerY): font = pygame.font.SysFont('arial', size) textSurface = font.render(text, True, color) TextRect = textSurface.get_rect() TextRect.center = ((centerX),(centerY)) screen.blit(textSurface, TextRect) #Snake Class class Body(): def __init__(self, rect, direction, first=False): self.rect = pygame.Rect(rect[0], rect[1], 20, 20) self.direction = direction self.first = first def draw(self): pygame.draw.rect(screen, [20, 20, 210], self.rect) def move(self, direction): directionDict = {'up' : [0, -20], 'down' : [0, 20], 'right' : [20, 0], 'left' : [-20, 0]} returnDirection = self.direction self.direction = direction additive = directionDict[direction] self.rect[0] += additive[0] self.rect[1] += additive[1] return returnDirection def StartScreen(): TextDisplay(screen, 'Snake Game', 50, [20, 210, 20], 250, 150) TextDisplay(screen, 'Press Enter/Return to start', 30, [20, 210, 20], 250, 300) pygame.display.update() while True: for event in pygame.event.get(): if event.type == pygame.QUIT: return False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_RETURN: return True def Main(): if StartScreen(): keyDict = {pygame.K_w : 'up', pygame.K_a : 'left', pygame.K_d : 'right', pygame.K_s : 'down', pygame.K_UP : 'up', pygame.K_LEFT : 'left', pygame.K_RIGHT : 'right', pygame.K_DOWN : 'down'} opposites = {'up' : 'down', 'left' : 'right', 'right' : 'left', 'down' : 'up'} firstDirectionAdditive = {'down' : [0, -40], 'up' : [0, 40], 'left' : [40, 0], 'right' : [-40, 0]} mainDirectionAdditive = {'down' : [0, -20], 'up' : [0, 20], 'left' : [20, 0], 'right' : [-20, 0]} BodyList = [] BodyList.append(Body([240, 0], 'down', True)) FoodRect = pygame.Rect(random.randint(10, 490), random.randint(250, 490), 10, 10) score = 0 direction = 'down' followingDirection = None debounceTime = time.time() - 1 playing = True while playing: keysPressed = pygame.key.get_pressed() for event in pygame.event.get(): if event.type == pygame.QUIT: return #Draw if time.time() - debounceTime >= 1: debounceTime = time.time() screen.fill([210, 20, 20]) TextDisplay(screen, f'Score: {score}', 30, [20, 210, 20], 250, 25) pygame.draw.rect(screen, [255, 255, 255], FoodRect) for body in BodyList: if body.first: followingDirection = body.move(direction) if body.rect[0] < 0 or body.rect[0] > 500 or body.rect[1] < 0 or body.rect[1] > 500: return if FoodRect.colliderect(body.rect): FoodRect[0] = random.randint(10, 490) FoodRect[1] = random.randint(75, 490) if len(BodyList) == 1: additive = firstDirectionAdditive[direction] else: additive = mainDirectionAdditive[direction] BodyList.append(Body([BodyList[len(BodyList) - 1].rect[0] + additive[0], BodyList[len(BodyList) - 1].rect[1] + additive[1]], BodyList[len(BodyList) - 1].direction)) score += 1 else: followingDirection = body.move(followingDirection) body.draw() #Check for movement for key in keyDict: if keysPressed[key]: if opposites[keyDict[key]] != direction: direction = keyDict[key] break #Tick and update clock.tick(fps) pygame.display.update() if __name__ == '__main__': Main() pygame.quit() sys.exit()