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 相关文章推荐
Python写的贪吃蛇游戏例子
Jun 16 Python
研究Python的ORM框架中的SQLAlchemy库的映射关系
Apr 25 Python
Python中easy_install 和 pip 的安装及使用
Jun 05 Python
详解appium+python 启动一个app步骤
Dec 20 Python
10招!看骨灰级Pythoner玩转Python的方法
Apr 15 Python
python设计tcp数据包协议类的例子
Jul 23 Python
python 使用socket传输图片视频等文件的实现方式
Aug 07 Python
python使用requests.session模拟登录
Aug 09 Python
Python序列化与反序列化pickle用法实例
Nov 11 Python
python异步Web框架sanic的实现
Apr 27 Python
Python xml、字典、json、类四种数据类型如何实现互相转换
May 27 Python
python基础之错误和异常处理
Oct 24 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
全国FM电台频率大全 - 6 辽宁省
2020/03/11 无线电
用php和MySql来与ODBC数据连接
2006/10/09 PHP
利用php递归实现无限分类 格式化数组的详解
2013/06/08 PHP
探讨:使用XMLSerialize 序列化与反序列化
2013/06/08 PHP
PHP程序员必须知道的两种日志实例分析
2020/05/14 PHP
js实现ASP分页函数 HTML分页函数
2006/09/22 Javascript
this和执行上下文实现代码
2010/07/01 Javascript
javascript下高性能字符串连接StringBuffer类
2010/08/16 Javascript
Jquery实现弹出层分享微博插件具备动画效果
2013/04/03 Javascript
jQuery的显示和隐藏方法与css隐藏的样式对比
2013/10/18 Javascript
HTML页面登录时的JS验证方法
2014/05/28 Javascript
Javascript中的getUTCHours()方法使用详解
2015/06/10 Javascript
Jquery遍历select option和添加移除option的实现方法
2016/08/26 Javascript
JS实现点击表头表格自动排序(含数字、字符串、日期)
2017/01/22 Javascript
react学习笔记之state以及setState的使用
2017/12/07 Javascript
vue-cli 3.x 配置Axios(proxyTable)跨域代理方法
2018/09/19 Javascript
微信小程序实现吸顶特效
2020/01/08 Javascript
jQuery操作元素的内容和样式完整实例分析
2020/01/10 jQuery
vue-cli设置css不生效的解决方法
2020/02/07 Javascript
完美解决通过IP地址访问VUE项目的问题
2020/07/18 Javascript
[48:24]完美世界DOTA2联赛循环赛LBZS vs Forest 第一场 10月30日
2020/10/31 DOTA
python中文件变化监控示例(watchdog)
2017/10/16 Python
Python3.7中安装openCV库的方法
2018/07/11 Python
Django 开发环境配置过程详解
2019/07/18 Python
python中的数组赋值与拷贝的区别详解
2019/11/26 Python
matplotlib jupyter notebook 图像可视化 plt show操作
2020/04/24 Python
美国最大的团购网站:Groupon
2016/07/23 全球购物
C语言编程练习
2012/04/02 面试题
理工科学生的自我评价
2013/12/15 职场文书
茶叶店创业计划书范文
2014/01/19 职场文书
超市活动计划书
2014/04/24 职场文书
会计专业毕业生求职信
2014/07/04 职场文书
2014年电厂工作总结
2014/12/04 职场文书
同事去世追悼词
2015/06/23 职场文书
体育教师教学随笔
2015/08/15 职场文书
javascript进阶篇深拷贝实现的四种方式
2022/07/07 Javascript