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选择排序算法的实现代码
Nov 21 Python
python二叉树的实现实例
Nov 21 Python
DJANGO-ALLAUTH社交用户系统的安装配置
Nov 18 Python
在Django同1个页面中的多表单处理详解
Jan 25 Python
Python实现将文本生成二维码的方法示例
Jul 18 Python
Python3 中文文件读写方法
Jan 23 Python
Atom的python插件和常用插件说明
Jul 08 Python
python基于socket实现的UDP及TCP通讯功能示例
Nov 01 Python
python 并发下载器实现方法示例
Nov 22 Python
python 实现turtle画图并导出图片格式的文件
Dec 07 Python
Python如何实现爬取B站视频
May 20 Python
使用python实现名片管理系统
Jun 18 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
初学者入门:细述PHP4的核心Zend
2006/09/05 PHP
检测png图片是否完整的php代码
2010/09/06 PHP
PHP 范围解析操作符(::)用法分析【访问静态成员和类常量】
2020/04/14 PHP
createElement动态创建HTML对象脚本代码
2008/11/24 Javascript
firefo xml 读写实现js代码
2009/06/11 Javascript
json对象转字符串如何实现
2012/12/02 Javascript
jquery原创弹出层折叠效果点击折叠弹出一个层
2014/03/12 Javascript
jQuery版本升级踩坑大全
2016/01/12 Javascript
AngularJS 输入验证详解及实例代码
2016/07/28 Javascript
AngularJS基础 ng-switch 指令简单示例
2016/08/03 Javascript
微信小程序 获取相册照片实例详解
2016/11/16 Javascript
js移动焦点到最后位置的简单方法
2016/11/25 Javascript
jQuery插件FusionCharts绘制ScrollColumn2D图效果示例【附demo源码下载】
2017/03/22 jQuery
Angular.JS中指令ng-if、ng-show/ng-hide和ng-switch的使用教程
2017/05/07 Javascript
jQuery绑定事件方法及区别(bind,click,on,live,one)
2017/08/14 jQuery
微信小程序倒计时功能实现代码
2017/11/09 Javascript
使用Vue构建可重用的分页组件
2018/03/26 Javascript
jsonp跨域获取数据的基础教程
2018/07/01 Javascript
Vue中使用canvas方法总结
2019/02/12 Javascript
vue 解决provide和inject响应的问题
2020/11/12 Javascript
[01:00:52]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第一场
2018/04/05 DOTA
Python中的文件和目录操作实现代码
2011/03/13 Python
在Django框架中伪造捕捉到的URLconf值的方法
2015/07/18 Python
PyQt5 pyqt多线程操作入门
2018/05/05 Python
Python3实现定时任务的四种方式
2019/06/03 Python
python为什么要安装到c盘
2020/07/20 Python
python boto和boto3操作bucket的示例
2020/10/30 Python
台湾乐天市场:日本No.1的网路购物网站
2017/03/22 全球购物
中文专业毕业生自荐书范文
2014/01/04 职场文书
中学教师请假制度
2014/02/03 职场文书
小学生安全演讲稿
2014/04/25 职场文书
质量主管工作职责
2014/09/26 职场文书
保送生自荐信
2015/03/06 职场文书
幼儿园托班教育随笔
2015/08/14 职场文书
民事纠纷协议书
2016/03/23 职场文书
MySQL数据库 任意ip连接方法
2022/05/20 MySQL