自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何向你的Python游戲中添加一個(gè)敵人

開發(fā) 后端
在本系列的第五部分,學(xué)習(xí)如何增加一個(gè)壞蛋與你的好人戰(zhàn)斗。在對(duì)玩家妖精實(shí)現(xiàn)全部功能之前,就來實(shí)現(xiàn)一個(gè)敵人似乎就很奇怪。但你已經(jīng)學(xué)到了很多東西,創(chuàng)造惡棍與與創(chuàng)造玩家妖精非常相似。所以放輕松,使用你已經(jīng)掌握的知識(shí),看看能挑起怎樣一些麻煩。

[[265946]]

在本系列的第五部分,學(xué)習(xí)如何增加一個(gè)壞蛋與你的好人戰(zhàn)斗。

在本系列的前幾篇文章中(參見 ***部分、第二部分、第三部分 以及 第四部分),你已經(jīng)學(xué)習(xí)了如何使用 Pygame 和 Python 在一個(gè)空白的視頻游戲世界中生成一個(gè)可玩的角色。但沒有惡棍,英雄又將如何?

如果你沒有敵人,那將會(huì)是一個(gè)非常無聊的游戲。所以在此篇文章中,你將為你的游戲添加一個(gè)敵人并構(gòu)建一個(gè)用于創(chuàng)建關(guān)卡的框架。

在對(duì)玩家妖精實(shí)現(xiàn)全部功能之前,就來實(shí)現(xiàn)一個(gè)敵人似乎就很奇怪。但你已經(jīng)學(xué)到了很多東西,創(chuàng)造惡棍與與創(chuàng)造玩家妖精非常相似。所以放輕松,使用你已經(jīng)掌握的知識(shí),看看能挑起怎樣一些麻煩。

針對(duì)本次訓(xùn)練,你能夠從 Open Game Art 下載一些預(yù)創(chuàng)建的素材。此處是我使用的一些素材:

  • 印加花磚(LCTT 譯注:游戲中使用的花磚貼圖)
  • 一些侵略者
  • 妖精、角色、物體以及特效

創(chuàng)造敵方妖精

是的,不管你意識(shí)到與否,你其實(shí)已經(jīng)知道如何去實(shí)現(xiàn)敵人。這個(gè)過程與創(chuàng)造一個(gè)玩家妖精非常相似:

  1. 創(chuàng)建一個(gè)類用于敵人生成
  2. 創(chuàng)建 update 方法使得敵人能夠檢測(cè)碰撞
  3. 創(chuàng)建 move 方法使得敵人能夠四處游蕩

從類入手。從概念上看,它與你的 Player 類大體相同。你設(shè)置一張或者一組圖片,然后設(shè)置妖精的初始位置。

在繼續(xù)下一步之前,確保你有一張你的敵人的圖像,即使只是一張臨時(shí)圖像。將圖像放在你的游戲項(xiàng)目的 images 目錄(你放置你的玩家圖像的相同目錄)。

如果所有的活物都擁有動(dòng)畫,那么游戲看起來會(huì)好得多。為敵方妖精設(shè)置動(dòng)畫與為玩家妖精設(shè)置動(dòng)畫具有相同的方式。但現(xiàn)在,為了保持簡(jiǎn)單,我們使用一個(gè)沒有動(dòng)畫的妖精。

在你代碼 objects 節(jié)的頂部,使用以下代碼創(chuàng)建一個(gè)叫做 Enemy 的類:

  1. class Enemy(pygame.sprite.Sprite):
  2.     '''
  3. 生成一個(gè)敵人
  4.     '''
  5.     def __init__(self,x,y,img):
  6.         pygame.sprite.Sprite.__init__(self)
  7.         self.image = pygame.image.load(os.path.join('images',img))
  8.         self.image.convert_alpha()
  9.         self.image.set_colorkey(ALPHA)
  10.         self.rect = self.image.get_rect()
  11.         self.rect.x = x
  12.         self.rect.y = y

如果你想讓你的敵人動(dòng)起來,使用讓你的玩家擁有動(dòng)畫的 相同方式。

