文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

pygame俄罗斯方块游戏

2023-10-25 20:47

关注

俄罗斯方块游戏开发

俄罗斯方块是一款世界级经典游戏,每门语言开发学习初步都会考虑制作俄罗斯方块游戏今天带着大家把俄罗斯方块用python语言开发一次

开发准备

安装python
2.引入游戏库pygame
3.引入随机数

import pygameimport random

俄罗斯游戏步骤

俄罗斯方块初始形状

这里使用一个二维数组 用来标记俄罗斯相对应的方块形状 代码如下:

# 定义方块的基本形状blocks = [    # I    [        [1, 1, 1, 1],        [0, 0, 0, 0],        [0, 0, 0, 0],        [0, 0, 0, 0],    ],    # O    [        [1, 1, 0, 0],        [1, 1, 0, 0],        [0, 0, 0, 0],        [0, 0, 0, 0],    ],    # T    [        [1, 1, 1, 0],        [0, 1, 0, 0],        [0, 0, 0, 0],        [0, 0, 0, 0],    ],    # S    [        [0, 1, 1, 0],        [1, 1, 0, 0],        [0, 0, 0, 0],        [0, 0, 0, 0],    ],    # Z    [        [1, 1, 0, 0],        [0, 1, 1, 0],        [0, 0, 0, 0],        [0, 0, 0, 0],    ],    # J    [        [1, 1, 1, 0],        [0, 0, 1, 0],        [0, 0, 0, 0],        [0, 0, 0, 0],    ],    # L    [        [1, 1, 1, 0],        [1, 0, 0, 0],        [0, 0, 0, 0],        [0, 0, 0, 0],    ],]

游戏移动方向是否可能判断

这里为了不让他出现穿墙,跨过方块下落 都做对应的碰撞判断 具体代码如下:

# 判断方块是否可以向左移动def can_move_left(x, y, block):    for i in range(len(block)):        for j in range(len(block[i])):            if block[i][j] == 1:                if x + j - 1 < 0 or play_area[y + i][x + j - 1] != EMPTY:                    return False    return True# 判断方块是否可以向右移动def can_move_right(x, y, block):    for i in range(len(block)):        for j in range(len(block[i])):            if block[i][j] == 1:                if x + j + 1 >= COLS or play_area[y + i][x + j + 1] != EMPTY:                    return False    return True# 判断方块是否可以向下移动def can_move_down(x, y, block):    for i in range(len(block)):        for j in range(len(block[i])):            if block[i][j] == 1:                if y + i + 1 >= ROWS or play_area[y + i + 1][x + j] != EMPTY:                    global count                    count += 1                    print(y,",",x,";不能下降了",count)                    return False    return True# 判断方块是否可以变形def can_rotate(x, y, block):    return rotate_block(x, y, block) != block

俄罗斯方块旋转变形代码实现

# 变形方块def rotate_block(x, y, block):    new_block = []    for i in range(len(block)):        row = []        for j in range(len(block[i])):            row.append(block[len(block) - j - 1][i])        new_block.append(row)    if x + len(new_block[0]) > COLS or y + len(new_block) > ROWS:        return block    for i in range(len(new_block)):        for j in range(len(new_block[i])):            if new_block[i][j] == 1 and play_area[y + i][x + j] != EMPTY:                return block    return new_block

俄罗斯方块整行满格删除对应行

# 删除行def delete_rows():    full_rows = []  # 总共要删除的行号列表    for i in range(len(play_area)):  # 检测整行没有空格了        if EMPTY not in play_area[i]:            full_rows.append(i)   # 加入删除这行    # 偏移量bu 在一次性删除多行的时候 因为边删边补 会引起删除索引改变    bu = 0    for row in sorted(full_rows, reverse=True):  # 必须逆序 删除没有空格的行        del play_area[row+bu]        play_area.insert(0, [EMPTY] * COLS)        bu += 1    return len(full_rows)  # 返回删除的总行数

删除行后 根据一次删除的行计算得分规则

一次一行得10分 一次2行得30分 一次3行得50分 一次四行得100分,代码如下:

# 消除几行加分规则def add_score(drow):    global score    if drow == 1:        score += 10  # 一次消除一行 得分加10    elif drow == 2:  # 一次消除2行 得分加30        score += 30    elif drow == 3:        score += 50    elif drow == 4:        score += 100

检测游戏失败后 是否重新继续

