Reputation: 350
I recently started making Snake in pygame. Firstly, I was writing the code without OOP. When I noticed that it would look better with classes, I edited the code. Now the first three times, the snake moves normally, but after that when I push the left arrow or the right arrow or the downwards arrow, snake goes down. When I didn't have classes, the program worked the way it should. Now it doesn't. Can you help me?
This is my code:
import pygame, math, random
pygame.init()
screen = pygame.display.set_mode((640,640))
pygame.display.set_caption('Snake')
class Snake(object):
def __init__(self):
self.x, self.y = 320,320
self.dirUp, self.dirDown = False, False
self.dirLeft, self.dirRight = False, False
self.body = [(self.x, self.y)]
self.snakeImg = [pygame.image.load('snakeblock.png') for i in range(len(self.body))]
snake = Snake()
squares = []
for i in range(640):
if i % 32 == 0:
squares.append(i)
food = pygame.image.load('fruit.png')
foodx,foody = random.choice(squares), random.choice(squares)
def isCollision(obsX, obsY, x, y):
# D I S T A N C E
return math.sqrt(math.pow(obsX - x, 2) + math.pow(obsY - y, 2)) <= 0
over_font = pygame.font.Font('freesansbold.ttf',64)
score_font = pygame.font.Font('freesansbold.ttf',32)
score = 0
def show_text():
score_text = score_font.render('Score: {}'.format(score), True, (255,255,255))
over_text = over_font.render('GAME OVER', True, (255,255,255))
screen.blit(score_text, (0,0))
running = True
while running:
pygame.time.delay(160)
screen.fill((0,128,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
snake.dirUp = True
snake.dirLeft, dirDown, dirRight = False, False, False
if event.key == pygame.K_DOWN:
snake.dirDown = True
snake.dirUp, dirLeft, dirRight = False, False, False
if event.key == pygame.K_RIGHT:
snake.dirRight = True
snake.dirUp, dirDown, dirLeft = False, False, False
if event.key == pygame.K_LEFT:
snake.dirLeft = True
snake.dirUp, dirDown, dirRight = False, False, False
if snake.dirUp:
snake.y -= 32
elif snake.dirDown:
snake.y += 32
elif snake.dirRight:
snake.x += 32
elif snake.dirLeft:
snake.x -= 32
for i in range(len(snake.body)):
if isCollision(foodx,foody,snake.body[i][0],snake.body[i][1]):
foodx, foody = random.choice(squares), random.choice(squares)
score += 1
screen.blit(food, (foodx, foody))
screen.blit(snake.snakeImg[i], (snake.x, snake.y))
show_text()
pygame.display.update()
Upvotes: 1
Views: 71
Reputation: 91
the problem is here
snake.dirLeft, dirDown, dirRight = False, False, False
which should have been
snake.dirLeft, snake.dirDown, snake.dirRight = False, False, False
in python it is not recommended to use multiple assigments unless you unpacking values from tuple/list. As you can see this would be much more readable :)
snake.dirLeft = False
snake.dirDown = False
snake.dirRight = False
and there is another problem because snake get his body coords static in a moment Snake instance created, here is possible solution
class Snake(object):
def __init__(self):
self.x, self.y = 320, 320
self.dirUp, self.dirDown = False, False
self.dirLeft, self.dirRight = False, False
self.snakeImg = [pygame.image.load('snakeblock.png')
for i in range(len(self.body))]
@property
def body(self):
return [(self.x, self.y)]
hovewer you still have to think out a way to increase it's body
Upvotes: 3