Game Snake in pygame: Snake growth function [closed]

0

I'm writing Snake in pygame, but I do not have a very clear idea of how to implement the snake's growth functionality. I made a list ("list_cobra") containing the coordinates of the head (which is approximately 30x30 pixels), and I thought of making another list from it, containing the last head positions, excluding the last follow, and thus drawing an image of the body of the snake ("corpito", also of 30x30 pixels), from her, to 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 movement characteristic of Snake. My question is, how do the body grow from the anterior coordinates of the head, 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()
    
asked by anonymous 25.09.2016 / 17:34

1 answer

1

Without really studying all your code - Snake's idea is that all the time you do not have to worry about the snake's "middle" segments - (except to check for a collision) - With every upgrade of the game state you only have to worry about the last part of the snake, and the head.

Another thing - a 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 for 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 wrap you up: semrpe the coordinates together as a 2-element tuple (that's how Pygame consumes coordinates as well). If you feel a need, you can even use a more sophisticated coordinate object with x and y attributes - but you will want to do this when you learn the language better.

So again, without a line-by-line analysis of your code - you only 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

    ...
    
26.09.2016 / 16:55