PyGame贪吃蛇的实现代码示例


Posted in Python onNovember 21, 2018

最近帮人做了个贪吃蛇的游戏(交作业用),很简单,界面如下:

开始界面:

PyGame贪吃蛇的实现代码示例

游戏中界面:

PyGame贪吃蛇的实现代码示例

是不是很简单、朴素。(欢迎大家访问GitHub)

游戏是基于PyGame框架制作的,程序核心逻辑如下:

  • 游戏界面分辨率是640*480,蛇和食物都是由1个或多个20*20像素的正方形块儿(为了方便,下文用点表示20*20像素的正方形块儿)组成,这样共有32*24个点,使用pygame.draw.rect来绘制每一个点;
  • 初始化时蛇的长度是3,食物是1个点,蛇初始的移动的方向是右,用一个数组代表蛇,数组的每个元素是蛇每个点的坐标,因此数组的第一个坐标是蛇尾,最后一个坐标是蛇头;
  • 游戏开始后,根据蛇的当前移动方向,将蛇运动方向的前方的那个点append到蛇数组的末位,再把蛇尾去掉,蛇的坐标数组就相当于往前挪了一位;
  • 如果蛇吃到了食物,即蛇头的坐标等于食物的坐标,那么在第2点中蛇尾就不用去掉,就产生了蛇长度增加的效果;食物被吃掉后,随机在空的位置(不能与蛇的身体重合)再生成一个;
  • 通过PyGame的event监控按键,改变蛇的方向,例如当蛇向右时,下一次改变方向只能向上或者向下;
  • 当蛇撞上自身或墙壁,游戏结束,蛇头装上自身,那么蛇坐标数组里就有和舌头坐标重复的数据,撞上墙壁则是蛇头坐标超过了边界,都很好判断;
  • 其他细节:做了个开始的欢迎界面;食物的颜色随机生成;吃到实物的时候有声音提示等。

代码:

#!/usr/bin/env python 
# -*- coding:utf-8 -*- 

""" 
@version: v1.0 
@author: Harp
@contact: liutao25@baidu.com 
@software: PyCharm 
@file: MySnake.py 
@time: 2018/1/15 0015 23:40 
"""


import pygame
from os import path
from sys import exit
from time import sleep
from random import choice
from itertools import product
from pygame.locals import QUIT, KEYDOWN


def direction_check(moving_direction, change_direction):
  directions = [['up', 'down'], ['left', 'right']]
  if moving_direction in directions[0] and change_direction in directions[1]:
    return change_direction
  elif moving_direction in directions[1] and change_direction in directions[0]:
    return change_direction
  return moving_direction


