1. 程式人生 > >python練手--自制俄羅斯方塊(文末附原始碼)

python練手--自制俄羅斯方塊(文末附原始碼)

小白python學習中,剛把面向物件弄了個大概,打算找個專案練練手,於是決定做一個俄羅斯方塊吧!然後到現在一個月就過去了。。。。。

期間接觸了一下pygame,參考了目光部落格的Pygame教程,當時感覺看懂了,等到用的時候,哈哈哈,感覺把pygame用成了畫圖程式。。。。。

其實,到現在我的俄羅斯方塊也只是完成了一個DEMO,還有很多東西沒有完善,而且也沒考慮過效能,不過要出差一段時間不能學習了,所以決定先把DEMO發出來,等回頭再來填坑。。。。。

整個程式如果不看註釋,只看程式碼,應該大概是400行吧,執行時圖如下,


主要說一下顯示區,方塊系統,和碰撞檢測的思路吧,其他的都比較簡單了。

顯示區,通過維護四個列表,分別記錄正在下落方塊和已經落地方塊的座標和顏色,之後在把方塊畫出來。這裡的座標不是方塊在視窗顯示位置的座標,而是列表內的‘相對座標’,其實就是索引值。

什麼是列表內的‘相對座標’呢,這個得先說一下這個列表是什麼鬼。


因為我的顯示區,是一個以20畫素的方塊為單位,一共寬10個方塊,高22個方塊的區域,所以我的想法是,建立一個12*26的列表來與之對應(為什麼是12*26呢,一開始我確實是做了一個10*22的列表,不過後來為了加入邊界,把列表加到了12*23,再後來為了讓方塊從螢幕外一格一格進入顯示區,就變成了12*26,這些後面再說。。。),在這個12*26的列表裡面,0表示沒有方塊,1表示左右邊界和下邊界,然後當方塊進入顯示區以後,0變成1,表示此處有方塊,而剛才所說的相對座標,其實就是這個列表的索引值了。

這樣我們有了相對座標系,不過還不能用它來畫方塊,因為pygame畫方塊需要視窗座標,所以我還要把相對座標轉換成螢幕座標,比較簡單,就是座標系換算,一道數學題而已。

然後方塊系統,我的方塊系統只包括了上下左右四個操作,分別對應了旋轉,向下移動一格,向左移動一格,向右移動一格,我把他們做成一個類的四個方法,其中左右下三個操作很簡單,座標加1減1就可以了,就是上操作,旋轉,比較麻煩,沒想到好辦法,我只能將7個方塊的所有狀態一一編號,然後把旋轉時座標的相對變化全都寫出來,累。。。。。中間還加上了貼牆位移,是為了防止旋轉以後方塊進到牆裡面去,或者因為與牆面發生碰撞檢測而導致不能旋轉的情況。

算旋轉時座標變化的草圖如下(要注意轉一圈以後能轉回初始位置,不然一直轉的話,方塊會產生位移)


再然後是碰撞檢測,原理就是先記錄動作前的座標,然後執行動作,判斷動作後的座標,與牆面,與已經落地方塊的座標,是否重合。因為碰撞檢測在每一次動作的時候都要執行一次,所以在實現的時候,我把它做成了一個裝飾器,裝飾在方塊類上。(為了做這個裝飾器,現學的如何對類進行裝飾。。。。。)

其他的還有一個自己做的用來完成座標運算的類,非常簡陋,因為只是為了一次使用做的,所以只有一個加法運算,而且沒有優化。這個類是參考了目光部落格pygame教程裡面向量運算的類做的。

剩下的就是邏輯了,本來以為寫邏輯很簡單的,沒想到寫邏輯寫到一度懷疑自己沒有邏輯。。。。尤其是,一直想做的按住左鍵就能一直向左移動的功能,感覺應該可以靠邏輯實現,不過到目前還沒想出來。

