pygame是主要构筑在SDL库基础上的一组Python模块的集合,它使我们能够用Python语言来创建功能完整的游戏和多媒体程序。pygame是高度括平台可移植的,在任何SDL支持的平台上都可以运行(几乎可以在任何平台和操作系统上运行)。

注:SDL(Simple DirectMedia Layer)是一个跨平台的多媒体库,可以用来访问底层的音频、键盘、鼠标、摇杆、3D硬件(通过OpenGL)以及2D视频缓冲。它被用在MPEG播放软件、模拟器和很多流行的游戏中,包括获得大奖的Linux版的”Civilization: Call To Power”。

安装Pygame

https://www.pygame.org/wiki/GettingStarted

1
2
3
4
pip install pygame
#检验是否安装成功
python3 -m pygame.examples.aliens

导入

1
2
3
import pygame
# 引入 pygame 中的所有常量
from pygame.locals import *

模块

模块 说明
cdrom 访问光驱
cursors 加载光标图像,包含标准光标
display 控制显示窗口或屏幕
draw 在Surface上绘制简单的图形
event 管理事件和事件队列
font 创建并呈现TrueType字体
image 保存并加载图像
joystick 管理游戏手柄设备
key 管理键盘
pygame.mixer 音效
mouse 管理鼠标
pygame.movie 播放视频
pygame.music 播放音频
pygame.rect 管理矩形区域
pygame.sprite 操作移动图像
sndarray 用numpy操纵声音
surfarray 用numpy处理图像
time 控制时间
transform 缩放,旋转和翻转图像

初始化和退出

1
2
3
4
5
# 导入并初始化所有 pygame 模块,使用其他模块之前,必须先调用 init 方法
pygame.init()
# 卸载所有 pygame 模块,在游戏结束之前调用,没有必要显式的调用这个函数,因为pygame会在python退出的时候自动清理所有已经初始化的模块
pygame.quit()

窗口/suiface pygame.display

pygame.display模块用于创建、管理游戏窗口
需要先创建一个窗口。其他的活动都是基于窗口的

1
pygame.display.set_mode(resolution=(0,0),flags=0,depth=0)
  • resolution:指定屏幕的宽和高,默认创建的窗口大小和屏幕大小一致
  • flags:标志位
    • FULLSCREEN 创建一个全屏窗口
    • DOUBLEBUF 创建一个“双缓冲”窗口,建议在HWSURFACE或者OPENGL时使用
    • HWSURFACE 创建一个硬件加速的窗口,必须和FULLSCREEN同时使用
    • OPENGL 创建一个OPENGL渲染的窗口
    • RESIZABLE 创建一个可以改变大小的窗口
    • NOFRAME 创建一个没有边框的窗口
  • depth:颜色的位深,默认自动匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 指定窗口的宽和高
# 只能有一个
screen = pygame.display.set_mode((600,500))
screen = pygame.display.set_mode((1024, 768), pygame.FULLSCREEN)
# 设置窗口的标题
pygame.display.set_caption('Hello World!')
# 填充背景颜色
screen.fill((255,255,255))
# 刷新屏幕内容显示,把内容显示到屏幕上
pygame.display.update()
# 如果使用DOUBLEBUF,需要用flip函数把内容显示到屏幕上
pygame.display.flip()
# 可以查看当前设备支持的分辨率
pygame.display.list_modes()

游戏循环

如果没有循环,窗口无法保持,只能看到一闪而过

一个游戏循环(也可以称为主循环)就做下面这三件事:

  1. 处理事件
  2. 更新游戏状态
  3. 绘制游戏状态到屏幕上
1
2
while True:
pass
1
2
3
4
5
6
7
8
9
10
11
12
13
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((600,500))
pygame.display.set_caption('Hello World')
while True:
pass
pygame.quit()

坐标系

以左上角为(0,0)点,往右方向为X轴,往下方向为Y轴,单位为像素

矩形区域 pygame.Rect

pygame.Rect是用于存储直角坐标的pygame对象,在游戏中所有可见的元素都是以矩形区域来描述位置的(区别于绘制图形中的矩形)

对象

1
2
Rect(left, top, width, height)
Rect((left, top), (width, height))

前两项描述位置,后两项描述大小

属性

1
2
3
4
5
6
x,y
top, left, bottom, right
topleft, bottomleft, topright, bottomright
midtop, midleft, midbottom, midright
center, centerx, centery
size, width, height

