简单改进俄罗斯方块

对俄罗斯方块进行一部分优化:
参考地址:https://www.cnblogs.com/27dCnc/p/18568655
一、作业要求:从网上寻找一个项目或者小游戏,找出里面存在的不足之处,并且将它的不足之处优化。
二、运行环境:Windows
三、编译器:VSCODE
四、源代码*

点击查看代码 import sys import pygame from pygame.locals import * import random

class Block:
blk_color = [(255, 255, 255),(255, 255, 0),(255, 0, 255),(0, 255, 255),(255, 0, 0),(0, 255, 0),(0, 0, 255),(32,32,32)]
BLANK = 7
type_coord=[[[-1,0],[0,0],[1,0],[2,0]]
,[[-1,0],[0,0],[1,0],[0,1]]
,[[-1,0],[0,0],[-1,1],[0,1]]
,[[-1,0],[0,0],[0,1],[1,1]]
,[[0,0],[1,0],[-1,1],[0,1]]
,[[-1,0],[0,0],[1,0],[1,1]]
,[[-1,0],[0,0],[1,0],[-1,1]]]
type_rotate = []

def __init__(self,x,y,blk,angle):
    self.x = x
    self.y = y
    self.blk = blk
    self.angle = angle
    
@staticmethod
def rotate(no):
    rt_all = []
    rt = Block.type_coord[no][:]
    cx,cy=0,0
    for b in range(4):
        rt[b][0],rt[b][1] = rt[b][0]*4,rt[b][1]*4
        cx += rt[b][0]
        cy += rt[b][1]
    cx = (cx)//8*2 if no !=6 else (cx+4)//8*2
    cy = (cy)//8*2 if no !=6 else (cy-4)//8*2
    rt_all.append(rt)
    for r in range(3):
        rt_new = []
        for b in range(4):
            rt_new.append([cx + (cy-rt[b][1]),cy-(cx-rt[b][0])])
        rt_all.append(rt_new)
        rt = rt_new
    for r in range(4):
        for b in range(4):
            rt_all[r][b][0] //= 4
            rt_all[r][b][1] //= 4
    return rt_all
@staticmethod
def init_rotate():
    for r in range(7):
        Block.type_rotate.append(Block.rotate(r))

class TRS:
screen = None
map = [[Block.BLANK]*10 for i in range(20)]
STATUS = 0
cbk = None

def __init__(self,screen):
    TRS.screen = screen

@staticmethod
def action(key_pressed):
    if(key_pressed[K_LEFT] and TRS.check_action(TRS.cbk.x-1,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle)):
        TRS.cbk.x -= 1
    elif (key_pressed[K_RIGHT] and TRS.check_action(TRS.cbk.x+1,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle)):
        TRS.cbk.x += 1
    elif (key_pressed[K_UP] and TRS.check_action(TRS.cbk.x,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle+1)):
        TRS.cbk.angle += 1
    elif (key_pressed[K_DOWN] and TRS.check_action(TRS.cbk.x,TRS.cbk.y+1,TRS.cbk.blk,TRS.cbk.angle)):
        TRS.cbk.y += 1
        
@staticmethod
def new_blk():
    TRS.cbk = Block(5,0,random.randint(0,6),0)
@staticmethod
def check_action(x,y,blk,angle):
    tr = Block.type_rotate[blk][angle%4]
    for b in range(4):
        bx,by = x + tr[b][0],y + tr[b][1]
        if(bx<0 or bx>9 or by <0 or by>19 or TRS.map[by][bx]!=Block.BLANK):
            return False
    return True
@staticmethod
def check_drop():
    if TRS.check_action(TRS.cbk.x,TRS.cbk.y+1,TRS.cbk.blk,TRS.cbk.angle):
        TRS.cbk.y += 1
    else:
        TRS.STATUS = 2
        
@staticmethod
def check_clear():
    blk = Block.type_rotate[TRS.cbk.blk][TRS.cbk.angle%4]
    row = list({TRS.cbk.y + blk[i][1] for i in range(4)})
    row.sort()
    row.reverse()
    for b in range(4):
        TRS.map[TRS.cbk.y + blk[b][1]][TRS.cbk.x + blk[b][0]] = TRS.cbk.blk
    del_rows = 0
    for r in row:
        if not (Block.BLANK in TRS.map[r]):
            TRS.map.pop(r)
            del_rows += 1
    for d in range(del_rows):
        TRS.map.insert(0,[Block.BLANK for i in range(10)])
        
@staticmethod
def print_game():
    TRS.screen.fill((0, 0, 0))
    for row in range(20):
        for col in range(10):
            pygame.draw.rect(TRS.screen, Block.blk_color[TRS.map[row][col]], ((col*21,row*21), (20, 20)), 0)
    blk = Block.type_rotate[TRS.cbk.blk][TRS.cbk.angle%4]
    for b in range(4):
        pygame.draw.rect(TRS.screen, Block.blk_color[TRS.cbk.blk], (((TRS.cbk.x+blk[b][0])*21,(TRS.cbk.y+blk[b][1])*21), (20, 20)), 0)

