pygame实现贪吃蛇游戏(上)


Posted in Python onOctober 29, 2019

本文实例为大家分享了pygame贪吃蛇游戏的具体代码,供大家参考,具体内容如下

1.准备工作

我们已经初始化了一个400*400的界面,为方便看我们的游戏,我们先在界面上画40*40的格子,即纵向切10份,横向切10份,这样我们就需要画20个线段,下面是20个线段的画法

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实现贪吃蛇游戏(上)

2.蛇头和豆子的位置

可以使用random取一个随机位置

import random
snake_x = random.randint(0,9)*40+20
snake_y = random.randint(0,9)*40+20

绘制一个圆形的蛇头

yellow = 255,255,0
pygame.draw.circle(screen,yellow,[snake_x,snake_y],20,2)

豆子的绘制类似,我们可以把豆子的圈画小一点,把线宽画宽一点,这样就有一个实心的豆子

pygame.draw.circle(screen,yellow,[bean_x,bean_y],10,10)

现在看到的界面是这样的

pygame实现贪吃蛇游戏(上)

目前的完整代码是这样的

# -*- coding=utf-8 -*-
import random
import pygame
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

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()

while True:
 for event in pygame.event.get():
  if event.type == pygame.QUIT:
  pygame.quit()
  exit()

 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)
 pygame.draw.circle(screen,yellow,[bean_x,bean_y],10,10)
 pygame.display.update() # 必须调用update才能看到绘图显示

3.用键盘控制蛇头的移动

导入事件判断的变量

from pygame.locals import KEYDOWN,K_LEFT,K_RIGHT,K_UP,K_DOWN

在事件判断中增加一下程序

if event.type == KEYDOWN:
 if event.key == K_LEFT:
    if snake_x-40>0: snake_x-=40
   if event.key == K_RIGHT:
    if snake_x+40<400: snake_x+=40
   if event.key == K_UP:
    if snake_y-40>0: snake_y-=40
   if event.key == K_DOWN:
    if snake_y+40<400: snake_y+=40

现在再运行程序时,已经看到可以对蛇头进行方向的控制了

4.使蛇头向某一方向匀速移动

首先我们定义一个用于计算时间间隔的时间戳

diff_ticks = 500 # 移动一次蛇头的事件,单位毫秒
ticks = pygame.time.get_ticks()
ticks += diff_ticks

在主循环里判断,如果时间满了则触发蛇头移动到下一个

if pygame.time.get_ticks() >= ticks:
  snake_x,snake_y = set_snake_next_pos(snake_x,snake_y)
  ticks += diff_ticks

set_snake_next_pos函数的实现如下

dire = random.randint(0,3) # 假设0、1、2、3分别代表方向左、右、上、下

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

此外,主循环里键盘的判断也要做下修改,一是要在键盘按下后修改移动方向,二是按下时不用马上移动蛇头,等待时间满后的自动移动,判断代码修改后如下

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

为避免蛇头出来就撞墙,我们对初始的蛇头方向再做个处理,让蛇头往空白多的地方前进,代码如下

#dire = random.randint(0,3) # 假设0、1、2、3分别代表方向左、右、上、下
if snake_x < 5:
 dire = 1 # 往右移动
else:
 dire = 0 # 往左移动

5.使给蛇增加身体

我们用一个方块做蛇的身体,身体应该是头的后面一格,按蛇头的移动方向放到后面一格,如果后面一个已经没有位置了,则往垂直方向上放到上方或者下方
定义身体初始位置的代码如下

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

主循环里增加矩形身体的绘制

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

在每次更新蛇位置时可以先把身体的位置变成蛇头的位置,再进行蛇头移动操作

if pygame.time.get_ticks() >= ticks:
  body_x = snake_x
  body_y = snake_y
  snake_x,snake_y = set_snake_next_pos(snake_x,snake_y)
  ticks += diff_ticks

目前的效果图如下

pygame实现贪吃蛇游戏(上)

最后附下目前的完整代码,下章再介绍吃豆和身体变长部分的代码修改

# -*- 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

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 = 500 # 移动一次蛇头的事件,单位毫秒
ticks = pygame.time.get_ticks()
ticks += diff_ticks