生成一個(gè)敵人

你能夠通過告訴類,妖精應(yīng)使用哪張圖像,應(yīng)出現(xiàn)在世界上的什么地方,來生成不只一個(gè)敵人。這意味著,你能夠使用相同的敵人類,在游戲世界的任意地方生成任意數(shù)量的敵方妖精。你需要做的僅僅是調(diào)用這個(gè)類,并告訴它應(yīng)使用哪張圖像,以及你期望生成點(diǎn)的 X 和 Y 坐標(biāo)。

再次,這從原則上與生成一個(gè)玩家精靈相似。在你腳本的 setup 節(jié)添加如下代碼:

  1. enemy   = Enemy(20,200,'yeti.png') # 生成敵人
  2. enemy_list = pygame.sprite.Group() # 創(chuàng)建敵人組
  3. enemy_list.add(enemy)              # 將敵人加入敵人組

在示例代碼中,X 坐標(biāo)為 20,Y 坐標(biāo)為 200。你可能需要根據(jù)你的敵方妖精的大小,來調(diào)整這些數(shù)字,但盡量生成在一個(gè)范圍內(nèi),使得你的玩家妖精能夠碰到它。Yeti.png 是用于敵人的圖像。

接下來,將敵人組的所有敵人繪制在屏幕上?,F(xiàn)在,你只有一個(gè)敵人,如果你想要更多你可以稍后添加。一但你將一個(gè)敵人加入敵人組,它就會(huì)在主循環(huán)中被繪制在屏幕上。中間這一行是你需要添加的新行:

  1.     player_list.draw(world)
  2.     enemy_list.draw(world)  # 刷新敵人
  3.     pygame.display.flip()

啟動(dòng)你的游戲,你的敵人會(huì)出現(xiàn)在游戲世界中你選擇的 X 和 Y 坐標(biāo)處。

關(guān)卡一

你的游戲仍處在襁褓期,但你可能想要為它添加另一個(gè)關(guān)卡。為你的程序做好未來規(guī)劃非常重要,因?yàn)殡S著你學(xué)會(huì)更多的編程技巧,你的程序也會(huì)隨之成長。即使你現(xiàn)在仍沒有一個(gè)完整的關(guān)卡,你也應(yīng)該按照假設(shè)會(huì)有很多關(guān)卡來編程。

思考一下“關(guān)卡”是什么。你如何知道你是在游戲中的一個(gè)特定關(guān)卡中呢?

你可以把關(guān)卡想成一系列項(xiàng)目的集合。就像你剛剛創(chuàng)建的這個(gè)平臺(tái)中,一個(gè)關(guān)卡,包含了平臺(tái)、敵人放置、戰(zhàn)利品等的一個(gè)特定排列。你可以創(chuàng)建一個(gè)類,用來在你的玩家附近創(chuàng)建關(guān)卡。最終,當(dāng)你創(chuàng)建了一個(gè)以上的關(guān)卡,你就可以在你的玩家達(dá)到特定目標(biāo)時(shí),使用這個(gè)類生成下一個(gè)關(guān)卡。

將你寫的用于生成敵人及其群組的代碼,移動(dòng)到一個(gè)每次生成新關(guān)卡時(shí)都會(huì)被調(diào)用的新函數(shù)中。你需要做一些修改,使得每次你創(chuàng)建新關(guān)卡時(shí),你都能夠創(chuàng)建一些敵人。

  1. class Level():
  2.     def bad(lvl,eloc):
  3.         if lvl == 1:
  4.             enemy = Enemy(eloc[0],eloc[1],'yeti.png') # 生成敵人
  5.             enemy_list = pygame.sprite.Group() # 生成敵人組
  6.             enemy_list.add(enemy)              # 將敵人加入敵人組
  7.         if lvl == 2:
  8.             print("Level " + str(lvl) )
  9.  
  10.         return enemy_list

return 語句確保了當(dāng)你調(diào)用 Level.bad 方法時(shí),你將會(huì)得到一個(gè) enemy_list 變量包含了所有你定義的敵人。

