当前位置: 首页 > article >正文

【Python】用Python写一个俄罗斯方块玩玩

【Python】用Python写一个俄罗斯方块玩玩

  • 一、引言
    • 1.成品效果展示
  • 二、思考准备
    • 1.思考设计
    • 2.代码设计
      • 2.1 游戏页面
      • 2.2 控件设计
        • 2.2.1 方块生成
        • 2.2.2 方块碰撞
        • 2.2.3 方块消融
        • 2.2.4 游戏主循环
        • 2.2.5 游戏窗口
  • 三、游戏完整版

一、引言

  • 今日看到侄子在玩游戏,凑近一看,原来是俄罗斯方块。熟悉又怀念,童年的记忆瞬间涌上心头。小时候觉得这游戏老厉害了,现在想想,好像就是数组的组合和消融,便想着自己写一个试试。说干就干,冲!

1.成品效果展示

俄罗斯方块实现过程

二、思考准备

1.思考设计

在这里插入图片描述

  • 俄罗斯方块作为风靡一时的游戏,由俄罗斯人阿列克谢·帕基特诺夫于1984年6月发明的休闲游戏,主要是通过方块的组合、消融完成的;
  • 所以得先设计有哪些方块、方块如何组合、完成一行时方块消融并下降一行、方块组合还得回旋转,单次90°等等,考虑中ing…

2.代码设计

2.1 游戏页面

  • 游戏首先得有个操控页面,所以得设计一个
# 设计游戏窗口尺寸
SCREEN_WIDTH, SCREEN_HEIGHT = 300, 600  
# 方块大小
GRID_SIZE = 30     
# 各种图形颜色 可自定义调整                    
COLORS = [            # 颜色配置(含背景色+7种方块色)(0, 0, 0),        # 0: 黑色背景(255, 0, 0),      # 1: 红色-I型(0, 255, 0),      # 2: 绿色-T型(0, 0, 255),      # 3: 蓝色-J型(255, 165, 0),    # 4: 橙色-L型(255, 255, 0),    # 5: 黄色-O型(128, 0, 128),    # 6: 紫色-S型(0, 255, 255)     # 7: 青色-Z型
]

2.2 控件设计

2.2.1 方块生成
  • 游戏开始最上方会有方块掉落,随机形状和颜色