绘制图形 pygame.draw

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pygame.draw.rect(Surface, color, Rect, width=0)
# 绘制一个矩形形状
pygame.draw.polygon(Surface, color, pointlist, width=0)
# 绘制多边形
pygame.draw.circle(Surface, color, pos, radius, width=0)
# 围绕一个点画一个圆
pygame.draw.ellipse(Surface, color, Rect, width=0)
# 在矩形内绘制圆形
pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width=1)
# 绘制一个椭圆的局部部分
pygame.draw.line(Surface, color, start_pos, end_pos, width=1)
# 画出一条直线段
pygame.draw.lines(Surface, color, closed, pointlist, width=1)
# 绘制多个连续的线段
pygame.draw.aaline(Surface, color, startpos, endpos, blend=1)
# 画精美的抗锯齿线
pygame.draw.aalines(Surface, color, closed, pointlist, blend=1)
# 绘制抗锯齿线的连接序列

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import pygame
from pygame.locals import *
from math import pi
# 定义颜色
RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
pygame.init()
screen = pygame.display.set_mode((600,600))
pygame.display.set_caption('绘制图形')
# screen.fill((255,255,255))
pygame.draw.rect(screen,BLUE,(400,400,100,100))
pygame.draw.polygon(screen,GREEN,[[400,0],[500,70],[450,100]],5)
pygame.draw.circle(screen,BLUE,[10,500],40)
pygame.draw.ellipse(screen,BLUE,(300,200,50,40))
pygame.draw.ellipse(screen,RED,(200,200,50,40),5)
pygame.draw.arc(screen,GREEN,(300,500,40,40),0,pi/2,2)
pygame.draw.arc(screen,RED,(300,500,40,40),pi/2,pi,2)
pygame.draw.arc(screen,BLUE,(300,500,40,40),pi,3*pi/2,2)
pygame.draw.arc(screen,(255,255,255),(300,500,40,40),3*pi/2,2*pi,2)
pygame.draw.line(screen,RED,[1,1],[50,50],5)
pygame.draw.lines(screen,RED,True,
[[0,80],[50,90],[200,80],[220,30]],5)
pygame.draw.aaline(screen,RED,[80,80],[40,90],True)
while 1:
pass
pygame.display.update()

字体/文本 pygame.font

pygame.font模块将文本打印到窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
pygame.font.Font(filename, size)
# filename:字体文件的文件名
# size:字体的高 height,单位为像素
pygame.font.Font.render(text, antialias, color, background=None)
# text:要显示的文字,文字只能包含一行,换行符不会被画出来
# antialias: 是否抗锯齿
# color:字体颜色
# background:背景颜色(可选参数),如果没有指定background,背景是透明的
# 返回一个surgace
pygame.font.get_fonts()
# 获取可用的字体的列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pygame
pygame.init()
screen = pygame.display.set_mode((300,300))
pygame.display.set_caption('Font')
# 1.字体对象,指定字体和大小
myfont = pygame.font.Font(None,60)
# myfont = pygame.font.Font('./font/楷体_GB2312.ttf',60)
# 2.指定文本内容,文本颜色,文本背景色
textSufaceObj = myfont.render('Hello world',True,(255,255,255),(0,255,0))
# 3.指定文本位置
screen.blit(textSufaceObj,(50,100))
while 1:
# 4.显示文本
pygame.display.update()
pygame.quit()

图像

1
2
3
4
5
6
7
8
9
img = pygame.image.load(filename)
# 加载一张图片
# 返回一个包含图像的Surface,Surface的格式和原来的文件相同(包括颜色格式、透明色和alpha透明)
pygame.Surface.blit(img, dest, area=None, special_flags = 0)
# 将图片绘制到屏幕相应坐标上(后面两个参数默认,可以不传)
pygame.image.save(img, filename)
# 把img这个Surface的内容保存为filename指定的图像文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((100,100))
pygame.display.set_caption('Image')
image = pygame.image.load('./Ball.png')
# 获得图像位置
imageRect = image.get_rect()
# 指定图片居中
imageRect.center = (50,50)
screen.fill((156,178,166))
# screen.blit(image,(50,50))
screen.blit(image,imageRect)
while 1:
pygame.display.update()
pygame.quit()

音频

背景音乐

1
pygame.mixer.music.load(filename)

filename:音频文件的文件名
该方法用来加载背景音乐,之后调用 pygame.mixer.music.play( ) 方法就可以播放背景音乐(Pygame 只允许加载一个背景音乐在同一个时刻)
音乐文件可以很大,系统以流的形式播放

