最近正在利用 Python 制作一个小游戏,但对于 Pygame 不熟悉,故在学习的过程记录相关知识点

Pygame 中文文档下载:Here

Pygame 2.0 (中文) 在线:Here 感谢 龙桑 提供

Pygame第1-1课:入门

什么是Pygame?

Pygame是一个“游戏开发库” - 一组帮助程序员制作游戏的代码库。包含:

  • 图形和动画
  • 声音(包括音乐)
  • 控制(键盘,鼠标,游戏手柄等)

Pygame安装

  • pip 安装

pip install pygame

如果下载缓慢或者下载失败了的话建议切换pip源到国内镜像,如何更换?

  • PyCharm 安装

第一步:打开Pycharm

第二步:点File ->Default Settings->Project Interpreter->点加号

第三步: 搜索Pygame->Install Package

Pygame游戏结构框架

每个游戏的核心都是一个循环,将其称为“游戏循环”。这个循环一直在不断运行,一遍又一遍地完成游戏工作所需的所有事情。每次循环显示一次游戏当前画面,称为帧。

Pygame游戏循环,主要处理3件事情

1.处理外部输入(鼠标点击或键盘按下事件)

这意味着游戏在进行的同时,需要响应与处理用户的操作—这些可能是键盘上的键被按下,或鼠标被点击等事件。

2.更新游戏对象位置或状态

如果飞机对象在空中飞行,收到重力作用,自身的位置需要改变。如果两个对象相互碰撞,则需要爆炸。

3.渲染

此步骤中,在屏幕上重新绘制所有更新位置后的所有游戏对象。

Pygame时钟

游戏循环的另一个重要方面是控制整个循环的运行速度。游戏中有个术语叫FPS(Frames Per Second),它代表每秒帧数,也叫帧率。这意味着游戏循环每秒应发生多少次。这很重要,因为我们不希望游戏运行得太快或太慢。也不希望它在不同的计算机上以不同的速度运行 。

构建Pygame游戏程序骨架

现在,制作一个简单的pygame程序,功能是除了打开一个窗口并运行游戏循环之外什么都不做。

在程序的开始部分,我们导入需要的库并为游戏设置一些变量:

import pygame
import randomWIDTH = 360  # 游戏窗口的宽度
HEIGHT = 480 # 游戏窗口的高度
FPS = 30 # 帧率

接下来,创建游戏窗口:

# initialize pygame and create window
pygame.init()
pygame.mixer.init()  #声音初始化
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Game")#设置游戏窗口标题栏文字
clock = pygame.time.Clock()

pygame.init()是启动pygame,并“初始化”它的命令。 screen指的是游戏屏幕,按照在配置常量中设置的窗口大小创建它。最后,创建了一个,clock时钟对象,以便能够确保游戏以想要的FPS运行。

让游戏循环:

# Game Loop
running = True
while running:# Process input (events)# Update# # Draw / Render

这是游戏循环,它是由变量running控制的循环。如果希望游戏结束,只需要设置running为False,循环就会结束。接下来用一些基本代码填写每个部分。

渲染/绘制部分

我们将从Draw部分开始。目前还没有任何游戏对象,用纯色填充屏幕。

图像由像素组成,这些像素有3个部分:红色,绿色和蓝色。每个部分点亮多少会决定像素的颜色,如下所示:

三原色中的每一个可以具有介于0和255之间的值,因此对于三种基色中的每一种,存在256种不同的可能性。以下是一些三种颜色的组合示例:

在程序的顶部定义一些颜色:

# Colors (R, G, B)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

在绘图部分用黑色填满屏幕。

# Draw / render
screen.fill(BLACK)

这样还不够。更改屏幕上的像素意味着告诉视频卡告诉显示器更改实际像素。从计算机的角度来看,这是一个非常非常缓慢的过程。因此,如果你在屏幕上绘制了很多东西,那么绘制它们可能需要很长时间。处理能力差的计算机表现为游戏运行卡顿。

我们可以通过使用称为双缓冲的技术,以巧妙的方式解决这个问题。