class App:
def init(self):
pygame.init()
screen = pygame.display.set_mode((300,430))
Block.init_rotate()
TRS(screen)

def main(self):
    clock = pygame.time.Clock()   # 创建游戏时钟
    count = 1
    # 进入游戏循环
    while True:
        # 设置刷新帧率
        clock.tick(15)
     
        # 事件检测
        for event in pygame.event.get():
            if event.type == pygame.QUIT:   # 退出事件
                sys.exit()
                
        if TRS.STATUS == 0:
            TRS.new_blk()
            if TRS.check_action(TRS.cbk.x,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle):
                TRS.STATUS = 1
            else:
                TRS.STATUS = 3
                print("GAME OVER")
        elif TRS.STATUS == 1:
            TRS.action(pygame.key.get_pressed())
            if count % 10 == 0:
                TRS.check_drop()
        elif TRS.STATUS == 2:
            TRS.check_clear()
            TRS.STATUS = 0

        TRS.print_game()
        pygame.display.update()   #刷新屏幕
        count += 1

App().main()


。 五、实验目的: 部分用户因为无法看到自己的实时分数,导致没有玩下去的动力。还有一部分的用户由于无法随时看到时间,容易花过长时间在上面。 为了让用户有玩下去的欲望以及观察自己的实时状况,优化一个得分和计时,便于用户能够随时看到自己的分数以及所花费的时间

六、代码优化:由于源代码无法显示得分以及用户用时情况,故优化一个计时以及得分牌子,来反映用户实时情况;
代码:

点击查看代码
import sys
import pygame
from pygame.locals import *
import random
import time

class Block:
    blk_color = [(255, 255, 255),(255, 255, 0),(255, 0, 255),(0, 255, 255),(255, 0, 0),(0, 255, 0),(0, 0, 255),(32,32,32)]
    BLANK = 7
    type_coord=[[[-1,0],[0,0],[1,0],[2,0]]\
        ,[[-1,0],[0,0],[1,0],[0,1]]\
        ,[[-1,0],[0,0],[-1,1],[0,1]]\
        ,[[-1,0],[0,0],[0,1],[1,1]]\
        ,[[0,0],[1,0],[-1,1],[0,1]]\
        ,[[-1,0],[0,0],[1,0],[1,1]]\
        ,[[-1,0],[0,0],[1,0],[-1,1]]]
    type_rotate = []
    
    def __init__(self,x,y,blk,angle):
        self.x = x
        self.y = y
        self.blk = blk
        self.angle = angle
        
    @staticmethod
    def rotate(no):
        rt_all = []
        rt = Block.type_coord[no][:]
        cx,cy=0,0
        for b in range(4):
            rt[b][0],rt[b][1] = rt[b][0]*4,rt[b][1]*4
            cx += rt[b][0]
            cy += rt[b][1]
        cx = (cx)//8*2 if no !=6 else (cx+4)//8*2
        cy = (cy)//8*2 if no !=6 else (cy-4)//8*2
        rt_all.append(rt)
        for r in range(3):
            rt_new = []
            for b in range(4):
                rt_new.append([cx + (cy-rt[b][1]),cy-(cx-rt[b][0])])
            rt_all.append(rt_new)
            rt = rt_new
        for r in range(4):
            for b in range(4):
                rt_all[r][b][0] //= 4
                rt_all[r][b][1] //= 4
        return rt_all
    @staticmethod
    def init_rotate():
        for r in range(7):
            Block.type_rotate.append(Block.rotate(r))

