I'm trying to make a simple snake game using images with python and pygame. Now I know that some other people had problem too in other languages but still I can't figure it out. So I create a head list and one body list too include easily collisions too, also i create a position list. Every 2 elements of the position list are the x and y attributes, [0][1]
head, [2][3]
first body(I create these 2 when the game starts). The problem is that the head is moving but the first body doesn't, the same happens after the head collide with an apple, creating a new body on the middle of the screen that immediately suppose to reposition according to the position list. But it just stays there on middle, I checked using some print statements just to be sure about the rect.x
and rect.y
values of head and position list [0][1]
and the list updates perfectly, but not the body when i give the new values. Any ideas because its the last part that needs to be done and I'm really stressed the last days about this.
Thanks in advance and here is some part of the code(some of it needs to be deleted or used as test, it will be done later).
Lists:
snake_positions_list = []
#snake = Snake(display_width, display_height,screen.WHITE)
snake_head_list = pygame.sprite.Group()
snake_head = snake_Head(display_width, display_height, screen.WHITE)
snake_head_list.add(snake_head)
all_sprites_list.add(snake_head)
snake_body_list = pygame.sprite.Group()
snake_body = snake_Body(display_width, display_height, screen.WHITE)
snake_body_list.add(snake_body)
all_sprites_list.add(snake_body)
Init head and body:
if init_list == 1:
for snake_head in snake_head_list:
snake_head.set_Init_Position()
snake_positions_list.append(snake_head.rect.x)
snake_positions_list.append(snake_head.rect.y)
for snake_body in snake_body_list:
snake_body.speedx = 30
snake_body.speedy = 0
snake_body.set_Init_Position()
snake_positions_list.append(snake_body.rect.x)
snake_positions_list.append(snake_body.rect.y)
init_list = 0
Body and head move - position part(It supposed to work for more than one body after new body spawn and increase on position list but it doesn't even work for the first :
i = 0
for snake_body in snake_body_list:
#snake_body.Reposition(snake_positions_list[i], snake_positions_list[i + 1])
snake_body.rect.x = snake_positions_list[i]
snake_body.rect.y = snake_positions_list[i + 1]
snake_body.set_Image()
print("Snake Body rect x : " +str(snake_body.rect.x))
print("Snake Body x : "+str(snake_body.x))
#snake_body.move()
i += 1
print("Head x position: "+str(snake_positions_list[0]))
print("Head y position: "+str(snake_positions_list[1]))
for snake_head in snake_head_list:
if snake_head.alive == 1:
snake_head.move()
print("SNake rect x : "+ str(snake_head.rect.x))
print("Snake x : "+ str(snake_head.x))
i = 0
Snake- fruit collision and new body spawn:
add_score = 0
add_score = fruit_collision(snake_head_list, objective_list, all_sprites_list)
game_score = game_score + add_score
if add_score == 1:
snake_body = snake_Body(display_width, display_height, screen.WHITE)
new_bodyx = snake_length * 2 - 2
new_bodyy = snake_length * 2 - 1
snake_positions_list .append(snake_positions_list[new_bodyx - 2])
snake_positions_list.append(snake_positions_list[new_bodyy - 1])
snake_body.rect.x = snake_positions_list[new_bodyx]
snake_body.rect.y = snake_positions_list[new_bodyy]
snake_body_list.add(snake_body)
all_sprites_list.add(snake_body)
snake_length += 1
add_score = 0
Collision method:
def fruit_collision(snake_head_List, objective_list, all_sprites_list):
k = 0
for snake_head in snake_head_List:
objective_snake_collide_list = pygame.sprite.spritecollide(snake_head, objective_list, False)
if objective_snake_collide_list:
print("Body list length before fruit: " + str(len(snake_head_List)))
for fruit in objective_list:
fruit.respawn()
k = fruit.points
return k
Updating head position on position list [0][1]
almost at the end of game while loop to be sure:
snake_positions_list[0] = snake_head.rect.x
snake_positions_list[1] = snake_head.rect.y
Body class:
class snake_Body(pygame.sprite.Sprite):
def __init__(self, display_width, display_height, colour):
super().__init__()
self.width = 30
self.height = 30
self.original_length = 3
self.display_width = display_width
self.display_height = display_height
self.colour = colour
self.rotation = 1
self.x = (self.display_width / 2) - self.width
self.y = (self.display_height / 2)
self.image = pygame.image.load(path + 'Snake_Body_30x30.png').convert()
self.rect = self.image.get_rect(topleft = (self.x, self.y))
self.image.set_colorkey(self.colour)
self.body_type = 2
self.set_Init_Position()
self.set_Image()
def set_Direction(self, x, y, r):
self.speedx = x
self.speedy = y
self.rotation = r
#Check window boundaries
if (-self.width > self.rect.x) or (self.rect.x > self.display_width +5) or (self.rect.y < -self.height) or (self.rect.y > self.display_height +5):
self.alive = 0
def Reposition(self, listx, listy):
self.rect.x = listx
self.rect.y = listy
def set_Rotation(self, r):
self.rotation = r
def set_Init_Position(self):
self.x = (self.display_width / 2) - self.width
self.y = (self.display_height / 2)
self.image = pygame.image.load(path + 'Snake_Body_30x30.png').convert()
self.rect = self.image.get_rect(topleft = (self.x, self.y))
self.image.set_colorkey(self.colour)
def set_Image(self):
self.image = pygame.image.load(path + 'Snake_Body_30x30.png').convert()
self.rect = self.image.get_rect(topleft = (self.x, self.y))
self.image.set_colorkey(self.colour)
Head class:
class snake_Head(pygame.sprite.Sprite):
def __init__(self, display_width, display_height, colour):
super().__init__()
self.speedx = 30
self.speedy = 0
self.width = 30
self.height = 30
self.original_length = 3
self.display_width = display_width
self.display_height = display_height
self.colour = colour
self.rotation = 1
self.alive = 1
self.points = 0
self.swap = 1
self.swapTimer = 0.0
self.x = (self.display_width / 2)
self.y = (self.display_height / 2)
self.image = pygame.image.load(path + 'Snake_Head_New_Right_30x30.png').convert()
self.rect = self.image.get_rect(topleft = (self.x, self.y))
self.image.set_colorkey(self.colour)
self.body_type = 1
self.set_Init_Position()
self.set_Image()
def set_body_type(self, t):
self.body_type = t
def set_Direction(self, x, y, r):
self.speedx = x
self.speedy = y
self.rotation = r
def move(self):
if self.speedx > 0 or self.speedx < 0:
self.rect.x += self.speedx
self.x = self.rect.x
else:
self.rect.y += self.speedy
self.y = self.rect.y
#Check window boundaries
if (-self.width > self.rect.x) or (self.rect.x > self.display_width +5) or (self.rect.y < -self.height) or (self.rect.y > self.display_height +5):
self.alive = 0
def Reposition(self, listx, listy):
self.rect.x = listx
self.rect.y = listy
def set_Rotation(self, r):
self.rotation = r
def set_Init_Position(self):
self.x = (self.display_width / 2)
self.y = (self.display_height / 2)
self.image = pygame.image.load(path + 'Snake_Head_New_Right_30x30.png').convert()
self.rect = self.image.get_rect(topleft = (self.x, self.y))
self.image.set_colorkey(self.colour)
def set_Image(self):
if self.rotation == 1:
self.image = pygame.image.load(path + 'Snake_Head_New_Right_30x30.png').convert()
self.rect = self.image.get_rect(topleft = (self.x, self.y))
self.image.set_colorkey(self.colour)
elif self.rotation == 2:
self.image = pygame.image.load(path + 'Snake_Head_New_Left_30x30.png').convert()
self.rect = self.image.get_rect(topleft = (self.x, self.y))
self.image.set_colorkey(self.colour)
elif self.rotation == 3:
self.image = pygame.image.load(path + 'Snake_Head_New_Up_30x30.png').convert()
self.rect = self.image.get_rect(topleft = (self.x, self.y))
self.image.set_colorkey(self.colour)
else:
self.image = pygame.image.load(path + 'Snake_Head_New_Down_30x30.png').convert()
self.rect = self.image.get_rect(topleft = (self.x, self.y))
self.image.set_colorkey(self.colour)
The classes don't need some functions, I reformed the project after i stacked on this issue, as I mentioned the cleaning will be done after the project will be ready.
Again thanks for your time!