2

I am remaking snake game. And have a moving function and don't know where to call it. The snake is the green rect

the function is just before the while loop. it is to make other segments of the snake move into the pos of the last segment.

here is the code so far:

import pygame, sys, random
from pygame.locals import *
pygame.init()
movement_x = movement_y = 0
RED = (240, 0, 0)
GREEN = (0, 255, 0)
ran = [0,25,50,75,100,125,150,175,200,225,250,275,300,325,350,375,400,425,450,475]
ax = 0
ay = 0
x = 0
y = 0
sa = 0
sizex = 500
sizey = 500
tilesize = 25
screen = pygame.display.set_mode((sizex,sizey))
pygame.display.set_caption('Snake')
pygame.display.set_icon(pygame.image.load('images/tile.png'))
tile = pygame.image.load('images/tile.png')
tile = pygame.transform.scale(tile, (tilesize, tilesize))
x2 = 0
pag = 0
clock = pygame.time.Clock()
sx = 0
sy = 0
vel_x = 0
vel_y = 0
ap = True

snake_parts = []   # /N/ Pygame rects 

def slither( new_head_coord ):
    # Move each body part to the location of the previous part
    # So we iterate over the tail-parts in reverse
    for i in range( len( snake_parts )-1, 0, -1 ):
        x, y = snake_parts[i-1].centerx, snake_parts[i-1].centery
        snake_parts[i].center = ( x, y )
    # Move the head
    snake_parts[0].centre = new_head_coord

while True:
    sx = x
    sy = y
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    for row in range(sizex):
        for column in range(sizey):
            screen.blit(tile,(column*tilesize, row*tilesize,tilesize,tilesize))
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_UP:
                vel_y = -25
                vel_x = 0
            elif event.key == K_DOWN:
                vel_y = 25
                vel_x = 0
            elif event.key == K_LEFT:
                vel_x = - 25
                vel_y = 0
            elif event.key == K_RIGHT:
                vel_x= 25
                vel_y = 0
            elif event.key == K_y:
                pag = 1
            elif event.key == K_n:
                pag = 2


    inBounds = pygame.Rect(0, 0, sizex, sizey).collidepoint(x+vel_x, y+vel_y)
    if inBounds:
        y += vel_y
        x += vel_x
    else:
        basicFont = pygame.font.SysFont(None, 48)
        text = basicFont.render('Game Over! Play again? y/n', True, GREEN, RED)
        textRect = text.get_rect()
        textRect.centerx = screen.get_rect().centerx
        textRect.centery = screen.get_rect().centery
        pygame.draw.rect(screen, RED, (textRect.left - 20, textRect.top - 20, textRect.width + 40, textRect.height + 40))
        screen.blit(text, textRect)
        ay = -25
        ax = -25
        x = -25
        y = -25
        if pag == 1:
            pag = 0
            inBounds = True
            x = 0
            y = 0
            vel_x = 0
            vel_y = 0
            ax = random.choice(ran)
            ay = random.choice(ran)
            pygame.draw.rect(screen, RED, pygame.Rect(ax,ay,tilesize,tilesize))
        if pag == 2:
            pygame.quit()
            sys.exit()

    if ap:
        pygame.draw.rect(screen, RED, pygame.Rect(ax,ay,tilesize,tilesize))
    if x == ax and y == ay:
        pygame.draw.rect(screen, RED, pygame.Rect(ax,ay,tilesize,tilesize))
        ax = random.choice(ran)
        ay = random.choice(ran)
        sa += 1
    pygame.draw.rect(screen, GREEN, pygame.Rect(x,y,tilesize,tilesize))
    pygame.display.update()
    clock.tick(100)

I am not quite sure on how to use functions yet as I have only been learning python for a few weeks.

Glitchd
  • 361
  • 2
  • 12
  • after you calculate the value for `new_head_coord` is when you **can** call it , and since you have some collision detection you want it to happen **after** moving, so seems like there's a place for that function in your code. also unrelated to the question here's something i was told when i made snake when i was new to programming : "you don't have to move all the pieces just move the last one to the front" – AntiMatterDynamite Feb 27 '19 at 08:10
  • With Snake, you're not supposed to move each segment into the square in front of it; you're supposed to just move the tail segment to the square in front of the head. – TigerhawkT3 Feb 27 '19 at 08:18

1 Answers1

2

Add a new function which draws the snake:

def drawSnake():
    for p in snake_parts: 
        screen.blit(shake, p.topleft)

Of course you can draw an image, instead of the recatangl. snake is an image of type pygame.Surface:

def drawSnake():
    for p in snake_parts: 
        pygame.draw.rect(screen, RED, p)

Add the head to the list snake_parts before the main loop (before while True:):

snake_parts.append(pygame.Rect(x,y,tilesize,tilesize))
ax, ay = random.choice(ran), random.choice(ran)

