Game Snake in pygame: snake growth function [closed]

closed . This question needs details or to be clearer and is not currently accepting answers.

want to improve this question? Add details and make it clearer what problem is being solved by editing this post .

Closed 4 years ago .

improve this question

I'm writing Snake in pygame, but, I don't have a very clear idea of how to implement snake growth functionality. I made a list ("lista_cobra") containing the coordinates of the head (which has approximately 30x30 pixels), and I thought of making another list from this, containing the last positions of the head, excluded the last follow, and thus draw an image of the body of the snake ("corpito", also of 30x30 pixels), from it, at each accumulated point. This idea does not work very well when I put it into practice, because the way I'm thinking the body still can not make the characteristic movement of Snake. I the question is, how to make the body grow from the previous coordinates of the head, while maintaining the characteristic movement of the body ?

#-*- coding: latin1 -*-

import pygame, sys, os, random, math, time
from pygame.locals import *

pygame.init()

##### Cores ######
preto = (0, 0, 0)
vermelho = (255, 0, 0)
##################

##################

dimensao = [800, 600]
tela = pygame.display.set_mode(dimensao)

######### Objetos ###########

gramado = pygame.image.load(os.path.join("images", "fundocobrinha.jpg"))
paredes = pygame.image.load(os.path.join("images", "paredes.png"))
comp = pygame.image.load(os.path.join("images", "comidacobra.png"))
comp = pygame.transform.scale(comp, (18, 20))
cabeca = pygame.image.load(os.path.join("images", "cabecadacobra.png"))
corpito = pygame.image.load(os.path.join("images", "corpodacobra.png"))
corpo = pygame.transform.rotate(cabeca, 0)
caminhodafonte = os.path.join("fonte", "lunchds.ttf")
fonte = pygame.font.Font(caminhodafonte, 22)
fonte_fim = pygame.font.Font(caminhodafonte, 25)

#############################

###### Distancia #########

def distancia(x, y, x2, y2):
    distancia = math.sqrt(((x2 - x) ** 2) + ((y2 - y) ** 2))
    return distancia

##########################

########### cobra #############

pontos = 0
vidas = 3
raio_cobra = 12
raio_corpo = 12
x = [130]
y = [130]

def cobrinha(): 
    global x, y, corpo, direcao, x_modificado, y_modificado

    tela.blit(corpo, (x[0] - raio_cobra, y[0] - raio_cobra))

    if direcao == "direita":
        corpo = pygame.transform.rotate(cabeca, 0)
        x_modificado = 3
        y_modificado = 0
    elif direcao == "esquerda":
        corpo = pygame.transform.rotate(cabeca, 180)
        x_modificado = -3
        y_modificado = 0
    elif direcao == "cima":
        corpo = pygame.transform.rotate(cabeca, 90)
        y_modificado = -3
        x_modificado = 0
    elif direcao == "baixo":
        corpo = pygame.transform.rotate(cabeca, 270)
        y_modificado = 3
        x_modificado = 0

    x[0] += x_modificado
    y[0] += y_modificado

################################

###### Comida da Cobra #########

raio_cCobra = 4
nova_comida = True
x2 = 0
y2 = 0

def comida():
    global x2, y2, comp, nova_comida
    if nova_comida:
        x2 = random.randint(47, 747)
        y2 = random.randint(56, 548)
        nova_comida = False
    tela.blit(comp, (x2 - raio_cCobra, y2 - raio_cCobra))

################################

########## Informações de status #############

def status_de_jogo():
    global pontos, fonte
    p = fonte.render("Pontos: " + str(pontos), True, preto)
    tela.blit(p, (45,37))
    v = fonte.render("Vidas :" + str(vidas), True, preto)
    tela.blit(v, (45,61))

###############################

######## mensagen de tela ######

def mensagem_de_tela():
    mensagem_de_texto = fonte_fim.render("Fim de Jogo, pressione C para jogar ou Q para sair.", True, vermelho)
    tela.blit(mensagem_de_texto,[55,200])

