俄罗斯方块【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是游戏的入口,运行代码,你就可以得到一个简单的俄罗斯方块游戏。

相关推荐
Envyᥫᩣ8 分钟前
C#语言:从入门到精通
开发语言·c#
云空17 分钟前
《Python 与 SQLite:强大的数据库组合》
数据库·python·sqlite
童先生29 分钟前
Go 项目中实现类似 Java Shiro 的权限控制中间件?
开发语言·go
lulu_gh_yu30 分钟前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
Re.不晚1 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
老秦包你会1 小时前
Qt第三课 ----------容器类控件
开发语言·qt
凤枭香1 小时前
Python OpenCV 傅里叶变换
开发语言·图像处理·python·opencv
ULTRA??1 小时前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++
测试杂货铺1 小时前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
艾派森1 小时前
大数据分析案例-基于随机森林算法的智能手机价格预测模型
人工智能·python·随机森林·机器学习·数据挖掘