网络编程
位置:首页>> 网络编程>> Python编程>> Python Pygame实现俄罗斯方块

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()

效果:

Python Pygame实现俄罗斯方块

更多俄罗斯方块精彩文章请点击专题:俄罗斯方块游戏集合 进行学习。

来源:https://blog.csdn.net/m0_46278037/article/details/113851443

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com