俄罗斯方块【python,小游戏】

俄罗斯方块(Tetris)是一款经典的俄罗斯益智游戏,游戏的核心玩法是通过移动、旋转和放置不同形状的方块,使它们在游戏界面的底部形成完整的水平线。一旦水平线填满,就会被清除,为新的方块腾出空间。

在 Python 中可以使用第三方库pygame来实现简单的俄罗斯方块游戏,使用pygame前需确保其已经安装。示例代码如下:

python 复制代码
import random
import sys

import pygame


# 定义俄罗斯方块类
class Tetris:
	# 初始化方块类型
	all_block_shapes = [[[0, 0], [0, -1], [0, 1], [0, 2]],
	                    [[0, 0], [0, 1], [1, 1], [1, 0]],
	                    [[0, 0], [0, -1], [-1, 0], [-1, 1]],
	                    [[0, 0], [0, 1], [-1, -1], [-1, 0]],
	                    [[0, 0], [0, 1], [1, 0], [0, -1]],
	                    [[0, 0], [1, 0], [-1, 0], [1, -1]],
	                    [[0, 0], [1, 0], [-1, 0], [1, 1]]]

	current_block_shape = list(random.choice(all_block_shapes))
	score = [0]
	game_over = []

	# 初始化
	def __init__(self, height, width, block_initial_position, screen):

		self.background = [[0 for column in range(0, width)] for row in
		                   range(0, height)]
		self.background[0] = [1 for column in range(0, width)]

		self.block_initial_position = block_initial_position
		self.screen = screen

	# 旋转方块函数
	def rotate_block(self):

		# 获取方块的初始位置
		y_drop, x_move = self.block_initial_position
		# 计算方块旋转后的位置
		rotating_position = [(-column, row) for row, column in
		                     self.current_block_shape]

		# 检查旋转后的位置是否合法
		for row, column in rotating_position:
			row += y_drop
			column += x_move

			# 如果超出边界或和背景方块重叠,则跳出循环
			if column < 0 or column > 9 or self.background[row][column]:
				break
			else:
				# 如果旋转后的位置合法,则更新方块的位置
				self.current_block_shape.clear()
				self.current_block_shape.extend(rotating_position)

	# 方块下移函数
	def block_move_down(self):
		# 获取方块的初始位置
		y_drop = self.block_initial_position[0]
		x_move = self.block_initial_position[1]
		y_drop -= 1

		# 检查方块下移后的位置是否合法
		for row, column in self.current_block_shape:
			row += y_drop
			column += x_move

			# 如果下方有背景方块,则停止下移
			if self.background[row][column] == 1:
				break
		else:
			# 如果下移位置合法,则更新方块的位置
			self.block_initial_position.clear()
			self.block_initial_position.extend([y_drop, x_move])
			return

		# 如果方块无法下移,则将方块固定在背景上,并处理消除的行
		y_drop, x_move = self.block_initial_position
		for row, column in self.current_block_shape:
			self.background[y_drop + row][x_move + column] = 1
		complete_row = []

		# 检查是否有行满了
		for row in range(1, 21):
			if 0 not in self.background[row]:
				complete_row.append(row)

		complete_row.sort(reverse=True)

		# 消除满行,并得分
		for row in complete_row:
			self.background.pop(row)
			self.background.append([0 for column in range(0, 10)])

		self.score[0] += len(complete_row)
		pygame.display.set_caption(str(self.score[0]) + '分')

		# 选择下一个方块并放置在顶部
		self.current_block_shape.clear()
		self.current_block_shape.extend(
			list(random.choice(self.all_block_shapes)))
		self.block_initial_position.clear()
		self.block_initial_position.extend([20, 5])
		y_drop, x_move = self.block_initial_position

		# 检查是否游戏结束
		for row, column in self.current_block_shape:
			row += y_drop
			column += x_move
			if self.background[row][column]:
				self.game_over.append(1)

	# 绘制元素函数
	def draw_elements(self):
		# 绘制方块
		y_drop, x_move = self.block_initial_position
		for row, column in self.current_block_shape:
			row += y_drop
			column += x_move
			pygame.draw.rect(self.screen, (255, 165, 0),
			                 (column * 25, 500 - row * 25, 23, 23))

		# 绘制背景方块
		for row in range(0, 20):
			for column in range(0, 10):
				bottom_block = self.background[row][column]
				if bottom_block:
					pygame.draw.rect(self.screen, (0, 0, 255),
					                 (column * 25, 500 - row * 25, 23, 23))

	# 方块左右移动函数
	def move_block_left_right(self, n):
		# 方块水平移动
		y_drop, x_move = self.block_initial_position
		x_move += n
		for row, column in self.current_block_shape:
			row += y_drop
			column += x_move
			# 如果超出边界或和背景方块重叠,则跳出循环
			if column < 0 or column > 9 or self.background[row][column]:
				break
		else:
			# 如果移动位置合法,则更新方块的位置
			self.block_initial_position.clear()
			self.block_initial_position.extend([y_drop, x_move])

	# 事件处理函数
	def handle_events(self):
		times = 0
		is_press = False
		while True:
			self.screen.fill((255, 255, 255))
			# 按键事件
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					sys.exit()
				elif event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
					self.move_block_left_right(-1)
				elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
					self.move_block_left_right(1)
				elif event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
					self.rotate_block()
				elif event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
					is_press = True
				elif event.type == pygame.KEYUP and event.key == pygame.K_DOWN:
					is_press = False

			# 如果下箭头键被按下,则加快方块下落速度
			if is_press:
				times += 10

			# 达到时间阈值时让方块向下移动,并重置时间
			if times >= 100:
				self.block_move_down()
				times = 0
			else:
				times += 1

			# 如果游戏结束,则退出程序
			if self.game_over:
				sys.exit()

			self.draw_elements()
			pygame.time.Clock().tick(200)
			pygame.display.flip()


# 游戏入口
def main():
	height = 22
	width = 10

	block_initial_position = [21, 5]
	pygame.init()
	screen = pygame.display.set_mode((250, 500))
	pygame.display.set_caption("俄罗斯方块")

	tetris = Tetris(height, width, block_initial_position, screen)
	# 调用按键事件处理函数
	tetris.handle_events()


# 启动游戏
main()

上述代码定义的Tetris类将游戏功能进行了封装,main是游戏的入口,运行代码,你就可以得到一个简单的俄罗斯方块游戏。

相关推荐
不知所云,1 小时前
qt cmake自定义资源目录,手动加载资源(图片, qss文件)
开发语言·qt
安冬的码畜日常1 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
阑梦清川1 小时前
Java继承、final/protected说明、super/this辨析
java·开发语言
PythonFun2 小时前
Python批量下载PPT模块并实现自动解压
开发语言·python·powerpoint
Death2002 小时前
Qt 6 相比 Qt 5 的主要提升与更新
开发语言·c++·qt·交互·数据可视化
机器视觉知识推荐、就业指导2 小时前
使用Qt实现实时数据动态绘制的折线图示例
开发语言·qt
炼丹师小米2 小时前
Ubuntu24.04.1系统下VideoMamba环境配置
python·环境配置·videomamba
GFCGUO2 小时前
ubuntu18.04运行OpenPCDet出现的问题
linux·python·学习·ubuntu·conda·pip
快乐就好ya3 小时前
Java多线程
java·开发语言
CS_GaoMing3 小时前
Centos7 JDK 多版本管理与 Maven 构建问题和注意!
java·开发语言·maven·centos7·java多版本