飛機(jī)大戰(zhàn)

# 敵機(jī)出場

##目標(biāo)

*使用**定時器**添加敵機(jī)

*設(shè)計`Enemy`類

## 01. 使用定時器添加敵機(jī)

運(yùn)行**備課代碼**武鲁,**觀察**敵機(jī)的**出現(xiàn)規(guī)律**:

1.游戲啟動后睁本,**每隔 1 秒**會**出現(xiàn)一架敵機(jī)**

2.每架敵機(jī)**向屏幕下方飛行**盆色,飛行**速度各不相同**

3.每架敵機(jī)出現(xiàn)的**水平位置**也不盡相同

4.當(dāng)敵機(jī)**從屏幕下方飛出**查刻,不會再飛回到屏幕中

### 1.1 定時器

* 在 `pygame` 中可以使用 `pygame.time.set_timer()` 來添加 **定時器**

*所謂**定時器**铐达,就是**每隔一段時間**,去**執(zhí)行一些動作**

```python

set_timer(eventid, milliseconds) -> None

```

*`set_timer`可以創(chuàng)建一個**事件**

*可以在**游戲循環(huán)**的**事件監(jiān)聽**方法中捕獲到該事件

*第 1 個參數(shù)**事件代號**需要基于常量`pygame.USEREVENT`來指定

? ? *`USEREVENT`是一個整數(shù)野芒,再增加的事件可以使用`USEREVENT + 1`指定,依次類推...

*第 2 個參數(shù)是**事件觸發(fā)**間隔的**毫秒值**

**定時器事件的監(jiān)聽**

*通過`pygame.event.get()`可以獲取當(dāng)前時刻所有的**事件列表**

***遍歷列表**并且判斷`event.type`是否等于`eventid`狞悲,如果相等,表示**定時器事件**發(fā)生

### 1.2 定義并監(jiān)聽創(chuàng)建敵機(jī)的定時器事件

`pygame`的**定時器**使用套路非常固定:

1.定義**定時器常量**——`eventid`

2.在**初始化方法**中妇斤,調(diào)用`set_timer`方法**設(shè)置定時器事件**

3.在**游戲循環(huán)**中摇锋,**監(jiān)聽定時器事件**

#### 1) 定義事件

* 在 `plane_sprites.py` 的頂部定義 **事件常量**

```python

# 敵機(jī)的定時器事件常量

CREATE_ENEMY_EVENT = pygame.USEREVENT

```

*在`PlaneGame`的**初始化方法**中**創(chuàng)建用戶事件**

```python

# 4. 設(shè)置定時器事件 - 每秒創(chuàng)建一架敵機(jī)

pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)

```

#### 2) 監(jiān)聽定時器事件

* 在 `__event_handler` 方法中增加以下代碼:

```python

def __event_handler(self):


? ? for event in pygame.event.get():


? ? ? ? # 判斷是否退出游戲

? ? ? ? if event.type == pygame.QUIT:

? ? ? ? ? ? PlaneGame.__game_over()

? ? ? ? elif event.type == CREATE_ENEMY_EVENT:

? ? ? ? ? ? print("敵機(jī)出場...")

```

## 02. 設(shè)計`Enemy`類

1.游戲啟動后丹拯,**每隔 1 秒**會**出現(xiàn)一架敵機(jī)**

2.每架敵機(jī)**向屏幕下方飛行**,飛行**速度各不相同**

3.每架敵機(jī)出現(xiàn)的**水平位置**也不盡相同

4.當(dāng)敵機(jī)**從屏幕下方飛出**荸恕,不會再飛回到屏幕中

![014_派生Enemy子類-w657](media/15025309517247/014_%E6%B4%BE%E7%94%9FEnemy%E5%AD%90%E7%B1%BB.png)

***初始化方法**

? ? *指定**敵機(jī)圖片**

? ? ***隨機(jī)**敵機(jī)的**初始位置**和**初始速度**

*重寫**update()**方法

? ? *判斷**是否飛出屏幕**乖酬,如果是,從**精靈組**刪除

### 2.1 敵機(jī)類的準(zhǔn)備

* 在 `plane_sprites` 新建 `Enemy` 繼承自 `GameSprite`

*重寫**初始化方法**融求,直接指定**圖片名稱**

*暫時**不實(shí)現(xiàn)****隨機(jī)速度**和**隨機(jī)位置**的指定

*重寫`update`方法咬像,判斷是否飛出屏幕

```python

class Enemy(GameSprite):

? ? """敵機(jī)精靈"""


? ? def __init__(self):


? ? ? ? # 1. 調(diào)用父類方法,創(chuàng)建敵機(jī)精靈生宛,并且指定敵機(jī)的圖像

? ? ? ? super().__init__("./images/enemy1.png")

? ? ? ? # 2. 設(shè)置敵機(jī)的隨機(jī)初始速度

? ? ? ? # 3. 設(shè)置敵機(jī)的隨機(jī)初始位置


? ? def update(self):


? ? ? ? # 1. 調(diào)用父類方法县昂,讓敵機(jī)在垂直方向運(yùn)動

? ? ? ? super().update()


? ? ? ? # 2. 判斷是否飛出屏幕,如果是陷舅,需要將敵機(jī)從精靈組刪除

? ? ? ? if self.rect.y >= SCREEN_RECT.height:

? ? ? ? ? ? print("敵機(jī)飛出屏幕...")? ?

```

### 2.2 創(chuàng)建敵機(jī)

**演練步驟**

1. 在 `__create_sprites`倒彰,添加 **敵機(jī)精靈組**