class TRS:
    screen = None
    map = [[Block.BLANK]*10 for i in range(20)]
    STATUS = 0
    cbk = None
    score = 0  # Added score variable
    start_time = time.time()  # Added timer variable

    def __init__(self,screen):
        TRS.screen = screen

    @staticmethod
    def action(key_pressed):
        if(key_pressed[K_LEFT] and TRS.check_action(TRS.cbk.x-1,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle)):
            TRS.cbk.x -= 1
        elif (key_pressed[K_RIGHT] and TRS.check_action(TRS.cbk.x+1,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle)):
            TRS.cbk.x += 1
        elif (key_pressed[K_UP] and TRS.check_action(TRS.cbk.x,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle+1)):
            TRS.cbk.angle += 1
        elif (key_pressed[K_DOWN] and TRS.check_action(TRS.cbk.x,TRS.cbk.y+1,TRS.cbk.blk,TRS.cbk.angle)):
            TRS.cbk.y += 1
            
    @staticmethod
    def new_blk():
        TRS.cbk = Block(5,0,random.randint(0,6),0)
    @staticmethod
    def check_action(x,y,blk,angle):
        tr = Block.type_rotate[blk][angle%4]
        for b in range(4):
            bx,by = x + tr[b][0],y + tr[b][1]
            if(bx<0 or bx>9 or by <0 or by>19 or TRS.map[by][bx]!=Block.BLANK):
                return False
        return True
    @staticmethod
    def check_drop():
        if TRS.check_action(TRS.cbk.x,TRS.cbk.y+1,TRS.cbk.blk,TRS.cbk.angle):
            TRS.cbk.y += 1
        else:
            TRS.STATUS = 2
            
    @staticmethod
    def check_clear():
        blk = Block.type_rotate[TRS.cbk.blk][TRS.cbk.angle%4]
        row = list({TRS.cbk.y + blk[i][1] for i in range(4)})
        row.sort()
        row.reverse()
        for b in range(4):
            TRS.map[TRS.cbk.y + blk[b][1]][TRS.cbk.x + blk[b][0]] = TRS.cbk.blk
        del_rows = 0
        for r in row:
            if not (Block.BLANK in TRS.map[r]):
                TRS.map.pop(r)
                del_rows += 1
        for d in range(del_rows):
            TRS.map.insert(0,[Block.BLANK for i in range(10)])
        # Update score based on the number of rows cleared
        if del_rows > 0:
            TRS.score += del_rows * 100  # 100 points per cleared row
            
    @staticmethod
    def print_game():
        TRS.screen.fill((0, 0, 0))
        for row in range(20):
            for col in range(10):
                pygame.draw.rect(TRS.screen, Block.blk_color[TRS.map[row][col]], ((col*21,row*21), (20, 20)), 0)
        blk = Block.type_rotate[TRS.cbk.blk][TRS.cbk.angle%4]
        for b in range(4):
            pygame.draw.rect(TRS.screen, Block.blk_color[TRS.cbk.blk]], (((TRS.cbk.x+blk[b][0])*21,(TRS.cbk.y+blk[b][1])*21), (20, 20)), 0)
        
        # Display score and timer
        font = pygame.font.SysFont("Arial", 24)
        score_text = font.render(f"Score: {TRS.score}", True, (255, 255, 255))
        elapsed_time = int(time.time() - TRS.start_time)
        timer_text = font.render(f"Time: {elapsed_time}s", True, (255, 255, 255))
        TRS.screen.blit(score_text, (10, 430 - 50))
        TRS.screen.blit(timer_text, (10, 430 - 30))

class App:
    def __init__(self):
        pygame.init()
        screen = pygame.display.set_mode((300,430))
        Block.init_rotate()
        TRS(screen)
        
    def main(self):
        clock = pygame.time.Clock()   # 创建游戏时钟
        count = 1
        # 进入游戏循环
        while True:
            # 设置刷新帧率
            clock.tick(15)
         
            # 事件检测
            for event in pygame.event.get():
                if event.type == pygame.QUIT:   # 退出事件
                    sys.exit()
                    
            if TRS.STATUS == 0:
                TRS.new_blk()
                if TRS.check_action(TRS.cbk.x,TRS.cbk.y,TRS.cbk.blk,TRS.cbk.angle):
                    TRS.STATUS = 1
                else:
                    TRS.STATUS = 3
                    print("GAME OVER")
            elif TRS.STATUS == 1:
                TRS.action(pygame.key.get_pressed())
                if count % 10 == 0:
                    TRS.check_drop()
            elif TRS.STATUS == 2:
                TRS.check_clear()
                TRS.STATUS = 0

            TRS.print_game()
            pygame.display.update()   #刷新屏幕
            count += 1
 
App().main()
def check_action(x, y, blk, angle): # 检查方块是否在屏幕范围内 for coord in Block.type_rotate[blk][angle]: nx, ny = x + coord, y + coord if nx < 0 or nx >= 10 or ny >= 20: return False # 检查是否与已放置的方块重叠 if TRS.map[ny][nx] != Block.BLANK: return False return True 这个方法检查方块在移动或旋转后是否会超出游戏板边界或与已存在的方块重叠。如果任何一部分超出边界或重叠,动作就不被允许。 运行结果:

注意事项:得分和计时器显示在屏幕底部。
当新方块无法放置在网格顶部时,游戏结束,并在控制台打印“游戏结束”。
你可以截取运行中的游戏画面以查看视觉效果。类和方法解释
‌Block 类‌:
代表游戏中的方块。
blk_color 定义了不同方块的颜色。
type_coord 定义了不同形状方块的坐标。
rotate 方法用于计算方块的旋转后的坐标。
init_rotate 方法初始化所有形状的旋转状态。
‌TRS 类‌:
代表整个游戏的状态和控制。
screen 是游戏的显示屏幕。
map 是游戏板的当前状态,用于存储每个位置是否有方块以及方块的颜色。
action 方法处理玩家的输入(移动和旋转方块)。
new_blk 方法生成一个新的方块。
check_action 方法检查玩家想要进行的动作(移动或旋转)是否合法。
七、心得体会:对博客园有了一个初步认识,并且简单了解了一下部分小游戏的代码,并且体验了一把开发游戏权限的部分乐趣。主要难点在于如何在不影响整体局面布局以及不影响游戏进行的情况下对游戏进行优化。计时机制应确保在游戏过程中实时更新,不影响游戏流畅性。得分机制应该要合理,并且也需要实时更新。

posted @   2352734  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
点击右上角即可分享
微信分享提示