# Python班
## 3/15社課
---
### 本次課程內容
* 場景設定
* 物件(角色)
* 畫面更新與遊戲流程
---
## 場景設定
Replit人還不錯,幫我們完成大部分設定,不過想要有更完整的條件,我們得加上幾行。
----
```=
import pygame, sys
from pygame.locals import QUIT
pygame.init()
FPS = 30
WIDTH = 400
HEIGHT = 300
DISPLAYSURF = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Hello World!')
clock = pygame.time.Clock()
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == QUIT:
running = False
sys.exit()
DISPLAYSURF.fill((0,255,0))
pygame.display.update()
pygame.quit()
```
----
我們一個一個來看
----
### 變數們
最開始的幾行通常會放「全域」變數
```python
FPS = 30
WIDTH = 400
HEIGHT = 300
```
通常會有幀率、螢幕長寬... 之類的
在程式的任何地方都可以隨時呼叫這些變數
----
### 時間
```
...
clock = pygame.time.Clock()
...
while running:
clock.tick(FPS)
```
先把$\texttt{clock}$的類別定義成Pygame裡的$\textbf{Clock}$
那$\texttt{clock}$就可以用$\texttt{tick}$的指令決定更新率
----
### 視窗
```python
pygame.init()
...
DISPLAYSURF = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('112-2-2')
...
```
第一行是初始化,寫就對了
$\texttt{DISPLAYSURF}$是執行的畫布,物件會被畫在上面
下一行則是視窗的標題
----
### 畫面更新
這個......先稍等
講完「角色」再回頭來講它
---
## 物件(角色)
----
### 定義
定義物件我們使用$\texttt{sprite}$,語法則是$\texttt{class}$
```python
class Block(pygame.sprite.Sprite):
```
可以想像我們定義一種物件的「類型」
為什麼這麼說呢?請繼續看下去
----
```python
class Block(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill((255, 0, 0))
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
def ...
```
看到了嗎?$\texttt{class}$的底下包著函式
意思是指這個「類型」的物件可以做的事
下頁還有
----
在所有函式中一定有一個「初始化」$\texttt{__init__}$
```
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill((255, 0, 0))
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
```
$\texttt{self}$代指「這個物件」(代名詞)
$\texttt{rect}$代表這個函數在畫面上的座標,有...很多種
----
### 坐標軸與坐標
坐標軸的定義需要熟悉一下

----
而配合上一頁的座標軸,就有了其他坐標

特別注意:topleft = (x, y)
(就是$\texttt{self.rect.x}$或$\texttt{self.rect.y}$)
----
對了,不要嘴我的「坐標」和「座標」

----
### 更新
另一個極高概率會有函式的叫做$\texttt{update}$
```
class Block(pygame.sprite.Sprite):
def __init__(self):
...
def update(self):
self.rect.x += 3
if self.rect.left > WIDTH:
self.rect.right = 0
```
記載著每次更新要做的事情
----
### 使用
```
...
all_sprite = pygame.sprite.Group()
block = Block()
all_sprite.add(block)
...
```
先定義$\texttt{all_sprite}$,是一個存著所有物件的群組
定義一個物件叫做$\texttt{block}$,類型是$\texttt{Block}$
並把他加到$\texttt{all_sprite}$裡面
---
## 畫面更新與遊戲流程
----
終於到了最後的環節,要讓遊戲動起來
----
### 畫面更新
```python=
while running:
...
all_sprite.update()
DISPLAYSURF.fill((255, 255, 255))
all_sprite.draw(DISPLAYSURF)
pygame.display.update()
```
第三行:會把$\texttt{all_sprite}$裡的物件都執行其底下定義的$\texttt{update()}$
第六行:把$\texttt{all_sprite}$裡的物件畫在畫布上
第七行:顯示更新好的畫面
----
### 遊戲流程
```python=
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == QUIT:
running = False
sys.exit()
all_sprite.update()
DISPLAYSURF.fill((255, 255, 255))
all_sprite.draw(DISPLAYSURF)
pygame.display.update()
pygame.quit()
```
----
對照著上一頁
第3~6行:偵測事件發生(按鍵盤、滑鼠...)
第7~10行:畫面更新
第4~6、11行:遊戲終止判定
----
完整程式碼:
```python=
import pygame, sys
from pygame.locals import QUIT
pygame.init()
FPS = 30
WIDTH, HEIGHT = 400, 300
DISPLAYSURF = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('112-2-pygame-2')
clock = pygame.time.Clock()
class Block(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill((255, 0, 0))
self.rect = self.image.get_rect()
self.rect.center = (WIDTH // 2, HEIGHT // 2)
def update(self):
self.rect.x += 3
if self.rect.left > WIDTH:
self.rect.right = 0
all_sprite = pygame.sprite.Group()
block = Block()
all_sprite.add(block)
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == QUIT:
running = False
sys.exit()
all_sprite.update()
DISPLAYSURF.fill((255, 255, 255))
all_sprite.draw(DISPLAYSURF)
pygame.display.update()
pygame.quit()
```
---
# 謝謝大家
{"title":"112-2-Python班-Pygame-場景、角色、畫面、遊戲","contributors":"[{\"id\":\"084e105f-92be-4605-b399-8d3c0ef40c64\",\"add\":4734,\"del\":124}]"}