總結寫俄羅斯方塊這一段時間的學習,對類有了新的認識,之前覺得類主要就是為了繼承而存在的,不過這次雖然也寫了類,卻沒用到繼承,反而發現類的屬性簡直太好用了!!!

對於俄羅斯方塊這個程式來說,感覺最難的是一開始,構想如何把方塊畫出來,這裡還要考慮方塊旋轉,還要考慮以後消除行的時候能不能操作,還要考慮碰撞檢測。最開始沒有決定用列表和座標解決這個問題的時候,還考慮過用精靈表示一個方塊,不過方塊是不規則的,不知道如何來做碰撞檢測,上網去搜,在網上看見小甲魚有一個飛機大戰裡面講到對透明部分進行處理,然後完成不規則的碰撞檢測,不過沒有搞懂,去研究官方文件也沒搞懂,還有什麼掩碼什麼的,也是搞得我暈頭轉向,所以不得不暫時放棄了使用精靈的打算,看來想入門遊戲要學的還有太多,手動哭一個吧。。。。

最後附上程式碼,和程式碼下載地址,歡迎討論,歡迎指導,一起成長,手動笑。

程式碼如下:

#俄羅斯方塊
# -*- coding: utf-8 -*-
import pygame, random, time
from pygame.locals import *

pygame.init()
#pygame.key.set_repeat(1, 100)    #重複輸入模式
#視窗
screen = pygame.display.set_mode((660,520), 0, 32)

#靜態介面(背景、色塊等)
interface = pygame.image.load(r'C:\Users\Administrator\Desktop\interface.jpg').convert()
gameover = pygame.image.load(r'C:\Users\Administrator\Desktop\GAME_OVER.jpg').convert()

#方塊名稱、顏色、初始位置
squares_dict = {0:'z_left', 1:'z_right', 2:'long', 3:'cross', 4:'rect', 5:'l_left', 6:'l_right'}
'''color_dict用於例項化的時候生成顏色標記'''
color_dict = {'z_left':1, 'z_right':2, 'long':3, 'cross':4, 'rect':5, 'l_left':6, 'l_right':7}
'''color_sheet用於表示顏色標記對應的顏色RGB'''
color_sheet = {1:(231,63,136), 2:(192,219,64), 3:(168,201,206), 4:(143,111,161), 5:(254,252,66), 6:(59,140,170), 7:(249,159,15)}
init_pos_dict = {'z_left':[(4,1), (5,1), (5,2), (6,2)],
                 'z_right':[(7,1), (6,1), (6,2), (5,2)],
                 'long':[(4,2), (5,2), (6,2), (7,2)],
                 'cross':[(5,1), (6,1), (7,1), (6,2)],
                 'rect':[(5,1), (6,1), (5,2), (6,2)],
                 'l_left':[(4,1), (5,1), (6,1), (6,2)],
                 'l_right':[(7,1), (6,1), (5,1), (5,2)]}

#碰撞檢測系統(裝飾器,對squares類內的方法進行裝飾)
def pp_test(cls):
    class new_class:
        def __init__(self, name, color, now_pos, flag, stop_flag):
            self.wrapper = cls(name, color, now_pos, flag, stop_flag)
            self.name = self.wrapper.name
            self.color = self.wrapper.color
            self.now_pos = self.wrapper.now_pos
            self.flag = self.wrapper.flag
            self.stop_flag = self.wrapper.stop_flag
        def TURN(self):
            temp = self.wrapper.now_pos
            temp1 = self.wrapper.flag
            self.wrapper.TURN()
            for i in self.wrapper.now_pos:
                if area[i[1]][i[0]] == 1:
                    self.wrapper.now_pos = temp
                    self.wrapper.flag = temp1
            self.now_pos = self.wrapper.now_pos
            self.flag = self.wrapper.flag
        def LEFT(self):
            temp = self.wrapper.now_pos
            self.wrapper.LEFT()
            for i in self.wrapper.now_pos:
                if area[i[1]][i[0]] == 1:
                    self.wrapper.now_pos = temp
            self.now_pos = self.wrapper.now_pos
        def RIGHT(self):
            temp = self.wrapper.now_pos
            self.wrapper.RIGHT()
            for i in self.wrapper.now_pos:
                if area[i[1]][i[0]] == 1:
                    self.wrapper.now_pos = temp
            self.now_pos = self.wrapper.now_pos
        def DOWN(self):
            temp = self.wrapper.now_pos
            self.wrapper.DOWN()
            for i in self.wrapper.now_pos:
                if area[i[1]][i[0]] == 1:
                    self.wrapper.now_pos = temp
                    self.wrapper.stop_flag = 1
            self.now_pos = self.wrapper.now_pos
            self.stop_flag = self.wrapper.stop_flag
    return new_class