Use drawSnake to draw the snake and update the positions of the parts right before:

slither( (x, y) )
if ap:
    pygame.draw.rect(screen, RED, pygame.Rect(ax,ay,tilesize,tilesize))
if x == ax and y == ay:
    pygame.draw.rect(screen, RED, pygame.Rect(ax,ay,tilesize,tilesize))
    ax, ay = random.choice(ran), random.choice(ran)
    sa += 1
    snake_parts.append(pygame.Rect(x, y, tilesize, tilesize))

drawSnake()
pygame.display.update()

There is a typo in slither. It has to be snake_parts[0].center rather than snake_parts[0].centre. But anyway, in your case the origin of the pars of the snake is topleft, rather than center. Change the function slither:

def slither( new_head_coord ):
    for i in range( len(snake_parts)-1, 0, -1 ):
        snake_parts[i] = snake_parts[i-1].copy()
    snake_parts[0].topleft = new_head_coord

Do only 1 event loop in the main loop:

e.g.

run = True
while run:
    sx, sy = x, y
    for row in range(sizex):
        for column in range(sizey):
            screen.blit(tile,(column*tilesize, row*tilesize,tilesize,tilesize))
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            run = False 
        if event.type == KEYDOWN:
            if event.key == K_UP:
                vel_y = -25
                vel_x = 0
            # [...]

Demo

import pygame, sys, random
from pygame.locals import *

pygame.init()
movement_x = movement_y = 0
RED = (240, 0, 0)
GREEN = (0, 255, 0)
ran = [0,25,50,75,100,125,150,175,200,225,250,275,300,325,350,375,400,425,450,475]
sizex, sizey = 500, 500
tilesize = 25
screen = pygame.display.set_mode((sizex,sizey))
pygame.display.set_caption('Snake')
tile = pygame.Surface((tilesize, tilesize))
tile.fill((0, 0, 64))
tile = pygame.transform.scale(tile, (tilesize, tilesize))
x2 = 0
pag = 0
clock = pygame.time.Clock()
sx, sy = 0, 0
vel_x, vel_y = 0, 0
x, y = 0, 0
sa = 0
ap = True

snake_parts = []   # /N/ Pygame rects 

def slither( new_head_coord ):
    for i in range( len(snake_parts)-1, 0, -1 ):
        snake_parts[i] = snake_parts[i-1].copy()
    snake_parts[0].topleft = new_head_coord

def drawSnake():
    for p in snake_parts: 
        pygame.draw.rect(screen, GREEN, p)

snake_parts.append(pygame.Rect(x,y,tilesize,tilesize))
ax, ay = random.choice(ran), random.choice(ran)
run = True
while run:
    sx, sy = x, y
    for row in range(sizex):
        for column in range(sizey):
            screen.blit(tile,(column*tilesize, row*tilesize,tilesize,tilesize))
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            run = False 
        if event.type == KEYDOWN:
            if event.key == K_UP:
                vel_x, vel_y = 0, -25
            elif event.key == K_DOWN:
                vel_x, vel_y = 0, 25
            elif event.key == K_LEFT:
                vel_x, vel_y = -25, 0
            elif event.key == K_RIGHT:
                vel_x, vel_y = 25, 0
            elif event.key == K_y:
                pag = 1
            elif event.key == K_n:
                pag = 2

    inBounds = pygame.Rect(0, 0, sizex, sizey).collidepoint(x+vel_x, y+vel_y)
    if inBounds:
        y += vel_y
        x += vel_x
    else:
        basicFont = pygame.font.SysFont(None, 48)
        text = basicFont.render('Game Over! Play again? y/n', True, GREEN, RED)
        textRect = text.get_rect()
        textRect.centerx = screen.get_rect().centerx
        textRect.centery = screen.get_rect().centery
        pygame.draw.rect(screen, RED, (textRect.left - 20, textRect.top - 20, textRect.width + 40, textRect.height + 40))
        screen.blit(text, textRect)
        ax, ay = -25, -25
        x, y = -25, -25
        if pag == 1:
            pag = 0
            inBounds = True
            x, y = 0, 0
            vel_x, vel_y = 0, 0
            ax, ay = random.choice(ran), random.choice(ran)
            pygame.draw.rect(screen, RED, pygame.Rect(ax,ay,tilesize,tilesize))
        if pag == 2:
            pygame.quit()
            sys.exit()

    slither( (x, y) )
    if ap:
        pygame.draw.rect(screen, RED, pygame.Rect(ax,ay,tilesize,tilesize))
    if x == ax and y == ay:
        pygame.draw.rect(screen, RED, pygame.Rect(ax,ay,tilesize,tilesize))
        ax, ay = random.choice(ran), random.choice(ran)
        sa += 1
        snake_parts.append(pygame.Rect(x, y, tilesize, tilesize))
    drawSnake()
    pygame.display.update()
    clock.tick(100)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174