Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help to fix PYTHON CODES
#1
I'm a beginner and I'm coding "Snake game". This is what I copied paste from the Internet and self-coded. This system did run but the scores didn't count and I have no idea why is it. I hope someone will show me the mistakes and help to fix this





import time,random,sys,pygame
pygame.init()

gameSurface = pygame.display.set_mode((735,475))
m = 20
Imgbody = pygame.transform.scale(pygame.image.load('Body.jpg'),(m,m))
Imghead = pygame.transform.scale(pygame.image.load('Head.png'),(m,m))
Imgfood = pygame.transform.scale(pygame.image.load('Covide.jpg'),(m,m))
red = pygame.Color(255,0,0)
Blue = pygame.Color(65,105,255)
Black = pygame.Color(0,0,0)
White = pygame.Color(255,255,255)
Grey = pygame.Color(128,128,128)
snakepos=[100,60]
snakebody =[[100,60],[80,60],[60,60]]
foodx = random.randrange(1,71)
foody = random.randrange(1,45)
if foodx % 2 !=0: foodx +=1
if foody % 2 !=0: foody +=1
foodpos = [foodx * 10, foody * 10]
foodflat = True
direction ='RIGHT'
changeto = direction
score = 0
def show_score(choice = 1):
  sfont = pygame.font.SysFont('conlaso',40)
  ssurf = sfont.render('Score: {0}'.format(score),True,Black)
  srect = ssurf.get_rect()
  if choice == 1:
    srect.midtop = (70,20)
  else:
    srect.midtop = (360,230)
  gameSurface.blit(ssurf,srect)
def game_over():
  gfont = pygame.font.SysFont('conlaso',40)
  gsurf = gfont.render('Game Over!',True,red)
  grect = gsurf.get_rect()
  grect.midtop = (360, 150 )
  gameSurface.blit(gsurf,grect)
  show_score(0)
  pygame.display.flip()
  time.sleep(5)
  pygame.quit()
  sys.exit() 
def game_loop():
  m = 20
  snakepos = [100,60]
  snakebody =[[100,60], [80,60],[60,60]]
  foodx = random.randrange(1,71)
  foody = random.randrange(1,45)
  if foodx % 2 !=0: foodx +=1
  if foody % 2 !=0: foody +=1
  foodpos = [foodx * 10, foody * 10]
  score = 0
  direction = "RIGHT"
  changeto =direction
  running = True
  gameOver= False
  foodflat = True
  Imgbody = pygame.transform.scale(pygame.image.load('Body.jpg'),(m,m))
  Imghead = pygame.transform.scale(pygame.image.load('Head.png'),(m,m))
  Imgfood = pygame.transform.scale(pygame.image.load('Covide.jpg'),(m,m))
  while running:
        if gameOver==True:
            message_to_screen("Game over",red,-50,size="large")
            message_to_screen("Press C to play again or Q to quit",Black,50,size="medium")
            pygame.display.update()
        while gameOver == True:
            for event in pygame.event.get():
                if event.type==pygame.QUIT:
                    gameOver=False
                    running=False
                if event.type==pygame.KEYDOWN:
                    if event.key==pygame.K_q:
                        running=False
                        gameOver=False
                    if event.key==pygame.K_c:
                        game_loop()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
            elif event.type == pygame.KEYDOWN:   
              if event.key == pygame.K_RIGHT or event.key == ord('d') : 
                changeto = "RIGHT" 
                if changeto == 'RIGHT' and not direction == 'LEFT':
                  direction = 'RIGHT'
              elif event.key == pygame.K_LEFT or event.key == ord('a'):
                  changeto = "LEFT"
                  if changeto == 'LEFT' and not direction == 'RIGHT':
                    direction = 'LEFT'
              elif event.key == pygame.K_DOWN or event.key == ord('s'):
                  changeto = "DOWN"
                  if changeto == 'DOWN' and not direction == 'UP':
                    direction = 'DOWN'
              elif event.key == pygame.K_UP or event.key == ord('w'):
                  changeto = "UP"
                  if changeto == 'UP' and not direction == 'DOWN':
                    direction = 'UP'
              elif event.key == pygame.K_ESCAPE:
                  pygame.event.post(pygame.event.Event(pygame.QUIT))
        if direction == "RIGHT":
            snakepos[0] += m
        elif direction == "UP":
            snakepos[1] -= m
        elif direction == "DOWN":
            snakepos[1] += m
        elif direction == "LEFT":
            snakepos[0] -= m
        
        snakebody.insert(0, list(snakepos))       
        if snakepos[0] == foodpos[0] and foodpos[1] ==  snakepos[1]:
              score += 1
              foodflat = False
        else:
            snakebody.pop()
        pygame.display.update()
        if foodflat == False:
          foodx = random.randrange(1,71)
          foody = random.randrange(1,45)
          if foodx % 2 !=0: foodx +=1
          if foody % 2 !=0: foody +=1
          foodpos = [foodx * 10, foody * 10]
        foodflat = True
        
        for pos in snakebody:
          gameSurface.blit(Imgbody,pygame.Rect(pos[0],pos[1],m,m))
        gameSurface.blit(Imghead, pygame.Rect(snakebody[0][0],snakebody[0][1],m,m))
        gameSurface.blit(Imgfood, pygame.Rect(foodpos[0],foodpos[1],m,m))
        pygame.draw.rect(gameSurface,Grey,(10,10,715,455),2)
        if snakepos[0] > 710 or snakepos[0] < 0:
          game_over()
        if snakepos[1] > 450 or snakepos[1] < 0:
          game_over()
        for block in snakebody[1:]:
          if snakepos[0] == block[0] and snakepos[1] == block[1]:
            game_over()
        pygame.display.flip()
        gameSurface.fill(White)
        pygame.time.delay(200)
        show_score()