1
2
3
4
5
6
7
8
9
大专栏  Pygame相关>10
11
12
13
14
15
16
pygame.init() #进行全部模块的初始化,
pygame.mixer.init() #或者只初始化音频部分
pygame.mixer.music.load('xx.mp3') #使用文件名作为参数载入音乐 ,音乐可以是ogg、mp3等格式。载入的音乐不会全部放到内容中,而是以流的形式播放的,即在播放的时候才会一点点从文件中读取。
pygame.mixer.music.play() #播放载入的音乐。该函数立即返回,音乐播放在后台进行。
#play方法还可以使用两个参数
pygame.mixer.music.play(loops=0, start=0.0) #loops和start分别代表重复的次数和开始播放的位置
pygame.mixer.music.stop() #停止播放
pygame.mixer.music.pause() #暂停播放
pygame.mixer.music.unpause() #取消暂停
pygame.mixer.music.fadeout(time) #用来进行淡出,在time毫秒的时间内音量由初始值渐变为0,最后停止播放
pygame.mixer.music.set_volume(value) #来设置播放的音量,音量value的范围为0.0到1.0
pygame.mixer.music.get_busy() #判断是否在播放音乐,返回1为正在播放
pygame.mixer.music.set_endevent(pygame.USEREVENT + 1) #在音乐播放完成时,用事件的方式通知用户程序,设置当音乐播放完成时发送
pygame.USEREVENT+1 #事件给用户程序
pygame.mixer.music.queue(filename) #使用指定下一个要播放的音乐文件,当前的音乐播放完成后自动开始播放指定的下一个。一次只能指定一个等待播放的音乐文件
1
2
3
4
5
6
7
8
9
import pygame
pygame.init()
pygame.mixer.music.load('./sound/background.mp3')
pygame.mixer.music.play()
while 1:
pass

循环播放

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pygame
pygame.init()
pygame.mixer.music.load('./sound/曲锦楠 - 霞光.mp3')
pygame.mixer.music.play()
clock = pygame.time.Clock()
while 1:
clock.tick(1)
isbusy = pygame.mixer.music.get_busy()
print(isbusy)
if isbusy == 0:
pygame.mixer.music.play()

特效声音

要在游戏中播放碰撞、爆炸、语音等音效,需要使用pygame.mixer模块。这个模块支持同时播放多个音效文件,多个文件在多个不同的通道Channel中播放,一个通道一次只能播放一个音效文件。

音效和音乐的区别是:音效要整个文件载入到Sound对象中才能播放,而音乐不用完全载入,而以流的方式播放。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
pygame.mixer.get_num_channels()
# 查看总共有多少个通道
channel = pygame.mixer.Channel(i)
# 取得第i个通道
channel = pygame.mixer.find_channel()
# 自动取得一个空闲的通道(没有音效正在播放的通道)
sound = pygame.mixer.Sound('./sound/enemy1_down.wav')
channel.play(sound)
# 在一个通道中播放一个音效
sound.play()
# 自动找一个空闲的通道播放音效
sound.stop()
# 停止音效sound的播放
channel.stop()
# 停止在通道channel中播放的音效
channel.pause()
# 暂停通道中的音效
channel.unpause()
# 暂停的音效继续播放
channel.get_busy()
# 检查通道是否正在播放音效
channel.fadeout(time)
# 淡出,在time毫秒的时间内音量由初始值渐变为0,最后停止播放
channel.queue(soundfile)
# 为正在播放音效的通道指定下一个要播放的音效。当前的音效播放完成后,下一个音效会自动播放。一个通道只能有一个等待播放的音效。
channel.set_volume(value)
# 设置通道中播放的音效的音量
sound.set_volume(value)
# 设置单个音效的音量
# 两者的取值范围都是0.0到1.0。音效播放的实际音量是通道音量和音效音量的乘积,比如通道音量0.5,音效音量0.6,则实际播放的音量为0.3

说了这么多,实际上只需要两句就足够了

1
2
sound = pygame.mixer.Sound('./sound/enemy1_down.wav')
sound.play()

视频 pygame.movie

https://stackoverflow.com/questions/37775635/pygame-movie-missing

该模块已经过时

要在游戏中播放片头动画、过场动画等视频画面,可以使用pygame.movie模块

要播放视频中的音乐,pygame.movie模块需要对音频接口的完全控制,不能初始化mixer模块。因此要这样完成初始化~~

1
2
pygame.init()
pygame.mixer.quit()

或者只初始化

