当前位置 主页 > 服务器问题 > Linux/apache问题 >

    pygame实现贪吃蛇游戏(下)

    栏目:Linux/apache问题 时间:2019-11-08 10:41

    接着上篇pygame实现贪吃蛇游戏(上)继续介绍

    1.豆子的吃掉效果

    只需在代码最后移动蛇头的代码后增加一个蛇头和豆子坐标的判断即可

    if snake_x == bean_x and snake_y == bean_y:
     bean_x,bean_y = get_bean_pos()

    体验一下,现在蛇头碰到豆子后,豆子已经会消失了

    2.蛇身的加长

    前面我们给蛇身只设置了一个坐标,既然蛇身会越加越长,当然我们用一个数组去存这个身体是更合适的,于是我们把蛇身的变量做一些修改。

    在初始化body_x和body_y完成后,将这个坐标加入一个名叫body_arr的数组

    body_arr = [(body_x,body_y)]

    将绘制蛇身的pygame.draw.rect做下修改,用遍历数组去绘制

    for body_x,body_y in body_arr:
     pygame.draw.rect(screen,yellow,[body_x-20,body_y-20,40,40],5)

    蛇身的移动也同样要改成循环,分别使身体的后一节使用前一节的位置

    body_arr = [(snake_x,snake_y)]+body_arr[:-1]

    最后吃到豆子后蛇身的加长我们可以这么做,先把蛇最后一节的位置备份一下

    last_body_x,last_body_y = body_arr[-1]

    如果吃到豆子,那么把这备份下的最后一节加到身体数组最后就好了

    body_arr.append((last_body_x,last_body_y))

    现在基本的游戏效果可以看到了

    3.蛇自身碰撞的游戏失败判断

    用一个标记表示游戏状态

    game_state = 1 # 游戏状态1.表示正常 2.表示失败

    将移动判断的代码加入标记的判断改成

    if game_state == 1 and pygame.time.get_ticks() >= ticks:

    在移动的最后增加一个头和身体、身体和身体的重合判断

    for body_x,body_y in body_arr: # 判断下蛇头和身体是否有重合
          if snake_x == body_x and snake_y == body_y:
            game_state = 2
            break
    for i in range(len(body_arr)-1):
          for j in range(i+1,len(body_arr)):
            if body_arr[i][0] == body_arr[j][0] and body_arr[i][1] == body_arr[j][1]: # 判断下身体每节是否有重合
              game_state = 2
              break

    游戏失败后的效果的图如下

    再把网格线去了,看起来干净一点

    最后再附一下完整的程序

    # -*- coding=utf-8 -*-
    import random
    import pygame
    from pygame.locals import KEYDOWN,K_LEFT,K_RIGHT,K_UP,K_DOWN
    pygame.init()
    screencaption = pygame.display.set_caption('first pygame')
    screen = pygame.display.set_mode((400,400)) #设置400*400窗口
    
    snake_x = random.randint(0,9)*40+20
    snake_y = random.randint(0,9)*40+20
    
    game_state = 1 # 游戏状态1.表示正常 2.表示失败
    def get_bean_pos():
     return random.randint(0,9)*40+20,random.randint(0,9)*40+20 
    
    yellow = 255,255,0 
    
    bean_x,bean_y = get_bean_pos()
    
    diff_ticks = 300 # 移动一次蛇头的事件,单位毫秒
    ticks = pygame.time.get_ticks()
    ticks += diff_ticks
    
    #dire = random.randint(0,3) # 假设0、1、2、3分别代表方向左、右、上、下
    if snake_x < 200:
     dire = 1 # 往右移动
    else: 
     dire = 0 # 往左移动 
    
    body_y = snake_y
    if dire == 0: # 向左移动
     if snake_x + 40 < 400: 
      body_x = snake_x + 40
     else: # 身体不能放右侧了,只能往上下方向放
      if snake_y > 200:
       body_x = snake_x
       body_y -= 40
      else:
       body_x = snake_x
       body_y += 40
    else: # 向右移动
     if snake_x - 40 > 0:
      body_x = snake_x - 40
     else: # 身体不能放左侧了,只能往上下方向放
      if snake_y > 200:
       body_x = snake_x
       body_y -= 40
      else:
       body_x = snake_x
       body_y += 40
    body_arr = [(body_x,body_y)]
    
    def set_snake_next_pos(snake_x, snake_y):
     if dire == 0:
      if snake_x - 40 > 0:
       snake_x -= 40
     if dire == 1:
      if snake_x + 40 < 400:
       snake_x += 40
     if dire == 2:
      if snake_y - 40 > 0:
       snake_y -= 40
     if dire == 3:
      if snake_y + 40 < 400:
       snake_y += 40
     return snake_x,snake_y
    
    while True:
     for event in pygame.event.get():
       if event.type == pygame.QUIT:
        pygame.quit()
        exit()
       if event.type == KEYDOWN:
        if event.key == K_LEFT:
         if dire!=0 and dire!=1 and snake_x - 40 > 0: # 和当前方向不是同方向或反方向并且可以左移
          dire = 0
        if event.key == K_RIGHT:
         if dire!=0 and dire!=1 and snake_x + 40 < 400: # 和当前方向不是同方向或反方向并且可以右移
          dire = 1
        if event.key == K_UP:
         if dire!=2 and dire!=3 and snake_y - 40 > 0: # 和当前方向不是同方向或反方向并且可以上移
          dire = 2
        if event.key == K_DOWN:
         if dire!=2 and dire!=3 and snake_y + 40 < 400: # 和当前方向不是同方向或反方向并且可以下移
          dire = 3
    
     screen.fill((0,0,255)) # 将界面设置为蓝色
    
     #for x in range(0,400,40):
     # pygame.draw.line(screen,(255,255,255),(x,0),(x,400),1)
     #for y in range(0,400,40):
     # pygame.draw.line(screen,(255,255,255),(0,y),(400,y),1)
    
     pygame.draw.circle(screen,yellow,[snake_x,snake_y],20,2)
     for body_x,body_y in body_arr:
      pygame.draw.rect(screen,yellow,[body_x-20,body_y-20,40,40],5) 
     
     pygame.draw.circle(screen,yellow,[bean_x,bean_y],10,10)
     
     if game_state == 2:
      myfont = pygame.font.Font(None,30)
      white = 255,255,255
      textImage = myfont.render("Game over", True, white)
      screen.blit(textImage, (160,190))
    
     
     pygame.display.update() # 必须调用update才能看到绘图显示
    
     if game_state == 1 and pygame.time.get_ticks() >= ticks:
      last_body_x,last_body_y = body_arr[-1]
      body_arr = [(snake_x,snake_y)]+body_arr[:-1]
      snake_x,snake_y = set_snake_next_pos(snake_x,snake_y)
      ticks += diff_ticks
      #if snake_x == bean_x and snake_y == bean_y:
      # bean_x,bean_y = get_bean_pos()
      # body_arr.append((last_body_x,last_body_y))
      for body_x,body_y in body_arr:
       if snake_x == body_x and snake_y == body_y: # 判断下蛇头和身体是否有重合
        game_state = 2
        break
      for i in range(len(body_arr)-1):
       for j in range(i+1,len(body_arr)):
        if body_arr[i][0] == body_arr[j][0] and body_arr[i][1] == body_arr[j][1]: # 判断下身体每节是否有重合
         game_state = 2
         break
     
     if snake_x == bean_x and snake_y == bean_y:
      bean_x,bean_y = get_bean_pos()
      body_arr.append((last_body_x,last_body_y))