面向?qū)ο蟮娘w機(jī)大戰(zhàn)編程

游戲框架分為兩部分

1.創(chuàng)建一個(gè)plane_main.py的主文件,寫出一個(gè)PlaneGame的主類。

import pygame
class PlaneGmae(object):
    def __init__(self):
        print('游戲初始化...')
    def start_game(self):
        print('游戲開始...')
if __name__ == '__main__':
    # 創(chuàng)建游戲?qū)ο?    game = PlaneGmae()
    # 啟動(dòng)游戲
    game.start_game()

運(yùn)行結(jié)果為

D:\python\python36\python.exe D:/PycharmProjects/feijidazhan_1/feiji.py
游戲初始化...
游戲開始...

2.另新建一個(gè)plane_sprite.py 的模塊

import pygame
class Game_Sprite(pygame.sprite.Sprite):#派生精靈子類
    '''飛機(jī)大戰(zhàn)游戲精靈'''
    def __init__(self,image_name,speed = 1):
        # 繼承父類的__init__()
        super().__init__()
        # 定義對(duì)象的屬性
        self.image =pygame.image.load(image_name)
        self.rect = self.image.get_rect()
        '''self.image的get_rect()返回pygame.Rect(0,0,width,height)'''
        self.speed = speed
        def update(self):
           self.rect.y += self.speed

3. 主程序中設(shè)置游戲初始化的步驟

class PlaneGmae(object):
    def __init__(self):
        print('游戲初始化...')
        # 1.創(chuàng)建游戲屏幕
        self.screen = pygame.display.set_mode(SCREEN_RECT.size) #引入的常量
        # 2.創(chuàng)建游戲時(shí)鐘
        self.clock = pygame.time.Clock()
        # 3.私有方法創(chuàng)建精靈和精靈組
        self.__creat_sprite()
    def __creat_sprite(self):
        pass

4主程序中游戲的開始部分的步驟

class PlaneGmae(object):
    游戲初始化部分...
    .......
    def start_game(self):
        print('游戲開始...')
        while True:
            # 1.設(shè)置幀率
            self.clock.tick(60)
            # 2. 事件監(jiān)聽
            self.__event_monitor()
            # 3. 碰撞檢測(cè)
            self.__check_collide()
            # 4. 繪制圖像
            self.__blit_photo()
            # 5.刷新顯示
            pygame.display.update()

5.為了讓程序可讀性高,便于維護(hù),建議是使用私有方法,由于上面的四個(gè)步驟都是私有方法,所以接下來(lái)在上面的主要類開始布置私有方法

    def __event_monitor(self):
        pass
    def __check_collide(self):
        pass
    def __blit_photo(self):
        pass
    @staticmethod
    def __game_over():
        print('退出游戲')
        # 卸載所有模塊
        pygame.quit()
        # 退出程序
        exit()
  • 需要注意的上面有一個(gè)靜態(tài)方法,由于這個(gè)方法調(diào)用這個(gè)類里的任何方法和屬性,所以要把它編程靜態(tài)方法,加修飾符@staticmethod 不用加self參數(shù)
  • 代碼走到上面的這些就已經(jīng)把飛機(jī)大戰(zhàn)的游戲的整體框架搞定了
    shift+f10 執(zhí)行一下代碼,顯示為:
image.png

6.接下來(lái)我們開始布置背景圖(這里用到一個(gè)小套路,讓背景圖在垂直方向上移動(dòng),這樣就可以讓英雄飛機(jī)相對(duì)運(yùn)動(dòng)了)

1.在模塊文檔那里開始寫背景類

class Background(Game_Sprite):
    def __init__(self,is_alt = False):
        super().__init__('./images/background.png')
        if is_alt:
            self.rect.bottom = 0
    def  update(self):
        # 讓屏幕往下移動(dòng),所以可以用到父類的方法。所以可以繼承
        super().update()
        # 判斷底部照片是否超出屏幕
        if self.rect.y > SCREEN_RECT.height:
            self.rect.y =-SCREEN_RECT.height

2.回到主程序中的初始化部分那里,開始填寫__creat_sprite()私有方法

 def __creat_sprite(self):
        # 創(chuàng)造背景精靈和精靈組
        bg1 = Background()
        bg2 = Background(True)
        self.bg_group = pygame.sprite.Group(bg1,bg2)