1
pygame.display.init()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
movie = pygame.movie.Movie(’filename’)
# 指定文件名载入视频。视频的格式可以为mpeg1。视频文件不会马上全部载入内存,而是在播放的时候一点一点的载入内存。
movie.set_display(pygame.display.set_mode((640,480)))
# 指定播放的surface。
movie.set_volume(value)
# 指定播放的音量。音量的值value的取值范围为0.0到1.0。
movie.play()
# 播放视频。这个函数会立即返回,视频在后台播放。这个函数可以带一个参数loops,指定重复次数。
movie.stop()
# 停止播放
movie.pause()
# 暂停播放
movie.skip(seconds)
# 使视频前进seconds秒钟。
如有不懂的可以参考Pygame的官方例子,在Python安装目录下的libsite-packagespygameexamplesmovieplayer.py文件。

动画

帧率(Frame rate):每秒钟能够刷新的次数

1
2
3
4
5
pygame.time.Clock()
# 获得 pygame 的时钟对象
pygame.time.Clock.tick(FPS)
# 设置 pygame 时钟的间隔时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((100,100))
pygame.display.set_caption('Image')
image = pygame.image.load('./Ball.png')
imageRect = image.get_rect()
imageRect.center = (50,50)
# screen.blit(image,(50,50))
fps = pygame.time.Clock()
while 1:
fps.tick(10)
imageRect.x += 1
# 需要重新绘制背景
screen.fill((156,178,166))
screen.blit(image,imageRect)
# pygame.display.flip()
pygame.display.update()
pygame.quit()

事件

Pygame通过一个事件系统与用户进行交互,以及处理一些系统发生的事件。事件系统包括一个事件队列,其中每一项都是一个Event对象。所有的用户输入和一些系统事件,都会形成一个Event对象被添加到事件队列中。
Event对象有各种不同的类型,通过Event.type属性来区分。不同的类型的Event对象还有不同的其它属性。通过Event.dict属性来查看。

详细:http://www.xefan.com/archives/83586.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((600,600))
pygame.display.set_caption('Event')
while 1:
# 获取事件列表
for event in pygame.event.get():
# 点击关闭
if event.type == QUIT:
pygame.quit()
exit()
# 鼠标移动
if event.type == MOUSEMOTION:
print(event.pos)
if event.type == MOUSEBUTTONDOWN:
print('鼠标按下',event.pos)
if event.type == MOUSEBUTTONUP:
print('鼠标抬起',event.pos)
# 方向键
if event.type == KEYDOWN:
if (event.key == K_UP or event.key == K_w):
print('上')
if (event.key == K_DOWN or event.key == K_s):
print('下')
if (event.key == K_LEFT or event.key == K_a):
print('左')
if (event.key == K_RIGHT or event.key == K_d):
print('右')
if event.key == K_ESCAPE:
pygame.quit()
exit()

定时器

每隔多少时间触发一次事件
pygame中的时间是以毫秒(千分之一秒)表示的

1
2
3
4
5
6
7
8
9
10
11
# 自定义计时事件
COUNT = pygame.USEREVENT +1
# 每隔1秒发送一次自定义事件
pygame.time.set_timer(COUNT,1000)
# 获取事件
for event in pygame.event.get():
# 判断事件是否为计时事件
if event.type == COUNT:
pass

计时器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import pygame,time
from pygame.locals import *
SCREEN_RECT = pygame.Rect(0,0,700,200)
COUNT = pygame.USEREVENT+1
pygame.init()
screen = pygame.display.set_mode(SCREEN_RECT.size)
pygame.display.set_caption('time')
font = pygame.font.Font(None,60)
pygame.time.set_timer(COUNT,1000)
while 1:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
exit()
if event.type == COUNT:
now = time.ctime()
clock = now[11:19]
timeObj = font.render(clock,True,(255,255,255))
# timeObj = font.render(now,True,(255,255,255))
timeRect = timeObj.get_rect()
timeRect.center = SCREEN_RECT.center
screen.fill((0,0,0))
screen.blit(timeObj,timeRect)
pygame.display.update()

冲突

while True: # 程序主循环
for event in pygame.event.get():# 获取事件
if event.type == QUIT:# 判断事件是否为退出事件
pygame.quit()# 退出pygame
sys.exit()# 退出系统
pygame.display.update()# 绘制屏幕内容

参考:

