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

【python小游戏】俄罗斯方块

 python小游戏之俄罗斯方块,供消遣娱乐:

import tkinter as tk
import random

# 游戏参数
CELL_SIZE = 30
COLS = 12
ROWS = 20
COLORS = ['#000000', '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF']
SHAPES = {
    'I': [(0, -1), (0, 0), (0, 1), (0, 2)],
    'O': [(-1, 0), (0, 0), (-1, 1), (0, 1)],
    'T': [(-1, 0), (0, 0), (1, 0), (0, 1)],
    'S': [(-1, 0), (0, 0), (0, 1), (1, 1)],
    'Z': [(-1, 1), (0, 1), (0, 0), (1, 0)],
    'J': [(-1, -1), (-1, 0), (0, 0), (1, 0)],
    'L': [(1, -1), (-1, 0), (0, 0), (1, 0)]
}

class Tetris:
    def __init__(self):
        self.win = tk.Tk()
        self.canvas = tk.Canvas(self.win, width=COLS*CELL_SIZE, height=ROWS*CELL_SIZE)
        self.canvas.pack()
        self.board = [[0]*COLS for _ in range(ROWS)]
        self.current_piece = self.new_piece()
        self.score = 0
        self.game_over = False

        # 绑定键盘事件
        self.win.bind('<Left>', lambda e: self.move(-1))
        self.win.bind('<Right>', lambda e: self.move(1))
        self.win.bind('<Down>', lambda e: self.move_down())
        self.win.bind('<Up>', lambda e: self.rotate())
        self.win.bind('<space>', lambda e: self.drop())

        self.draw_board()
        self.update()
        self.win.mainloop()

    def new_piece(self):
        shape = random.choice(list(SHAPES.keys()))
        return {
            'shape': shape,
            'cells': SHAPES[shape],
            'x': COLS//2,
            'y': 0,
            'color': random.randint(1, len(COLORS)-1)
        }

    def draw_cell(self, x, y, color):
        x1 = x * CELL_SIZE
        y1 = y * CELL_SIZE
        x2 = x1 + CELL_SIZE
        y2 = y1 + CELL_SIZE
        self.canvas.create_rectangle(x1, y1, x2, y2, fill=COLORS[color], outline='white')

    def draw_board(self):
        self.canvas.delete('all')
        for y in range(ROWS):
            for x in range(COLS):
                if self.board[y][x]:
                    self.draw_cell(x, y, self.board[y][x])

        for (dx, dy) in self.current_piece['cells']:
            x = self.current_piece['x'] + dx
            y = self.current_piece['y'] + dy
            if 0 <= x < COLS and 0 <= y < ROWS:
                self.draw_cell(x, y, self.current_piece['color'])

    def valid_move(self, dx=0, dy=0, rotation=0):
        new_cells = [(dy + dx*cell[1], dx - dy*cell[0]) 
                    for cell in self.current_piece['cells']] if rotation else self.current_piece['cells']
        for (cx, cy) in new_cells:
            x = self.current_piece['x'] + cx + dx
            y = self.current_piece['y'] + cy + dy
            if x < 0 or x >= COLS or y >= ROWS or (y >=0 and self.board[y][x]):
                return False
        return True

    def move(self, dx):
        if not self.game_over and self.valid_move(dx=dx):
            self.current_piece['x'] += dx
            self.draw_board()

    def move_down(self):
        if not self.game_over and self.valid_move(dy=1):
            self.current_piece['y'] += 1
            self.draw_board()
        else:
            self.merge_piece()

    def rotate(self):
        if self.valid_move(rotation=1):
            self.current_piece['cells'] = [(-cell[1], cell[0]) 
                                          for cell in self.current_piece['cells']]
            self.draw_board()

    def drop(self):
        while self.valid_move(dy=1):
            self.current_piece['y'] += 1
        self.merge_piece()

    def merge_piece(self):
        for (dx, dy) in self.current_piece['cells']:
            x = self.current_piece['x'] + dx
            y = self.current_piece['y'] + dy
            if y >= 0:
                self.board[y][x] = self.current_piece['color']
        self.clear_lines()
        self.current_piece = self.new_piece()
        if not self.valid_move():
            self.game_over = True
            self.canvas.create_text(COLS*CELL_SIZE//2, ROWS*CELL_SIZE//2,
                                   text=f"Game Over! Score: {self.score}", fill="red", font=('Arial', 20))

    def clear_lines(self):
        lines = 0
        for y in range(ROWS-1, -1, -1):
            if 0 not in self.board[y]:
                del self.board[y]
                self.board.insert(0, [0]*COLS)
                lines += 1
        self.score += lines**2 * 100

    def update(self):
        if not self.game_over:
            self.move_down()
            self.win.after(800, self.update)

if __name__ == "__main__":
    Tetris()

相关文章:

  • 主流NoSQL数据库类型及选型分析
  • Redis客户端Jedis、Lettuce 和 Redisson优缺点总结
  • 【Linux———生产消费模型】
  • ubuntu20.04下的opencv4.8.0安装教程(其他版本通用)
  • git clone, 算是解决可以访问github但无法clone的问题
  • 动态规划合集——动态规划基本原理
  • Java JMX 未授权访问漏洞分析与修复指南
  • 云计算迁移革命:企业如何摆脱“单一云”锁定,构建自主云未来?
  • GPU 上的 Reduction(归约)和 Scan(前缀和)优化:LLVM、GPU 指令集与架构差异
  • 在线教育网站项目第四步:deepseek骗我, WSL2不能创建两个独立的Ubuntu,但我们能实现实例互访及外部访问
  • 全局上下文网络GCNet:创新架构提升视觉识别性能
  • mac calDAV 日历交互
  • 抖音视频数据获取实战:从API调用到热门内容挖掘
  • Android Studio控制台中文乱码解决方案
  • 利用knn算法实现手写数字分类
  • 检索增强生成(2)本地PDF 本地嵌入模型
  • 顺序表:数据结构的“上古神兽”
  • 程序化广告行业(30/89):利用“4W1H”模型优化广告投放策略
  • windows 10 系统配置Node
  • Unity 项目工程结构目录
  • 俄罗斯总统普京:5月8日零时至11日零时实施停火
  • 古籍新书·2025年春季|中国土司制度史料集成
  • 人民日报社论:做新时代挺膺担当的奋斗者
  • 这场迪图瓦纪念拉威尔的音乐会,必将成为乐迷反复品味的回忆
  • 王一博赛车故障退赛冲上热搜,工作室回应:下次再战
  • 最高法专门规范涉企案件审执工作:从源头防止趋利性执法司法