3.回到主程序中游戲開始部分那里,self.__blit_photo() 圖像繪制更新那里

    def __blit_photo(self):
        # 背景圖片的繪制
        self.bg_group.update()
        self.bg_group.draw(self.screen)

shift+f10 運(yùn)行的效果是一向下移動(dòng)的背景圖

7.為了方便后面測(cè)試程序,我們?cè)谶@里就開始寫事件監(jiān)聽的代碼,一旦檢測(cè)到退出的信號(hào)就直接退出

    def __event_monitor(self):
        for event in pygame.event.get():
            # 判斷監(jiān)聽是否有退出動(dòng)作
            if event.type == pygame.QUIT:
                PlaneGmae. __game_over()
  • 注意靜態(tài)方法的調(diào)用是直接類名.方法名

8.敵機(jī)的類的填寫以及精靈類和精靈組的填寫(由于敵機(jī)較多,要用到定時(shí)器)

class Enemy(Game_Sprite):
    def __init__(self):
        super().__init__('./images/enemy1')
        # 敵機(jī)初始化位置
        # 1.x軸上的隨機(jī)位置
        Max_x = SCREEN_RECT.width-self.rect.width
        self.rect.x = random.randint(0,Max_x)
        # 2.y軸上的隨機(jī)位置
        self.rect.bottom = 0
        # 初始速度的設(shè)置
        self.speed = random.randint(1,3)
    def update(self):
        # 繼承父類的update讓敵機(jī)向下移動(dòng)
        super().update()
        # 判斷敵機(jī)是否超出屏幕
        if self.rect.y > SCREEN_RECT.height:
            self.kill()
    def __del__(self):
        print('敵機(jī)掛了%s' % self.rect)

1.敵機(jī)定時(shí)器的三步驟:
a.在模塊文件中寫出定時(shí)器常量 eg:XXX = pygame.USEREVENT
b.在主程序的初始化中

pygame.time.set_timer(CREAT_TIMER,1000)

其中1000指的1000毫秒也就是1秒執(zhí)行一個(gè)定時(shí)器的動(dòng)作
c.在事件監(jiān)聽里

            elif event.type == CREAT_TIMER:
                print('產(chǎn)生敵機(jī)...')

那樣就可以1秒一個(gè)敵機(jī)出現(xiàn)
2.開始在初始化位置創(chuàng)建精靈組

# 創(chuàng)建敵機(jī)精靈組
       self.enemy_group = pygame.sprite.Group()

3.在事件監(jiān)聽那里去寫精靈組,因?yàn)檫@是持續(xù)不斷的要精靈組的

 elif event.type == CREAT_TIMER:
                print('產(chǎn)生敵機(jī)...')
                # 敵機(jī)精靈
                enemy = Enemy()

                # 敵機(jī)精靈組
                self.enemy_group.add(enemy)

4.將敵機(jī)精靈組進(jìn)行繪制

 # 敵機(jī)的繪制
        self.enemy_group.update()
        self.enemy_group.draw(self.screen)
  • 此時(shí)屏幕開始持續(xù)出現(xiàn)敵機(jī)


    image.png

9.開始英雄的類已經(jīng)精靈的布置

class Hero(Game_Sprite):
    # 繼承父類,設(shè)置imgae和speed
    def __init__(self):
        super().__init__('./images/me1.png',0)
        # 確定好英雄的初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom-120
  • 在創(chuàng)建精靈的私有方法里開始創(chuàng)建英雄的精靈和精靈組
# 創(chuàng)建英雄精靈和精靈組
       self. hero_sprite = Hero()  #此對(duì)象要在其他方法被調(diào)用所以加self
        self.hero_sprite_group = pygame.sprite.Group(hero_sprite)
  • 繪制圖像
 # 英雄的繪制
        self.hero_sprite_group.update()
        self.hero_sprite_group.draw(self.screen)
  • shift + f10


    image.png

10.開始讓飛機(jī)在左右移動(dòng)但是不能超出左右邊界

  • 1.使用鍵盤按鍵獲取按鍵元組
