<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                    接下來,我們為我方飛機添加武器——發射子彈。   考慮到Python語言的模塊化,我們同樣將子彈封裝為一個模塊,bullet.py。新建py文件,導入Pygame,編程開始。   1、定義子彈類——Bullet1   強調這里之所謂命名為Bullet1,是因為游戲中我方飛機射出的子彈是有兩種形式,一種是普通子彈,另外一種是超級子彈。其中超級子彈(Bullet2)將在之后的補給發放機制中進行講解,這里先給出Bullet1類的代碼: ~~~ # ====================定義普通子彈==================== class Bullet1(pygame.sprite.Sprite): def __init__(self, position): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load("image/bullet1.png") self.rect = self.image.get_rect() self.rect.left, self.rect.top = position self.speed = 12 self.active = True self.mask = pygame.mask.from_surface(self.image) def move(self): if self.rect.top < 0: self.active = False else: self.rect.top -= self.speed def reset(self, position): self.rect.left, self.rect.top = position self.active = True ~~~   Bullet1與之前定義的飛機類在結構上很相似,同樣都繼承至Pygame的精靈類,同樣具有active標志位、mask掩膜成員、具有移動函數move()和復位函數reset(),需要注意的有一下幾點:1、子彈的速度屬性speed要稍微大一點。2、子彈的初始化位置是一個隨我方飛機位置變化而變化的量,因此需要在初始化子彈對象時由外部傳入(代碼中的position,是一個rect類型變量)。3、子彈在屏幕中是自下而上移動的,因此是“-= self.speed”。   2、在主程序中實例化子彈   玩過小蜜蜂游戲的同學都知道,這種打飛機類的游戲子彈的發射速度是要比90坦克的炮彈速度快的,嚴格的說不是速度快,而是頻率高。90坦克中我方坦克一次只發射一枚炮彈,在炮彈達到最大射程或者擊中敵方坦克之后才能打出下一發炮彈。打飛機則不然,一次只發射一發子彈顯然不能應付眾多敵機,需要源源不斷的發射子彈,落實到程序中也就是需要實例化多個子彈對象并且循環打印,這與之前敵方飛機的初始化方式很像,都是添加多個精靈對象并循環顯示,因此我們采用和之前敵機實例化時相類似的機制,首先在main函數的while循環之前創建子彈精靈的索引,然后向其中添加指定數目的子彈: ~~~ # ====================生成普通子彈==================== bullet1 = [] bullet1_index = 0 bullet1_num = 6 # 定義子彈實例化個數 for i in range(bullet1_num): bullet1.append(bullet.Bullet1(me.rect.midtop)) ~~~   這里通過for循環語句來產生指定數目的子彈對象,并存儲于列表結構體中(bullet1),值得注意的一點是,在前面已經提到,在實例化子彈對象時,需要外部傳入子彈的初始位置,這里的me.rect.midtop代表的是我方飛機的上方正中間的位置,其實rect結構體還有很多有趣的成員變量來表征其某部分屬性,比如說以后我們會用到的rect.center,代表矩形的中心位置,這些知識遇到了再積累吧。   3、顯示子彈及音效   子彈初始化完成后需要將子彈顯示在屏幕上: ~~~ if not (delay % 10): # 每十幀發射一顆移動的子彈 bullet_sound.play() bullets = bullet1 bullets[bullet1_index].reset(me.rect.midtop) bullet1_index = (bullet1_index + 1) % bullet1_num ~~~   這部分代碼應該放在while循環之內,這里if not (delay % 10)是設置子彈打印的速度,即每十幀繪制一發子彈,delay參數在之前已經詳細介紹過,這里不再贅述。在調用子彈對象的reset()成員函數是,即將該對象的active成員變量設置為true,說明該子彈對象已經處于激活狀態了。程序編寫到這里,如果此時運行程序的話,只能聽到發射子彈的聲音,并不能看到實際發射的子彈,原因是沒有對子彈進行繪制(blit函數)。但這里并不能簡單的把子彈繪制到屏幕上,因為我們還要為子彈賦予它的本質功能,擊毀敵機,也就是和敵機的碰撞檢測。   4、子彈與敵機的碰撞檢測   在實例化完子彈之后,我們要做的第一件事并不是將子彈顯示出來,二是要先檢測該發子彈是否擊中了敵機,如果擊中,就不再顯示這發子彈了。因此這里正常的程序設計思路應該是:每一發子彈 -> 該發子彈是否已經激活 -> 如果激活,是否擊中敵機 -> 如果沒擊中,正常繪制子彈圖像 -> 如果擊中,則子彈損毀,同時敵機損毀,代碼如下: ~~~ for b in bullets: if b.active: # 只有激活的子彈才可能擊中敵機 b.move() screen.blit(b.image, b.rect) enemies_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask) if enemies_hit: # 如果子彈擊中飛機 b.active = False # 子彈損毀 for e in enemies_hit: e.active = False # 小型敵機損毀 ~~~   這里在碰撞檢測是,考慮到子彈對象和敵機對象都已經在內部定義了mask(掩膜)成員變量,因此直接調用基于掩膜的的碰撞檢測函數即可(詳見上篇博文),再次說明碰撞檢測函數的返回值(enemise_hit)是一個存放精靈的精靈組結構,通過for()循環遍歷其中的元素及確定那個精靈檢測到了碰撞。   ok,程序編寫到這里,按道理來說應該能夠正常運行,但在這里很可能會出現一個類似于“local variable 'bullets' referenced before assignment”的錯誤,在這里簡單分析一下。錯誤的意思是bullets變量沒有定義,出現這個錯誤的原因在于我們過早的將delay延時參數進行了減一操作。假如我們將“delay -= 1”這句話放在了while循環的開始位置,delay的初始值為60,進入while循環的一瞬間它就會減為59,這樣“if not (delay % 10)”這個條件就不會成立,也就不會執行“bullets = bullet1”,當然也不會播放子彈音效,因此在程序執行到“for b in bullets:”時,由于之前的“bullets = bullet1”操作沒有順利執行,自然bullets參數屬于未定義的狀態。解決方案也很簡單,就是把delay參數的控制代碼: ~~~ if delay == 0: delay = 60 delay -= 1 ~~~ 移至while循環的末尾,這樣程序在進入循環是delay=60,所有代碼順利執行。   截止到這里,程序順利運行,我方飛機射出的子彈將敵機一擊斃命。當然這里也有不合理的地方,小型敵機可以一擊斃命,但中型敵機和大型敵機皮糙肉厚,應該能多挨幾發子彈才對,這在之后的博文中會給中型敵機和大型敵機賦予一定血量,并以血槽的形式顯示出來。OK,這篇博文就到這里,大家工作順利。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看