game_loop()
Reply
#2
Can you move the snake around? Maybe the snake doesn't hit the food?

Try printing to find out a hint.

if snakepos[0] == foodpos[0] and foodpos[1] ==  snakepos[1]:
              print("snakepos: ", snakepos, "foodpos: ", foodpos) #<--- add line
              score += 1
              foodflat = False
        else:
            snakebody.pop()
Reply
#3
1. You code is hard to read. You also have repeat code. You need rewrite. Don't use time. pygame has it own time module.

2. Import pygame.locals. Instead of using 'Right' use K_RIGHT for direction movement. Definitely don't use ord('d'). Use K_d. Never update direction in event loop. Because the next event can make a collision with self. All because snake didn't get to move.
    # Event loop
    if event.key in [K_RIGHT, K_d] and direction != K_LEFT:
        new_direction = K_RIGHT

if new_direction:
    direction = new_direction
    new_direction = None

if direction == K_RIGHT:
    x, y = snakebody[0]
    snake_head = (x + m, y)
# etc

snakebody.insert(0, snake_head)
if snake_head == foodpos:
    score += 1
    # Generate next food position
else:
    snakebody.pop()
3. Never use pygame.time.delay to control snake speed. You use delta, ticks, or timer. Ticks example.
# Varaibles
snake_interval = 200
snake_next_tick = snake_interval

# Main loop
ticks = pygame.time.get_ticks():
if ticks > snake_next_tick:
    snake_next_tick += snake_interval
    if new_direction:
        direction = new_direction
        new_direction = None

    if direction == K_RIGHT:
        x, y = snakebody[0]
        snake_head = (x + m, y)
    # etc

    snakebody.insert(0, snake_head)
    if snake_head == foodpos:
        score += 1
        # Update score text
        # Generate next food position
    else:
        snakebody.pop()
4. You want pygame.time.Clock to idle program.
# Variable
clock = pygame.time.Clock()
fps = 60

# In Main loop
clock.tick(fps)
5. You can have all body position at the start be the same position. When snake move. Then you only check the snake head if it collide. Not the body. Using tuples because list are reference and mutable.
snakebody = [(60, 60)] * 3
6 Food position has to match snake position. So you can not multiply it by 10. It has to be multiply by m. You can also offset it when you draw it. Otherwise snake might never be able to collide with food.
99 percent of computer problems exists between chair and keyboard.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020