Pygame相关的更多相关文章

  1. pygame游戏开发-简介

    转自白月黑羽Python教程:http://www.python3.vip/doc/tutorial/python/game/ 推荐对Python有兴趣的童鞋可以关注去看看,教程语言平实,简单易懂. ...

  2. Python实战练习_贪吃蛇 (pygame的初次使用)

    正如标题所写的那样,我将一步步的完成本次实战练习——贪吃蛇.废话不多说,感兴趣的伙伴可以一同挑战一下. 首先说明本次实战中我的配备: 开发环境:python 3.7: 开发工具:pycharm2019 ...

  3. Python3+Pygame实现的射击游戏,很流畅,有音效

    之前看到过很多人写的飞机大战,当然了之前我也写过多个版本,总体来说功能是实现了,但总感觉不够"炫" 今天浏览Python资料的时候,意外发现了这个很好的"射击" ...

  4. 嵌入式单片机STM32应用技术(课本)

    目录SAIU R20 1 6 第1页第1 章. 初识STM32..................................................................... ...

  5. pyinstaller相关问题 & pygame文件打包成exe文件 & 武装飞船 & 飞机大战

    自己照书写了一个飞机大战游戏的python程序,想把它打包成一个exe文件,在查阅相关教程并经过数次尝试后终于成功. 安装打包应用 pyinstaller 在cmd命令窗口下pip install p ...

  6. centos上安装pygame

    安装前依赖包检查及安装 python-devel SDL_image-devel SDL_mixer-devel SDL_ttf-devel SDL-devel numpy subversion po ...

  7. 【python游戏编程之旅】第六篇---pygame中的Sprite(精灵)模块和加载动画

    本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 直到现在我们已经学了很多pygame基础知识了,从这篇博客开始我们将会学习pygame中高级部分,更多和精灵 ...

  8. 【python游戏编程之旅】第三篇---pygame事件与设备轮询

    本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 在上一篇博客中,我们学习了pygame中的IO.数据http://www.cnblogs.com/msxh/ ...

  9. 【python游戏编程之旅】第一篇---初识pygame

    本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 一.pygame简介 Pygame 是一组用来开发游戏软件的 Python 程序模块,基于 SDL 库的基础 ...

随机推荐

  1. leetcode腾讯精选练习之最长公共前缀(九)

    最长公共前缀 题目 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower"," ...

  2. React Native 开发

    摘自:<React Native 开发之 IDE 选型和配置> 一个在不断更新的有关React Native讲解:<江清清的技术专栏> ES5和ES6的区别:<React ...

  3. Codeforces Round #517 (Div. 2)(1~n的分配)

    题:https://codeforces.com/contest/1072/problem/C 思路:首先找到最大的x,使得x*(x+1)/2 <= a+b 那么一定存在一种分割使得 a1 &l ...

  4. mysql命令行操作大全

    Mysql安装目录 数据库目录/var/lib/mysql/配置文件/usr/share/mysql(mysql.server命令及配置文件)相关命令/usr/bin(mysqladmin mysql ...

  5. XEN 3166

    XEN 3166 这题原题是spj,校oj上只用判断yes no,不过也差不多 题意分析之后就是求两个东西: 字典序最小的长度为m的子序列 同时这个字典序严格大于某个字符串 用序列自动机 先尽量相同, ...

  6. iTOP-4418开发板_重实力_优势突出_有原理图源码开源

    核心板参数 尺寸:50mm*60mm 高度:核心板连接器组合高度1.5mm PCB层数:6层PCB沉金设计 4418 CPU:ARM Cortex-A9 四核 S5P4418处理器 1.4GHz 68 ...

  7. [LC] 1048. Longest String Chain

    Given a list of words, each word consists of English lowercase letters. Let's say word1 is a predece ...

  8. springboot学习笔记:12.解决springboot打成可执行jar在linux上启动慢的问题

    有时候,当你把你的springboot项目打成可执行的jar,放在linux上启动时,发现启动超级慢: 这往往是因为springboot内置tomcat启动时实例化SecureRandom对象随机数策 ...

  9. numpy矩阵运算--矩阵乘法

    1)元素对应相乘,使用 multiply 函数或 * 运算符来实现 a = np.array([2,2,2])b = np.array([3,3,3]) c1 = a*a c1 array([4, 4 ...

  10. 【Linux_Shell 脚本编程学习笔记六、shell的数值运算】

    1.bc 命令的用法(可以整数也可以小数): bc是 UNIX下的计算器,它也可以用在命令行下面: 例: 给自变量 i 加 1 [root@docker Demo_test]# i= [root@do ...