想象一下,有一个双面白板,可以翻转显示一侧或另一侧。前面是显示器(玩家看到的屏幕),而背面是隐藏的,只有计算机可以“看到”它。每一帧,都在背面(内存中)绘制所有图画 - 每个角色,每个子弹,每个闪耀的光线等等。然后,当完成后,将白板翻转并显示。这意味着每帧只是执行一次白板翻转的过程。

所有这些都在pygame中自动发生。完成绘图后,只需要告诉它翻转白板。命令为flip():

# Draw / render
screen.fill(BLACK)
# *after* drawing everything, flip the display
pygame.display.flip()

处理游戏过程中发生的事件

如果现在尝试运行该程序,我们会发现遇到了问题:无法关闭窗口!单击屏幕右上角中的“X”按钮不起作用。那是因为当用户点击关闭按钮时产生了一个事件,我们需要程序监听该事件,并做出相应处理—退出游戏。

Pygame内部保存自上一帧以来发生的所有事件。可以通过下面的代码检查发生了哪些事件

for event in pygame.event.get():# check for closing windowif event.type == pygame.QUIT:running = False

Pygame有很多事件。 pygame.QUIT是单击“X”按钮时发生的事件。程序检查到该事件发生后,将running变量设置成False,从而推出游戏循环,结束游戏。

输出文本

pygame支持使用pygame.font对象将文本打印到窗口上。要打印文本的话,首先需要创建一个字体对象,Font的第一个参数为None是告诉pygame获得系统默认字体,也可以是具体的字体名称。Font的第二个参数指明字体大小。

myfont = pygame.font.Font(None,60)

文本绘制过程比较耗费时间,常用的做法是先在内存中创建文本图像,然后将文本当作一个图像来渲染。

textImage = myfont.render("pygame", True, WHITE)

textImage 对象可以使用screen.blit()来绘制。上面代码中的render函数第一个参数是要绘制的文本,第二个参数是启用抗锯齿能力,第三个参数是文本的颜色。

下面的代码,将刚刚产生文本图像绘制到屏幕的坐标(10,100)处。

screen.fill(BLACK)
screen.blit(textImage, (10,100))
pygame.display.flip()

控制FPS

虽然现在还没有任何东西要放在“更新”部分,但仍然需要设置FPS来控制游戏运行速度。可以这样做:

while running:# keep loop running at the right speedclock.tick(FPS)

该tick()命令告诉pygame一秒循环多少次。如果设置FPS为20,这意味着我们命令游戏的每个循环持续1 / 20(0.05)秒。如果循环代码(更新,绘图等)只需要0.03秒,那么pygame将等待0.02秒。以上是计算机处理比较快的情况。如果电脑比较差,运行缓慢,一秒钟未必能执行20次循环— 那么clock.tick(20)就成为一个指导意见。

在屏幕上显示出FPS

首先,在while循环之前定义2个变量

count = 0
start = time.time()

每次循环计算出当前的FPS并显示

计算方法为:循环开始前获得当前系统时间,在每次循环中,累加循环次数count;同时在每次循环时,获得当前系统时间,那么从开始循环到目前为止流逝的时间(时间差)为:now-start。再用count除以这个时间差,即为FPS(每秒循环了多少次)。代码如下:

# Update
count+=1
now = time.time()
fps = count/(now-start)
fpsImage = myfont.render(str(fps), True, WHITE)
# Draw / render
screen.fill(BLACK)
screen.blit(fpsImage, (10, 100))
# *after* drawing everything, flip the display
pygame.display.flip()

我们可以修改FPS的值,看看是否界面上输出的值会跟着变化

FPS = 10
FPS = 100
FPS = 1000
FPS = 10000

我的电脑,将FPS设置成10000时,发现屏幕上打印的是2000,说明,我的电脑配置最多可以支持到1秒中运行循环中的代码2000次。

最后,为了确保当游戏循环结束时,游戏窗口正确退出。我们通过将代码pygame.quit()的放到最后一行来实现这一点。

整合到一起

最终代码如下所示:

# Pygame template - skeleton for a new pygame project
import time
import pygame
import randomWIDTH = 360
HEIGHT = 480
FPS = 30# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)# initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Game")
clock = pygame.time.Clock()myfont = pygame.font.Font(None,60)
textImage = myfont.render("pygame", True, WHITE)
# Game loop
running = True
count = 0
start = time.time()while running:# keep loop running at the right speedclock.tick(FPS)# Process input (events)for event in pygame.event.get():# check for closing windowif event.type == pygame.QUIT:running = False# Updatecount+=1now = time.time()fps = count/(now-start)fpsImage = myfont.render(str(fps), True, WHITE)# Draw / renderscreen.fill(BLACK)screen.blit(fpsImage, (10, 100))# *after* drawing everything, flip the displaypygame.display.flip()pygame.quit()

Pygame第1-2课:使用精灵

什么是精灵?

当您玩任何2D游戏时,您在屏幕上看到的所有对象都是精灵。精灵可以是动画的,它们可以由玩家控制,甚至可以互相交互。

将在游戏循环的UPDATE和DRAW部分更新和绘制精灵。你可以想象,如果你的游戏中有大量的精灵,那么游戏循环的这些部分可能会变得非常冗长和复杂。幸运的是,Pygame有一个很好的解决方案:精灵组。

精灵组只是精灵的集合,您可以同时对所有精灵进行操作。让创建一个sprite组来保存游戏中的所有精灵:

 clock = pygame.time.Clock()all_sprites = pygame.sprite.Group()

现在可以通过在循环中添加以下内容来利用该组:

# Update
all_sprites.update()# Draw / render
screen.fill(BLACK)
all_sprites.draw(screen)

现在,对于创建的每个精灵,只需确保将它添加到all_sprites组中,它将自动在屏幕上绘制,并在每次循环时更新。

创建一个精灵

现在准备好制作第一个精灵了。在Pygame中,精灵是对象。
首先定义新精灵:

class Player(pygame.sprite.Sprite):

class告诉Python正在定义一个新对象,它将成为玩家精灵,它的父类型是pygame.sprite.Sprite,这意味着它将基于Pygame的预定义Sprite类。

在class Player定义中需要的第一个函数是特殊__init__()函数,它定义了在创建此类型的新对象时,需要初始化的一些属性。每个Pygame精灵都必须拥有两个属性: image和 rect:

class Player(pygame.sprite.Sprite):def __init__(self):pygame.sprite.Sprite.__init__(self)self.image = pygame.Surface((50, 50))self.image.fill(GREEN)self.rect = self.image.get_rect()

第一行pygame.sprite.Sprite.init(self)是Pygame所必需的 - 它运行内置Sprite类初始化程序。接下来,定义image属性 - 在这种情况下,只是创建一个简单的50 x 50正方形并用颜色填充它GREEN。稍后将学习如何让精灵image变得更加漂亮,比如角色或宇宙飞船,但现在一个稳固的方块已经足够好了。

接下来,必须定义精灵rect,它是“矩形”的缩写。在Pygame中使用矩形来跟踪对象的坐标。该get_rect()命令只是查看image并计算将它包围它的矩形。

可以使用rect它将精灵放在想要的任何地方在屏幕上。让从中心开始:

class Player(pygame.sprite.Sprite):def __init__(self):pygame.sprite.Sprite.__init__(self)self.image = pygame.Surface((50, 50))self.image.fill(GREEN)self.rect = self.image.get_rect()self.rect.center = (WIDTH / 2, HEIGHT / 2)

现在已经定义了Player精灵,需要通过创建一个Player类的实例来“生成”(意思是创建)它。还需要确保将精灵添加到all_sprites组中:

all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)

现在,如果你运行你的程序,你会看到屏幕中央的绿色方块。来吧,增加WIDTH和HEIGHT设置,这样你将有足够的窗口空间,使得精灵在接下来的步骤中移动。

精灵运动

请记住,在游戏循环中,有all_sprites.update()。这意味着对于组中的每个sprite,Pygame将查找一个update()函数并运行它。所以为了让精灵移动,只需要定义它的更新规则(定义update函数):

class Player(pygame.sprite.Sprite):def __init__(self):pygame.sprite.Sprite.__init__(self)self.image = pygame.Surface((50, 50))self.image.fill(GREEN)self.rect = self.image.get_rect()self.rect.center = (WIDTH / 2, HEIGHT / 2)def update(self):self.rect.x += 5