# 使用鍵盤方法獲取按鍵元組
        keys_pressed = pygame.key.get_pressed()
        # 判斷元組中對(duì)應(yīng)按鍵索引值
        if keys_pressed[pygame.K_RIGHT]:
            self.hero_sprite.speed = 2
        elif keys_pressed[pygame.K_LEFT]:
            self.hero_sprite.speed = -2
        else:
            self.hero_sprite.speed = 0
  • 這個(gè)按鍵元組的value值是1時(shí)鍵值就是左右的一種

  • 此時(shí)的Hero類

class Hero(Game_Sprite):
    # 繼承父類,設(shè)置imgae和speed
    def __init__(self):
        super().__init__('./images/me1.png',0)
        # 確定好英雄的初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom-120
    def update(self):
        # 因?yàn)槭亲笥乙苿?dòng),所以可以完全改寫父類方法
        self.rect.x += self.speed

        # 判斷英雄飛機(jī)是否飛出屏幕外
        if self.rect.x < 0:
            self.rect.x = 0
        elif self.rect.x > SCREEN_RECT.width-self.rect.width:
            self.rect.right = SCREEN_RECT.right
  • 此時(shí)的效果為,英雄可以左右移動(dòng)但不會(huì)超出邊界


    image.png

11.開始設(shè)置子彈

  • 1.設(shè)置子彈的類
class Bullet(Game_Sprite):
    def __init__(self):
        # 繼承父類,加載圖片
        super().__init__('./images/bullet1.png',-2)
        # 初始位置先不要管,等到英雄類里再去弄
    def update(self):
        # 繼承父類方法,讓子彈移動(dòng)
        super().update()

        # 判斷子彈是否超出屏幕
        if self.rect.bottom < 0:
            self.kill()
    def __del__(self):
        print('超出子彈被銷毀%s'%self.rect)

注意下,這里不要設(shè)置子彈的初始位置,因?yàn)樽訌椀某跏嘉恢檬且陀⑿垡黄鹋?/strong>

  • 2.設(shè)置子彈的定時(shí)器
# 子彈常量
HERO_FIRE = pygame.USEREVENT+1
 # 5. 發(fā)射子彈的定時(shí)器調(diào)用
        pygame.time.set_timer(HERO_FIRE,500)
 elif event.type ==  HERO_FIRE:
                self.hero_sprite.fire()

考慮到子彈是要和英雄一起弄的,我們把創(chuàng)建子彈精靈和精靈組放到英雄類中去

    1. 在英雄的類初始化方法里設(shè)置子彈精靈組
class Hero(Game_Sprite):
    # 繼承父類,設(shè)置imgae和speed
    def __init__(self):
        super().__init__('./images/me1.png',0)
        # 確定好英雄的初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom-120

        # 創(chuàng)建子彈精靈組
        self.bullets = pygame.sprite.Group()
  • 4 .開始設(shè)置在英雄類里設(shè)置fire()方法
            elif event.type ==  HERO_FIRE:
                self.hero_sprite.fire()
def fire(self):
      print('發(fā)射子彈...')
      for i in range(3):
          # 創(chuàng)建子彈精靈
          bullet = Bullet()
          # 設(shè)置子彈的初始位置
          bullet.rect.bottom = self.rect.y- i*20
          bullet.rect.centerx = self.rect.centerx
          # 設(shè)置子彈的精靈組
          self.bullets.add(bullet)
  • 5 .開始將子彈精靈組放到繪制圖像的方法里
 # 子彈的繪制
        self.hero_sprite.bullets.update()
        self.hero_sprite.bullets.draw(self.screen)

呈現(xiàn)的效果為


image.png

12.開始碰撞檢測(cè)

 def __check_collide(self):
        # 子彈碰到飛機(jī)
        pygame.sprite.groupcollide(self.hero_sprite.bullets,self.enemy_group,True,True)
        # 敵機(jī)撞毀飛機(jī)
        enemies = pygame.sprite.spritecollide(self.hero_sprite, self.enemy_group, True)
        # 判斷列表是否有內(nèi)容
        if len(enemies) > 0:
            # 讓英雄犧牲
            self.hero_sprite.kill()

            # 結(jié)束游戲
            PlaneGmae.__game_over()

shift +f10


image.png

碰撞的基礎(chǔ)知識(shí)

image.png

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容