用Python的Pygame包实现水果忍者小游戏

先上一下运行结果

长按鼠标左键出刀, 切割水果几分, 切割炸弹结束游戏, 漏掉的水果也会几分, 难度会随时间慢慢提高(水果的刷新频率变快)

初始化

帧率200帧/秒, 游戏窗口大小800×600

python 复制代码
# 游戏设置
pygame.init()
FPS = 200
fpsClock = pygame.time.Clock()
WIDTH, HEIGHT = 800, 600
sur = pygame.display.set_mode((WIDTH, HEIGHT))
back = pygame.image.load('back2.jpg')
sur.blit(back, (0, 0))

# 颜色资源
WHITE = (255, 255, 255)
RED  = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE  = (0, 0, 255)
BLACK = (0, 0, 0)
YELLOW = (255, 255, 0)
SILVER = (192, 192, 192)
GRAY = (169, 169, 169)
PURPLE = (127, 0, 255)
PINK = (255, 51, 153)
ORANGE = (255, 128, 0)
BROWN = (165, 42, 42)
LIGHTBLUE = (137, 207, 240)

基础变量

主要是一些语法糖, 图片导入, 和基本存储数据结构的定义, 后面会一一细说这些变量的作用

python 复制代码
# 水果变量
MAXFRUIT = 10  # 同时存在的水果最多数量
SCORE = pygame.image.load('score.png')
ERROR = pygame.image.load('error.png')
APPLE, BANANA, PEACH, STRAWBERRY, WATERMELON = 'apple', 'banana', 'peach', 'strawberry', 'watermelon'
FRUIT = (APPLE, BANANA, PEACH, STRAWBERRY, WATERMELON)
# 导入水果图片
FRUIT_IMG = {BANANA:pygame.image.load('banana.png'), APPLE:pygame.image.load('apple.png'),
    PEACH:pygame.image.load('peach.png'), STRAWBERRY:pygame.image.load('strawberry.png'),
    WATERMELON:pygame.image.load('watermelon.png')}
# 导入切割水果图片
FRUITCUT_IMG = {BANANA: (pygame.image.load('banana1.png'), pygame.image.load('banana2.png')),
    APPLE: (pygame.image.load('apple1.png'), pygame.image.load('apple2.png')),
    PEACH: (pygame.image.load('peach1.png'), pygame.image.load('peach2.png')),
    STRAWBERRY: (pygame.image.load('strawberry1.png'), pygame.image.load('strawberry2.png')),
    WATERMELON: (pygame.image.load('watermelon2.png'), pygame.image.load('watermelon1.png'))}
FRUIT_SIZE = {BANANA:(126, 50), APPLE:(65, 65), PEACH:(62, 59), STRAWBERRY:(68, 72),
    WATERMELON:(97, 84)}  # 水果的尺寸
existfruit = 0  # 目前存在水果的数量
fruits = [False for _ in range(MAXFRUIT)]  # 当前存在的水果
cutfruits = [False for _ in range(MAXFRUIT*2)]  # 被切割的水果数组
cut_count = 0  # 已经切割水果的数量
error_count = 0  # 失误次数
boom = None  # 炸弹的信息
BOOMSIZE = (65, 67)  # 炸弹尺寸
points = []  # 刀痕的点存放数组

# 水果类
class Afruit:
    sx, sy = 0, 0  # x和y的速度
    p, t = 0, 0  # 初始位置, 生成时间
    dis, img, fru = None, None, None    # 方向, 图片, 水果类型
    x, y = 0, 0  # 坐标

    def __init__(self, x, y, position, dis, img, fru):
        self.sx, self.sy = x, y
        self.p = position
        self.dis, self.img, self.fru = dis, img, fru

# 被切割的水果类
class Acut_fruit:
    sx = 0  # x速度
    x1, x2 = 0, 0
    y = 0
    fru = None
    t = 0  # 时间
    def __init__(self, sx, x1, x2, y, fru):
        self.sx = sx
        self.x1, self.x2 = x1, x2
        self.y = y
        self.fru = fru
复制代码

如何随机生成一个水果

水果有八种生成方式, 即: 从左边出来往右上或右下走, 从右边出来往左上或左下走, 从上面出来往左下或右下走, 从下面出来往左上或右上走