#方塊系統
@pp_test #碰撞檢測裝飾器
class squares:
    def __init__(self, name, color, now_pos, flag, stop_flag):
        self.name = name
        self.color = color
        self.now_pos = now_pos
        self.flag = flag
        self.stop_flag = stop_flag
    #方塊的旋轉操作
    def TURN(self):
        global now_pos
        now_pos = self.now_pos
        #z_left的兩種狀態
        if self.name == 'z_left':
            if self.flag == 0:
                now_pos[0] = Pos(self.now_pos[0]) + (2,-1)
                now_pos[1] = Pos(self.now_pos[1]) + (1,0)
                now_pos[2] = Pos(self.now_pos[2]) + (0,-1)
                now_pos[3] = Pos(self.now_pos[3]) + (-1,0)
                self.flag += 1
            elif self.flag == 1:
                if now_pos[2][0] == 1:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (1,0)
                    self.now_pos = now_pos
                now_pos[0] = Pos(self.now_pos[0]) + (-2,1)
                now_pos[1] = Pos(self.now_pos[1]) + (-1,0)
                now_pos[2] = Pos(self.now_pos[2]) + (0,1)
                now_pos[3] = Pos(self.now_pos[3]) + (1,0)
                self.flag -= 1
        #z_right的兩種狀態
        elif self.name == 'z_right':
            if self.flag == 0:
                now_pos[0] = Pos(self.now_pos[0]) + (-2,-1)
                now_pos[1] = Pos(self.now_pos[1]) + (-1,0)
                now_pos[2] = Pos(self.now_pos[2]) + (0,-1)
                now_pos[3] = Pos(self.now_pos[3]) + (1,0)
                self.flag += 1
            elif self.flag == 1:
                if now_pos[2][0] == 10:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (-1,0)
                    self.now_pos = now_pos
                now_pos[0] = Pos(self.now_pos[0]) + (2,1)
                now_pos[1] = Pos(self.now_pos[1]) + (1,0)
                now_pos[2] = Pos(self.now_pos[2]) + (0,1)
                now_pos[3] = Pos(self.now_pos[3]) + (-1,0)
                self.flag -= 1
        #long的兩種狀態
        elif self.name == 'long':
            if self.flag == 0:
                now_pos[0] = Pos(self.now_pos[0]) + (2,-2)
                now_pos[1] = Pos(self.now_pos[1]) + (1,-1)
                now_pos[2] = Pos(self.now_pos[2]) + (0,0)
                now_pos[3] = Pos(self.now_pos[3]) + (-1,1)
                self.flag += 1
            elif self.flag == 1:
                if now_pos[2][0] == 1:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (2,0)
                    self.now_pos = now_pos
                elif now_pos[2][0] == 2:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (1,0)
                    self.now_pos = now_pos
                elif now_pos[2][0] == 10:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (-1,0)
                    self.now_pos = now_pos
                now_pos[0] = Pos(self.now_pos[0]) + (-2,2)
                now_pos[1] = Pos(self.now_pos[1]) + (-1,1)
                now_pos[2] = Pos(self.now_pos[2]) + (0,0)
                now_pos[3] = Pos(self.now_pos[3]) + (1,-1)
                self.flag -= 1
        #cross的四種狀態
        elif self.name == 'cross':
            if self.flag == 0:
                now_pos[0] = Pos(self.now_pos[0]) + (1,-1)
                now_pos[1] = Pos(self.now_pos[1]) + (0,0)
                now_pos[2] = Pos(self.now_pos[2]) + (-1,1)
                now_pos[3] = Pos(self.now_pos[3]) + (-1,-1)
                self.flag += 1
            elif self.flag == 1:
                if now_pos[2][0] == 10:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (-1,0)
                    self.now_pos = now_pos
                now_pos[0] = Pos(self.now_pos[0]) + (1,1)
                now_pos[1] = Pos(self.now_pos[1]) + (0,0)
                now_pos[2] = Pos(self.now_pos[2]) + (-1,-1)
                now_pos[3] = Pos(self.now_pos[3]) + (1,-1)
                self.flag += 1
            elif self.flag == 2:
                now_pos[0] = Pos(self.now_pos[0]) + (-1,1)
                now_pos[1] = Pos(self.now_pos[1]) + (0,0)
                now_pos[2] = Pos(self.now_pos[2]) + (1,-1)
                now_pos[3] = Pos(self.now_pos[3]) + (1,1)
                self.flag += 1
            elif self.flag == 3:
                if now_pos[2][0] == 1:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (1,0)
                    self.now_pos = now_pos
                now_pos[0] = Pos(self.now_pos[0]) + (-1,-1)
                now_pos[1] = Pos(self.now_pos[1]) + (0,0)
                now_pos[2] = Pos(self.now_pos[2]) + (1,1)
                now_pos[3] = Pos(self.now_pos[3]) + (-1,1)
                self.flag -= 3
        #rect無變化
        elif self.name == 'rect':
            pass
        #l_left的四種狀態
        elif self.name == 'l_left':
            if self.flag == 0:
                now_pos[0] = Pos(self.now_pos[0]) + (2,-1)
                now_pos[1] = Pos(self.now_pos[1]) + (1,0)
                now_pos[2] = Pos(self.now_pos[2]) + (0,1)
                now_pos[3] = Pos(self.now_pos[3]) + (-1,0)
                self.flag += 1
            elif self.flag == 1:
                if now_pos[2][0] == 10:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (-1,0)
                    self.now_pos = now_pos
                now_pos[0] = Pos(self.now_pos[0]) + (1,2)
                now_pos[1] = Pos(self.now_pos[1]) + (0,1)
                now_pos[2] = Pos(self.now_pos[2]) + (-1,0)
                now_pos[3] = Pos(self.now_pos[3]) + (0,-1)
                self.flag += 1
            elif self.flag == 2:
                now_pos[0] = Pos(self.now_pos[0]) + (-2,0)
                now_pos[1] = Pos(self.now_pos[1]) + (-1,-1)
                now_pos[2] = Pos(self.now_pos[2]) + (0,-2)
                now_pos[3] = Pos(self.now_pos[3]) + (1,-1)
                self.flag += 1
            elif self.flag == 3:
                if now_pos[2][0] == 1:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (1,0)
                    self.now_pos = now_pos
                now_pos[0] = Pos(self.now_pos[0]) + (-1,-1)
                now_pos[1] = Pos(self.now_pos[1]) + (0,0)
                now_pos[2] = Pos(self.now_pos[2]) + (1,1)
                now_pos[3] = Pos(self.now_pos[3]) + (0,2)
                self.flag -= 3
        #l_right的四種狀態
        elif self.name == 'l_right':
            if self.flag == 0:
                now_pos[0] = Pos(self.now_pos[0]) + (-1,1)
                now_pos[1] = Pos(self.now_pos[1]) + (0,0)
                now_pos[2] = Pos(self.now_pos[2]) + (1,-1)
                now_pos[3] = Pos(self.now_pos[3]) + (0,-2)
                self.flag += 1
            elif self.flag == 1:
                if now_pos[3][0] == 1:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (1,0)
                    self.now_pos = now_pos
                now_pos[0] = Pos(self.now_pos[0]) + (-2,0)
                now_pos[1] = Pos(self.now_pos[1]) + (-1,1)
                now_pos[2] = Pos(self.now_pos[2]) + (0,2)
                now_pos[3] = Pos(self.now_pos[3]) + (1,1)
                self.flag += 1
            elif self.flag == 2:
                now_pos[0] = Pos(self.now_pos[0]) + (1,-2)
                now_pos[1] = Pos(self.now_pos[1]) + (0,-1)
                now_pos[2] = Pos(self.now_pos[2]) + (-1,0)
                now_pos[3] = Pos(self.now_pos[3]) + (0,1)
                self.flag += 1
            elif self.flag == 3:
                if now_pos[2][0] == 1:  #貼牆位移
                    now_pos = Pos(self.now_pos) + (1,0)
                    self.now_pos = now_pos
                now_pos[0] = Pos(self.now_pos[0]) + (1,1)
                now_pos[1] = Pos(self.now_pos[1]) + (0,0)
                now_pos[2] = Pos(self.now_pos[2]) + (-1,-1)
                now_pos[3] = Pos(self.now_pos[3]) + (-2,0)
                self.flag -= 3        
        self.now_pos = now_pos
    #方塊的向左操作    
    def LEFT(self):
        now_pos = Pos(self.now_pos) + (-1, 0)
        self.now_pos = now_pos
    #方塊的向右操作    
    def RIGHT(self):
        now_pos = Pos(self.now_pos) + (1, 0)
        self.now_pos = now_pos
    #方塊的下降操作    
    def DOWN(self):
        now_pos = Pos(self.now_pos) + (0, 1)
        self.now_pos = now_pos

