blit( )

语法

1
2
3
4
blit(source,dest=None,special_flags=0


screen.blit(image, rect)

将source参数指定的Surface对象绘制到该对象上。dest参数指定绘制的位置。dest的值可以是source的左上角坐标,如果传入一个rect对象给dest,那么blit()会使用它的左上角坐标。

source:一个surface对象,可以理解为一张图; dest:一个可以标识坐标的东西,可以是一个(x,y)元组。也可以是一个(x,y,height,width)元组,也可以是一个Rect对象,Rect对象可以理解为有位置有大小的矩形。

理解:把目标surface对象的左上角

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
import pygame

screen = pygame.display.set_mode((645, 483))
pygame.display.set_caption('动画测试')
image = pygame.image.load('不知名女友.gif')
rect = image.get_rect()


screen.blit(image, rect)

pygame.display.flip()

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

pygame.font

pygame中font模块方法

pygame.font.init()

初始化

pygame.font.Font.render()

语法:

render(text, antialias, color, background=None) -> Surface

  1. 创建一个新Surface,并在其上呈现指定的文本。pygame不提供直接在现有surface上绘制文本的方法:若要创建文本的图像(Surface)必须使用 Font.render(),然后将此图像blit到另一个surface上。
  2. 文本只能是单独一行:换行符不能呈现。空字符('x00') 会引发TypeError。Unicode和字符(byte)字符串都可以。对于Unicode字符串,只能识别UCS-2字符('u0001' to 'uFFFF')。任何更大的值都会引发UnicodeError。对于字符字符串,假定采用 LATIN1 编码。抗锯齿参数(antialias)是布尔值:如果为真,字符将具有平滑的边。颜色参数是文本的颜色[例如:(0,0255)表示蓝色]。可选的背景参数是用于文本背景的颜色。如果没有传递背景,文本外部的区域将是透明的。
  3. 返回的Surface应保存文本所需尺寸。(与Font.size()一致)。如果为文本传递空字符串,则将返回零像素宽和高的空白surface。
  4. 根据背景和抗锯齿使用的类型,返回不同类型的曲面。出于性能原因,最好知道将使用哪种类型的图像。如果不使用抗锯齿,则返回图像将始终是带有双调色板的8-bit图像。如果背景是透明的,则设置colorkey。抗锯齿图像被渲染为24-bit RGB图像。如果背景是透明的,将包括像素alpha。 ## 封装按钮 【pygame】创建输入框和按钮_pygame 按钮_小勺子哦的博客-CSDN博客
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77


    class Button:
    NORMAL = 0
    MOVE = 1
    DOWN = 2
    def __init__(self, x, y, text, imgNormal, imgMove=None, imgDown=None, callBackFunc=None, font=None, rgb=(0, 0, 0)):
    # """
    # 初始化按钮的相关参数
    # :param x: 按钮在窗体上的x坐标
    # :param y: 按钮在窗体上的y坐标
    # :param text: 按钮显示的文本
    # :param imgNormal: surface类型,按钮正常情况下显示的图片
    # :param imgMove: surface类型,鼠标移动到按钮上显示的图片
    # :param imgDown: surface类型,鼠标按下时显示的图片
    # :param callBackFunc: 按钮弹起时的回调函数
    # :param font: pygame.font.Font类型,显示的字体
    # :param rgb: 元组类型,文字的颜色
    # """
    # 初始化按钮相关属性
    self.imgs = []
    if not imgNormal:
    raise Exception("请设置普通状态的图片")
    self.imgs.append(imgNormal) # 普通状态显示的图片
    self.imgs.append(imgMove) # 被选中时显示的图片
    self.imgs.append(imgDown) # 被按下时的图片
    for i in range(2, 0, -1):
    if not self.imgs[i]:
    self.imgs[i] = self.imgs[i - 1]

    self.callBackFunc = callBackFunc # 触发事件
    self.status = Button.NORMAL # 按钮当前状态
    self.x = x
    self.y = y
    self.w = imgNormal.get_width()
    self.h = imgNormal.get_height()
    self.text = text
    self.font = font
    # 文字表面
    self.textSur = self.font.render(self.text, True, rgb)

    def draw(self, destSuf):
    dx = (self.w / 2) - (self.textSur.get_width() / 2)
    dy = (self.h / 2) - (self.textSur.get_height() / 2)
    # 先画按钮背景
    if self.imgs[self.status]:
    destSuf.blit(self.imgs[self.status], [self.x, self.y])
    # 再画文字
    destSuf.blit(self.textSur, [self.x + dx, self.y + dy])

    def colli(self, x, y):
    # 碰撞检测
    if self.x < x < self.x + self.w and self.y < y < self.y + self.h:
    return True
    else:
    return False

    def getFocus(self, x, y):
    # 按钮获得焦点时
    if self.status == Button.DOWN:
    return
    if self.colli(x, y):
    self.status = Button.MOVE
    else:
    self.status = Button.NORMAL

    def mouseDown(self, x, y):
    # '''通过在这个函数里加入返回值,可以把这个函数当做判断鼠标是否按下的函数,而不仅仅是像这里只有改变按钮形态的作用'''

    if self.colli(x, y):
    self.status = Button.DOWN

    def mouseUp(self):
    if self.status == Button.DOWN: # 如果按钮的当前状态是按下状态,才继续执行下面的代码
    self.status = Button.NORMAL # 按钮弹起,所以还原成普通状态
    if self.callBackFunc: # 调用回调函数
    return self.callBackFunc()
    实例化
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    import pygame

    from Button import Button

    # 初始化pygame
    pygame.init()
    winSur = pygame.display.set_mode([300, 300])

    # 加载按钮图片
    '''这里需要自己准备三张按钮的图片,分别对应正常形态,鼠标悬停形态,鼠标按下形态,把图片放在和此文件同一目录下即可''''
    surBtnNormal = pygame.image.load("./btn_normal.png").convert_alpha()
    surBtnMove = pygame.image.load("./btn_move.png").convert_alpha()
    surBtnDown = pygame.image.load("./btn_down.png").convert_alpha()

    #按钮使用的字体
    btnFont = pygame.font.SysFont("lisu", 40)

    # 按钮的回调函数
    def btnCallBack():
    print("我被按下了")


    # 创建按钮
    btn1 = Button(30, 50, "按钮测试", surBtnNormal, surBtnMove, surBtnDown, btnCallBack,btnFont,(255,0,0))
    btn2 = Button(30, 150, "", surBtnNormal, surBtnMove, surBtnDown, btnCallBack,btnFont)

    # 游戏主循环
    while True:
    mx, my = pygame.mouse.get_pos() # 获得鼠标坐标

    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    exit()
    elif event.type == pygame.MOUSEMOTION: # 鼠标移动事件
    # 判断鼠标是否移动到按钮范围内
    btn1.getFocus(mx, my)
    btn2.getFocus(mx, my)

    elif event.type == pygame.MOUSEBUTTONDOWN: # 鼠标按下
    if pygame.mouse.get_pressed() == (1, 0, 0): #鼠标左键按下
    btn1.mouseDown(mx,my)
    btn2.mouseDown(mx, my)

    elif event.type == pygame.MOUSEBUTTONUP: # 鼠标弹起
    btn1.mouseUp()
    btn2.mouseUp()

    pygame.time.delay(16)
    winSur.fill((0, 0, 0))
    #绘制按钮
    btn1.draw(winSur)
    btn2.draw(winSur)
    #刷新界面
    pygame.display.flip()
    ## 封装输入框
    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
    import pygame
    import os

    class InputBox:
    def __init__(self, rect: pygame.Rect = pygame.Rect(100, 100, 140, 32)) -> None:
    self.boxBody: pygame.Rect = rect
    self.color_inactive = pygame.Color('lightskyblue3') # 未被选中的颜色
    self.color_active = pygame.Color('dodgerblue2') # 被选中的颜色
    self.color = self.color_inactive # 当前颜色,初始为未激活颜色
    self.active = False
    self.text = '' # 输入的内容
    self.done = False
    self.font = pygame.font.Font(None, 32)

    def dealEvent(self, event: pygame.event.Event):
    if(event.type == pygame.MOUSEBUTTONDOWN):
    if(self.boxBody.collidepoint(event.pos)): # 若按下鼠标且位置在文本框
    self.active = not self.active
    else:
    self.active = False
    self.color = self.color_active if(
    self.active) else self.color_inactive
    if(event.type == pygame.KEYDOWN): # 键盘输入响应
    if(self.active):
    if(event.key == pygame.K_RETURN):
    print(self.text)
    # self.text=''
    elif(event.key == pygame.K_BACKSPACE):
    self.text = self.text[:-1]
    else:
    self.text += event.unicode

    def draw(self, screen: pygame.surface.Surface):
    txtSurface = self.font.render(
    self.text, True, self.color,(255,255,255)) # 文字转换为图片
    #'''注意,输入框的宽度实际是由这里max函数里的第一个参数决定的,改这里才有用'''
    width = max(200, txtSurface.get_width()+10) # 当文字过长时,延长文本框
    self.boxBody.w = width
    screen.blit(txtSurface, (self.boxBody.x+5, self.boxBody.y+5))
    pygame.draw.rect(screen, self.color, self.boxBody, 2)
    实例化
    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
    import pygame
    from pygame import Surface
    from pygame.constants import QUIT

    from draw import InputBox

    WIDTH = 600
    HEIGHT = 500
    FPS = 120

    screen: Surface = None # 窗口实例
    clock = None # 时钟实例

    textFont = None # 字体


    def pygameInit(title: str = "pygame"):
    """初始化 pygame"""
    pygame.init()
    pygame.mixer.init() # 声音初始化
    pygame.display.set_caption(title)
    global screen, clock, textFont # 修改全局变量
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    clock = pygame.time.Clock()

    if __name__ == "__main__":
    pygameInit("输入框示例")
    inputbox = InputBox(pygame.Rect(100, 20, 140, 32)) # 输入框
    running = True
    while running:
    clock.tick(FPS) # 限制帧数
    screen.fill((255, 255, 255)) # 铺底
    for event in pygame.event.get():
    if event.type == QUIT:
    running = False
    inputbox.dealEvent(event) # 输入框处理事件
    inputbox.draw(screen) # 输入框显示
    pygame.display.flip()
    pygame.quit()