Python Pygame实现俄罗斯方块
作者:一个超会写Bug的安太狼 发布时间:2023-03-17 07:18:03
标签:python,pygame,俄罗斯方块
本文实例为大家分享了Python Pygame实现俄罗斯方块的具体代码,供大家参考,具体内容如下
源码:
# coding : utf-8
#: pip install pygame
import random
import sys
import pygame
#: 颜色定义
COLOR_WHITE = (255, 255, 255)
COLOR_BLACK = (0, 0, 0)
class Block:
"""小块"""
width = 24
height = 24
@staticmethod
def draw(s, left, top, color, bg_color):
pygame.draw.rect(s, bg_color, pygame.Rect(left, top, Block.width, Block.height))
pygame.draw.rect(s, color, pygame.Rect(left, top, Block.width - 1, Block.height - 1))
class Building:
"""积木"""
def __init__(self):
"""
方块的7种基本形状
每次初始化随机选择一个形状
@:return True / False
"""
self.form = random.choice(
[
[
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[1, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 1, 0],
[0, 1, 1, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]
],
[
[0, 0, 0, 0, 0],
[0, 1, 1, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
]
])
def __getitem__(self, pos):
return self.form[pos]
def __setitem__(self, key, value):
self.form[key] = value
class Layout:
"""棋盘"""
def __init__(self):
self.block_x_count = 16;
self.block_y_count = 22;
self.layout = [[0 if 1 < i < self.block_x_count - 2 and j < self.block_y_count - 2 else 1
for i in range(self.block_x_count)] for j in range(self.block_y_count)]
@property
def size(self):
"""返回棋盘屏幕大小(width,height)"""
return (self.block_x_count * Block.width, self.block_y_count * Block.height)
def create_new_building(self):
"""
创建新的积木,初始化位置为第5,0格, 速度为4
:return: 返回是否无空间创建了
"""
self.building = Building()
self.building_left, self.building_top = 5, 0 #
self.drop_speed = 3
print(self.test_building_touch_wall())
return self.test_building_touch_wall()
@property
def speed(self):
return self.drop_speed
def test_building_touch_wall(self, x_offset=0, y_offset=0):
"""
积木是否已经触底/墙壁
具体操作:
判断积木最后一排的1,是否在当前棋牌对应的位置是也是1
@:param x_offset: x的偏移量 移动时可以传入1/-1来判断
@:param y_offset: y的偏移量 正常下落时可以传入1来判断
"""
for i in range(4, -1, -1):
for j in range(5):
if self.building[i][j]:
if self.layout[i + self.building_top + y_offset][j + self.building_left + x_offset]:
return True
return False
def move_left_right(self, x):
"""
左右移动
@:param x: 移动量 x_offset
"""
#: 移动时不能撞墙
if not self.test_building_touch_wall(x_offset=x):
self.building_left += x
def down_build(self):
""" 盒子的自动下移 """
self.building_top += 1
def direct_down(self):
""" 手动快速降落 """
self.drop_speed = 50
def convert_building(self):
"""
* 扭转盒子的总方位 (右转)
具体操作:
把第一竖排的倒序给第一横排的
把第二竖排的倒序给第二横排的
后面同理.
"""
new_box = [[0 for i in range(5)] for j in range(5)]
for i in range(5):
for j in range(4, -1, -1):
new_box[i][j] = self.building[4 - j][i]
self.building = new_box
def clear_full_lines(self):
"""消除满行的所有行"""
new_layout = [[0 if 1 < i < self.block_x_count - 2 and j < self.block_y_count - 2 else 1
for i in range(self.block_x_count)] for j in range(self.block_y_count)]
row_len = self.block_x_count - 4
new_row = self.block_y_count - 2 - 1
for cur_row in range(self.block_y_count - 2 - 1, 0, -1):
if sum(self.layout[cur_row][2:self.block_x_count - 2]) < row_len:
new_layout[new_row] = self.layout[cur_row]
new_row -= 1
self.layout = new_layout
def put_building_to_layout(self):
"""将积木放到棋盘里"""
for i in range(4, -1, -1):
for j in range(5):
if self.building[i][j]:
self.layout[i + self.building_top][j + self.building_left] = 1
#: 这里会调用消除函数
self.clear_full_lines()
def draw_building(self, s):
"""
显示积木
@:param s : pygame = screen
"""
cur_left, cur_top = self.building_left * Block.width, self.building_top * Block.height
for i in range(5):
for j in range(5):
# 只画积木实体,不管盒子本身
if self.building[j][i]:
Block.draw(s, cur_left + i * Block.width, cur_top + j * Block.height, COLOR_BLACK, COLOR_WHITE)
def draw(self, s):
"""
显示棋盘
@:param s : pygame = screen
"""
for i in range(self.block_x_count):
for j in range(self.block_y_count):
if self.layout[j][i] == 0:
Block.draw(s, i * Block.width, j * Block.height, COLOR_WHITE, COLOR_BLACK)
else:
Block.draw(s, i * Block.width, j * Block.height, COLOR_BLACK, COLOR_WHITE)
# -------------------------------------------------------------------
# Main
# -------------------------------------------------------------------
def main():
#: 初始化
while True:
layout = Layout()
layout.create_new_building()
pygame.init()
pygame.display.set_caption('俄罗斯方块')
screen = pygame.display.set_mode((layout.size), 0, 32)
is_over = False
#: 单局游戏循环开始 [结束后直接重新开始]
while not is_over:
#: 处理游戏消息
for e in pygame.event.get():
if e.type == pygame.QUIT:
sys.exit()
#: 处理按键
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_UP:
layout.convert_building()
if e.key == pygame.K_DOWN:
layout.direct_down()
if e.key == pygame.K_LEFT:
layout.move_left_right(-1)
if e.key == pygame.K_RIGHT:
layout.move_left_right(1)
#: 是否碰触底部地面了,是 -> 融合背景 否 -> 继续下落
if layout.test_building_touch_wall(y_offset=1):
layout.put_building_to_layout()
is_over = layout.create_new_building()
else:
layout.down_build()
#: 绘制
layout.draw(screen)
layout.draw_building(screen)
pygame.display.update()
#: 速度
pygame.time.Clock().tick(layout.speed)
if __name__ == '__main__':
main()
效果:
更多俄罗斯方块精彩文章请点击专题:俄罗斯方块游戏集合 进行学习。
来源:https://blog.csdn.net/m0_46278037/article/details/113851443


猜你喜欢
- 前文主要纠正title用法上的几点误区,其实除链接和表单的常规标签用法。在内容组织方面还有大潜力待发掘,比如写网志经常会有针对词、短语说明的
- 本文实例讲述了layer弹窗插件操作方法。分享给大家供大家参考,具体如下:1、首先去http://layer.layui.com/下载插件2
- javascript编写的窗口代码,可以关闭显示窗口,可以最小化或还原窗口大小,还可以鼠标移动窗口,不错的一个功能。截图如下:<htm
- 读写 JSON 数据问题你想读写 JSON(JavaScript Object Notation) 编码格式的数据。解决方案json模块提供
- 本文实例为大家分享了一组典型数据格式转换的python实现代码,供大家参考,具体内容如下有一组源数据,第一行会是个日期数据,第二行标明字段,
- Stickyworld 的网页应用已经支持视频拨放一段时间,但都是通过YouTube的嵌入模式实现。我们开始提供新的版本支持视频操作,可以让
- 介绍据官方所述,mango Cache是对Guava Cache基于go的部分实现,同时mangoCache参考了Caffeine以及go-
- 大致介绍TypeScript是由C#语言之父Anders Hejlsberg主导开发的一门编程语言,TypeScript本质上是向JavaS
- os 包 和 bufio 包Go 标准库的 os 包,为我们提供很多操作文件的函数,如 Open(name) 打开文件、Create(nam
- 本次主要是使用selenium模拟登录网页端的TX新闻,本来最开始是模拟请求的,但是某一天突然发现,部分账号需要经过滑块验证才能正常登录,如
- SQL Server数据库备份有两种方式,一种是使用BACKUP DATABASE将数据库文件备份出去,另外一种就是直接拷贝数据库文件mdf
- 这是 2020 年第 3 个版本,也是最后一个版本。在 GoLand 2020.3 中,您可以探索 goroutines dumps,运行并
- 一、Python 下载Python是运行的环境,必不可少,如果你是Linux系统的话,不用安装,自带了Python。首先我们打开浏览器搜索P
- 目录引言response响应元组形式响应make_response函数返回json格式数据其他特殊响应redirect() 重定向abort
- 经常看到说正则的文章,但说的只是方法,却很少有说以下几个基本概念:1.贪婪:+,*,?,{m,n}等默认是贪婪匹配,即尽可能多匹配,也叫最大
- 1.1 什么是多线程 Threading多线程可简单理解为同时执行多个任务。多进程和多线程都可以执行多个任务,线程是进程的一部分。线程的特点
- 关于DHT协议DHT协议作为BT协议的一个辅助,是非常好玩的。它主要是为了在BT正式下载时得到种子或者BT资源。传统的网络,需要一台中央服务
- 在Microsoft OfficeAccess和 Microsoft OfficeExcel之间存在多种交换数据的方法。若要将Access中
- Python自动的os库是和操作系统交互的库,常用的操作包括文件/目录操作,路径操作,环境变量操作和执行系统命令等。文件/目录操作获取当前目
- 下面请看本文详细介绍.Perl字符串处理函数1. index语法:position=index(string,substring,posit