zhizyy 发表于 2023-10-22 15:06:11

新手刚看完小甲鱼的视频,写的俄罗斯方块,求大神指导


#导入模块
import pygame
from random import randint
from time import time,sleep
from sys import exit

#初始化
pygame.init()

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

#下落盒子类
class Draw_Block:
      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)}
      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)))
      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)))
      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)))
      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)))
      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)))
      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)))
      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)))
      structure_dict = {1:type_I,2:type_J,3:type_T,4:type_L,5:type_Z,6:type_O,7:type_S}
      Xposition_list =

      def __init__(self):
                self.open_block()

      #设置方块基本参数
      def open_block(self):
                self.blocktype = randint(1,7)
                self.Xposition = self.Xposition_list
                self.Yposition = 20
                self.color = self.color_dict
                self.structure = self.structure_dict
                self.angle = 0

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

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

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

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

                elif chr(each.key) == 'l':
                        touch_judgment(5)
                        self.angle -= 1
                        
                if self.angle == 4 or self.angle == -4:
                        self.angle =0

                self.draw_block()
                self.Yposition -= 20

      #一般下落
      def draw_block(self):
                for each in range(4):
                        x = self.Xposition + self.structure * 20
                        y = self.Yposition + self.structure * 20
                        pygame.draw.rect(screen,self.color,(x,y,20,20),2)
                touch_judgment()
                self.Yposition += 20

#堆积方块类
class Stacked_Blocks:
      #保存方块落地后的位置
      position_list = []
      color_list = []

      #向列表输入数据
      def input_data(self):
                for each in range(4):
                        x = block.Xposition + block.structure * 20
                        y = block.Yposition + block.structure * 20
                        self.position_list.append((x,y))
                        self.color_list.append(block.color)

      #从列表删除数据
      def delete_data(self,Yrow):
                pointer = 0
                while pointer < len(self.position_list):
                        if self.position_list == Yrow:
                              self.position_list.pop(pointer)
                              self.color_list.pop(pointer)
                              pointer -= 1
                        pointer += 1

      #更改纵坐标(下落)
      def change_Yposition(self,count,minY):
                for each in range(len(self.position_list)):
                        if self.position_list < minY:
                              self.position_list = (self.position_list,self.position_list + 20 * count)

      #绘图
      def draw_stacked_blocks(self):
                for each in range(len(self.position_list)):
                        pos_and_lengh = (self.position_list,self.position_list,20,20)
                        pygame.draw.rect(screen,self.color_list,pos_and_lengh,2)

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

#检测碰撞
def touch_judgment(detection_type=1):
      if detection_type == 1:                #检测触底
                for each in range(4):
                        x = block.Xposition + block.structure * 20
                        y = block.Yposition + block.structure * 20 + 20
                        if ((x,y) in stack.position_list) or (y == 500):
                              conversion()

      elif detection_type == 2:         #检测右边界
                right_boundary = block.Xposition + max(block.structure) * 20 + 20
                if right_boundary == 380:
                        block.Xposition -= 20

      elif detection_type == 3:      #检测左边界
                left_boundary = block.Xposition + min(block.structure) * 20
                if left_boundary == 20:
                        block.Xposition += 20

      elif detection_type == 4:      #检测顺时针旋转边界
                midvar = block.angle + 1
                if midvar == 4:
                        midvar = 0
                for each in range(4):
                        x = block.Xposition + block.structure * 20
                        y = block.Yposition + block.structure * 20 + 20
                        if (x >= 380) or (x <= 0) or ((x,y) in stack.position_list) or (y >= 500):
                              block.angle -= 1
                              break

      else:      #检测逆时针旋转边界
                midvar = block.angle - 1
                if midvar == -4:
                        midvar = 0
                for each in range(4):
                        x = block.Xposition + block.structure * 20
                        y = block.Yposition + block.structure * 20 + 20
                        if (x >= 380) or (x <= 0) or ((x,y) in stack.position_list) or (y >= 500):
                              block.angle += 1
                              break

#抵消下落
def detection_offset():
      Rows = set()
      for each in range(4):
                Rows.add(block.Yposition + block.structure * 20)
      newRows_dict = {}
      for each in Rows:
                newRows_dict.update({each:set()})
      for each in stack.position_list:
                if each in newRows_dict:
                        newRows_dict].add(each)
      count = 0
      eliminate_ordinates = []
      for each in newRows_dict:
                if sum(newRows_dict) == 3420:
                        eliminate_ordinates.append(each)
                        count += 1
                        stack.delete_data(each)
      if count:
                stack.change_Yposition(count,min(eliminate_ordinates))
                score.add(count)

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

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

      keys_font = pygame.font.SysFont('arial',16)
      key_texta = keys_font.render('A   move left',True,(0,0,0),(242, 240, 240))
      key_textd = keys_font.render('D   move right',True,(0,0,0),(242, 240, 240))
      key_texts = keys_font.render('S   fater down',True,(0,0,0),(242, 240, 240))
      key_textk = keys_font.render('K   rotate cw',True,(0,0,0),(242, 240, 240))
      key_textl = keys_font.render('L   rotate acw',True,(0,0,0),(242, 240, 240))
      key_textp = keys_font.render('P   suspend',True,(0,0,0),(242, 240, 240))
      text_list =
      position =
      for each in range(len(text_list)):
                screen.blit(text_list,position)
                position += 20

#绘制下一个盒子
def draw_next():
      position_list = [(410,105),(418,110),(418,110),(418,110),(448,110),(425,110),(418,110)]
      for each in range(4):
                x = position_list + next_block.structure * 15
                y = position_list + next_block.structure * 15
                pygame.draw.rect(screen,next_block.color,(x,y,15,15),2)

#循环函数
def unified_drawing():
      draw_background()
      draw_next()
      score.draw_socre()
      block.draw_block()
      stack.draw_stacked_blocks()
      pygame.display.update()

#创立窗口
screen = pygame.display.set_mode()
pygame.display.set_caption('俄罗斯方块')
pygame.display.flip()

#生产实例对象
score = Calculate_Score()
block = Draw_Block()
next_block = Draw_Block()
stack = Stacked_Blocks()

num = 0
state = True
while True:
      while state:
                num += 1
                if num % 100000 == 0:
                        unified_drawing()
                for each in pygame.event.get():
                        if each.type == pygame.QUIT:
                              exit()
                        elif each.type == pygame.KEYDOWN:
                              if each.key == pygame.K_p:
                                        state = False
                              block.change_fall(each)
      for each in pygame.event.get():
                if each.type == pygame.QUIT:
                              exit()
                if each.type == pygame.KEYDOWN:
                        if each.key == pygame.K_p:
                              state = True

rtiuyttr 发表于 2023-10-26 13:45:37

页: [1]
查看完整版本: 新手刚看完小甲鱼的视频,写的俄罗斯方块,求大神指导