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实现批量把SVG格式转成png、pdf格式的代码分享
Aug 21 Python
简单介绍使用Python解析并修改XML文档的方法
Oct 15 Python
详解Python编程中基本的数学计算使用
Feb 04 Python
python基于物品协同过滤算法实现代码
May 31 Python
pandas 快速处理 date_time 日期格式方法
Nov 12 Python
Python 最大概率法进行汉语切分的方法
Dec 14 Python
Python 调用 Outlook 发送邮件过程解析
Aug 08 Python
python 3.6.7实现端口扫描器
Sep 04 Python
关于Python内存分配时的小秘密分享
Sep 05 Python
解决Python spyder显示不全df列和行的问题
Apr 20 Python
用OpenCV进行年龄和性别检测的实现示例
Jan 29 Python
python 实现德洛内三角剖分的操作
Apr 22 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 开发环境配置(测试开发环境)
2010/04/28 PHP
Yii2使用$this-&gt;context获取当前的Module、Controller(控制器)、Action等
2017/03/29 PHP
Yii2.0框架实现带分页的多条件搜索功能示例
2019/02/20 PHP
Nginx+php配置文件及原理解析
2020/12/09 PHP
js 完美图片新闻轮转效果,腾讯大粤网首页图片轮转改造而来
2011/11/21 Javascript
用jQuery实现一些导航条切换,显示隐藏的实例代码
2013/06/08 Javascript
jquery购物车实时结算特效实现思路
2013/09/23 Javascript
2014 年最热门的21款JavaScript框架推荐
2014/12/25 Javascript
Jquery插件之Fancybox丰富的弹出层效果附源码下载
2015/12/02 Javascript
BootStrap智能表单实战系列(三)分块表单配置详解
2016/06/13 Javascript
vuejs通过filterBy、orderBy实现搜索筛选、降序排序数据
2020/10/26 Javascript
JavaScript闭包和回调详解
2017/08/09 Javascript
浅谈在fetch方法中添加header后遇到的预检请求问题
2017/08/31 Javascript
jquery 实现拖动文件上传加载进度条功能
2018/03/18 jQuery
vue.js实现二级菜单效果
2019/10/19 Javascript
稍微学一下Vue的数据响应式(Vue2及Vue3区别)
2019/11/21 Javascript
vue项目使用高德地图的定位及关键字搜索功能的实例代码(踩坑经验)
2020/03/07 Javascript
Node Mongoose用法详解【Mongoose使用、Schema、对象、model文档等】
2020/05/13 Javascript
[04:28]DOTA2亚洲邀请赛小组赛第五日 TOP10精彩集锦
2015/02/03 DOTA
Python实现配置文件备份的方法
2015/07/30 Python
用python实现简单EXCEL数据统计的实例
2017/01/24 Python
python 获取键盘输入,同时有超时的功能示例
2018/11/13 Python
Python实现多属性排序的方法
2018/12/05 Python
python中的decimal类型转换实例详解
2019/06/26 Python
Flask-WTF表单的使用方法
2019/07/12 Python
戴尔马来西亚官网:Dell Malaysia
2020/05/02 全球购物
2014年基层党组织公开承诺书
2014/03/29 职场文书
付款委托书范本
2014/04/04 职场文书
小学生学雷锋演讲稿
2014/04/25 职场文书
尊老爱幼演讲稿
2014/09/04 职场文书
2014年防汛工作总结
2014/12/08 职场文书
四年级学生期末评语
2014/12/26 职场文书
特岗教师个人总结
2015/02/10 职场文书
小学班主任工作随笔
2015/08/15 职场文书
2016年小学端午节活动总结
2016/04/01 职场文书
2019安全宣传标语大全
2019/08/14 职场文书