这意味着每次循环时,都会将精灵的x坐标增加5个像素。继续运行它,你会看到精灵向屏幕右侧移动,但是会移出窗口:

让通过使精灵环绕来解决这个问题 - 只要它到达屏幕的右侧,就会将它移到左侧。看一下矩形rect的结构:

因此,如果rect屏幕的左边缘离开屏幕,会将右边缘设置为0:

class Player(pygame.sprite.Sprite):def __init__(self):pygame.sprite.Sprite.__init__(self)self.image = pygame.Surface((50, 50))self.image.fill(GREEN)self.rect = self.image.get_rect()self.rect.center = (WIDTH / 2, HEIGHT / 2)def update(self):self.rect.x += 5if self.rect.left > WIDTH:self.rect.right = 0

现在可以看到精灵会一直在屏幕上滚动:

整合到一起

# Pygame sprite Example
import pygame
import randomWIDTH = 800
HEIGHT = 600
FPS = 30# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)class Player(pygame.sprite.Sprite):# sprite for the Playerdef __init__(self):# this line is required to properly create the spritepygame.sprite.Sprite.__init__(self)# create a plain rectangle for the sprite imageself.image = pygame.Surface((50, 50))self.image.fill(GREEN)# find the rectangle that encloses the imageself.rect = self.image.get_rect()# center the sprite on the screenself.rect.center = (WIDTH / 2, HEIGHT / 2)def update(self):# any code here will happen every time the game loop updatesself.rect.x += 5if self.rect.left > WIDTH:self.rect.right = 0# initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Sprite Example")
clock = pygame.time.Clock()all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
# Game loop
running = True
while running:# keep loop running at the right speedclock.tick(FPS)# Process input (events)for event in pygame.event.get():# check for closing windowif event.type == pygame.QUIT:running = False# Updateall_sprites.update()# Draw / renderscreen.fill(BLACK)all_sprites.draw(screen)# *after* drawing everything, flip the displaypygame.display.flip()pygame.quit()

Pygame第1-3课:图片精灵

转向图形精灵

彩色矩形很好 - 它们是一个好的开始,并确保你的游戏基本工作,但迟早你会想要为你的精灵使用一个很酷的宇宙飞船图像或角色。这引出了第一个问题:在哪里获得游戏资源。

获得图片资源

当你需要为你的游戏添加图片资源时,你有3个选择:

  1. 自己制作
  2. 找一位美工为你制作
  3. 使用互联网上已有的图片资源

在本课中,将使用图像“p1_jump.png”:

管理游戏资源

首先,需要一个文件夹img来保存游戏资源,然后将图像放入其中。

要在游戏中使用此图像,需要让Pygame加载图片文件,这意味着需要程序知道文件的位置。根据使用的计算机类型,这可能会有所不同,希望能够在任何计算机上运行程序,因此需要导入一个名为os的Python库。

 import pygameimport randomimport os# set up asset foldersgame_folder = os.path.dirname(__file__)

特殊的Python变量__file__指的是当前代码文件所在的文件夹,函数os.path.dirname会获得该文件夹的路径。例如

/Users/chris/Documents/gamedev/tutorials/1-3 sprite example.py

如果使用的是Windows,路径可能如下所示:

C:\Users\chris\Documents\python\game.py

不同的操作系统使用不同的方式来描述计算机上的位置。通过使用os.path命令,可以让计算机找出正确的路径。

 import pygameimport randomimport os# set up asset foldersgame_folder = os.path.dirname(__file__)img_folder = os.path.join(game_folder, 'img')player_img = pygame.image.load(os.path.join(img_folder, 'p1_jump.png')).convert()

现在已经加载了图像,pygame.image.load()并且已经确保使用convert(),这将通过将图像转换为在屏幕上绘制更快的格式来加速Pygame的绘制。现在准备用精美的玩家图片形象替换精灵中的普通绿色方块:

class Player(pygame.sprite.Sprite):def __init__(self):pygame.sprite.Sprite.__init__(self)self.image = player_imgself.rect = self.image.get_rect()self.rect.center = (WIDTH / 2, HEIGHT / 2)

请注意,已经删除了命令self.image.fill(GREEN)- 不再需要填充纯色。

现在,如果你运行该程序,你应该看到一个漂亮的小卡通外星人在屏幕上运行。但是遇到了一个问题:
目前无法看到,因为背景目前是黑色的。
用screen.fill(BLUE)将背景改为蓝色。现在可以看到问题:

当您在计算机上有图像文件时,该文件始终是矩形像素网格。无论你绘制什么样的形状,仍然会有像素边框填充图像的“背景”。需要做的是告诉Pygame忽略不关心的图像中的像素。在此图像中,这些像素恰好是黑色,因此可以添加以下内容:

class Player(pygame.sprite.Sprite):def __init__(self):pygame.sprite.Sprite.__init__(self)self.image = player_imgself.image.set_colorkey(BLACK)self.rect = self.image.get_rect()self.rect.center = (WIDTH / 2, HEIGHT / 2)

set_colorkey()只是告诉Pygame,当绘制图像时,要忽略指定颜色的任何像素。现在图像看起来好多了:

整合到一起

# Pygame sprite Example
import pygame
import random
import osWIDTH = 800
HEIGHT = 600
FPS = 30# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)# set up assets folders
# Windows: "C:\Users\chris\Documents\img"
# Mac: "/Users/chris/Documents/img"
game_folder = os.path.dirname(__file__)
img_folder = os.path.join(game_folder, "img")class Player(pygame.sprite.Sprite):# sprite for the Playerdef __init__(self):pygame.sprite.Sprite.__init__(self)self.image = pygame.image.load(os.path.join(img_folder, "p1_jump.png")).convert()self.image.set_colorkey(BLACK)self.rect = self.image.get_rect()self.rect.center = (WIDTH / 2, HEIGHT / 2)self.y_speed = 5def update(self):self.rect.x += 5self.rect.y += self.y_speedif self.rect.bottom > HEIGHT - 200:self.y_speed = -5if self.rect.top < 200:self.y_speed = 5if self.rect.left > WIDTH:self.rect.right = 0# initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Game")
clock = pygame.time.Clock()all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
# Game loop
running = True
while running:# keep loop running at the right speedclock.tick(FPS)# Process input (events)for event in pygame.event.get():# check for closing windowif event.type == pygame.QUIT:running = False# Updateall_sprites.update()# Draw / renderscreen.fill(BLUE)all_sprites.draw(screen)# *after* drawing everything, flip the displaypygame.display.flip()pygame.quit()

The desire of his soul is the prophecy of his fate

你灵魂的欲望,是你命运的先知。

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你

关注我的微信公众号【伤心的辣条】免费获取~

送上一句话:

世界的模样取决于你凝视它的目光,自己的价值取决于你的追求和心态,一切美好的愿望,不在等待中拥有,而是在奋斗中争取。

我的学习交流群:902061117 群里有技术大牛一起交流分享~

如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!

好文推荐:

转行面试,跳槽面试,软件测试人员都必须知道的这几种面试技巧!

测试岗反复跳槽,跳着跳着就跳没了…

软件测试人员该学习 Python 的七个理由

App公共测试用例梳理

面试经:一线城市搬砖!又面软件测试岗,5000就知足了…

35岁之后软件测试工程师靠什么养家?我能继续做测试!