# 游戏结束,重置游戏def reset_game():    global score    # 绘制提示语言    font = pygame.font.Font("simsun.ttc", 24)    # font = pygame.font.SysFont(None, 24)    text = font.render("游戏结束您的得分是{},重新开始请按空格键".format(score), True, WHITE)    screen.blit(text, (10, height//2-12))    pygame.display.update()    flag = True    while flag:        for event in pygame.event.get():            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:                flag = False                break    global play_area, cur_block, cur_color    play_area = [[EMPTY] * COLS for i in range(ROWS)]    # play_area = [[EMPTY] * width for i in range(height)]    # 随机生成俄罗斯方块    cur_block = blocks[random.randint(0, len(blocks) - 1)]    cur_color = random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)    # 重置分数    score = 0

游戏窗体创建与游戏初始数据设置

# 颜色定义BLACK = (0, 0, 0)WHITE = (255, 255, 255)# 初始化游戏pygame.init()# 设置游戏界面大小size = width, height = 640, 480# 游戏设置EMPTY = -1FPS = 60   ## 祯数SIZE = 20ROWS = height//SIZECOLS = width//SIZEcount = 0# 创建游戏界面screen = pygame.display.set_mode(size)# 设置游戏pygame.display.set_caption("俄罗斯方块")# 随机生成俄罗斯方块cur_block = blocks[random.randint(0, len(blocks) - 1)]cur_color = random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)play_area = [[EMPTY] * COLS for i in range(ROWS)]x, y = width // 2//SIZE, 0  # 方块的初始位置clock = pygame.time.Clock()score = 0  # 分数 speed = 1000 #下降速度 目前没用到 后续会根据这个值来调整关卡速度(方块下落速度)# 设置定时器来控制下降速度  如果用帧数控制游戏速度的话 会影响按键 帧数低的时候 按键也失灵 这里用定时器来控制速度pygame.time.set_timer(pygame.USEREVENT ,speed)

主体控制代码:

while True:    for event in pygame.event.get():        if event.type == pygame.QUIT:            pygame.quit()            exit()        elif event.type == pygame.USEREVENT:            y += 1  # 一秒下降一格        elif event.type == pygame.KEYDOWN:            if event.key == pygame.K_LEFT and can_move_left(x, y, cur_block):                x -= 1            elif event.key == pygame.K_RIGHT and can_move_right(x, y, cur_block):                x += 1            elif event.key == pygame.K_UP and can_rotate(x, y, cur_block):                cur_block = rotate_block(x, y, cur_block)            elif event.key == pygame.K_DOWN and can_move_down(x, y+3, cur_block):                y += 3    # print(x,",",y)    # 消除行并计分    add_score(delete_rows())    # 随机生成新方块    if not can_move_down(x, y, cur_block):        # 将方块添加到游戏区域        for i in range(len(cur_block)):            for j in range(len(cur_block[i])):                if cur_block[i][j] == 1:                    print("y=",y,";x=",x,";i=",i,";j=",j)                    play_area[y + i][x + j] = cur_color        # 随机生成俄罗斯方块        cur_block = blocks[random.randint(0, len(blocks) - 1)]        cur_color = random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)        x, y = width // 2//SIZE, 0  # 方块的初始位置        # 判断游戏是否结束        for i in play_area[0]:            if i != EMPTY:                reset_game()    # 绘制游戏区域    screen.fill(BLACK)    # print(play_area)    for i in range(ROWS):        for j in range(COLS):            if play_area[i][j] != EMPTY:                pygame.draw.rect(screen, play_area[i][j], pygame.Rect(j * 20, i * 20, 20, 20), 0)    # 绘制当前方块    for i in range(len(cur_block)):        for j in range(len(cur_block[i])):            if cur_block[i][j] == 1:                pygame.draw.rect(screen, cur_color, pygame.Rect((x + j) * 20, (y + i) * 20, 20, 20), 0)    # 绘制分数    font = pygame.font.SysFont(None, 24)    text = font.render("Score: {}".format(score), True, WHITE)    screen.blit(text, (10, 10))    pygame.display.update()    clock.tick(FPS)

开发总结

整个项目下载链接: pygame-俄罗斯方块游戏项目
1.游戏细节比较多,容易出错,需要清晰的逻辑思维,
2.速度控制上原先一直用FPS(帧数)来调节速度发现 按键灵敏度也跟帧数息息相关,所以这里用定时器来控制。不知道如果有多个定时器同时使用的话 会不会有新的问题,后续继续研究
3.消除行判断 原先没考虑到整个屏幕用二维列表来定义是否占格,浪费了很长时间无法很好的实现消除整行,这里用二维可以完美解决这个问题。
4.要显示中文字体需要加载字体,后面我会放整个项目下载链接,里面包括字体,后续持续更新 可能会加上音效等。
5.整个游戏花费了我5,6个小时的精力,还有很多心得 得大家一起去写写用用改改才能发现。有什么问题可以互相交流

游戏截图

俄罗斯方块游戏截图

来源地址:https://blog.csdn.net/yu126long/article/details/133691398

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