#虛擬寄存座標系(對應遊戲顯示區,邊界和有方塊的座標,在area中值為1,無方塊為0)座標轉換,返回方塊在視窗內的實際位置
area = []
for i in range(25):
    area.append([1,0,0,0,0,0,0,0,0,0,0,1])
area.append([1,1,1,1,1,1,1,1,1,1,1,1])
'''建立12*26的虛擬座標系(其中頭三行用於存放頂部越界的方塊,然後左右下有一圈1,代表邊界,此座標系只存放已經stop的方塊)'''

def stop_pos_to_area(obj):
    for i in obj.now_pos:
        area[i[1]][i[0]] = 1 #方塊虛擬座標系橫軸x,縱軸y,存入列表的話,xy需要互換
'''將方塊stop時的位置寫進area'''

def now_pos_to_temp_area(obj):
    global temp_area
    temp_area = []
    for i in range(25):
        temp_area.append([1,0,0,0,0,0,0,0,0,0,0,1])
    temp_area.append([1,1,1,1,1,1,1,1,1,1,1,1])
    for i in obj.now_pos:
        temp_area[i[1]][i[0]] = 1
'''將移動中方塊的動態位置寫進temp_area'''
#顏色標記系統
'''繪製方塊的時候發現沒法上顏色,無奈,只能在開一個標記顏色的座標系'''
stop_color = []
for i in range(25):
    stop_color.append([1,0,0,0,0,0,0,0,0,0,0,1])
