用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

從上圖和遊戲玩法可以得出以下兩點:

1,方塊位置十分有規律

2,兩類方塊(上面移動的,下方固定的 都比較有特點)

方塊的大小都是固定的,只需要操心位置的問題,下面建座標系

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

下一步,

座標的儲存方式

記錄方式有兩種:

1,橫縱座標做一個二元元組,再用一個列表裝著一堆二元元組

例如:[(20,1),(20,2),(20,3),(20,4)]代表第20行的1~4列的四個方塊

2,二維數組,一行是一個列表,用兩個索引代表橫縱座標,值為1就代表有方塊,0就是沒有方塊

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

補充:座標轉換

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

鍵盤到圖像(本質:鍵盤到核心變量)

下面簡略列出需要的函數

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

首先,方塊移動的難點在“旋轉”上

Q:為什麼不先考慮左右移動

A:旋轉的問題的有些複雜,需要變更“核心變量”

核心變量一但變更 其它相關函數都得改寫

所以為了省心,優先考慮可能涉及“核心變量”的事情

解決思路:

1,為每個形狀建立一個“狀態庫”,手寫出每個姿態,旋轉時再讀取

2,旋轉前後存在明確的數學關係

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

選那個沒有懸念

追加一個變量,記錄旋轉中心座標

旋轉時依照方程轉換座標

公式很簡單吧

如果旋轉在原點,將會更簡單

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

PS:注意座標系,公式不能直接抄

所以,從記錄“絕對座標”變更為“中心座標+相對座標”

PS:繪製函數需要做相應的調整

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

旋轉過程 ( x , y ) --> (-y , x)

重要的細節:移動是有限制的

方塊在邊界處,就得限制向外的移動,如果移動後與已有的方塊重疊,也得限制移動

用Python開發遊戲!可是裝逼神技!開發一款俄羅斯方塊!都玩過吧

旋轉的

def rotate(): x, y = centre l = [(-j, i) for i, j in active] for i, j in l: i += x j += y if j < 0 or j > 9 or background[i][j]: break else: active.clear() active.extend(l)

PS:因為旋轉的機制很簡陋,會有田字形方塊的也能旋轉的奇怪現象發生。

講道理下落並不難,關鍵是下落結束後會有很多後事要處理

1,檢查是否落到底部,是:繼續,否:跳出

2,active的信息轉到background,

3,檢查background是否有“行”被填滿 是:繼續,否:跳至5

4,清掉滿行,補上空行,計分

5,生成新的active,檢查其位置是否被佔(被佔<=>方塊被堆至頂部<=>game over)

那就開始擼代碼

def move_down(): x, y = centre x -= 1 for i, j in active: i += x j += y if background[i][j]: break else: centre.clear() centre.extend([x, y]) return # 如果新位置未被佔用 通過return結束 # 如果新位置被佔用則繼續向下執行 x, y = centre for i, j in active: background[x + i][y + j] = 1 l = [] for i in range(1, 20): if 0 not in background[i]: l.append(i) # l裝 行號,鑑於刪去後,部分索引變化,對其降序排列,倒著刪除 l.sort(reverse=True) for i in l: background.pop(i) background.append([0 for j in range(10)]) # 隨刪隨補 score[0] += len(l) pygame.display.set_caption("分數:%d" % (score[0])) active.clear() active.extend(list(random.choice(all_block))) # all_block保存7種形狀的信息,手打出來的 centre.clear() centre.extend([20, 4]) x, y = centre for i, j in active: i += x j += y if background[i][j]: break else: return alive.append(1)

控制結構

下一步組裝

因為核心變量發生變化,new_draw重寫

def new_draw(): screen.fill(white) for i in range(1, 21): for j in range(10): bolck = background[i][j] if bolck: pygame.draw.rect(screen, blue, (j * 25 + 1, 500 - i * 25 + 1, 23, 23)) x, y = centre for i, j in active: i += x j += y pygame.draw.rect(screen, blue, (j * 25 + 1, 500 - i * 25 + 1, 23, 23)) pygame.display.update()

核心變量定義

all_block = (((0, 0), (0, -1), (0, 1), (0, 2)), ((0, 0), (0, 1), (-1, 0), (-1, 1)), ((0, 0), (0, -1), (-1, 0), (-1, 1)), ((0, 0), (0, 1), (-1, -1), (-1, 0)), ((0, 0), (0, 1), (1, 0), (0, -1)), ((0, 0), (1, 0), (-1, 0), (1, -1)), ((0, 0), (1, 0), (-1, 0), (1, 1)))background = [[0 for i in range(10)] for j in range(24)]background[0] = [1 for i in range(10)]active = list(random.choice(all_block))centre = [20, 4]score = [0] for i in range(1, 20): if 0 not in background[i]: l.append(i)

這個部分是從第1行才開始檢查的(~ ̄▽ ̄)~

3,我懶,不想傳參,所以 老套路

pygame固定結構,控制結構,控制變量,龍套變量

pygame.init()screen = pygame.display.set_mode((250, 500))pygame.display.set_caption("俄羅斯方塊")fclock = pygame.time.Clock()black = 0, 0, 0white = 255, 255, 255blue = 0, 0, 255times = 0alive = []press = Falsewhile True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: move_LR(-1) elif event.key == pygame.K_RIGHT: move_LR(1) elif event.key == pygame.K_UP: rotate() elif event.key == pygame.K_DOWN: press = True elif event.type == pygame.KEYUP: if event.key == pygame.K_DOWN: press = False if press: times += 10 if times >= 50: move_down() times = 0 else: times += 1 if alive: pygame.display.set_caption("over分數:%d" % (score[0])) time.sleep(3) break new_draw() fclock.tick(100)

說明:

1,原來按一次“下”,方塊只會移動一格。。。。

所以修正了一下,支持 長按,為此加了一個變量press

2,times用於計時

3,遊戲結束的有點突兀,直接就brake啦

最後發現漏了一行沒拷上來


分享到:


相關文章: