Pygame学习笔记8:Block Breaker游戏

这次来制作一个Block Breaker游戏,即我们以前玩过的一个小游戏,用一块板子撞击小球,而小球碰到砖块会反弹,同时被碰到的砖块会消失,直到所有的砖块都消失,游戏结束,进入下一关。
那么接下来就好好介绍一下这个游戏的制作过程。

Block Breaker

在这次制作中,上一章制作的MyLibrary.py有一些改动和添加,完整的新代码如下:

import random
import sys
import math
import time
import pygame
from pygame.locals import *


# 类中的X、Y、position用于设置精灵的位置
class MySprite(pygame.sprite.Sprite):
    def __init__(self):
        # 调用父类的初始化方法
        pygame.sprite.Sprite.__init__(self)
        # self.image = pygame.image.load(image_file).convert_alpha()
        # self.rect = self.image.get_rect()
        self.master_image = None
        self.frame = 0
        self.old_frame = -1
        self.frame_width = 1
        self.frame_height = 1
        self.first_frame = 0
        self.last_frame = 0
        self.columns = 1
        self.last_time = 0
        self.direction = 0
        self.velocity = Point(0.0, 0.0)

    def getx(self):
        return self.rect.x

    def setx(self, value):
        self.rect.x = value
    X = property(getx, setx)

    def gety(self):
        return self.rect.y

    def sety(self, value):
        self.rect.y = value
    Y = property(gety, sety)

    def getpos(self):
        return self.rect.topleft

    def setpos(self, pos):
        self.rect.topleft = pos
    position = property(getpos, setpos)

    def load(self, filename, width=0, height=0, columns=1):
        self.master_image = pygame.image.load(filename).convert_alpha()
        self.set_image(self.master_image, width, height, columns)

    def set_image(self, image, width=0, height=0, columns=1):
        self.master_image = image
        if width == 0 and height == 0:
            self.frame_width = image.get_width()
            self.frame_height = image.get_height()
        else:
            self.frame_width = width
            self.frame_height = height
            rect = self.master_image.get_rect()
            self.last_frame = (rect.width // width) * (rect.height // height) - 1
        self.rect = Rect(0, 0, self.frame_width, self.frame_height)
        self.columns = columns

    def update(self, current_time, rate=30):
        # 帧变动
        if self.last_frame > self.first_frame:
            if current_time > self.last_time + rate:
                self.frame += 1
                if self.frame > self.last_frame:
                    self.frame = self.first_frame
                self.last_time = current_time
        else:
            self.frame = self.first_frame
        # 当帧发生变化时,进行修改
        if self.frame != self.old_frame:
            frame_x = (self.frame % self.columns) * self.frame_width
            frame_y = (self.frame // self.columns) * self.frame_height
            rect = Rect(frame_x, frame_y, self.frame_width, self.frame_height)
            # 将要展示的图片送给image属性,以便展示出来
            self.image = self.master_image.subsurface(rect)
            self.old_frame = self.frame

    def __str__(self):
        return str(self.frame) + "," + str(self.first_frame) + "," + str(self.last_frame) + \
               "," + str(self.frame_width) + "," + str(self.frame_height) + "," + \
               str(self.columns) + "," + str(self.rect)


class Point(object):
    def __init__(self, x, y):
        self.__x = x
        self.__y = y

    def getx(self):
        return self.__x

    def setx(self, x):
        self.__x = x
    x = property(getx, setx)

    def gety(self):
        return self.__y

    def sety(self, y):
        self.__y = y
    y = property(gety, sety)

    def __str__(self):
        return "{X:" + "{:.0f}".format(self.__x) + ",Y:" + "{:.0f}".format(self.__y) + "}"


def print_text(font, x, y, text, color=(255, 255, 255), shadow=True):
    imgText = font.render(text, True, color)
    screen = pygame.display.get_surface()
    screen.blit(imgText, (x, y))

关卡设置

游戏中设置了4个关卡,存储在levels中,每一关的样子如下。

关卡1:

(
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
    )

图形如下:
在这里插入图片描述
关卡2:

(
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2,
        2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2,
        2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
    )

图形如下:
在这里插入图片描述
关卡3:

(
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
    )

图形如下:
在这里插入图片描述
关卡4:

(
        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
        4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4,
        4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4,
        4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4,
        4, 4, 4, 0, 0, 4, 4, 4, 0, 0, 4, 4,
        4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4,
        4, 4, 0, 0, 0, 0, 4, 4, 0, 0, 4, 4,
        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
        4, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 4,
        4, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 4
    )

图形如下:
在这里插入图片描述

游戏初始化

这一次,因为代码量比较大,所以我们将很多部分进行了模块化,游戏的一些初始化操作都封装到一个函数中:

# 游戏的一些初始化设置
def game_init():
    global screen, font, timer
    global paddle_group, block_group, ball_group
    global paddle, block_image, block, ball

    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    pygame.display.set_caption("Block Breaker Game")
    font = pygame.font.Font(None, 40)
    pygame.mouse.set_visible(False)
    timer = pygame.time.Clock()

    # 创建精灵组
    paddle_group = pygame.sprite.Group()
    block_group = pygame.sprite.Group()
    ball_group = pygame.sprite.Group()

    # 创建板子
    paddle = MySprite()
    paddle.load("paddle.png")
    paddle.position = 400, 540
    paddle_group.add(paddle)

    # 创建球
    ball = MySprite()
    ball.load("ball.png")
    ball.position = 400, 300
    ball_group.add(ball)

为了能够让函数中初始化后的变量能够在其他地方被使用,因此都是使用的global变量。

关卡的加载和修改

和关卡相关的一些操作其实就是对砖块的处理,共有3个函数:

# 加载关卡
def load_level():
    global level, levels, block_image, block_group
    block_image = pygame.image.load("blocks.png").convert_alpha()
    # 先将砖块组中的对象清空
    block_group.empty()
    for bx in range(0, 12):
        for by in range(0, 10):
            block = MySprite()
            block.set_image(block_image, 58, 28, 4)
            x = 40 + bx * (block.frame_width + 1)
            y = 60 + by * (block.frame_height + 1)
            block.position = x, y

            num = levels[level][by * 12 + bx]
            block.first_frame = num - 1
            block.last_frame = num - 1
            if num > 0:
                block_group.add(block)


# 更新砖块
def update_blocks():
    global block_group, waiting
    if len(block_group) == 0:
        goto_next_level()
        waiting = True
    block_group.update(ticks, 50)


# 进入到下一个关卡
def goto_next_level():
    global level, levels
    level += 1
    if level > len(levels) - 1:
        level = 0
    load_level()

精灵图像的移动

需要移动的精灵图像分别是球和板子,其中球的处理如下:

# 重置球的速度
def reset_ball():
    ball.velocity = Point(4.5, -7.0)


# 移动球
def move_ball():
    global waiting, ball, game_over, lives
    ball_group.update(ticks, 50)
    # 若球掉下去了,重新将球放到板子上
    if waiting:
        ball.X = paddle.X + 40
        ball.Y = paddle.Y - 20
    ball.X += ball.velocity.x
    ball.Y += ball.velocity.y
    if ball.X < 0:
        ball.X = 0
        ball.velocity.x *= -1
    elif ball.X > 780:
        ball.X = 780
        ball.velocity.x *= -1
    if ball.Y < 0:
        ball.Y = 0
        ball.velocity.y *= -1
    elif ball.Y > 580:
        waiting = True
        lives -= 1
        if lives < 1:
            game_over = True

板子的移动如下:

# 移动板子
def move_paddle():
    global movex, movey, keys, waiting
    paddle_group.update(ticks, 50)
    # 可以通过空格、左右键控制板子
    if keys[K_SPACE]:
        if waiting:
            waiting = False
            reset_ball()
    elif keys[K_LEFT]:
        paddle.velocity.x = -10.0
    elif keys[K_RIGHT]:
        paddle.velocity.x = 10.0
    else:
        if movex < -2:
            paddle.velocity.x = movex
        elif movex > 2:
            paddle.velocity.x = movex
        else:
            paddle.velocity.x = 0
    paddle.X += paddle.velocity.x
    if paddle.X < 0:
        paddle.X = 0
    elif paddle.X > 710:
        paddle.X = 710

碰撞检测

对于碰撞检测,我们既需要检测球与板子之间的碰撞,也需要检测球与砖块之间的碰撞,其中球与板子之间的碰撞检测如下:

# 球与板子的冲突检测
def collision_ball_paddle():
    if pygame.sprite.collide_rect(ball, paddle):
        ball.velocity.y = -abs(ball.velocity.y)
        bx = ball.X + 8
        by = ball.Y + 8
        px = paddle.X + paddle.frame_width / 2
        py = paddle.Y + paddle.frame_height / 2
        if bx < px:
            ball.velocity.x = -abs(ball.velocity.x)
        else:
            ball.velocity.x = abs(ball.velocity.x)

这里可以看到,我们并不是简单地按照相反的方向反弹,而是要根据球落在板子的位置的不同,以不同的方式反弹。
球与砖块之间的碰撞检测如下:

# 球与砖块的冲突检测
def collision_ball_blocks():
    global score, block_group, ball
    hit_block = pygame.sprite.spritecollideany(ball, block_group)
    if hit_block:
        score += 10
        block_group.remove(hit_block)
        bx = ball.X + 8
        by = ball.Y + 8

        if bx > hit_block.X + 5 and bx < hit_block.X + hit_block.frame_width - 5:
            if by < hit_block.Y + hit_block.frame_height / 2:
                ball.velocity.y = -abs(ball.velocity.y)
            else:
                ball.velocity.y = abs(ball.velocity.y)
        elif bx < hit_block.X + 5:
            ball.velocity.x = -abs(ball.velocity.x)
        elif bx > hit_block.X + hit_block.frame_width - 5:
            ball.velocity.x = abs(ball.velocity.x)
        else:
            ball.velocity.y *= -1

这里用到了pygame.sprite.spritecollideany()函数进行检测,因为我们需要将被碰到的砖块消去,同时对碰撞后球的速度和方向的处理同前面一样,而不是简单的相反的方向。

完整源代码

完整的代码如下:

import random
import sys
import pygame
from pygame.locals import *
from MyLibrary import *

levels = (
    (
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
    ), (
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2,
        2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2,
        2, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
    ), (
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 0, 0, 0, 3, 3, 0, 0, 0, 3, 3,
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
    ), (
        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
        4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4,
        4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4,
        4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4,
        4, 4, 4, 0, 0, 4, 4, 4, 0, 0, 4, 4,
        4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4,
        4, 4, 0, 0, 0, 0, 4, 4, 0, 0, 4, 4,
        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
        4, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 4,
        4, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 4
    )
)


# 游戏的一些初始化设置
def game_init():
    global screen, font, timer
    global paddle_group, block_group, ball_group
    global paddle, block_image, block, ball

    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    pygame.display.set_caption("Block Breaker Game")
    font = pygame.font.Font(None, 40)
    pygame.mouse.set_visible(False)
    timer = pygame.time.Clock()

    # 创建精灵组
    paddle_group = pygame.sprite.Group()
    block_group = pygame.sprite.Group()
    ball_group = pygame.sprite.Group()

    # 创建板子
    paddle = MySprite()
    paddle.load("paddle.png")
    paddle.position = 400, 540
    paddle_group.add(paddle)

    # 创建球
    ball = MySprite()
    ball.load("ball.png")
    ball.position = 400, 300
    ball_group.add(ball)


# 加载关卡
def load_level():
    global level, levels, block_image, block_group
    block_image = pygame.image.load("blocks.png").convert_alpha()
    # 先将砖块组中的对象清空
    block_group.empty()
    for bx in range(0, 12):
        for by in range(0, 10):
            block = MySprite()
            block.set_image(block_image, 58, 28, 4)
            x = 40 + bx * (block.frame_width + 1)
            y = 60 + by * (block.frame_height + 1)
            block.position = x, y

            num = levels[level][by * 12 + bx]
            block.first_frame = num - 1
            block.last_frame = num - 1
            if num > 0:
                block_group.add(block)


# 更新砖块
def update_blocks():
    global block_group, waiting
    if len(block_group) == 0:
        goto_next_level()
        waiting = True
    block_group.update(ticks, 50)


# 进入到下一个关卡
def goto_next_level():
    global level, levels
    level += 1
    if level > len(levels) - 1:
        level = 0
    load_level()


# 移动板子
def move_paddle():
    global movex, movey, keys, waiting
    paddle_group.update(ticks, 50)
    # 可以通过空格、左右键控制板子
    if keys[K_SPACE]:
        if waiting:
            waiting = False
            reset_ball()
    elif keys[K_LEFT]:
        paddle.velocity.x = -10.0
    elif keys[K_RIGHT]:
        paddle.velocity.x = 10.0
    else:
        if movex < -2:
            paddle.velocity.x = movex
        elif movex > 2:
            paddle.velocity.x = movex
        else:
            paddle.velocity.x = 0
    paddle.X += paddle.velocity.x
    if paddle.X < 0:
        paddle.X = 0
    elif paddle.X > 710:
        paddle.X = 710


# 重置球的速度
def reset_ball():
    ball.velocity = Point(4.5, -7.0)


# 移动球
def move_ball():
    global waiting, ball, game_over, lives
    ball_group.update(ticks, 50)
    # 若球掉下去了,重新将球放到板子上
    if waiting:
        ball.X = paddle.X + 40
        ball.Y = paddle.Y - 20
    ball.X += ball.velocity.x
    ball.Y += ball.velocity.y
    if ball.X < 0:
        ball.X = 0
        ball.velocity.x *= -1
    elif ball.X > 780:
        ball.X = 780
        ball.velocity.x *= -1
    if ball.Y < 0:
        ball.Y = 0
        ball.velocity.y *= -1
    elif ball.Y > 580:
        waiting = True
        lives -= 1
        if lives < 1:
            game_over = True


# 球与板子的冲突检测
def collision_ball_paddle():
    if pygame.sprite.collide_rect(ball, paddle):
        ball.velocity.y = -abs(ball.velocity.y)
        bx = ball.X + 8
        by = ball.Y + 8
        px = paddle.X + paddle.frame_width / 2
        py = paddle.Y + paddle.frame_height / 2
        if bx < px:
            ball.velocity.x = -abs(ball.velocity.x)
        else:
            ball.velocity.x = abs(ball.velocity.x)


# 球与砖块的冲突检测
def collision_ball_blocks():
    global score, block_group, ball
    hit_block = pygame.sprite.spritecollideany(ball, block_group)
    if hit_block:
        score += 10
        block_group.remove(hit_block)
        bx = ball.X + 8
        by = ball.Y + 8

        if bx > hit_block.X + 5 and bx < hit_block.X + hit_block.frame_width - 5:
            if by < hit_block.Y + hit_block.frame_height / 2:
                ball.velocity.y = -abs(ball.velocity.y)
            else:
                ball.velocity.y = abs(ball.velocity.y)
        elif bx < hit_block.X + 5:
            ball.velocity.x = -abs(ball.velocity.x)
        elif bx > hit_block.X + hit_block.frame_width - 5:
            ball.velocity.x = abs(ball.velocity.x)
        else:
            ball.velocity.y *= -1


if __name__ == "__main__":
    game_init()
    game_over = False
    waiting = True
    score = 0
    lives = 3
    level = 3
    load_level()

    while True:
        timer.tick(30)
        ticks = pygame.time.get_ticks()

        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
            elif event.type == MOUSEMOTION:
                movex, movey = event.rel
            elif event.type == MOUSEBUTTONUP:
                if waiting:
                    waiting = False
                    reset_ball()
            elif event.type == KEYUP:
                if event.key == K_RETURN:
                    goto_next_level()

        keys = pygame.key.get_pressed()
        if keys[K_ESCAPE]:
            sys.exit()

        if not game_over:
            update_blocks()
            move_paddle()
            move_ball()
            collision_ball_paddle()
            collision_ball_blocks()

        screen.fill((50, 50, 100))
        block_group.draw(screen)
        ball_group.draw(screen)
        paddle_group.draw(screen)
        print_text(font, 0, 0, "SCORE:" + str(score))
        print_text(font, 200, 0, "LEVEL:" + str(level + 1))
        print_text(font, 400, 0, "BLOCKS:" + str(len(block_group)))
        print_text(font, 670, 0, "BALLS:" + str(lives))
        if game_over:
            print_text(font, 300, 380, "G A M E O V E R")
        pygame.display.update()


运行结果如下:
在这里插入图片描述

任务一:将游戏的背景颜色设置成随着游戏的进行而逐渐淡入淡出,多种颜色循环变化,同时添加一个计时器,记录玩家的攻关时间

添加颜色的部分如下,首先添加一个颜色的元组:

colors = (
    (0, 0, 0), (0, 100, 50), (50, 50, 50), (100, 100, 100), (200, 200, 200), (150, 200, 255)
)

然后在循环外面申明一个color赋初值:

color = colors[0]

最后在循环内部:

if ticks % 50 == 0:
	i = colors.index(color)
    color = colors[(i + 1) % len(colors)]
screen.fill(color)

而添加计时功能则如下:

times = 0.0
times = ticks / 1000
print_text(font, 640, 0, "TIME:" + "{:.0f}".format(times) + "s")

因为ticks记录的是毫秒,因此将其转换成秒缩短表示的长度

任务二:每次球撞击板子的时候,球的速度都会随机发生变化,让游戏变得不可预测

这个问题只需要修改一下collision_ball_paddle()函数即可,如下:

# 球与板子的冲突检测
def collision_ball_paddle():
    if pygame.sprite.collide_rect(ball, paddle):
        ball.velocity.y = -abs(random.randint(5, 15))
        bx = ball.X + 8
        by = ball.Y + 8
        px = paddle.X + paddle.frame_width / 2
        py = paddle.Y + paddle.frame_height / 2
        if bx < px:
            ball.velocity.x = -abs(random.randint(5, 15))
        else:
            ball.velocity.x = abs(random.randint(5, 15))
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花无凋零之时

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值