stop_color.append([1,1,1,1,1,1,1,1,1,1,1,1])
'''建立12*26的虛擬座標系(其中頭三行用於存放頂部越界的方塊,然後左右下有一圈1,代表邊界,此座標系只存放已經stop的方塊)'''

def color_to_stop_color(obj):
    for i in obj.now_pos:
        stop_color[i[1]][i[0]] = obj.color #方塊虛擬座標系橫軸x,縱軸y,存入列表的話,xy需要互換
'''將方塊stop時的顏色寫進stop_color'''

def color_to_temp_color(obj):
    global temp_color
    temp_color = []
    for i in range(25):
        temp_color.append([1,0,0,0,0,0,0,0,0,0,0,1])
    temp_color.append([1,1,1,1,1,1,1,1,1,1,1,1])
    for i in obj.now_pos:
        temp_color[i[1]][i[0]] = obj.color
'''將移動中方塊的顏色寫進temp_color'''
 
#將顏色和位置(方塊的狀態)存進rect_box
def area_to_rect_box():
    rect_box = []
    c1 = -1
    for i in area:
        c1 += 1
        c2 = -1
        for j in i:
            c2 += 1
            if j == 1 and c1 > 2 and c2 != 0 and c2 != 11 and c1 != 25:   #c1 > 2才開始計入rect_box,頭三行不需要畫
                rect_box.append( (stop_color[c1][c2], (20*(c2-1)+40, 20*(c1-3)+40, 20, 20)) )
    c3 = -1
    for k in temp_area:
        c3 += 1
        c4 = -1
        for l in k:
            c4 += 1
            if l == 1 and c3 > 2 and c4 != 0 and c4 != 11 and c3 != 25:
                rect_box.append( (temp_color[c3][c4], (20*(c4-1)+40, 20*(c3-3)+40, 20, 20)) )
    return rect_box