################################

######################################## Loop principal ###################################################

def loop_jogo():
    global x, y, x2, x2, vidas, pontos, distancia, corpo, raio_cCobra, raio_cobra, counter, nova_comida, lista_cobra,lista_corpo, direcao

    direcao = "direita" 

    lista_cobra = []

    clock = pygame.time.Clock()

    sair_do_jogo = False
    fim_de_jogo = False

    while not sair_do_jogo:

        while fim_de_jogo == True:
            mensagem_de_tela()
            pygame.display.update()
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        sair_do_jogo = True
                        fim_de_jogo = False
                    if event.key == pygame.K_c:
                        loop_jogo()

        #### Capturando todos os eventos durante a execução ####
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    direcao = "direita"

                elif event.key == pygame.K_LEFT:
                    direcao = "esquerda"

                elif event.key == pygame.K_UP:
                    direcao = "cima"

                elif event.key == pygame.K_DOWN:
                    direcao = "baixo"

            if event.type == QUIT:
                sair_do_jogo = True

        ####### posição da cabeça da cobra ###########

        cabeca_cobra = []
        cabeca_cobra.append(x[0])
        cabeca_cobra.append(y[0])
        lista_cobra.append(cabeca_cobra)

        tela.blit(gramado, (0, 0))
        tela.blit(paredes, (0, 0))

        comida()
        cobrinha()
        status_de_jogo()

        clock.tick(60)

        fps = clock.get_fps()

        pygame.display.set_caption("Shazam Caraí II ## FPS: %.2f" %fps)

        ########## Se bater nas paredes ##################
        if (x[0] >= 751 or x[0] <= 44) or (y[0] >= 553 or y[0] <= 42):

            vidas -= 1
            x = 400
            y = 300

        ##################################################

        if distancia(int(x[0]), int(y[0]), x2, y2) < (raio_cobra + raio_cCobra):

            nova_comida = True
            pontos += 1

        if vidas == 0:

            fim_de_jogo = True
            mensagem_de_tela()

        pygame.display.flip()
###########################################################################################################

loop_jogo()
Author: Junio Calú, 2016-09-25

1 answers

Without actually studying all your code - Snake's idea is that all the time you don't have to worry about the "middle" segments of the snake- (except to check for collision) - With each update of the game state you just need to worry about the last part of the snake, and the head.

Another thing - an lsita is a legal framework for storing data about the snake, and all youẽ need to do is:

1) in each game update - add a new position to the head in the direction of movement - if the snake is not growing (normal movement): - remove the last segment of the snake

Another thing - I noticed that in your code you keep a list of separate numbers for X and y coordinates-this will wind you up: quarde semrpe the coordinates together as a tuple of 2 elements (that's how Pygame consumes coordinates too). If you feel the need, you can even use a more sophisticated coordinate object with X and y attribute - but you'll want to do that when you learn the language better.

Then again, without a line-by-line analysis of your code - you just need a single "snake" list- (not a separate one for head, etc...)

cima = (0, -1)
baixo = (0, 1)
direita = (1, 0)
esquerda = (0, 1)

# POsicao inicial da cobra
cobra = [(10, 10)] 

aumentando_de_tamanho = 0
while not sair_do_jogo:
    ...
    # código para saber a direcao do moviemnto a partir do teclado
    ...
    # nova posicao da cabeça:
    x = cobra[0][0] + direcao[0]
    y = cobra[0][1]  + direcao[1]
    cobra = cobra.insert(0, (x, y))
    if not aumentando_de_tamanho:
        # remove ultimo segmento da cobra:
        cobra.pop()
    else:
         aumentando_de_tamanho += 1
    #verificar colisoes de morte:
    ...
    # verificar colisao com comida - 
    if cobra[0] == comida: # (vai  funcionar automaticamente se voce
                           # usar o esquema de coordenadas para a posição da comida taambém
         aumentando_de_tamanho += 5

    ...
 1
Author: jsbueno, 2016-09-26 14:55:08