大家好,我是西安电子科技大学的大一新生。我刚接触过编程,现在正处于学习阶段。因此,我会在学习的同时使用它 markdown 写一些笔记,然后和大家分享,但是因为时间有限,可能需要很长时间才能更新一次,一般不会带图片。
而且都是干货! 希望对大家有所帮助! 有意见可以评论或留言,有时间肯定会回复!
文章目录
- pygame:
-
- 关于 pygame:
- 导入 pygame 模块:
-
- 关于 sys 的导入:
- pygame.locals 中的常量:
- pygame 方法、模块和数据类型:
- pygame.Rect:
- pygame.Surface:
- pygame.event.Event:
- pygame.font.Font:
- pygame.time.Clock:
- 初始化 pygame:
-
- 方法 init():
- 创建游戏实例:
- 设置鼠标的可见度:
- 设置 pygame 窗口:
-
- 方法 set_mode() 和 GUI:
- 全屏游戏:
- 像素:
- Surface 对象:
- 使用函数 pygame.set_caption() 设置窗口标题:
- 设置颜色变量:
-
- RGB 颜色:
- 定义颜色常量:
- 将文本写到 pygame 窗口上:
-
- 使用字体风格化文本:
- Font对象:
- 渲染一个 Font 对象:
- 方法 render():
- 使用 Rect 属性(attribute)设置文本位置:
- 各种 Rect 属性:
- 构造函数 constructor functions:
- 用一种颜色填充整个 Surface 对象:
-
- fill() 函数:
- pygame.display.update() 函数:
- pygame 的绘图函数:
-
- 画多边形 pygame.draw.polygon() 函数:
- 绘制直线 pygame.draw.line() 函数:
- 绘制圆形 pygame.draw.circle() 函数:
- 绘制椭圆 pygame.draw.ellipse() 函数:
- 绘制矩形 pygame.draw.rect() 函数:
- 给像素着色 PixelArray 对象:
- 删除 PixelArray 对象:
- Surface 对象的 blit() 方法:
- 将 Surface 在屏幕上绘制对象:
- 事件和游戏循环:
-
- 获取事件对象和退出程序:
- pygame hello world! 创建图形示例:
- 创建动画图像:
-
- 设置变量常量:
- 常量变量用于方向:
- 设置物体结构数据:
- 游戏循环任务:
- 移动物体:
- 边缘反弹:
- 将积木绘制到窗户的新位置:
- 看物体,处理一团模糊:
- 动画图形实例:Animation:
- 碰撞检测:
-
- 同步程序的时钟:
- 关于帧:
- 检测碰撞:
- 处理事件:
-
- 处理 KEYDOWN / KEYUP 事件:
- 碰撞与按键实例:Collision Detection。
- 在屏幕上移动玩家:
-
- 移动玩家:
- 转移玩家:
- 在屏幕上画玩家:
- 处理鼠标移动事件:
- 声音和图像:
-
- 使用精灵添加图像:
- 声音和图像文件:
- 添加精灵:
- 改变精灵的大小:
- 添加声音文件:
- 切换和关闭声音:
- Sprits and Sounds 程序运行示例:
- 多文件项目 AlienInvasion:
-
- alieninvasion.py
- Settings.py
- ship.py
- alien.py
- bulle.py
- button.py
- game_stats.py
- scoreboard.py
pygame:
关于 pygame:
pygame 一组功能强大的有趣模块。
可用于图形管理、动画甚至声音,可以轻松开发复杂的游戏。
导入 pygame 模块:
import sys import pygame from pygame.locals import *
关于 sys 的导入:
通常会配合sys一起导入,sys它包含使程序退出的函数,sys.exit()。
pygame.locals 中的常量:
pygame.locals它包含一系列可能使用的常量,QUIT,K_ESCAPE。
可以直接去调用他们。
pygame 方法、模块和数据类型:
在 pygame 中,是 font 和 surface 在这些模块中,模块是 Font 和 Surface 数据类型。
pygame 程序员用小写字母表示模块名,用大写字母表示数据类型,让我们能够区分。
pygame.Rect:
Rect 对象表示矩形空间区域的位置和大小。
位置可以通过 Rect 对象的属性来确定。这些属性是表示 X 坐标和 Y 坐标的一个整数值的元组。
矩形的大小可通过 width 属性和 height 属性来确定。这些属性决定矩形的宽和高是多少个像素。
Rect 对象有一个 colliderect() 方法,用来检查矩形是否和其他 Rect 对象有碰撞。
pygame.Surface:
Surface 对象是一个带颜色的像素区域。
Surface 对象表示一个矩形图像,而 Rect 对象表示一个矩形的空间和位置。
Surface 对象有一个 blit() 方法,它可以将一个 Surface 对象绘制到另一个 Surface 对象之上。
由 pygame.display.set_mode() 函数返回的 Surface 对象是特殊的,在该 Surface 对象上绘制的任何物体都会显示到用户的屏幕上。
pygame.event.Event:
当用户提供鼠标、键盘和其他类型的输入时,pygame.event 模块会创建一个 Event 对象。
pygame.event.get() 函数返回这些 Event 对象的一个列表。
可通过查看 Event 对象的 type 属性来查看事件的类型:QUIT, KEYDOWN, KEYUP。
pygame.font.Font:
pygame.font 模块拥有一个 Font 数据类型,用于表示 pygame 中的文本字体。
传递给 pygame.font.SysFont() 函数的参数时表示字体名称的一个字符串以及表示字体大小的一个整数。
传递 None 作为字体名称以获取系统默认字体。
pygame.time.Clock:
pygame.time 模块中的 Clock 对象有助于避免程序运行得过快。
Clock 对象有一个 tick() 方法,它接收的参数表示想要游戏运行的速度时多少帧 (FPS)。
FPS 越高,游戏运行速度越快。
初始化 pygame:
# set up pygame
pygame.init()
方法 init():
在调用其他pygame函数之前都要先调用pygame.init()函数初始化。
通过创建游戏实例运行:
在文件的末尾,可以通过创建游戏的实例并调用 run_game()。
if __name__ == '__main__':
ai = my_game
ai = run_game()
设置鼠标的可见度:
pygame.mouse.set_visible(boolen)
可向其传入一个布尔值,表示鼠标是否可见。
设置 pygame 窗口:
# set up the window.
windowSurface = pygame.display.set_mode((500, 400), 0, 32)
pygame.display.set_caption('hello world!')
方法 set_mode() 和 GUI:
调用pygame中的display模块中的set_mode()方法去创建图形化用户界面(graphical user interface, GUI)。pygame模块中也有自己的模块。
去生成一个窗口,而surface 变量 windowSurface 就表示那个窗口。
向set_mode()传递一个元组,表示窗口的宽度和高度。
pygame.display.set_mode() 是个特殊函数,生成的 Surface 是个特殊的对象,能代表整个屏幕。
全屏游戏:
pygame.display.set_mode() 函数的第二个参数是可选的。
我们可以传递 pygame.FULLSCREEN 常量,使得窗口占据整个屏幕,而不是显示一个小窗口。
像素:
像素是计算机屏幕上的最小的点。
生成的窗口是以像素为单位的。
屏幕上的单个像素可以以任何颜色显示。
屏幕上的所有像素一起工作显示出你所看到的照片。
Surface 对象:
set_mode()函数返回一个 pygame.Surface 对象。
对象(object)是对拥有方法的数据类型的值的另一种叫法。
Surface 对象就表示这个窗口。
对象 == 数据 + 方法。
使用函数 pygame.set_caption() 设置窗口标题:
向其传入一个字符串表示窗口的标题。
设置颜色变量:
# set up the color.
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
RGB 颜色:
光主要有三种颜色:红、绿、蓝。通过这三种颜色可以组合出任意颜色。
在 python 中,颜色数据就是3个整数的元组,叫RGB颜色。
第一个值代表有多少红色,0表示没用红色,255代表红色达到了最大值。
第二个值表示绿色,第三值表示蓝色。
定义颜色常量:
由于我们不希望每次都要在程序中用一个具体的颜色时都要重新编写3个整数的元组。
所有我们可以创建一系列颜色常量。
| Black | (0, 0, 0) |
| Blue | (0, 0, 255) |
| Gray | (128, 128, 128) |
| Green | (0, 255, 0) |
| Lime | (0, 128, 0) |
| Purple | (128, 0, 128) |
| Red | (255, 0, 0) |
| Teal | (0, 128, 128) |
| White | (255, 255, 255) |
| Yellow | (255, 255, 0) |
将文本写到 pygame 窗口上:
# set up the fonts.
basicFont = pygame.font.SysFont(None, 48)
# set up the text.
text = basicFont.render('hello world!', True, White, Blue)
# set up the location.
textRect = text.get_rect()
textRect.centerx = windowSurface.get_rect().centerx
textRect.centery = windowSurface.get_rect().centery
使用字体来样式化文本:
字体是有统一风格绘制的一整套字母,文字,数字,符号和字符。
python 程序不能修改字体,但是 pygame 可以以任何字体来绘制文本。
Font对象:
使用两个参数来调用 pygame.font.SysFont() 函数创建一个 pygame.font.Font对象。
-
第一个参数是字体的名称,传递 None 表示使用系统默认字体。
-
第二个参数是字体的大小(以点为单位)。
将字符串 ‘hello world!‘ 绘制到窗口上形成一幅图像,叫做渲染(rendering)。
渲染一个 Font 对象:
储存在变量 basicFont 中的 Font 对象有一个叫做 render() 的方法。
这个方法将返回一个 Surface 对象,文本就绘制其上。
方法 render():
方法 render() 有多个参数:
-
第一个参数表示要绘制的文本字符串。
-
第二个参数指定是否想要抗锯齿的一个 Boolean 值,为文本抗锯齿,会使文本看起来更平滑些。
-
第三个参数和第四个参数都是一个 RGB 元组。
-
第三个参数是文本的颜色,第四个参数是文本背后的背景颜色。
我们将这个 Font 对象赋值给 text 。
使用 Rect 属性(attribute)设置文本位置:
一旦设置了 Font 对象,需要将其放置到窗口的一个位置上。
pygame.Rect 数据类型表示特定大小和位置的矩形区域。我们使用它来设置窗口中对象的位置。
各种 Rect 属性:
使用函数 get_rect() 获取某一个 Font 对象的 Rect 属性。
Rect 数据类型有多个属性:.centerx centery。
我们需要访问这些属性,并为这些属性赋值。
| pygame.Rect 属性 | 描述 |
|---|---|
| myRect.centerx | 矩形的中央的X坐标的整数值 |
| myRect.centery | 矩形的中央的Y坐标的整数值 |
| myRect.left | 矩形的左边的X坐标的整数值 |
| myRect.right | 矩形的右边的X坐标的整数值 |
| myRect.top | 矩形的顶部的Y坐标的整数值 |
| myRect.bottom | 矩形的底部的Y坐标的整数值 |
| myRect.width | 矩形宽度的整数值 |
| myRect.height | 矩形高度的整数值 |
| myRect.size | 两个整数的一个元组:(width, height) |
| myRect.topleft | 两个整数的一个元组:(left, top) |
| myRect.topright | 两个整数的一个元组:(right, top) |
| myRect.bottomleft | 两个整数的一个元组:(left, bottom) |
| myRect.bottomright | 两个整数的一个元组:(right, bottom) |
| myRect.midleft | 两个整数的一个元组:(left, centery) |
| myRect.midright | 两个整数的一个元组:(right, centery) |
| myRect.midtop | 两个整数的一个元组:(centery, top) |
| myRect.midbottom | 两个整数的一个元组:(centery, bottom) |
构造函数 constructor functions:
pygame.Rect() 函数和 pygame.Rect 数据类型的名称相同。
与其数据类型的名称形同并且创建其数据类型的对象或值的函数,叫做构造函数。
用一种颜色填充整个 Surface 对象:
pygame 的初始化背景是一个黑框框。
# Draw the white background onto the surface.
windowSurface.fill(White)
fill() 函数:
fill() 函数会使用一种颜色来填充整个窗口屏幕。
pygame.display.update() 函数:
当调用 fill() 或是其他函数时,屏幕上的窗口不会改变。
但是他们会改变 Surface 对象。
需要调用 pygame.display.update() 函数来更新画面。
因为计算机内存中修改 Surface 对象比在屏幕上修改图像要快很多。
pygame 的绘图函数:
在 pygame 中,每一种图形都有自己的函数,可以将这些形状组合到不同的照片中,以便于图形化游戏。
绘制一个多边形 pygame.draw.polygon() 函数:
pygame.draw.polygon() 函数可以绘制指定的任意多边形。
多边形是由多条直线边组成的形状,圆和椭圆不是多边形。
# Draw a green polygon onto the surface.
pygame.draw.polyon(windowSurface, Green, ((146, 0), (291, 106), (56, 277)
(236, 277), (0, 106)))
该函数的参数是:
-
要在其上绘制多边形的 Surface 对象。
-
多边形的颜色。
-
由要依次绘制的点的XY坐标的元组的元组所构成的一个元组。最后一个元组将自动连接到第一个元组的点。
-
可选项:表示多边形的线条宽度的整数值。如果没有这个选项,多边形将会填充。
绘制直线 pygame.draw.line() 函数:
从屏幕上一点到另一点绘制一条直线:
# Draw some blue line onto the surface.
pygame.draw.line(windowSurface, Blue, (60, 60), (120, 60), 4)
pygame.draw.line(windowSurface, Blue, (120, 60), (60, 120))
pygame.draw.line(windowSurface, Blue, (60, 120), (120, 120), 4)
pygame.draw.line() 函数的参数依次是:
-
要在其上绘制直线的 Surface 对象。
-
直线的颜色。
-
直线起点和终点分别的 XY 元组。
-
可选项: 直线宽度的整数值。
绘制圆形 pygame.draw.circle() 函数:
# Draw a blue circle onto the surface.
pygame.draw.circle(windowSurface, Blue, (300, 50), 20, 0)
pygame.draw.circle() 函数的参数依次是:
-
要在其上绘制圆的 Surface 对象。
-
圆的颜色。
-
表示圆心的 XY 坐标的两个整数的元组。
-
表示圆的半径(大小)的整数值。
-
可选项:线条宽度的整数值。宽度为0,表示填充圆。
绘制椭圆 pygame.draw.ellipse() 函数:
通过传入椭圆的外接矩形绘制:
# Draw a red ellipse onto the surface.
pygame.draw.ellipse(windowSurface, Red, (300, 250, 40, 80), 1)
pygame.draw.ellipse() 函数的参数依次是:
-
要在其上绘制椭圆的 Surface 对象。
-
椭圆的颜色。
-
传递分别表示椭圆左上角的 X 和 Y 坐标以及椭圆的宽和高的4个整数的一个元组。
-
可选项:表示线条宽度的整数值。宽度为0表示填充椭圆。
绘制矩形 pygame.draw.rect() 函数:
# Draw the text's background rectangle onto the surface.
pygame.draw.rect(windowSurface, Red, (textRect.left - 20, textRect.top - 20
text.Rect.width + 40, textRect.height + 40))
pygame.draw.rect() 函数的参数依次是:
-
要在其上绘制矩形的 Surface 对象。
-
矩形的颜色。
-
包含了矩形的左上角的 X 和 Y 的坐标,以及矩形的宽和高的四个整数的一个元组。也可以给第三个对象传递一个 Rect 对象,而不是 四个整数。
给像素着色 PixelArray 对象:
为单独像素设定颜色。
创建一个 pygame.PixelArray 对象,是颜色元组的列表的一个列表,这些颜色元组传递给它的 Surface 对象。
PinxArray 对象能让我们进行跟高的像素级别的控制,因此,如果需要在屏幕上绘制非常详细或是定制化图像,而不是较大的图形是,可以选择 PixelArray 对象。
# Get a pixel array of the surface.
pixArray = pygame.PixelArray(windowSurface)
pixArray[480][380] = Black
使用 PixArray 对象让屏幕上的一个像素点变成黑色。
需要把 Surface 对象作为参数传递给 pygame.PixelArray() 函数调用。
PixelArray 对象的第一个索引是 X 的坐标,第二个索引是 Y 的坐标。
删除 PixelArray 对象:
从一个 Surface 对象创建一个 PixelArray 对象,将会锁定这个 Surface 对象。
锁定意味着该 Surface 对象不能调用 blit() 函数。
要解锁这个 Surface 对象,必须用 del 操作符删除 PixelArray 对象。
del pixelArray
如果忘记删除 PixelArray 对象,就会产生异常。
pygame.error : Surfaces must not be locked during blit.
Surface 对象的 blit() 方法:
blit() 方法是将一个 Surface 对象的内容绘制到另一个 Surface 对象之上。
render() 方法所创建的所有文本对象,都存在于其自己的 Surface 对象上,我们的文本储存在 text 变量中而不是绘制到 windowSurface 上。为了将 text 绘制到我们想要让其出现的 Surface 上,必须使用 blit() 方法:
# Draw the text onto the surface.
windowSurface.blit(text, textRect)
blit() 方法的两个参数:
-
第一个参数是要加入在其上的 Surface 对象。
-
第二个参数指定了应该将 text surface 绘制到 windowSurface 上的何处。
text 的Rect 对象通过调用 text.get_rect() 获取。
将 Surface 对象绘制到屏幕上:
在调用 pygame.display.update() 函数之前,并不会真的将任何内容绘制到屏幕上。
# Draw the window onto the screen.
pygame.display.update()
为了节省内存,我们并不想在每次调用了绘图函数之和都更新到屏幕上。
只有在所有绘制函数都调用完后,才想要一次性更新屏幕。
事件和游戏循环:
pygame 程序会不断地运行叫做游戏循环 ( game loop ) 的一个循环。在这个程序中,游戏循环的所有代码行每秒钟都会执行一百次左右。
游戏循环是不断的查看新事件、更新窗口的状态并在屏幕上绘制窗口的一个循环。
任何时候,当用户按下一个按键、点击或移动鼠标或使得其他一些事件发生的时候,pygame 都会创建该对象。
获取事件对象和退出程序:
事件 ( event ) 是 pygame.event.Event 数据类型的对象。
调用 pygame.event.get() 函数检索自从上次调用 pygame.event.get() 后所生成的任何新的 pygame.event.Event 对象。这些事件会以 Event 对象的一个列表的形式返回。
所有的 Event 对象都有一个叫做 type 的属性,它会告诉我们事件是什么类型。
# Run the game loop.
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
使用一个 for 循环遍历了 pygame.event.get() 所返回的列表中的每一个 Event 对象,如果事件的 type 属性等于常量 QUIT,那么我们就知道了产生了 QUIT 事件。
当用户关闭程序窗口,或者当计算机关闭并尝试终止所有运行程序的时候,pygame 模块会产生 QUIT 事件。
pygame.quit() 函数时和 pygame.init() 函数相对的一种函数。在退出函数之前,需要调用它。
pygame hello world! 创建图形示例:
import pygame, sys
from pygame.locals import *
# Set up pygame.
pygame.init()
# Set up the window.
windowSurface = pygame.display.set_mode((500, 400), 0, 32)
pygame.display.set_caption('Hello world!')
# Set up the colors.
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# Set up fonts.
basicFont = pygame.font.SysFont(None, 48)
# Set up the text.
text = basicFont.render('Hello world!', True, WHITE, BLUE)
textRect = text.get_rect()
textRect.centerx = windowSurface.get_rect().centerx
textRect.centery = windowSurface.get_rect().centery
# Draw the white background onto the surface.
windowSurface.fill(WHITE)
# Draw a green polygon onto the surface.
pygame.draw.polygon(windowSurface, GREEN, ((146, 0), (291, 106), (236, 277), (56, 277), (0, 106)))
# Draw some blue lines onto the surface.
pygame.draw.line(windowSurface, BLUE, (60, 60), (120, 60), 4)
pygame.draw.line(windowSurface, BLUE, (120, 60), (60, 120))
pygame.draw.line(windowSurface, BLUE, (60, 120), (120, 120), 4)
# draw a blue circle onto the surface.
pygame.draw.circle(windowSurface, BLUE, (300, 50), 20, 0)
# Draw a red ellipse onto the surface.
pygame.draw.ellipse(windowSurface, RED, (300, 250, 40, 80), 1)
# Draw the text's background rectangle onto the surface.
pygame.draw.rect(windowSurface, RED, (textRect.left - 20, textRect.top - 20, textRect.width + 40, textRect.height + 40))
# Get a pixel array of the surface.
pixArray = pygame.PixelArray(windowSurface)
pixArray[480][380] = BLACK
del pixArray
# Draw the text onto the surface.
windowSurface.blit(text, textRect)
# Draw the window onto the screen.
pygame.display.update()
# Run the game loop.
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
创建动画图像:
为了让物体有动画效果,我们将在游戏循环的每一次迭代中,让这些物体移动一些像素,这会使得物体看上去像是在屏幕上移动一样。
-
通过游戏循环,实现物体动画。
-
改变一个物体的运动方向。
设置变量常量:
# Set up the window.
WINDOWWIDTH = 400
WINDOWHEIGHT = 400
pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Animation')
为窗口的高度和宽度设置常量变量。
用于方向的常量变量:
# Set up the direction variables.
DOWNLEFT = 'downleft'
DOWNRIGTH = 'downright'
UPLEFT = 'upleft'
UPRIGHT = 'upright'
# Set up the moving speed.
MOVESPEED = 4
我们也可以不使用常量,而使用任何想要的值来表示这些方向。
设置移动速度:告诉程序,每一次迭代中每个物体应该移动多少像素。
设置物体结构数据:
要定义积木:创建一个字典来表示每个移动的积木的数据结构。
这个字典有 ‘rect’ 键、‘color’ 键和 ‘dir’ 键,分别控制 物体的 位置形状、颜色和移动方向。
# Set up the box data structure.
b1 = {
'rect':pygame.Rect(300, 80, 50, 100), 'color':RED, 'dir':UPRIGHT}
b2 = {
'rect':pygame.Rect(200, 200, 20, 20), 'color':GREEN, 'dir':UPLEFT}
b3 = {
'rect':pygame.Rect(100, 150, 60, 60), 'color':BLUE, 'dir':DOWNLEFT}
boxes = [b1, b2, b3]
需要从列表中访问一个值,可以通过索引和键值,及两层方括号来进行。
游戏循环的任务:
游戏循环负责实现物体移动的动画:
- 绘制一系列不同的图像,这些图像一个接一个的显示。
- 在每一个图像中,积木都会移动4个像素位置。
- 图像显示的如此之快,以至于积木看上去就像是在屏幕上平滑的移动。
游戏循环的每一次迭代,代码都会重新绘制整个窗口,使得新的积木位置随时间而改变几个像素。
它会重新绘制一个 Rect 而不会擦去旧的 Rect 绘制,如果我们只是让游戏循环不断的在屏幕上绘制 Rect 对象,最终将会得到一条 Rect 对象的一条轨迹,而不是一个平滑的动画。
为了避免这种情况,在游戏循环的每一次迭代中,我们都需要清除窗口。
# Draw the white background onto the surface.
windowSurface.fill(White)
在屏幕表面绘制一层白色去覆盖原本的绘制图案。
移动物体:
为了更新每一个物体,我们需要在游戏循环中加入遍历每一个列表:
-
我们需要根据每个物体已经移动的方向来修改每个积木,以便使用 if 语句来检查物体数据结构的 dir 键,从而判断积木的移动方向。
-
然后,我们将根据积木在该方向上的移动来修改积木的位置。
for b in boxes: # Move the box data structure. if b['dir'] == DOWNLEFT: b['rect'].left -= MOVESPEED b['rect'].top += MOVESPEED if b['dir'] == DOWNRIGHT: b[