因?yàn)槟悻F(xiàn)在將創(chuàng)造敵人作為每個(gè)關(guān)卡的一部分,你的 setup 部分也需要做些更改。不同于創(chuàng)造一個(gè)敵人,取而代之的是你必須去定義敵人在那里生成,以及敵人屬于哪個(gè)關(guān)卡。

  1. eloc = []
  2. eloc = [200,20]
  3. enemy_list = Level.bad( 1, eloc )

再次運(yùn)行游戲來確認(rèn)你的關(guān)卡生成正確。與往常一樣,你應(yīng)該會(huì)看到你的玩家,并且能看到你在本章節(jié)中添加的敵人。

痛擊敵人

一個(gè)敵人如果對(duì)玩家沒有效果,那么它不太算得上是一個(gè)敵人。當(dāng)玩家與敵人發(fā)生碰撞時(shí),他們通常會(huì)對(duì)玩家造成傷害。

因?yàn)槟憧赡芟胍ジ櫷婕业纳?,因此碰撞檢測(cè)發(fā)生在 Player 類,而不是 Enemy 類中。當(dāng)然如果你想,你也可以跟蹤敵人的生命值。它們之間的邏輯與代碼大體相似,現(xiàn)在,我們只需要跟蹤玩家的生命值。

為了跟蹤玩家的生命值,你必須為它確定一個(gè)變量。代碼示例中的***行是上下文提示,那么將第二行代碼添加到你的 Player 類中:

  1.         self.frame  = 0
  2.         self.health = 10

在你 Player 類的 update 方法中,添加如下代碼塊:

  1.         hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
  2.         for enemy in hit_list:
  3.             self.health -= 1
  4.             print(self.health)

這段代碼使用 Pygame 的 sprite.spritecollide 方法,建立了一個(gè)碰撞檢測(cè)器,稱作 enemy_hit。每當(dāng)它的父類妖精(生成檢測(cè)器的玩家妖精)的碰撞區(qū)觸碰到 enemy_list 中的任一妖精的碰撞區(qū)時(shí),碰撞檢測(cè)器都會(huì)發(fā)出一個(gè)信號(hào)。當(dāng)這個(gè)信號(hào)被接收,for 循環(huán)就會(huì)被觸發(fā),同時(shí)扣除一點(diǎn)玩家生命值。

一旦這段代碼出現(xiàn)在你 Player 類的 update 方法,并且 update 方法在你的主循環(huán)中被調(diào)用,Pygame 會(huì)在每個(gè)時(shí)鐘滴答中檢測(cè)一次碰撞。

移動(dòng)敵人

如果你愿意,靜止不動(dòng)的敵人也可以很有用,比如能夠?qū)δ愕耐婕以斐蓚Φ募獯毯拖葳?。但如果敵人能夠四處徘徊,那么游戲?qū)⒏挥刑魬?zhàn)。

與玩家妖精不同,敵方妖精不是由玩家控制,因此它必須自動(dòng)移動(dòng)。

最終,你的游戲世界將會(huì)滾動(dòng)。那么,如何在游戲世界自身滾動(dòng)的情況下,使游戲世界中的敵人前后移動(dòng)呢?

舉個(gè)例子,你告訴你的敵方妖精向右移動(dòng) 10 步,向左移動(dòng) 10 步。但敵方妖精不會(huì)計(jì)數(shù),因此你需要?jiǎng)?chuàng)建一個(gè)變量來跟蹤你的敵人已經(jīng)移動(dòng)了多少步,并根據(jù)計(jì)數(shù)變量的值來向左或向右移動(dòng)你的敵人。

首先,在你的 Enemy 類中創(chuàng)建計(jì)數(shù)變量。添加以下代碼示例中的***一行代碼:

  1.         self.rect = self.image.get_rect()
  2.         self.rect.x = x
  3.         self.rect.y = y
  4.         self.counter = 0 # 計(jì)數(shù)變量