'''將area中值為1的座標(邊界除外),轉換為實際座標,並生成rect格式,存入rect_box中'''

#消除系統
def remove():
    v = -1
    for i in area:
        v += 1
        result = 0
        for j in i:
            result += j
        if result == 12 and v != 25:
            del area[v]
            area.insert(0,[1,0,0,0,0,0,0,0,0,0,0,1])
            del stop_color[v]
            stop_color.insert(0,[1,0,0,0,0,0,0,0,0,0,0,1])
            global score
            score += 1
            level_just()
            
#game over系統
def game_over():
    result = 0
    for i in area[2]:
        result += i
    if result > 2:
        global game_over
        game_over = 1
        
#方塊位置運算系統,用於運算方塊的position
class Pos:
    def __init__(self, pos):  #ob_pos = Pos([(x1, y1), (x2,y2), (x3, y3), (x4, y4)])
        self.len = len(pos)
        self.pos = pos
    def __add__(self, pair):
        if type(self.pos[0]) != int:
            return list((self.pos[i][0] + pair[0], self.pos[i][1] + pair[1]) for i in range(self.len))
        else:
            return list((self.pos[0] + pair[0], self.pos[1] + pair[1]))
        
#音樂系統
        
#計分系統(掛在消除系統裡,每次消除的時候score+1)
score = 0