Pygame 入门基本指南相关推荐

  1. 《Python和Pygame游戏开发指南》——2.16 pygame.display.update()函数

    本节书摘来自异步社区<Python和Pygame游戏开发指南>一书中的第2章,第2.16节,作者[美]Al Sweigart(斯维加特), 李强 译,更多章节内容可以访问云栖社区" ...

  2. 《Python和Pygame游戏开发指南》——1.12 图书中的文本折行

    本节书摘来自异步社区<Python和Pygame游戏开发指南>一书中的第1章,第1.12节,作者[美]Al Sweigart(斯维加特), 李强 译,更多章节内容可以访问云栖社区" ...

  3. python入门必备指南-致Python初学者 Anaconda入门使用指南完整版

    打算学习 Python 来做数据分析的你,是不是在开始时就遇到各种麻烦呢? 到底该装 Python2 呢还是 Python3 ? 为什么安装 Python 时总是出错? 怎么安装工具包呢? 为什么提示 ...

  4. python编程入门指南 代码库在哪下-致Python初学者 Anaconda入门使用指南完整版

    打算学习 Python 来做数据分析的你,是不是在开始时就遇到各种麻烦呢? 到底该装 Python2 呢还是 Python3 ? 为什么安装 Python 时总是出错? 怎么安装工具包呢? 为什么提示 ...

  5. python入门基础代码图-python入门代码指南教程书籍推荐2020总结全集汇总

    python入门代码指南教程书籍推荐2020总结全集汇总 记住,如果您想学习Python,市场上有很多可用的资源.这些可以包括书籍,甚至在线课程..在这篇文章中,我们为Python编写了最好的书籍,无 ...

  6. Python入门学习指南--内附学习框架

    Python入门学习指南 原文链接:https://blog.csdn.net/weixin_44558127/article/details/86527360 最近开始整理python的资料,博主建 ...

  7. python入门代码大全-python入门代码指南教程书籍推荐2020总结全集汇总

    python入门代码指南教程书籍推荐2020总结全集汇总 记住,如果您想学习Python,市场上有很多可用的资源.这些可以包括书籍,甚至在线课程..在这篇文章中,我们为Python编写了最好的书籍,无 ...

  8. python人门指南小说-致Python初学者 Anaconda入门使用指南完整版

    打算学习 Python 来做数据分析的你,是不是在开始时就遇到各种麻烦呢? 到底该装 Python2 呢还是 Python3 ? 为什么安装 Python 时总是出错? 怎么安装工具包呢? 为什么提示 ...

  9. python从零开始到精通_「Python 入门学习指南」0基础小白助你从入门到精通!

    Python比较简单,非常适合初学者入门,内置了各种库,还有丰富的大约13万第三方库,掌握了语法和编程思维后,可以直接使用这些库做出自己的产品.这篇 Python 入门学习指南,针对没有任何编程经验. ...

  10. 干货满满 | 不容错过的数据科学入门数学指南

    作者 | Randall Hall 来源 | 机器之心 想要入行数据科学而又不知如何开始吗?先看看这篇使用的数据科学入门数学指南吧! 数学就像一个章鱼:它的「触手」可以触及到几乎所有学科.虽然有些学科 ...

最新文章

  1. c#,Winform同一系统中只运行一个实例。
  2. 监控利器Prometheus初探
  3. 关于重构,看此文就够了
  4. SOP,TSSOP,PLCC,BGA这些封装的中英文解释
  5. mycncart操作使用教程 - 横幅广告
  6. Android/Java中使用Protobuf的Any类型实现泛型解析
  7. MOCTF-Web-没时间解释了
  8. 编程之美-2.17-数组循环移位
  9. 新风口下:嵌入式AI学习中较好的练手项目(附代码资料/学习视频/学习规划)...
  10. Windows下安装Vim插件管理Vundle
  11. @font-face的用法,css3使用web字体教程
  12. Lock and Load FCPX 报错处理方法
  13. Linux命令(2):ls命令
  14. 【AIQ合集】人工智能技术学习资料年度整理大合集电子书 PDF下载
  15. 接口测试基础思维导图
  16. Pillow 库简介
  17. 2020美团实习试题
  18. php 热搜词,2020 十大网络热搜流行语来了!你知道几个?
  19. MediBangPaint Pro for mac(优秀漫画制作软件)
  20. 蓝绿部署、红黑部署、AB测试、灰度发布、金丝雀发布、滚动发布的概念与区别...

热门文章

  1. iOS 图片裁剪功能。
  2. 如何判断Activity是否在前台显示
  3. FFmpeg+SDL纯视频播放器
  4. 有了这个 Python 库,以后再也不用写正则表达式了
  5. 这家饱受诟病的三线大厂,福利居然秒杀BATJ!
  6. 2021暑假Leetcode刷题——Two Pointers(3)
  7. 美团实习生C++后台
  8. Adobe Dreamweaver CS6已停止工作的解决办法
  9. 一文快速了解Docker和Kubernetes
  10. Vue项目上传图片后在ie浏览器卡死