鱼C论坛

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

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

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

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

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

x
#导入模块
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 = [i for i in range(60,320,20)]

        def __init__(self):
                self.open_block()

        #设置方块基本参数
        def open_block(self):
                self.blocktype = randint(1,7)
                self.Xposition = self.Xposition_list[randint(0,12)]
                self.Yposition = 20
                self.color = self.color_dict[self.blocktype]
                self.structure = self.structure_dict[self.blocktype]
                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[self.angle][each][0] * 20
                        y = self.Yposition + self.structure[self.angle][each][1] * 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[block.angle][each][0] * 20
                        y = block.Yposition + block.structure[block.angle][each][1] * 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[pointer][1] == 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[each][1] < minY:
                                self.position_list[each] = (self.position_list[each][0],self.position_list[each][1] + 20 * count)

        #绘图
        def draw_stacked_blocks(self):
                for each in range(len(self.position_list)):
                        pos_and_lengh = (self.position_list[each][0],self.position_list[each][1],20,20)
                        pygame.draw.rect(screen,self.color_list[each],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[block.angle][each][0] * 20
                        y = block.Yposition + block.structure[block.angle][each][1] * 20 + 20
                        if ((x,y) in stack.position_list) or (y == 500):
                                conversion()

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

        elif detection_type == 3:        #检测左边界
                left_boundary = block.Xposition + min(block.structure[block.angle])[0] * 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[midvar][each][0] * 20
                        y = block.Yposition + block.structure[midvar][each][1] * 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[midvar][each][0] * 20
                        y = block.Yposition + block.structure[midvar][each][1] * 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[block.angle][each][1] * 20)
        newRows_dict = {}
        for each in Rows:
                newRows_dict.update({each:set()})
        for each in stack.position_list:
                if each[1] in newRows_dict:
                        newRows_dict[each[1]].add(each[0])
        count = 0
        eliminate_ordinates = []
        for each in newRows_dict:
                if sum(newRows_dict[each]) == 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 = [key_texta,key_textd,key_texts,key_textk,key_textl,key_textp]
        position = [400,350]
        for each in range(len(text_list)):
                screen.blit(text_list[each],position)
                position[1] += 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.blocktype-1][0] + next_block.structure[0][each][0] * 15
                y = position_list[next_block.blocktype-1][1] + next_block.structure[0][each][1] * 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([500,500])
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

评分

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

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

头像被屏蔽
发表于 2023-10-26 13:45:37 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-21 13:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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