# 實作:迷宮
## 程式概述
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)