def new_piece(self):"""生成新方块,随机形状和颜色"""shape = random.choice(SHAPES)return {'shape': shape,                                        # 方块形状矩阵'x': (SCREEN_WIDTH//GRID_SIZE - len(shape[0])) // 2,   # 初始水平居中'y': 0,                                                # 初始垂直位置'color': random.randint(1, len(COLORS)-1)              # 随机颜色(排除背景色)}
2.2.2 方块碰撞
  • 方块会一直下降,碰撞,下降时还要符合可以多次旋转

def check_collision(self, dx=0, dy=0, rotate=False):"""碰撞检测函数:param dx: 水平移动偏移量:param dy: 垂直移动偏移量:param rotate: 是否正在旋转:return: 是否发生碰撞"""shape = self.current_piece['shape']# 旋转时生成临时形状if rotate:         shape = [list(row[::-1]) for row in zip(*shape)]  # 矩阵旋转算法:先转置再反转每行(顺时针90度)for y, row in enumerate(shape):for x, cell in enumerate(row):if cell:                        # 仅检测实体方块new_x = self.current_piece['x'] + x + dxnew_y = self.current_piece['y'] + y + dy# 边界检测(左右越界/触底/与其他方块重叠)if not (0 <= new_x < len(self.grid[0])) or new_y >= len(self.grid):return Trueif new_y >=0 and self.grid[new_y][new_x]:return Truereturn False
2.2.3 方块消融
  • 方块接触时,合适的会消融、不合适的会叠加,消融了计算分数,消融的还要剔除
def merge_piece(self):"""将当前方块合并到游戏网格,并触发消行检测"""for y, row in enumerate(self.current_piece['shape']):for x, cell in enumerate(row):if cell:# 将方块颜色写入网格对应位置self.grid[self.current_piece['y']+y][self.current_piece['x']+x] = self.current_piece['color']# 消行并更新分数lines = self.clear_lines()self.score += lines * 100def clear_lines(self):"""消除满行并返回消除行数"""lines = 0# 从底部向上扫描for i, row in enumerate(self.grid):if all(cell !=0 for cell in row):       # 检测整行填满del self.grid[i]                    # 删除该行self.grid.insert(0, [0]*len(row))   # 在顶部插入新空行lines +=1return lines
2.2.4 游戏主循环
  • 游戏主体逻辑写入,方块的处理时间、操作事项和刷新等

def run(self):"""游戏主循环"""fall_time = 0       # 下落时间累计器while True:self.screen.fill(COLORS[0])            # 用背景色清屏# 计时系统(控制自动下落速度)fall_time += self.clock.get_rawtime()self.clock.tick()        # 保持帧率稳定# 自动下落逻辑(每800ms下落一格)if fall_time >= 800:if not self.check_collision(dy=1):self.current_piece['y'] +=1                 # 正常下落else:self.merge_piece()                          # 触底合并self.current_piece = self.new_piece()       # 生成新方块# 游戏结束检测(新方块无法放置)if self.check_collision():print("Game Over 你完蛋啦! Score:", self.score)returnfall_time =0   # 重置计时器# 事件处理(适配Mac键盘布局)for event in pygame.event.get():if event.type == QUIT:pygame.quit()returnif event.type == KEYDOWN:# 左右移动(带碰撞检测)if event.key == K_LEFT and not self.check_collision(dx=-1):self.current_piece['x'] -=1elif event.key == K_RIGHT and not self.check_collision(dx=1):self.current_piece['x'] +=1# 软下落(手动加速)elif event.key == K_DOWN:if not self.check_collision(dy=1):self.current_piece['y'] +=1# 旋转方块(带碰撞检测)elif event.key == K_UP and not self.check_collision(rotate=True):self.current_piece['shape'] = [list(row[::-1]) for row in zip(*self.current_piece['shape'])]# 硬下落(空格键一键到底)    elif event.key == K_SPACE:  while not self.check_collision(dy=1):self.current_piece['y'] +=1# 绘制逻辑,游戏网格for y, row in enumerate(self.grid):for x, color in enumerate(row):if color:# 绘制已落下方块(留1像素间隙)pygame.draw.rect(self.screen, COLORS[color], (x*GRID_SIZE, y*GRID_SIZE, GRID_SIZE-1, GRID_SIZE-1))# 绘制当前操作方块for y, row in enumerate(self.current_piece['shape']):for x, cell in enumerate(row):if cell:pygame.draw.rect(self.screen, COLORS[self.current_piece['color']],((self.current_piece['x']+x)*GRID_SIZE, (self.current_piece['y']+y)*GRID_SIZE, GRID_SIZE-1, GRID_SIZE-1))# 刷新画面pygame.display.flip()  
2.2.5 游戏窗口
  • 最后,游戏设计好了,必须有个游戏窗口来展示

def __init__(self):# 初始化游戏窗口self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))pygame.display.set_caption("Mac M1俄罗斯方块")self.clock = pygame.time.Clock()   # 游戏时钟控制帧率# 游戏状态初始化self.grid = [[0]*(SCREEN_WIDTH//GRID_SIZE) for _ in range(SCREEN_HEIGHT//GRID_SIZE)]              # 20x10游戏网格self.current_piece = self.new_piece()     # 当前操作方块self.score = 0                           

三、游戏完整版


# 俄罗斯方块设计
# -*- coding: utf-8 -*-  
"""
功能:俄罗斯方块,童年的回忆
作者:看海的四叔
最后更新:2025-04-16
"""import pygame
import random
from pygame.locals import *# 初始化配置
pygame.init()                           
SCREEN_WIDTH, SCREEN_HEIGHT = 300, 600  
GRID_SIZE = 30                          
COLORS = [            (0, 0, 0),        (255, 0, 0),      (0, 255, 0),      (0, 0, 255),      (255, 165, 0),    (255, 255, 0),    (128, 0, 128),    (0, 255, 255)     
]SHAPES = [[[1,1,1,1]],                [[1,1],[1,1]],              [[0,1,0], [1,1,1]],         [[1,1,1], [1,0,0]],         [[1,1,1], [0,0,1]],         [[0,1,1], [1,1,0]],         [[1,1,0], [0,1,1]]          
]class Tetris:"""游戏主控制类,处理游戏逻辑与渲染"""def __init__(self):self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))pygame.display.set_caption("Mac M1俄罗斯方块")self.clock = pygame.time.Clock()  self.grid = [[0]*(SCREEN_WIDTH//GRID_SIZE) for _ in range(SCREEN_HEIGHT//GRID_SIZE)] self.current_piece = self.new_piece()    self.score = 0                           def new_piece(self):"""生成新方块(随机形状和颜色)"""shape = random.choice(SHAPES)return {'shape': shape,                                        'x': (SCREEN_WIDTH//GRID_SIZE - len(shape[0])) // 2,   'y': 0,                                                'color': random.randint(1, len(COLORS)-1)              }def check_collision(self, dx=0, dy=0, rotate=False):"""碰撞检测函数:param dx: 水平移动偏移量:param dy: 垂直移动偏移量:param rotate: 是否正在旋转:return: 是否发生碰撞"""shape = self.current_piece['shape']if rotate:         shape = [list(row[::-1]) for row in zip(*shape)]  for y, row in enumerate(shape):for x, cell in enumerate(row):if cell:                       new_x = self.current_piece['x'] + x + dxnew_y = self.current_piece['y'] + y + dyif not (0 <= new_x < len(self.grid[0])) or new_y >= len(self.grid):return Trueif new_y >=0 and self.grid[new_y][new_x]:return Truereturn Falsedef merge_piece(self):"""将当前方块合并到游戏网格,并触发消行检测"""for y, row in enumerate(self.current_piece['shape']):for x, cell in enumerate(row):if cell:self.grid[self.current_piece['y']+y][self.current_piece['x']+x] = self.current_piece['color']lines = self.clear_lines()self.score += lines * 100def clear_lines(self):"""消除满行并返回消除行数"""lines = 0for i, row in enumerate(self.grid):if all(cell !=0 for cell in row):       del self.grid[i]                    self.grid.insert(0, [0]*len(row))   lines +=1return linesdef run(self):"""游戏主循环"""fall_time = 0      while True:self.screen.fill(COLORS[0])           fall_time += self.clock.get_rawtime()self.clock.tick()       if fall_time >= 800:if not self.check_collision(dy=1):self.current_piece['y'] +=1                 # 正常下落else:self.merge_piece()                          self.current_piece = self.new_piece()       # 游戏结束检测(新方块无法放置)if self.check_collision():print("Game Over 你完蛋啦! Score:", self.score)returnfall_time =0   # 重置计时器for event in pygame.event.get():if event.type == QUIT:pygame.quit()returnif event.type == KEYDOWN:if event.key == K_LEFT and not self.check_collision(dx=-1):self.current_piece['x'] -=1elif event.key == K_RIGHT and not self.check_collision(dx=1):self.current_piece['x'] +=1elif event.key == K_DOWN:if not self.check_collision(dy=1):self.current_piece['y'] +=1elif event.key == K_UP and not self.check_collision(rotate=True):self.current_piece['shape'] = [list(row[::-1]) for row in zip(*self.current_piece['shape'])]elif event.key == K_SPACE:  while not self.check_collision(dy=1):self.current_piece['y'] +=1for y, row in enumerate(self.grid):for x, color in enumerate(row):if color:pygame.draw.rect(self.screen, COLORS[color], (x*GRID_SIZE, y*GRID_SIZE, GRID_SIZE-1, GRID_SIZE-1))for y, row in enumerate(self.current_piece['shape']):for x, cell in enumerate(row):if cell:pygame.draw.rect(self.screen, COLORS[self.current_piece['color']],((self.current_piece['x']+x)*GRID_SIZE, (self.current_piece['y']+y)*GRID_SIZE, GRID_SIZE-1, GRID_SIZE-1))pygame.display.flip()  if __name__ == "__main__":game = Tetris()game.run()

相关文章:

【Python】用Python写一个俄罗斯方块玩玩

【Python】用Python写一个俄罗斯方块玩玩 一、引言1.成品效果展示 二、思考准备1.思考设计2.代码设计2.1 游戏页面2.2 控件设计2.2.1 方块生成2.2.2 方块碰撞2.2.3 方块消融2.2.4 游戏主循环2.2.5 游戏窗口 三、游戏完整版 一、引言 今日看到侄子在玩游戏&#xff0c;凑近一看…...

Java 本地缓存的实现:常见的四种方式

在 Java 中&#xff0c;常用的本地缓存实现主要有以下几种&#xff0c;以下是它们的代码示例及适用场景&#xff1a; 一、‌使用 ConcurrentHashMap 实现简单缓存‌ 适合轻量级、无需复杂淘汰策略的场景。 import java.util.concurrent.ConcurrentHashMap;public class Simp…...

记录一次生产中mysql主备延迟问题处理

登录库&#xff1a; mysql -uXXXX -pXXXX -P3306 -hXXXXXX -A 备库上执行&#xff1a;show slave status\G 查看 seconds_Behind_Master&#xff0c;延迟 2705s&#xff0c;而且还一直在增加。 SHOW CREATE TABLE proc_i_income_temp; -- 查看表的结构 show index from proc…...

路由器原理与配置技术详解

一、路由基础原理 1.1 路由器的核心功能 网络层设备&#xff1a;工作在OSI参考模型第三层&#xff0c;实现不同网络间的互联互通智能路径选择&#xff1a;基于路由表为数据包选择最优传输路径协议转换&#xff1a;处理不同网络接口间的协议差异&#xff08;如以太网与PPP&…...

第五节:React Hooks进阶篇-如何用useMemo/useCallback优化性能

反模式&#xff1a;滥用导致的内存开销React 19编译器自动Memoization原理 React Hooks 性能优化进阶&#xff1a;从手动到自动 Memoization &#xff08;基于 React 18 及以下版本&#xff0c;结合 React 19 新特性分析&#xff09; 一、useMemo/useCallback 的正确使用场景…...

STL迭代器:C++泛型编程的核心工具 [特殊字符]

在C中&#xff0c;STL&#xff08;标准模板库&#xff09;的迭代器是泛型编程的核心&#xff0c;它不仅解决了指针的局限性&#xff0c;还为算法与容器之间提供了抽象的访问接口。接下来&#xff0c;我们将探讨迭代器的核心作用、与指针的关键区别以及其设计哲学。 一、迭代器的…...

ffmpeg无损转格式的命令行

将ffmpeg.exe拖入命令行窗口 c:\users\zhangsan>D:\ffmpeg-2025-03-11\bin\ffmpeg.exe -i happy.mp4 -c:v copy -c:a copy 格式转换后.mkv -c:v copy 仅做拷贝视频,不重新编码 -c:a copy 仅做拷贝音频 ,不重新编码...

Monorepo 是什么?前端项目的多模块管理终极方案

前言 你是否曾经维护过多个前端项目?是否在多个项目之间来回复制粘贴组件,工具函数?是否经常被"组件更新没同步","构建时间太长","依赖版本冲突"等问题困扰? 这些问题都指向一个关键点: 项目结构和管理方式 今天,我来聊聊一种非常火但又容…...

对象池模式在uniapp鸿蒙APP中的深度应用

文章目录 对象池模式在uniapp鸿蒙APP中的深度应用指南一、对象池模式核心概念1.1 什么是对象池模式&#xff1f;1.2 为什么在鸿蒙APP中需要对象池&#xff1f;1.3 性能对比数据 二、uniapp中的对象池完整实现2.1 基础对象池实现2.1.1 核心代码结构2.1.2 在Vue组件中的应用 2.2 …...

条款05:了解C++默默编写并调用哪些函数

目录 1.默认生成的函数 2.无法生成的情况 2.1当成员函数有引用 或者 被const修饰 2.2.operator在基类被私有 1.默认生成的函数 class empty {};//相当于class empty { public:empty(){ ... } // 构造函数empty(const empty& rhs) { ... }// 拷贝构造~empty(){ ... } //…...

PythonFlask打造高效流式接口的实战

一、环境搭建与项目初始化 要使用 Flask 提供流式接口,首先得确保开发环境正确配置。在 Ubuntu 系统上,可借助 apt 包管理器便捷安装 Python 和 pip: sudo apt update sudo apt install python3 python3-pip对于 Windows 用户,推荐从官网下载安装包进行安装。安装完成后,…...

强化学习算法系列(五):最主流的算法框架——Actor-Critic算法框架

强化学习算法 &#xff08;一&#xff09;动态规划方法——策略迭代算法(PI)和值迭代算法(VI) &#xff08;二&#xff09;Model-Free类方法——蒙特卡洛算法(MC)和时序差分算法(TD) &#xff08;三&#xff09;基于动作值的算法——Sarsa算法与Q-Learning算法 &#xff08;四…...

设计模式(结构型)-桥接模式

目录 摘要 定义 类图 角色 具体实现 优缺点 优点 缺点 使用场景 使用案例 JDBC 和桥接模式 总结 摘要 在软件开发领域&#xff0c;随着系统规模和复杂性的不断攀升&#xff0c;如何设计出具有良好扩展性、灵活性以及可维护性的软件架构成为关键挑战。桥接模式作为一…...

【MySQL】MySQL数据库 —— 简单认识

目录 1. 数据库的介绍 1.1 什么是数据库 1.2 数据库和数据结构之间关系 2. 数据库分类 2.1 关系型数据库&#xff08;RDBMS&#xff09; 2.2 非关系型数据库 2.3 区别 一些行内名词简单解释&#xff1a; 3. 关于mysql 主要学什么 4. MySQL中重要的概念 4.1 概念 4…...

RNN - 语言模型

语言模型 给定文本序列 x 1 , … , x T x_1, \ldots, x_T x1​,…,xT​&#xff0c;语言模型的目标是估计联合概率 p ( x 1 , … , x T ) p(x_1, \ldots, x_T) p(x1​,…,xT​)它的应用包括 做预训练模型&#xff08;eg BERT&#xff0c;GPT-3&#xff09;生成本文&#xff…...

过拟合、归一化、正则化、鞍点

过拟合 过拟合的本质原因往往是因为模型具备方差很大的权重参数。 定义一个有4个特征的输入&#xff0c;特征向量为,定义一个模型&#xff0c;其只有4个参数&#xff0c;表示为。当模型过拟合时&#xff0c;这四个权重参数的方差会很大&#xff0c;可以假设为。当经过这个模型后…...

【python画图】:从入门到精通绘制完美柱状图

目录 Python数据可视化&#xff1a;从入门到精通绘制完美柱状图一、基础篇&#xff1a;快速绘制柱状图1.1 使用Matplotlib基础绘制1.2 使用Pandas快速绘图 二、进阶篇&#xff1a;专业级柱状图定制2.1 多系列柱状图2.2 堆叠柱状图2.3 水平柱状图 三、专业参数速查表Matplotlib …...

基础知识:离线安装docker、docker compose

(1)离线安装docker 确认版本:Ubuntu 18.04 LTS - bionic 确认架构:X86_64 lsb_release -a uname -a 官方指南:https://docs.docker.com/engine/install/ 选择Ubuntu,发现页面上最低是Ubuntu20.04, 不要紧...

畅游Diffusion数字人(27):解读字节跳动提出主题定制视频生成技术Phantom

畅游Diffusion数字人(0):专栏文章导航 前言:主题定制视频生成,特别是zero-shot主题定制视频生成,一直是当前领域的一个难点,之前的方法效果很差。字节跳动提出了一个技术主题定制视频生成技术Phantom,效果相比于之前的技术进步非常显著。这篇博客详细解读一下这一工作。 …...

《Adaptive Layer-skipping in Pre-trained LLMs》- 论文笔记

作者&#xff1a;Xuan Luo, Weizhi Wang, Xifeng Yan Department of Computer Science, UC Santa Barbara xuan_luoucsb.edu, weizhiwangucsb.edu, xyancs.ucsb.edu 1. 引言与动机 1.1 背景 LLM 的成功与挑战: 大型语言模型 (LLMs) 在翻译、代码生成、推理等任务上取得巨大成…...

阅读分析Linux0.11 /boot/head.s

目录 初始化IDT、IDTR和GDT、GDTR检查协处理器并设置CR0寄存器初始化页表和CR3寄存器&#xff0c;开启分页 初始化IDT、IDTR和GDT、GDTR startup_32:movl $0x10,%eaxmov %ax,%dsmov %ax,%esmov %ax,%fsmov %ax,%gslss _stack_start,%espcall setup_idtcall setup_gdtmovl $0x1…...

android11 DevicePolicyManager浅析

目录 &#x1f4d8; 简单定义 &#x1f4d8;应用启用设备管理者 &#x1f4c2; 文件位置 &#x1f9e0; DevicePolicyManager 功能分类举例 &#x1f6e1;️ 1. 安全策略控制 &#x1f4f7; 2. 控制硬件功能 &#x1f9f0; 3. 应用管理 &#x1f512; 4. 用户管理 &am…...

《前端性能优化秘籍:打造极致用户体验》

在当下&#xff0c;网站和应用的性能表现直接关乎用户去留。快速加载、流畅交互的页面能让用户沉浸其中&#xff0c;反之&#xff0c;缓慢的响应速度则会让他们毫不犹豫地离开。对于前端开发者而言&#xff0c;性能优化不仅是技术追求&#xff0c;更是提升用户体验、增强产品竞…...

微信小程序实现table样式,自带合并行合并列

微信小程序在代码编写过程好像不支持原生table的使用&#xff0c;在开发过程中偶尔又得需要拿table来展示。 1.table效果展示 1.wxml <view class"table-container"><view class"table"><view class"table-row"><view cla…...

学习笔记十二——Rust 高阶函数彻底入门(超详细过程解析 + 每步数值追踪)

&#x1f4a1; 彻底搞懂 Rust 高阶函数&#xff01;新手最容易卡住的语法 调用流程全讲透&#xff08;含逐步拆解&#xff09; Rust 函数式编程中有一个常见却经常让人懵的概念&#xff1a;高阶函数&#xff08;Higher-Order Function&#xff09; 一看到 fn(i32) -> i32、…...

电脑的品牌和配置

我的笔记本是2020年买的&#xff0c;之前的订单找不到了&#xff0c;就知道是联想&#xff0c;不清楚具体的配置。 本文来源&#xff1a;腾讯元宝 检查系统信息&#xff08;Windows&#xff09; 这通常是 ​​联想&#xff08;Lenovo&#xff09;​​ 的型号代码。 81XV 是联想…...

Redis面试——常用命令

一、String &#xff08;1&#xff09;设置值相关命令 1.1.1 SET 功能&#xff1a;设置一个键值对&#xff0c;如果键已存在则覆盖旧值语法&#xff1a; SET key value [EX seconds] [PX milliseconds] [NX|XX]EX seconds&#xff1a;设置键的过期时间为 seconds 秒 PX milli…...

Swin-Transformer-UNet改进:融合Global-Local Spatial Attention (GLSA) 模块详解

目录 1.模块概述 2.swinUNet网络 3. 完整代码 1.模块概述 Global-Local Spatial Attention (GLSA) 是一种先进的注意力机制模块,专为计算机视觉任务设计,能够同时捕捉全局上下文信息和局部细节特征。 该模块通过创新的双分支结构和自适应融合机制,显著提升了特征表示能…...

ubuntu 向右拖动窗口后消失了、找不到了

这是目前单显示器的设置&#xff0c;因为实际只有1个显示器&#xff0c;之前的设置如下图所示&#xff0c;有2个显示器&#xff0c;一个主显示器&#xff0c;一个23寸的显示器 ubuntu 22.04 系统 今天在操作窗口时&#xff0c;向右一滑&#xff0c;发现这个窗口再也不显示了、找…...

大语言模型(LLMs)中的强化学习(Reinforcement Learning, RL)

第一部分&#xff1a;强化学习基础回顾 在深入探讨LLMs中的强化学习之前&#xff0c;我们先快速回顾一下强化学习的核心概念&#xff0c;确保基础扎实。 1. 强化学习是什么&#xff1f; 强化学习是一种机器学习范式&#xff0c;目标是让智能体&#xff08;Agent&#xff09;…...