class Snake:

  colors = list(product([0, 64, 128, 192, 255], repeat=3))[1:-1]

  def __init__(self):
    self.map = {(x, y): 0 for x in range(32) for y in range(24)}
    self.body = [[100, 100], [120, 100], [140, 100]]
    self.head = [140, 100]
    self.food = []
    self.food_color = []
    self.moving_direction = 'right'
    self.speed = 4
    self.generate_food()
    self.game_started = False

  def check_game_status(self):
    if self.body.count(self.head) > 1:
      return True
    if self.head[0] < 0 or self.head[0] > 620 or self.head[1] < 0 or self.head[1] > 460:
      return True
    return False

  def move_head(self):
    moves = {
      'right': (20, 0),
      'up': (0, -20),
      'down': (0, 20),
      'left': (-20, 0)
    }
    step = moves[self.moving_direction]
    self.head[0] += step[0]
    self.head[1] += step[1]

  def generate_food(self):
    self.speed = len(self.body) // 16 if len(self.body) // 16 > 4 else self.speed
    for seg in self.body:
      x, y = seg
      self.map[x//20, y//20] = 1
    empty_pos = [pos for pos in self.map.keys() if not self.map[pos]]
    result = choice(empty_pos)
    self.food_color = list(choice(self.colors))
    self.food = [result[0]*20, result[1]*20]


def main():
  key_direction_dict = {
    119: 'up', # W
    115: 'down', # S
    97: 'left', # A
    100: 'right', # D
    273: 'up', # UP
    274: 'down', # DOWN
    276: 'left', # LEFT
    275: 'right', # RIGHT
  }

  fps_clock = pygame.time.Clock()
  pygame.init()
  pygame.mixer.init()
  snake = Snake()
  sound = False
  if path.exists('eat.wav'):
    sound_wav = pygame.mixer.Sound("eat.wav")
    sound = True
  title_font = pygame.font.SysFont('arial', 32)
  welcome_words = title_font.render('Welcome to My Snake', True, (0, 0, 0), (255, 255, 255))
  tips_font = pygame.font.SysFont('arial', 24)
  start_game_words = tips_font.render('Click to Start Game', True, (0, 0, 0), (255, 255, 255))
  close_game_words = tips_font.render('Press ESC to Close', True, (0, 0, 0), (255, 255, 255))
  gameover_words = title_font.render('GAME OVER', True, (205, 92, 92), (255, 255, 255))
  win_words = title_font.render('THE SNAKE IS LONG ENOUGH AND YOU WIN!', True, (0, 0, 205), (255, 255, 255))
  screen = pygame.display.set_mode((640, 480), 0, 32)
  pygame.display.set_caption('My Snake')
  new_direction = snake.moving_direction
  while 1:
    for event in pygame.event.get():
      if event.type == QUIT:
        exit()
      elif event.type == KEYDOWN:
        if event.key == 27:
          exit()
        if snake.game_started and event.key in key_direction_dict:
          direction = key_direction_dict[event.key]
          new_direction = direction_check(snake.moving_direction, direction)
      elif (not snake.game_started) and event.type == pygame.MOUSEBUTTONDOWN:
        x, y = pygame.mouse.get_pos()
        if 213 <= x <= 422 and 304 <= y <= 342:
          snake.game_started = True
    screen.fill((255, 255, 255))
    if snake.game_started:
      snake.moving_direction = new_direction # 在这里赋值,而不是在event事件的循环中赋值,避免按键太快
      snake.move_head()
      snake.body.append(snake.head[:])
      if snake.head == snake.food:
        if sound:
          sound_wav.play()
        snake.generate_food()
      else:
        snake.body.pop(0)
      for seg in snake.body:
        pygame.draw.rect(screen, [0, 0, 0], [seg[0], seg[1], 20, 20], 0)
      pygame.draw.rect(screen, snake.food_color, [snake.food[0], snake.food[1], 20, 20], 0)
      if snake.check_game_status():
        screen.blit(gameover_words, (241, 310))
        pygame.display.update()
        snake = Snake()
        new_direction = snake.moving_direction
        sleep(3)
      elif len(snake.body) == 512:
        screen.blit(win_words, (33, 210))
        pygame.display.update()
        snake = Snake()
        new_direction = snake.moving_direction
        sleep(3)
    else:
      screen.blit(welcome_words, (188, 100))
      screen.blit(start_game_words, (236, 310))
      screen.blit(close_game_words, (233, 350))
    pygame.display.update()
    fps_clock.tick(snake.speed)


if __name__ == '__main__':
  main()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
pyramid配置session的方法教程
Nov 27 Python
python多线程编程方式分析示例详解
Dec 06 Python
使用python分析git log日志示例
Feb 27 Python
Python之PyUnit单元测试实例
Oct 11 Python
Python3实现并发检验代理池地址的方法
Sep 18 Python
Python实现二分查找与bisect模块详解
Jan 13 Python
使用python遍历指定城市的一周气温
Mar 31 Python
python模块smtplib学习
May 22 Python
python 通过麦克风录音 生成wav文件的方法
Jan 09 Python
python实现输入三角形边长自动作图求面积案例
Apr 12 Python
python如何进入交互模式
Jul 06 Python
python playwright之元素定位示例详解
Jul 23 Python
python+flask实现API的方法
Nov 21 #Python
python实现事件驱动
Nov 21 #Python
python事件驱动event实现详解
Nov 21 #Python
python程序封装为win32服务的方法
Mar 07 #Python
pygame游戏之旅 添加icon和bgm音效的方法
Nov 21 #Python
pygame游戏之旅 添加游戏暂停功能
Nov 21 #Python
使用50行Python代码从零开始实现一个AI平衡小游戏
Nov 21 #Python
You might like
PHP下编码转换函数mb_convert_encoding与iconv的使用说明
2009/12/16 PHP
PHP 文件缓存的性能测试
2010/04/25 PHP
如何实现动态删除javascript函数
2007/05/27 Javascript
jQuery 各种浏览器下获得日期区别
2008/12/22 Javascript
IE iframe的onload方法分析小结
2010/01/07 Javascript
在Windows上安装Node.js模块的方法
2011/09/25 Javascript
node.js中RPC(远程过程调用)的实现原理介绍
2014/12/05 Javascript
超赞的动手创建JavaScript框架的详细教程
2015/06/30 Javascript
JS实现slide文字框缩放伸展效果代码
2015/11/05 Javascript
一道关于JavaScript变量作用域的面试题
2016/03/08 Javascript
基于javascript数组实现图片轮播
2016/05/02 Javascript
快速获取/设置iframe内对象元素的几种js实现方法
2016/05/20 Javascript
利用jquery实现实时更新歌词的方法
2017/01/06 Javascript
浅谈js中function的参数默认值
2017/02/20 Javascript
详解ES6中的 Set Map 数据结构学习总结
2018/11/06 Javascript
vue如何实现自定义底部菜单栏
2019/07/01 Javascript
详解JavaScript执行模型
2020/11/16 Javascript
JS实现超级好看的鼠标小尾巴特效
2020/12/01 Javascript
[10:04]国际邀请赛采访专栏:DK.Farseer,mouz.Black^,采访员Josh专访
2013/08/05 DOTA
[48:51]完美世界DOTA2联赛PWL S2 Magma vs InkIce 第一场 11.28
2020/12/02 DOTA
Python跳出循环语句continue与break的区别
2014/08/25 Python
详解python进行mp3格式判断
2016/12/23 Python
Python3.4实现从HTTP代理网站批量获取代理并筛选的方法示例
2017/09/26 Python
python shell根据ip获取主机名代码示例
2017/11/25 Python
Python深度优先算法生成迷宫
2018/01/22 Python
Python入门之后再看点什么好?
2018/03/05 Python
Windows 8.1 64bit下搭建 Scrapy 0.22 环境
2018/11/18 Python
python opencv 图像拼接的实现方法
2019/06/27 Python
Python从入门到精通之环境搭建教程图解
2019/09/26 Python
python实现简单遗传算法
2020/09/18 Python
Python基于爬虫实现全网搜索并下载音乐
2021/02/14 Python
会计电算化专业求职信
2014/06/10 职场文书
2015年中秋节演讲稿
2015/03/20 职场文书
致地震灾区的慰问信
2015/03/23 职场文书
2015年体育教师个人工作总结
2015/05/12 职场文书
事业单位岗位说明书
2015/10/08 职场文书