Game Snake in pygame: Snake growth function

Asked

Viewed 1,154 times

0

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

#-*- 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()
  • 1

    Hello. Your question is not clear. You explain that "you don’t have much idea", but it presents a code you made. What exactly is the difficulty in this code? Why that idea does not work? Provide more details to avoid receiving negative or closing votes as unclear. If you haven’t done it yet, do the [tour] and mainly read [Ask].

1 answer

1


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 game status update you only need 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 have to do is:

1) on each game update - add a new head position 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: quarde semrpe the coordinates together as a tuple of 2 elements (it’s how Pygame consumes coordinates as well). If you feel the need, you can even use a more sophisticated coordinate object with attribute x and y - but you’ll want to do this when you learn the language better.

So 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

    ...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.