#dire = random.randint(0,3) # 假设0、1、2、3分别代表方向左、右、上、下
if snake_x < 5:
 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

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)
 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)

 pygame.display.update() # 必须调用update才能看到绘图显示

 if pygame.time.get_ticks() >= ticks:
  body_x = snake_x
  body_y = snake_y
  snake_x,snake_y = set_snake_next_pos(snake_x,snake_y)
  ticks += diff_ticks

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

Python 相关文章推荐
简单讲解Python中的数字类型及基本的数学计算
Mar 11 Python
Python程序中的观察者模式结构编写示例
May 27 Python
Python实现单词翻译功能
Jun 06 Python
Python 处理数据的实例详解
Aug 10 Python
通过Python 获取Android设备信息的轻量级框架
Dec 18 Python
python tensorflow基于cnn实现手写数字识别
Jan 01 Python
深入理解Python 关于supper 的 用法和原理
Feb 28 Python
Django 跨域请求处理的示例代码
May 02 Python
python自动截取需要区域,进行图像识别的方法
May 17 Python
Django中间件实现拦截器的方法
Jun 01 Python
Python计算信息熵实例
Jun 18 Python
Pycharm同步远程服务器调试的方法步骤
Nov 04 Python
利用Python小工具实现3秒钟将视频转换为音频
Oct 29 #Python
pygame实现打字游戏
Feb 19 #Python
Python 实现自动导入缺失的库
Oct 29 #Python
python实现的读取网页并分词功能示例
Oct 29 #Python
python实现LRU热点缓存及原理
Oct 29 #Python
Python 中的 import 机制之实现远程导入模块
Oct 29 #Python
Centos7 下安装最新的python3.8
Oct 28 #Python
You might like
星际争霸任务指南——神族
2020/03/04 星际争霸
php的计数器程序
2006/10/09 PHP
PHP大批量数据操作时临时调整内存与执行时间的方法
2011/04/20 PHP
DOM XPATH获取img src值的query
2013/09/23 PHP
php中mysql操作buffer用法详解
2015/03/19 PHP
PHP使用mysqldump命令导出数据库
2015/04/14 PHP
PHP提高编程效率的20个要点
2015/09/23 PHP
Yii中表单用法实例详解
2016/01/05 PHP
PHP实现单条sql执行多个数据的insert语句方法
2019/10/11 PHP
基于JQuery的cookie插件
2010/04/07 Javascript
defer属性导致引用JQuery的页面报“浏览器无法打开网站xxx,操作被中止”错误的解决方法
2010/04/27 Javascript
鼠标选择动态改变网页背景颜色的JS代码
2013/12/10 Javascript
jQuery使用元素属性attr赋值详解
2015/02/27 Javascript
浅谈javascript构造函数与实例化对象
2015/06/22 Javascript
JavaScript的ExtJS框架中表格的编写教程
2016/05/21 Javascript
node.js路径处理方法以及绝对路径详解
2021/03/04 Javascript
解决nodejs中使用http请求返回值为html时乱码的问题
2017/02/18 NodeJs
JavaScript函数柯里化原理与用法分析
2017/03/31 Javascript
vue获取当前激活路由的方法
2018/03/17 Javascript
JavaScript引用类型Object常见用法实例分析
2018/08/08 Javascript
js限制输入框只能输入数字(onkeyup触发)
2018/09/28 Javascript
Python的面向对象思想分析
2015/01/14 Python
Python实现的rsa加密算法详解
2018/01/24 Python
python 筛选数据集中列中value长度大于20的数据集方法
2018/06/14 Python
Python生成MD5值的两种方法实例分析
2019/04/26 Python
python中web框架的自定义创建
2019/09/08 Python
python中os包的用法
2020/06/01 Python
50个强大璀璨的CSS3/JS技术运用实例
2010/02/27 HTML / CSS
纯CSS3实现漂亮的input输入框动画样式库(Text input love)
2018/12/29 HTML / CSS
html5中canvas学习笔记1-画板的尺寸与实际显示尺寸
2013/01/06 HTML / CSS
Happy Socks英国官网:购买五颜六色的袜子
2020/11/03 全球购物
幼儿园教师节活动方案
2014/02/02 职场文书
国际贸易毕业生求职信范文
2014/02/21 职场文书
文体活动实施方案
2014/03/27 职场文书
紧急通知
2015/04/17 职场文书
初中班级口号霸气押韵
2015/12/24 职场文书