鱼C论坛

 找回密码
 立即注册
查看: 1239|回复: 1

[作品展示] 新手刚看完小甲鱼的视频,写的俄罗斯方块,求大神指导

[复制链接]
发表于 2023-10-22 15:06:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

  1. #导入模块
  2. import pygame
  3. from random import randint
  4. from time import time,sleep
  5. from sys import exit

  6. #初始化
  7. pygame.init()

  8. #分数类
  9. class Calculate_Score:
  10.         number = 0
  11.         font_type = pygame.font.SysFont('微软雅黑',30)
  12.         def add(self,count):
  13.                 self.number += 10 * count
  14.         def draw_socre(self):
  15.                 text = self.font_type.render(f'socre:{self.number}',True,(0,0,0),(242, 240, 240))
  16.                 screen.blit(text,(405,30))

  17. #下落盒子类
  18. class Draw_Block:
  19.         color_dict = {1:(33,97,140),2:(11,143,147),3:(248,196,113),4:(185,119,14),5:(236,112,99),6:(142,68,173),7:(40,180,99)}
  20.         type_I = (((0,0),(1,0),(2,0),(3,0)),((0,0),(0,-1),(0,-2),(0,-3)),((0,0),(1,0),(2,0),(3,0)),((0,0),(0,-1),(0,-2),(0,-3)))
  21.         type_J = (((0,0),(1,0),(2,0),(0,-1)),((0,0),(0,-1),(0,-2),(1,-2)),((0,0),(0,-1),(-1,-1),(-2,-1)),((0,0),(1,0),(1,-1),(1,-2)))
  22.         type_T = (((0,0),(1,0),(2,0),(1,-1)),((0,0),(0,-1),(0,-2),(1,-1)),((0,0),(-1,-1),(0,-1),(1,-1)),((0,0),(0,-1),(0,-2),(-1,-1)))
  23.         type_L = (((0,0),(1,0),(2,0),(2,-1)),((0,0),(1,0),(0,-1),(0,-2)),((0,0),(0,-1),(1,-1),(2,-1)),((0,0),(0,-1),(0,-2),(-1,-2)))
  24.         type_Z = (((0,0),(-1,0),(-1,-1),(-2,-1)),((0,0),(0,-1),(1,-1),(1,-2)),((0,0),(-1,0),(-1,-1),(-2,-1)),((0,0),(0,-1),(1,-1),(1,-2)))
  25.         type_O = (((0,0),(1,0),(0,-1),(1,-1)),((0,0),(1,0),(0,-1),(1,-1)),((0,0),(1,0),(0,-1),(1,-1)),((0,0),(1,0),(0,-1),(1,-1)))
  26.         type_S = (((0,0),(1,0),(1,-1),(2,-1)),((0,0),(0,-1),(-1,-1),(-1,-2)),((0,0),(1,0),(1,-1),(2,-1)),((0,0),(0,-1),(-1,-1),(-1,-2)))
  27.         structure_dict = {1:type_I,2:type_J,3:type_T,4:type_L,5:type_Z,6:type_O,7:type_S}
  28.         Xposition_list = [i for i in range(60,320,20)]

  29.         def __init__(self):
  30.                 self.open_block()

  31.         #设置方块基本参数
  32.         def open_block(self):
  33.                 self.blocktype = randint(1,7)
  34.                 self.Xposition = self.Xposition_list[randint(0,12)]
  35.                 self.Yposition = 20
  36.                 self.color = self.color_dict[self.blocktype]
  37.                 self.structure = self.structure_dict[self.blocktype]
  38.                 self.angle = 0

  39.         #变化下落
  40.         def change_fall(self,each):
  41.                 if chr(each.key) == 'a':
  42.                         touch_judgment(3)
  43.                         self.Xposition -= 20

  44.                 elif chr(each.key) == 'd':
  45.                         touch_judgment(2)
  46.                         self.Xposition += 20

  47.                 elif chr(each.key) == 's':
  48.                         self.Yposition += 20
  49.                         touch_judgment(1)

  50.                 elif chr(each.key) == 'k':
  51.                         touch_judgment(4)
  52.                         self.angle += 1

  53.                 elif chr(each.key) == 'l':
  54.                         touch_judgment(5)
  55.                         self.angle -= 1
  56.                         
  57.                 if self.angle == 4 or self.angle == -4:
  58.                         self.angle =0

  59.                 self.draw_block()
  60.                 self.Yposition -= 20

  61.         #一般下落
  62.         def draw_block(self):
  63.                 for each in range(4):
  64.                         x = self.Xposition + self.structure[self.angle][each][0] * 20
  65.                         y = self.Yposition + self.structure[self.angle][each][1] * 20
  66.                         pygame.draw.rect(screen,self.color,(x,y,20,20),2)
  67.                 touch_judgment()
  68.                 self.Yposition += 20

  69. #堆积方块类
  70. class Stacked_Blocks:
  71.         #保存方块落地后的位置
  72.         position_list = []
  73.         color_list = []

  74.         #向列表输入数据
  75.         def input_data(self):
  76.                 for each in range(4):
  77.                         x = block.Xposition + block.structure[block.angle][each][0] * 20
  78.                         y = block.Yposition + block.structure[block.angle][each][1] * 20
  79.                         self.position_list.append((x,y))
  80.                         self.color_list.append(block.color)

  81.         #从列表删除数据
  82.         def delete_data(self,Yrow):
  83.                 pointer = 0
  84.                 while pointer < len(self.position_list):
  85.                         if self.position_list[pointer][1] == Yrow:
  86.                                 self.position_list.pop(pointer)
  87.                                 self.color_list.pop(pointer)
  88.                                 pointer -= 1
  89.                         pointer += 1

  90.         #更改纵坐标(下落)
  91.         def change_Yposition(self,count,minY):
  92.                 for each in range(len(self.position_list)):
  93.                         if self.position_list[each][1] < minY:
  94.                                 self.position_list[each] = (self.position_list[each][0],self.position_list[each][1] + 20 * count)

  95.         #绘图
  96.         def draw_stacked_blocks(self):
  97.                 for each in range(len(self.position_list)):
  98.                         pos_and_lengh = (self.position_list[each][0],self.position_list[each][1],20,20)
  99.                         pygame.draw.rect(screen,self.color_list[each],pos_and_lengh,2)

  100. #下落盒子和堆积盒子转换
  101. def conversion():
  102.         global block,next_block
  103.         stack.input_data()
  104.         detection_offset()
  105.         block,next_block = (next_block,Draw_Block())

  106. #检测碰撞
  107. def touch_judgment(detection_type=1):
  108.         if detection_type == 1:                #检测触底
  109.                 for each in range(4):
  110.                         x = block.Xposition + block.structure[block.angle][each][0] * 20
  111.                         y = block.Yposition + block.structure[block.angle][each][1] * 20 + 20
  112.                         if ((x,y) in stack.position_list) or (y == 500):
  113.                                 conversion()

  114.         elif detection_type == 2:         #检测右边界
  115.                 right_boundary = block.Xposition + max(block.structure[block.angle])[0] * 20 + 20
  116.                 if right_boundary == 380:
  117.                         block.Xposition -= 20

  118.         elif detection_type == 3:        #检测左边界
  119.                 left_boundary = block.Xposition + min(block.structure[block.angle])[0] * 20
  120.                 if left_boundary == 20:
  121.                         block.Xposition += 20

  122.         elif detection_type == 4:        #检测顺时针旋转边界
  123.                 midvar = block.angle + 1
  124.                 if midvar == 4:
  125.                         midvar = 0
  126.                 for each in range(4):
  127.                         x = block.Xposition + block.structure[midvar][each][0] * 20
  128.                         y = block.Yposition + block.structure[midvar][each][1] * 20 + 20
  129.                         if (x >= 380) or (x <= 0) or ((x,y) in stack.position_list) or (y >= 500):
  130.                                 block.angle -= 1
  131.                                 break

  132.         else:        #检测逆时针旋转边界
  133.                 midvar = block.angle - 1
  134.                 if midvar == -4:
  135.                         midvar = 0
  136.                 for each in range(4):
  137.                         x = block.Xposition + block.structure[midvar][each][0] * 20
  138.                         y = block.Yposition + block.structure[midvar][each][1] * 20 + 20
  139.                         if (x >= 380) or (x <= 0) or ((x,y) in stack.position_list) or (y >= 500):
  140.                                 block.angle += 1
  141.                                 break

  142. #抵消下落
  143. def detection_offset():
  144.         Rows = set()
  145.         for each in range(4):
  146.                 Rows.add(block.Yposition + block.structure[block.angle][each][1] * 20)
  147.         newRows_dict = {}
  148.         for each in Rows:
  149.                 newRows_dict.update({each:set()})
  150.         for each in stack.position_list:
  151.                 if each[1] in newRows_dict:
  152.                         newRows_dict[each[1]].add(each[0])
  153.         count = 0
  154.         eliminate_ordinates = []
  155.         for each in newRows_dict:
  156.                 if sum(newRows_dict[each]) == 3420:
  157.                         eliminate_ordinates.append(each)
  158.                         count += 1
  159.                         stack.delete_data(each)
  160.         if count:
  161.                 stack.change_Yposition(count,min(eliminate_ordinates))
  162.                 score.add(count)

  163. #绘制背景图
  164. def draw_background():
  165.         screen.fill((242, 240, 240))
  166.         for i in range(40,380,20):
  167.                 pygame.draw.line(screen,(212, 208, 208),(i,0),(i,500))
  168.         for i in range(20,500,20):
  169.                 pygame.draw.line(screen,(212, 208, 208),(20,i),(380,i))
  170.         pygame.draw.line(screen,(0,0,0),(380,0),(380,500),2)
  171.         pygame.draw.line(screen,(0,0,0),(18,0),(18,500),2)
  172.         pygame.draw.rect(screen,(171,169,169),(390,80,100,60),2)

  173.         cueword_font = pygame.font.SysFont('微软雅黑',22)
  174.         next_text = cueword_font.render('NEXT',True,(0,0,0),(242, 240, 240))
  175.         actkeys_text = cueword_font.render('ACTION KEYS',True,(0,0,0),(242, 240, 240))
  176.         screen.blit(next_text,(420,145))
  177.         screen.blit(actkeys_text,(388,330))

  178.         keys_font = pygame.font.SysFont('arial',16)
  179.         key_texta = keys_font.render('A   move left',True,(0,0,0),(242, 240, 240))
  180.         key_textd = keys_font.render('D   move right',True,(0,0,0),(242, 240, 240))
  181.         key_texts = keys_font.render('S   fater down',True,(0,0,0),(242, 240, 240))
  182.         key_textk = keys_font.render('K   rotate cw',True,(0,0,0),(242, 240, 240))
  183.         key_textl = keys_font.render('L   rotate acw',True,(0,0,0),(242, 240, 240))
  184.         key_textp = keys_font.render('P   suspend',True,(0,0,0),(242, 240, 240))
  185.         text_list = [key_texta,key_textd,key_texts,key_textk,key_textl,key_textp]
  186.         position = [400,350]
  187.         for each in range(len(text_list)):
  188.                 screen.blit(text_list[each],position)
  189.                 position[1] += 20

  190. #绘制下一个盒子
  191. def draw_next():
  192.         position_list = [(410,105),(418,110),(418,110),(418,110),(448,110),(425,110),(418,110)]
  193.         for each in range(4):
  194.                 x = position_list[next_block.blocktype-1][0] + next_block.structure[0][each][0] * 15
  195.                 y = position_list[next_block.blocktype-1][1] + next_block.structure[0][each][1] * 15
  196.                 pygame.draw.rect(screen,next_block.color,(x,y,15,15),2)

  197. #循环函数
  198. def unified_drawing():
  199.         draw_background()
  200.         draw_next()
  201.         score.draw_socre()
  202.         block.draw_block()
  203.         stack.draw_stacked_blocks()
  204.         pygame.display.update()

  205. #创立窗口
  206. screen = pygame.display.set_mode([500,500])
  207. pygame.display.set_caption('俄罗斯方块')
  208. pygame.display.flip()

  209. #生产实例对象
  210. score = Calculate_Score()
  211. block = Draw_Block()
  212. next_block = Draw_Block()
  213. stack = Stacked_Blocks()

  214. num = 0
  215. state = True
  216. while True:
  217.         while state:
  218.                 num += 1
  219.                 if num % 100000 == 0:
  220.                         unified_drawing()
  221.                 for each in pygame.event.get():
  222.                         if each.type == pygame.QUIT:
  223.                                 exit()
  224.                         elif each.type == pygame.KEYDOWN:
  225.                                 if each.key == pygame.K_p:
  226.                                         state = False
  227.                                 block.change_fall(each)
  228.         for each in pygame.event.get():
  229.                 if each.type == pygame.QUIT:
  230.                                 exit()
  231.                 if each.type == pygame.KEYDOWN:
  232.                         if each.key == pygame.K_p:
  233.                                 state = True
复制代码

评分

参与人数 1荣誉 +5 贡献 +3 收起 理由
liuhongrun2022 + 5 + 3 鱼C有你更精彩^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

头像被屏蔽
发表于 2023-10-26 13:45:37 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-22 19:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表