#計時系統
start_time = time.clock()
def TIME():
    over_time = time.clock()
    used_time = over_time - start_time
    global time_sec, time_min, time_hour
    time_sec = int(used_time % 60)
    time_min = int((used_time // 60) % 60)
    time_hour = int((used_time // 60) // 60)

#等級系統(掛在消除系統裡,每次消除後,計分,判斷等級,不同等級速度不同)
level_list = [511, 255, 127, 63, 31]
level = level_list[0]
def level_just():
    global level
    if score < 10:
        level = level_list[0]
    elif score < 20:
        level = level_list[1]
    elif score < 30:
        level = level_list[2]
    elif score < 40:
        level = level_list[3]
    elif score < 50:
        level = level_list[4]
        
#下一個方塊預覽圖        
surface_z_left = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_z_left.png').convert_alpha()
surface_z_right = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_z_right.png').convert_alpha()
surface_long = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_long.png').convert_alpha()
surface_cross = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_cross.png').convert_alpha()
surface_rect = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_rect.png').convert_alpha()
surface_l_left = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_l_left.png').convert_alpha()
surface_l_right = pygame.image.load(r'C:\Users\Administrator\Desktop\surface_l_right.png').convert_alpha()
next_square = {'z_left':surface_z_left,
               'z_right':surface_z_right,
               'long':surface_long,
               'cross':surface_cross,
               'rect':surface_rect,
               'l_left':surface_l_left,
               'l_right':surface_l_right}

#動態文字、圖形(右側選單顯示的分數、時間、等級、下一個)
score_font = pygame.font.SysFont('tahoma.ttf', 40)
level_font = pygame.font.SysFont('tahoma.ttf', 40)
time_font = pygame.font.SysFont('tahoma.ttf', 40)

#畫出
def draw(obj, next_name):
    now_pos_to_temp_area(obj)
    color_to_temp_color(obj)
    #畫介面、文字、按鈕
    screen.blit(interface,(0, 0))
    score_surface = score_font.render('{0}'.format(score), True, (0, 0, 0))   #因為分數是動態的,所以每次畫之前重新整理一遍surface
    screen.blit(score_surface,(300, 100))
    TIME()
    time_surface = time_font.render('{0:0>2}:{1:0>2}:{2:0>2}'.format(time_hour, time_min, time_sec), True, (0, 0, 0))
    screen.blit(time_surface,(480, 100))
    level_surface = level_font.render('{0}'.format(level_list.index(level)), True, (0, 0, 0))    #因為等級是動態的,所以每次畫之前重新整理一遍surface
    screen.blit(level_surface,(480,340))
    screen.blit(next_square[next_name],(280, 330))
    new_rect_box = area_to_rect_box()
    for i in new_rect_box:
        pygame.draw.rect(screen, color_sheet[i[0]], i[1], 0)
    pygame.display.update()
    
#初始化第一個方塊
next_name = squares_dict[random.randint(0,6)]

def main():
    while True :
        global next_name
        this_name = next_name
        next_name = squares_dict[random.randint(0,6)]
        dynamic_square = squares(this_name, color_dict[this_name], init_pos_dict[this_name], flag = 0, stop_flag = 0)
        draw(dynamic_square, next_name)
        while True :
            for event in pygame.event.get():
                if event.type == QUIT:
                    exit()
                if event.type == KEYDOWN:
                    if event.key == K_LEFT:
                        dynamic_square.LEFT()
                        draw(dynamic_square, next_name)
                    elif event.key == K_RIGHT:
                        dynamic_square.RIGHT()
                        draw(dynamic_square, next_name)
                    elif event.key == K_UP:
                        dynamic_square.TURN()
                        draw(dynamic_square, next_name)
                    elif event.key == K_DOWN:
                        dynamic_square.DOWN()
                        draw(dynamic_square, next_name)
            while int(pygame.time.get_ticks()) & level == 1:  #每當時間迴圈到1的時候就下降一格
                dynamic_square.DOWN()
                draw(dynamic_square, next_name)
                break
            if dynamic_square.stop_flag == 1:       #如果stop_flag = 1,則方塊落地,記錄位置和顏色,判斷是否需要消除,或者GAME OVER,然後跳過本次迴圈,開始下一方塊
                stop_pos_to_area(dynamic_square)
                color_to_stop_color(dynamic_square)
                remove()
                game_over()
                break
        if game_over == 1:
            break
    screen.blit(gameover,(0,0))
    pygame.display.update()
if __name__ == '__main__':
    main()
    
'''碰撞檢測在TURN時會失效_____bug
l_left在turn時出現bug_____bug(2次了,原因尚不明確)
剛開始的下降不穩定,有時候會一次下降兩格_____bug
持續按鍵還未實現_____func
還沒有暫停功能_____func
消除的動畫還沒有加_____cool
畫面貼圖還沒做_____cool
音樂還沒有加_____cool
最高分功能還沒有____func
開始介面_____func'''