然后,在你的 Enemy 類中創(chuàng)建一個(gè) move 方法。使用 if-else 循環(huán)來創(chuàng)建一個(gè)所謂的死循環(huán):

  • 如果計(jì)數(shù)在 0 到 100 之間,向右移動(dòng);
  • 如果計(jì)數(shù)在 100 到 200 之間,向左移動(dòng);
  • 如果計(jì)數(shù)大于 200,則將計(jì)數(shù)重置為 0。

死循環(huán)沒有終點(diǎn),因?yàn)檠h(huán)判斷條件永遠(yuǎn)為真,所以它將永遠(yuǎn)循環(huán)下去。在此情況下,計(jì)數(shù)器總是介于 0 到 100 或 100 到 200 之間,因此敵人會(huì)永遠(yuǎn)地從左向右再從右向左移動(dòng)。

你用于敵人在每個(gè)方向上移動(dòng)距離的具體值,取決于你的屏幕尺寸,更確切地說,取決于你的敵人移動(dòng)的平臺(tái)大小。從較小的值開始,依據(jù)習(xí)慣逐步提高數(shù)值。首先進(jìn)行如下嘗試:

  1.     def move(self):
  2.         '''
  3. 敵人移動(dòng)
  4.         '''
  5.         distance = 80
  6.         speed = 8
  7.  
  8.         if self.counter >= 0 and self.counter <= distance:
  9.             self.rect.x += speed
  10.         elif self.counter >= distance and self.counter <= distance*2:
  11.             self.rect.x -= speed
  12.         else:
  13.             self.counter = 0
  14.  
  15.         self.counter += 1

你可以根據(jù)需要調(diào)整距離和速度。

當(dāng)你現(xiàn)在啟動(dòng)游戲,這段代碼有效果嗎?

當(dāng)然不,你應(yīng)該也知道原因。你必須在主循環(huán)中調(diào)用 move 方法。如下示例代碼中的***行是上下文提示,那么添加***兩行代碼:

  1.     enemy_list.draw(world) #refresh enemy
  2.     for e in enemy_list:
  3.         e.move()

啟動(dòng)你的游戲看看當(dāng)你打擊敵人時(shí)發(fā)生了什么。你可能需要調(diào)整妖精的生成地點(diǎn),使得你的玩家和敵人能夠碰撞。當(dāng)他們發(fā)生碰撞時(shí),查看 IDLENinja-IDE 的控制臺(tái),你可以看到生命值正在被扣除。

你應(yīng)該已經(jīng)注意到,在你的玩家和敵人接觸時(shí),生命值在時(shí)刻被扣除。這是一個(gè)問題,但你將在對(duì) Python 進(jìn)行更多練習(xí)以后解決它。

現(xiàn)在,嘗試添加更多敵人。記得將每個(gè)敵人加入 enemy_list。作為一個(gè)練習(xí),看看你能否想到如何改變不同敵方妖精的移動(dòng)距離。 

責(zé)任編輯:龐桂玉 來源: Linux中國
相關(guān)推薦

2019-05-21 13:55:22

Python編程語言游戲

2020-11-30 14:00:16

Python游戲編程語言

2010-02-01 14:48:43

2020-01-14 12:05:20

Python游戲引力

2010-03-11 18:57:17

Python腳本

2015-08-11 08:51:40

游戲死亡

2020-11-30 13:33:25

Python平臺(tái)類游戲編程語言

2021-01-01 19:30:21

Python編程語言

2011-08-24 11:14:25

LUA 游戲

2022-01-12 10:37:09

區(qū)塊鏈技術(shù)金融

2015-07-28 14:35:40

2019-09-23 09:11:02

Python文本編輯器操作系統(tǒng)

2013-04-03 15:10:09

GMGC全球移動(dòng)游戲大

2015-06-02 04:13:23

Python乒乓球類游戲

2012-12-25 10:51:39

IBMdW

2013-08-19 10:45:36

社交游戲手機(jī)游戲

2021-09-09 09:16:06

機(jī)器學(xué)習(xí)人工智能計(jì)算機(jī)

2019-09-30 09:26:29

Java編程語言國旗

2022-03-24 07:57:58

Python水果忍者游戲

2021-11-15 10:35:46

Python線程代碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)