# 實作:迷宮 ## 程式概述 7x7迷宮,玩家利用鍵盤來控制方向並移動到終點 ## 程式碼 ```python= import pygame pygame.init() y1 = [1, 1, 1, 1, 1, 1, 1] y2 = [1, 2, 0, 0, 0, 0, 1] y3 = [1, 0, 1, 0, 1, 0, 1] y4 = [1, 0, 0, 0, 0, 0, 1] y5 = [1, 0, 1, 0, 1, 0, 1] y6 = [1, 0, 0, 0, 0, 3, 1] y7 = [1, 1, 1, 1, 1, 1, 1] x_7 = [y1, y2 , y3, y4, y5, y6, y7] player_x = 1 player_y = 1 #X_7[1][1]初始座標[y軸][x軸] screen = pygame.display.set_mode((700, 700)) pygame.display.set_caption("迷宮") screen.fill((255, 255, 255)) font = pygame.font.SysFont("microsoftjhenghei", 100) text_surface = font.render("過關", True, (0, 255, 255)) text_rect = text_surface.get_rect(center=(350, 350)) pygame.key.set_repeat(250, 50) running = True while running: x = y = 0 for a in x_7: for b in a: if b == 1: pygame.draw.rect(screen, (0, 0, 0),(100*x, 100*y, 100, 100),width=0) elif b == 2: pygame.draw.rect(screen, (0, 255, 0),(100*x, 100*y, 100, 100),width=0) elif b == 3: pygame.draw.rect(screen, (255, 0, 0),(100*x, 100*y, 100, 100),width=0) else: pygame.draw.rect(screen, (255, 255, 255),(100*x, 100*y, 100, 100),width=0) x +=1 x = 0 y += 1 pygame.display.flip() if player_y == 5 and player_x == 5: screen.blit(text_surface, text_rect) pygame.display.flip() while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_w: if x_7[player_y-1][player_x] != 1: x_7[player_y-1][player_x] = 2 x_7[player_y][player_x] = 0 player_y -= 1 elif event.key == pygame.K_a: if x_7[player_y][player_x-1] != 1: x_7[player_y][player_x-1] = 2 x_7[player_y][player_x] = 0 player_x -= 1 elif event.key == pygame.K_s: if x_7[player_y+1][player_x] != 1: x_7[player_y+1][player_x] = 2 x_7[player_y][player_x] = 0 player_y += 1 elif event.key == pygame.K_d: if x_7[player_y][player_x+1] != 1: x_7[player_y][player_x+1] = 2 x_7[player_y][player_x] = 0 player_x += 1 running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False pygame.quit() ``` ## 程式架構及功能解釋 功能部分主要可以分為**素材**及**遊戲流程**兩大類,我們會先從比較簡單的素材開始介紹 ### 程式架構 ``` 迷宮 ├── 素材 │ ├── 迷宮坐標系 │ ├── 建立視窗 │ ├── 建立文字 │ └── 其他設定 ├── 遊戲流程 │ ├── 迷宮繪製 │ ├── 過關判斷及視窗保留與退出 │ └── 事件處理 └── 退出pygame ``` ### 迷宮座標系 :::success ```python= y1 = [1, 1, 1, 1, 1, 1, 1] y2 = [1, 2, 0, 0, 0, 0, 1] y3 = [1, 0, 1, 0, 1, 0, 1] y4 = [1, 0, 0, 0, 0, 0, 1] y5 = [1, 0, 1, 0, 1, 0, 1] y6 = [1, 0, 0, 0, 0, 3, 1] y7 = [1, 1, 1, 1, 1, 1, 1] x_7 = [y1, y2 , y3, y4, y5, y6, y7] player_x = 1 player_y = 1 #X_7[1][1]初始座標[y軸][x軸] ``` >[!Note]1~9行 >1~9行構建了整個迷宮的坐標系,由七個Y軸List合成一個X軸,以此為一平面 >[!Note]11~12行 >為玩家在此坐標系中的座標位置 ::: ### 建立視窗 :::success ```python= screen = pygame.display.set_mode((700, 700)) pygame.display.set_caption("迷宮") screen.fill((255, 255, 255)) ``` >[!Note]1~3行 >建立一個700x700的視窗,視窗名稱為「迷宮」,背景色為白色 ::: ### 建立文字 :::success ```python= font = pygame.font.SysFont("microsoftjhenghei", 100) text_surface = font.render("過關", True, (0, 255, 255)) text_rect = text_surface.get_rect(center=(350, 350)) ``` >[!Note]1~3行 >建立一個字體大小100的微軟正黑體的藍色字串,並設定位置 ::: ### 其他設定 :::success ```python= pygame.key.set_repeat(250, 50) running = True ``` >[!Note]第1行 >設定長按,若無此行則鍵盤事件不支援長按 >[!Note]第3行 >設定遊戲狀態,為進行中 ::: ### 迷宮繪製 :::success ```python= x = y = 0 for a in x_7: for b in a: if b == 1: pygame.draw.rect(screen, (0, 0, 0),(100*x, 100*y, 100, 100),width=0) elif b == 2: pygame.draw.rect(screen, (0, 255, 0),(100*x, 100*y, 100, 100),width=0) elif b == 3: pygame.draw.rect(screen, (255, 0, 0),(100*x, 100*y, 100, 100),width=0) else: pygame.draw.rect(screen, (255, 255, 255),(100*x, 100*y, 100, 100),width=0) x +=1 x = 0 y += 1 pygame.display.flip() ``` >[!Note]1~15行 >透過遍歷迴圈,來讀取迷宮數據,並畫出對應顏色的方格 ::: ### 過關判斷及視窗保留與退出 :::success ```python= if player_y == 5 and player_x == 5: screen.blit(text_surface, text_rect) pygame.display.flip() while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False ``` >[!Note]1~7行 >透過檢查玩家的座標位置,來判斷是否過關,並在過關後保留視窗等待玩家退出 ::: ### 事件處理 :::success ```python= for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_w: if x_7[player_y-1][player_x] != 1: x_7[player_y-1][player_x] = 2 x_7[player_y][player_x] = 0 player_y -= 1 elif event.key == pygame.K_a: if x_7[player_y][player_x-1] != 1: x_7[player_y][player_x-1] = 2 x_7[player_y][player_x] = 0 player_x -= 1 elif event.key == pygame.K_s: if x_7[player_y+1][player_x] != 1: x_7[player_y+1][player_x] = 2 x_7[player_y][player_x] = 0 player_y += 1 elif event.key == pygame.K_d: if x_7[player_y][player_x+1] != 1: x_7[player_y][player_x+1] = 2 x_7[player_y][player_x] = 0 player_x += 1 ``` >[!Note]1~24行 >這是一個完整的事件處理迴圈,負責處理玩家中途退出以及鍵盤輸入等事件,在將事件分配給事件處理器 >[!Tip]玩家移動 >透過座標比對來判斷是否移動 ::: ### 退出pygame :::success ```python= pygame.QUIT() ``` >[!Note]第1行 >退出pygame ::: ## 運行影片 {%youtube OG0zzVah2pk %} ## [實作:迷宮 - 時間差](https://hackmd.io/@Huanyu763/實作-迷宮-時間差) ## [回到主頁](https://hackmd.io/@Huanyu763/home)