Hi,

Each segment of your snake is a reference to the same pygame rect. So when you 
move one, they all appear to move. The line

Snake[tail] = Snake[tail-1]

Is not making new rect. If you print out the id of each segment, you should see 
that they are the same object. 

Use Rect.copy() to make the ones in the list be disconnected to the original. 
Or append a new Rect where the head has moved (you don’t really need to copy 
everything yourself, you can insert a new one at the front and remove it from 
the back).

Thanks,
David


> On Jun 24, 2019, at 11:28 AM, DR0ID <dr...@bluewin.ch> wrote:
> 
> On 24.06.2019 17:19, Adam Coombes wrote:
>> I've created a list of sprites to try and make a basic 'snake' game. The 
>> idea is to shuffle each sprite to the position of the next, starting at the 
>> end of the tail, and then move the head. As I append new tail pieces, they 
>> should 'snake' along. However, when I move the head sprite ( Snake[0] in my 
>> list 'Snake'), they all seem to move to the same position. Even when I omit 
>> the line that moves them along by commenting out 'Snake[tail] = 
>> Snake[tail-1]' in my for loop, it still moves every sprite in the list 
>> Snake[] to the same place as Snake[0], which is inexplicable to me as I'm 
>> not even moving them then. Can anyone point out my mistake please? This is 
>> just a learner project, but it's driving me nuts.
>> 
>> import pygame, sys
>> from pygame.locals import*
>> import random
>> #colours========================================================
>> BLACK = (0,0,0)
>> WHITE = (255,255,255)
>> RED = (255,0,0)
>> GREEN = (0,255,0)
>> BLUE = (0,0,255)
>> PURPLE = (128,0,128)
>> GREY = (128,128,128)
>> YELLOW = (255,255,0)
>> pygame.init()
>> Height = 1920
>> Width = 1080
>> score = 0
>> basicfont = pygame.font.SysFont(None, 50)
>> Score = basicfont.render("Score: " + str(score), True, WHITE, GREEN)
>> ScoreRect = Score.get_rect()
>> ScoreRect.left =560
>> ScoreRect.bottom = 130
>> moveLeft = False
>> moveRight = False
>> moveUp = False
>> moveDown = False
>> PlayerSpeed = 40
>> def GameBoard():
>>     pygame.display.set_caption("Snake_Game")
>>     Window.fill(GREEN)
>>     pygame.draw.line(Window, BLACK,(560,140),(1360,140),4)
>>     pygame.draw.line(Window, BLACK,(560,140),(560,940),4)
>>     pygame.draw.line(Window, BLACK,(1360,140),(1360,940),4)
>>     pygame.draw.line(Window, BLACK,(560,940),(1360,940),4)
>> #GAME===========================================================
>> mainClock = pygame.time.Clock()
>> Window = pygame.display.set_mode((Height,Width), 0, 32)
>> #PLayer=========================================================             
>>        
>> Snake =[]
>> Snake.append (pygame.Rect(940,500,40,40))
>> playerImage = pygame.image.load("Snake.GIF")
>> Window.blit(playerImage,Snake[0])
>> #Apple==========================================================
>> def PlotApple():
>>     global AppleX
>>     global AppleY
>>     global Apple
>>     AppleX = random.randint(560,1320)
>>     AppleY = random.randint(140,900)
>>     Apple = pygame.Rect(AppleX,AppleY,40,40)
>> PlotApple()
>> AppleImage = pygame.image.load("Apple.GIF") 
>> Window.blit(AppleImage,Apple)
>> pygame.display.update()
>> #================================================================
>> while True:
>>     for event in pygame.event.get():
>>         if event.type == KEYDOWN:
>>             if event.key == K_ESCAPE:
>>                 pygame.quit()
>>         #===================================================
>>         if event.type == KEYDOWN:
>>             #===============================================
>>             if event.key == K_LEFT:
>>                 moveRight = False
>>                 moveLeft = True
>>                 moveDown = False
>>                 moveUp = False
>>             #===============================================
>>             if event.key == K_RIGHT:
>>                 moveLeft = False
>>                 moveRight = True
>>                 moveDown = False
>>                 moveUp = False
>>             #===============================================
>>             if event.key == K_UP:
>>                 moveDown = False
>>                 moveUp = True
>>                 moveLeft = False
>>                 moveRight = False
>>             #===============================================
>>             if event.key ==K_DOWN:
>>                 moveUp = False
>>                 moveDown = True
>>                 moveLeft = False
>>                 moveRight = False
>>             #KEYUP===============================================
>>             if event.type == KEYUP:
>>             #===================================================
>>                 if event.key == K_ESCAPE:
>>                     pygame.quit()
>>                     sys.exit()
>>     #MovePlayer===================================================
>>     mainClock.tick(10)
>>     GameBoard()
>>     for tail in range (len(Snake)-1,0,-1):
>>         print(Snake,tail)
>>         Snake[tail] = Snake[tail-1]
>>         Window.blit(playerImage,Snake[tail])
>>         print(Snake,tail)
>>     if moveDown:
>>         Snake[0].top += PlayerSpeed
>>     if moveUp:
>>         Snake[0].top -= PlayerSpeed
>>     if moveLeft:
>>         Snake[0].left -= PlayerSpeed
>>     if moveRight:
>>         Snake[0].right += PlayerSpeed
>>     if Snake[0].bottom >=940 or Snake[0].top<+140 or Snake[0].left<=560 or 
>> Snake[0].right>=1360:
>>         pygame.quit()
>>     Score = basicfont.render("Score:" + str(score), True, WHITE, GREEN)
>>     Window.blit(playerImage,Snake[0])
>>     Window.blit(AppleImage,Apple)
>>     Window.blit(Score,ScoreRect)
>>     if Snake[0].colliderect(Apple):
>>         score = score +50
>>         Snake.append (Snake[0])
>>         PlotApple()
>>     pygame.display.update()
> 
> Hi
> 
> flying over your code (without executing it) I think these loop is setup 
> wrongly:
> 
> 
> 
>     for tail in range (len(Snake)-1,0,-1):
>         print(Snake,tail)
>         Snake[tail] = Snake[tail-1]
> 
> Because the for loop will generate 'tail' sequence as: 9, 8, 7, 6, 5, 4, 3, 
> 2, 1
> But then you do: Snake[tail] = Snake[tail-1]   which is using concrete 
> indices: Snake[9] = Snake[9-1] 
> ...
> 
> So this means that if you had a Snake like this ['a', 'b', 'c', 'd'] this 
> loop will transform it to:
> ['a', 'a', 'b', 'c'] 
> and so on until its all 'a': ['a', 'a', 'a', 'a']
> which is what you see (all seem to be at index 0 because only this sprite 
> exists in the list).
> 
> ...
> 
> I wondered and run the code. It seems there are some other issues.
> 
> 1. I would suggest to draw all elements of the snake not only the head (so 
> you see where they are actually placed and the snake should be growing with 
> each apple eaten).
> 2. I would think about object references. If a rect1 is put into a list at 
> index 0 and then Snake[1] = Snake[0] is executed the same object is now at 
> index 0 and 1. This means that if Snake[0].x is changed its also changed for 
> Snake[1] (because both are actually the same object). So adding a tail part 
> or moving the last to the front should be carefully done. I would think about 
> moving the last part to the front (don't forget to update the coordinates 
> accordingly because next lines in the code move the head relative to the old 
> position).
> 
> I hope I gave you some pointers where to look.
> 
> ~DR0ID
> 
> 
> 
> 
> 

Reply via email to