I've been working on a snake code for quite a while now. It is still rather primitive and very very basic. I have gotten the collisions to work, food generation and very basic movement. What I'm struggling on is figuring out the movement. Whenever you press WASD or the Arrow Keys it would move the head, and the "body" of the snake follows the part in front of it. So snakecol follows snakecol and so on.
Thank you in advance for any tips and pointers on how to improve my code.
#W to move up, A to move to the left, S to move down, D to move right.
#Snake by Juan Jaramillo
print "Snake is",point,"long."
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if(pygame.key.get_pressed()[pygame.K_a]) or (pygame.key.get_pressed()[pygame.K_LEFT]):
if(pygame.key.get_pressed()[pygame.K_d]) or (pygame.key.get_pressed()[pygame.K_RIGHT]):
if(pygame.key.get_pressed()[pygame.K_w]) or (pygame.key.get_pressed()[pygame.K_UP]):
if(pygame.key.get_pressed()[pygame.K_s]) or (pygame.key.get_pressed()[pygame.K_DOWN]):
#stop moving paddle
for m in range(0,len(snakecol)):
for m in range(0,len(snakecol)):
The body blocks don't need to know the direction. You can just append a new head block (with the next x, y coords) to the list and remove the last block.
You could also use a
collections.deque, pronounced "deck", a double ended queue which allows fast appends and pops on either end (although efficiency isn't really needed here, the code just looks a bit nicer).
A few more suggestions, you should check out how functions, classes and Pygame sprites work. There's a nice, free book about Python and Pygame called Program Arcade Games. Also, you shouldn't use global variables for everything, since they can make code really hard to understand (use classes).
Edit: To emphasize my answer above: Don't move the rects (the parts of the snake) in your list directly by changing their x and y values. Just pop or remove the last rect and append a new head rect. This will create the illusion of movement but the rects actually all stay at the same position.
I mentioned the deque, because it has efficient methods for popping and appending at the left end. For lists this is very inefficient, but I think it won't matter in your case, because the list won't grow too much and computers nowadays are very powerful.
Some code review (this should rather be in http://codereview.stackexchange.com/ though):
Line 132: You don't call
pop because you forgot the parentheses. But if you actually called it, the snakecol list would shrink and the game would crash.
Handle the event loop first, then the game logic (e.g. collisions) and then the drawing. In a game class you would use different methods for these parts of the program.
pygame.key.get_pressed() several times. Instead assign the keys list to a variable
keys = pygame.key.get_pressed() and use this variable later in the loop.
time.sleep is usually not used in Pygame (the game controls will seem to be unresponsive). There's the
pygame.time.Clock class which you can use to limit the framerate and you can use a timer variable to keep track of when the snake can move. Instantiate a clock before the main loop
clock = pygame.time.Clock() and in the loop you call
clock.tick(enter_max_fps_here) every frame.