? ? *敵機(jī)是**定時被創(chuàng)建的**,因此在初始化方法中莱睁,不需要創(chuàng)建敵機(jī)

2.在`__event_handler`待讳,創(chuàng)建敵機(jī),并且**添加到精靈組**

? ? *調(diào)用**精靈組**的`add`方法可以**向精靈組添加精靈**

3. 在 `__update_sprites`仰剿,讓 **敵機(jī)精靈組** 調(diào)用 `update` 和 `draw` 方法

![006_pygame.SpriteII](media/15025309517247/006_pygame.SpriteII.png)

**演練代碼**

* 修改 `plane_main` 的 `__create_sprites` 方法

```python

# 敵機(jī)組

self.enemy_group = pygame.sprite.Group()

```

* 修改 `plane_main` 的 `__update_sprites` 方法

```python

self.enemy_group.update()

self.enemy_group.draw(self.screen)

```

*定時出現(xiàn)敵機(jī)

```python

elif event.type == CREATE_ENEMY_EVENT:

? ? self.enemy_group.add(Enemy())

```

### 2.3 隨機(jī)敵機(jī)位置和速度

#### 1) 導(dǎo)入模塊

*在導(dǎo)入模塊時创淡,**建議**按照以下順序?qū)?/p>

```python

1. 官方標(biāo)準(zhǔn)模塊導(dǎo)入

2. 第三方模塊導(dǎo)入

3. 應(yīng)用程序模塊導(dǎo)入

```

* 修改 `plane_sprites.py` 增加 `random` 的導(dǎo)入

```python

import random

```

#### 2) 隨機(jī)位置

![015_飛機(jī)初始位置-w360](media/15025309517247/015_%E9%A3%9E%E6%9C%BA%E5%88%9D%E5%A7%8B%E4%BD%8D%E7%BD%AE.png)

使用`pygame.Rect`提供的`bottom`屬性,在指定敵機(jī)初始位置時南吮,會比較方便

*? `bottom = y + height`

*? `y = bottom - height`

#### 3) 代碼實(shí)現(xiàn)

*修改**初始化方法**辩昆,隨機(jī)敵機(jī)出現(xiàn)**速度**和**位置**

```python

def __init__(self):

? ? # 1. 調(diào)用父類方法,創(chuàng)建敵機(jī)精靈旨袒,并且指定敵機(jī)的圖像

? ? super().__init__("./images/enemy1.png")

? ? # 2. 設(shè)置敵機(jī)的隨機(jī)初始速度 1 ~ 3

? ? self.speed = random.randint(1, 3)

? ? # 3. 設(shè)置敵機(jī)的隨機(jī)初始位置

? ? self.rect.bottom = 0


? ? max_x = SCREEN_RECT.width - self.rect.width

? ? self.rect.x = random.randint(0, max_x)

```

### 2.4 移出屏幕銷毀敵機(jī)

*敵機(jī)移出屏幕之后汁针,如果**沒有撞到英雄**,敵機(jī)的歷史使命已經(jīng)終結(jié)

*需要從**敵機(jī)組**刪除砚尽,否則會造成**內(nèi)存浪費(fèi)**

#### 檢測敵機(jī)被銷毀

*`__del__`內(nèi)置方法會在對象被銷毀前調(diào)用施无,在開發(fā)中,可以用于**判斷對象是否被銷毀**

```python

def __del__(self):

? ? print("敵機(jī)掛了 %s" % self.rect)

```

####代碼實(shí)現(xiàn)

![006_pygame.SpriteII](media/15025309517247/006_pygame.SpriteII.png)

*判斷敵機(jī)是否飛出屏幕必孤,如果是猾骡,調(diào)用`kill()`方法從所有組中刪除

```python

def update(self):

? ? super().update()


? ? # 判斷敵機(jī)是否移出屏幕

? ? if self.rect.y >= SCREEN_RECT.height:

? ? ? ? # 將精靈從所有組中刪除

? ? ? ? self.kill()

```

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市敷搪,隨后出現(xiàn)的幾起案子兴想,更是在濱河造成了極大的恐慌,老刑警劉巖赡勘,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫂便,死亡現(xiàn)場離奇詭異,居然都是意外死亡闸与,警方通過查閱死者的電腦和手機(jī)毙替,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門岸售,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人厂画,你說我怎么就攤上這事凸丸。” “怎么了袱院?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵屎慢,是天一觀的道長。 經(jīng)常有香客問我忽洛,道長腻惠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任脐瑰,我火速辦了婚禮妖枚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苍在。我一直安慰自己绝页,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布寂恬。 她就那樣靜靜地躺著续誉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪初肉。 梳的紋絲不亂的頭發(fā)上酷鸦,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機(jī)與錄音牙咏,去河邊找鬼臼隔。 笑死,一個胖子當(dāng)著我的面吹牛妄壶,可吹牛的內(nèi)容都是我干的摔握。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼丁寄,長吁一口氣:“原來是場噩夢啊……” “哼氨淌!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起伊磺,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤盛正,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后屑埋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豪筝,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了壤蚜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片即寡。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡徊哑,死狀恐怖袜刷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情莺丑,我是刑警寧澤著蟹,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站梢莽,受9級特大地震影響萧豆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜昏名,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一涮雷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧轻局,春花似錦洪鸭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至镇饮,卻和暖如春蜓竹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背储藐。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工俱济, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钙勃。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓蛛碌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親肺缕。 傳聞我的和親對象是個殘疾皇子左医,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容