在主循环里只需要用随机概率来随机生成即可, 这里difficult表示当前游戏的难度, 每秒平均生成 (8*difficult*FPS) /1000个水果, 也就是每秒平均生成 1.6*difficult 个水果

然后根据不同的生成位置, 设置不同的速度和初始坐标即可, 生成炸弹同理, 这里就不赘述了, 代码如下:

python 复制代码
while True:
        ...
        ...
        if random.randint(0, 1000) < difficult: create_fruit('left_down')
        if random.randint(0, 1000) < difficult: create_fruit('left_up')
        if random.randint(0, 1000) < difficult: create_fruit('right_down')
        if random.randint(0, 1000) < difficult: create_fruit('right_up')
        if random.randint(0, 1000) < difficult: create_fruit('up_left')
        if random.randint(0, 1000) < difficult: create_fruit('up_right')
        if random.randint(0, 1000) < difficult: create_fruit('down_left')
        if random.randint(0, 1000) < difficult: create_fruit('down_right')      


def create_fruit(dis):  # 随机生成一个水果
    global idx, existfruit, MAXFRUIT
    if existfruit >= MAXFRUIT:  # 如果已经存在足够多的水果, 就不生成
        return
    existfruit += 1
    fru = random.choice(FRUIT)  # 水果类型
    img = FRUIT_IMG[fru]  # 获取图片
    if dis in ('left_up', 'right_up'):  # 从两边出来, 往上走
        position = random.randint(300, 650)
        speed_x = random.randint(200, 300)
        speed_y = random.randint(50, 100)
    elif dis in ('left_down', 'right_down'):  # 从两边出来, 往下走
        position = random.randint(-50, 300)
        speed_x = random.randint(200, 300)
        speed_y = random.randint(50, 100)
    elif dis in ('up_left', 'down_left'):  # 从上下出来, 往左走
        position = random.randint(400, 850)
        speed_x = random.randint(100, 300)
        speed_y = random.randint(100, 200)
    elif dis in ('down_right', 'up_right'):  # 从上下出来, 往右走
        position = random.randint(-50, 400)
        speed_x = random.randint(100, 300)
        speed_y = random.randint(100, 200)
    else:
        position, speed_x, speed_y = 0, 0, 0
    for i in range(MAXFRUIT):  # 生成水果
        if not fruits[i]:
            fruits[i] = Afruit(speed_x, speed_y, position, dis, img, fru)
            break  

如何画出刀锋划过的痕迹

首先需要记录鼠标的位置, 从按下左键开始, 每一帧都会搜集鼠标的坐标, 直到松开左键, 在此过程中还要边搜集边画出刀锋

代码思路就用列表来实现动态增删即可

python 复制代码
while True:
        ...
        ...
      # 根据鼠标走过的点绘制刀锋轨迹
        if points:
            copy = list(points)
            while points[-1][2] - points[0][2] >= 0.05:
                points.pop(0)
            linex, liney, _ = copy.pop(0)
            for temx, temy, _ in points:
                pygame.draw.line(sur, WHITE, (linex, liney-2), (temx, temy-2), 1)
                pygame.draw.line(sur, GRAY, (linex, liney), (temx, temy), 3)
                pygame.draw.line(sur, WHITE, (linex, liney+2), (temx, temy+2), 1)
                linex, liney = temx, temy
      ...
        ...
# 响应事件
for event in pygame.event.get():
    if event.type == QUIT:
        pygame.quit()
        sys.exit()
    # 鼠标长按响应, 连续的点形成刀锋
    elif event.type == MOUSEBUTTONDOWN:
        loose = True
    elif event.type == MOUSEBUTTONUP:
        loose = False
        points.clear()
        sur.blit(back, (0, 0))
    if event.type == MOUSEMOTION and loose:
        x1, y1 = event.pos
        points.append((x1, y1, p_time))

...
...
相关推荐
数据智能老司机5 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机6 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机6 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机6 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i6 小时前
drf初步梳理
python·django
每日AI新事件6 小时前
python的异步函数
python
这里有鱼汤7 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python
databook16 小时前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室17 小时前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
倔强青铜三18 小时前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试