香雨站

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 86|回复: 0

自己动手制作小游戏——俄罗斯方块

[复制链接]

3

主题

6

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2023-1-8 10:48:18 | 显示全部楼层 |阅读模式
谁还没有玩过俄罗斯方块呢,这款单机小游戏,简单易懂,最好打发无聊时间了。
使用python除了可以爬取图片,视频,当然可以制作一些小游戏了。


其实这个很简单,就是转化数据很麻烦 ☹
实际流程:

  • 新生成图形块,如果从下往上已经堆到这里了(图形块出现位置出现不为空白的背景)游戏结束
  • 下落(途中可以键盘操作块的移动,转动)
  • 到底,图形数据记录到map,检查是否消去一行
所有的检查,就用check_action(位置x,位置y,图形块号,图形转动角度):检查是否出界或遇到原先的块,

  • 游戏是否结束判断:新生成图形块位置是否check_action == False
  • 下落是否到底:y+1位置是否check_action == False
  • 操作动作(x-1,x+1,y+1,角度+1):是否check_action == False
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[0],rt[1] = rt[0]*4,rt[1]*4
            cx += rt[0]
            cy += rt[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[1]),cy-(cx-rt[0])])
            rt_all.append(rt_new)
            rt = rt_new
        for r in range(4):
            for b in range(4):
                rt_all[r][0] //= 4
                rt_all[r][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[0],y + tr[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[1] for i in range(4)})
        row.sort()
        row.reverse()
        for b in range(4):
            TRS.map[TRS.cbk.y + blk[1]][TRS.cbk.x + blk[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[0])*21,(TRS.cbk.y+blk[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()<hr/>ok,分享到这里也就结束啦。感兴趣的朋友可以去试试,有不会的可以来找我!


希望你们能够喜欢,记得三连哦。我是小圆,我们下篇文章见啦 ~
回复

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|香雨站

GMT+8, 2025-9-15 05:33 , Processed in 0.085586 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.. 技术支持 by 巅峰设计

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