<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用pygame回顧飛機(jī)大戰(zhàn)

          共 7825字,需瀏覽 16分鐘

           ·

          2021-12-25 22:33

          點(diǎn)擊上方“Python爬蟲與數(shù)據(jù)挖掘”,進(jìn)行關(guān)注

          回復(fù)“書籍”即可獲贈(zèng)Python從入門到進(jìn)階共10本電子書

          少小雖非投筆吏,論功還欲請(qǐng)長(zhǎng)纓。

          本文主要內(nèi)容

          • 通過(guò)例子示范窗口繪制及其所需函數(shù)簡(jiǎn)要說(shuō)明

          • 圖片移動(dòng)、通過(guò)用戶事件移動(dòng)圖片及所需函數(shù)簡(jiǎn)要說(shuō)明

          • 碰撞檢測(cè)及所需函數(shù)簡(jiǎn)要說(shuō)明

          • 音頻加載及所需函數(shù)簡(jiǎn)要說(shuō)明

          • 成果展示


          環(huán)境

          • python3.6+

          • windows/linux

          模塊安裝

          pip?install?pygame


          游戲窗口建立及所需函數(shù)簡(jiǎn)要說(shuō)明

          import?os
          import?time
          import?pygame

          #?屏幕寬度
          SCREEN_WIDTH?=?500
          #?屏幕高度
          SCREEN_HEIGHT?=?250
          #?圖片絕對(duì)路徑
          IMG_PATH?=?os.path.join(os.getcwd(),?"img")


          def?main():
          ???#?初始化顯示模塊
          ???pygame.display.init()
          ???#?創(chuàng)建窗口
          ???screen?=?pygame.display.set_mode((SCREEN_WIDTH,?SCREEN_HEIGHT))
          ???#?設(shè)置窗口標(biāo)題
          ???pygame.display.set_caption("python小demo?飛機(jī)大戰(zhàn)")
          ???#?設(shè)置窗口icon
          ???pygame.display.set_icon(pygame.image.load(os.path.join(IMG_PATH,?"icon.jpg")))
          ???#?加載背景圖片
          ???background?=?pygame.image.load(os.path.join(IMG_PATH,?"test_bj.png"))

          ???while?True:
          ???????#?將背景圖片繪制到窗口上
          ???????screen.blit(background,?(0,?0))
          ???????#?更新屏幕上內(nèi)容
          ???????pygame.display.update()
          ???????time.sleep(0.02)


          if?__name__?==?"__main__":
          ???main()

          查看下效果:


          x、y是我手動(dòng)繪制的,讓大家可以更加直觀的看到窗口坐標(biāo)軸情況


          所需函數(shù)簡(jiǎn)要說(shuō)明

          • pygame.display pygame用來(lái)控制屏幕和窗口

            https://www.pygame.org/docs/ref/display.html

          display.init()?->?None
          #?該函數(shù)只做初始化顯示模塊,且不返回任何東西
          #?如果在使用display其他方法未初始化,會(huì)自動(dòng)調(diào)用

          display.set_mode(size=(0,?0),?flags=0,?depth=0,?display=0,?vsync=0)?->?Surface
          #?該函數(shù)會(huì)創(chuàng)建并返回一個(gè)Surface的窗口對(duì)象
          #?參數(shù):
          #???size=(0,?0)?設(shè)置窗口大小,第一個(gè)是屏幕寬度,第二個(gè)是窗口高度
          #?? flags 控制您想要的顯示類型,例如是否全屏,可選參數(shù):
          #?????? pygame.FULLSCREEN:創(chuàng)建一個(gè)全屏
          #?????? pygame.DOUBLEBUF:雙緩沖模式,推薦和HWSURFACE或OPENGL一起使用
          #?????? pygame.HWSURFACE:硬件加速,只有在 FULLSCREEN 下可以使用
          #?????? pygame.OPENGL:創(chuàng)建一個(gè) OPENGL 渲染的顯示
          #?????? pygame.RESIZABLE:創(chuàng)建一個(gè)可調(diào)整尺寸的窗口
          #?????? pygame.NOFRAME:創(chuàng)建一個(gè)沒有邊框和控制按鈕的窗口
          #???????可以使用按位或選擇多個(gè)參數(shù),如:
          #???????????flags?=?pygame.OPENGL?|?pygame.FULLSCREEN
          #???depth?參數(shù)表示顏色位數(shù),不建議傳遞,默認(rèn)會(huì)選擇最佳的顏色深度
          #???display?窗口索引,默認(rèn)0
          #???vsync?傳入1時(shí),可以獲得垂直同步顯示,只有同時(shí)設(shè)置了pygame.OPENGL、
          #???pygame.FULLSCREEN才能傳值

          display.set_caption(title,?icontitle=None)?->?None
          #?設(shè)置窗口標(biāo)題
          #?參數(shù):
          #???title?窗口的標(biāo)題
          #???icontitle?部分系統(tǒng)支持最小窗口時(shí)切換標(biāo)題欄

          display.set_icon(Surface)?->?None
          #?設(shè)置窗口LOGO
          #?參數(shù):
          #???Surface?可以傳入任何Surface對(duì)象作為圖標(biāo),但大多數(shù)系統(tǒng)要求大小是32*32

          display.update(rectangle=None)?->?None
          display.update(rectangle_list)?->?None
          #?更新屏幕內(nèi)容顯示,如果設(shè)置了pygame.OPENGL情況下調(diào)用,會(huì)觸發(fā)異常
          #?參數(shù):
          #???rectangle?一個(gè)矩形區(qū)域
          #???rectangle_list?多個(gè)矩形區(qū)域
          #?如果傳入None或者空列表,就會(huì)更新整個(gè)窗口
          • pygame.image pygame用于傳輸圖像模塊

            https://www.pygame.org/docs/ref/image.html

          image.load(filename)?->?Surface
          #?加載圖像,返回一個(gè)Surface對(duì)象,pygame支持常見PNG、JPG、GIF等格式圖片
          #參數(shù):
          #???filename?圖片路徑,兼容運(yùn)行環(huán)境,路徑建議通過(guò)os.path.join()獲取
          • pygame.Surface pygame用于表示圖片的模塊

            https://www.pygame.org/docs/ref/surface.html

          Surface.blit(source,?dest,?area=None,?special_flags=0)?->?Rect
          #?將圖像繪制到另外一個(gè)圖像上,返回值是一個(gè)Rect對(duì)象,表示在screen上繪制的矩形區(qū)域
          #?參數(shù):
          #???source?矩形圖像的Surface實(shí)例對(duì)象
          #???dest?是坐標(biāo)對(duì)象,繪制在屏幕的坐標(biāo)
          #???area?表示從scorce的area區(qū)域取出繪制的到Surface對(duì)象上
          #?結(jié)合上面例子
          #?background?=?pygame.image.load(os.path.join(IMG_PATH,?"test_bj.png"))
          #?screen.blit(background,?(0,?0))
          #?就是將background圖片繪制到screen屏幕的0,?0坐標(biāo)處

          Surface.get_rect(**kwargs)?->?Rect
          #?獲取Surface的矩形區(qū)域,該矩形區(qū)域始終從坐標(biāo)0,?0開始,寬度和高度與圖片大小相同
          #?返回一個(gè)rect對(duì)象,rect對(duì)象記錄著Surface的屬性信息,如:
          #???rect.x?Surface對(duì)象x軸坐標(biāo)
          #???rect.y?Surface對(duì)象y軸坐標(biāo)
          #???rect.width?Surface對(duì)象的寬度
          #???rect.height?Surface對(duì)象的高度



          圖片移動(dòng)、通過(guò)用戶事件移動(dòng)圖片
          上面代碼已經(jīng)能夠建立游戲窗口和加載背景圖,現(xiàn)在創(chuàng)建英雄,通過(guò)改變坐標(biāo)實(shí)現(xiàn)移動(dòng)

          import?os
          import?time
          import?pygame

          #?屏幕寬度
          SCREEN_WIDTH?=?500
          #?屏幕高度
          SCREEN_HEIGHT?=?250
          #?圖片絕對(duì)路徑
          IMG_PATH?=?os.path.join(os.getcwd(),?"img")


          class?HeroPlane(object):
          ???def?__init__(self):
          ???????super(HeroPlane,?self).__init__()
          ???????self.image?=?pygame.image.load(os.path.join(IMG_PATH,?"hero_show_1.png"))
          ???????self.rect?=?self.image.get_rect()
          ???????self.rect.x?=?0??#?飛機(jī)x軸位置
          ???????self.rect.y?=?int(SCREEN_HEIGHT?-?self.rect.height)?/?2??#?飛機(jī)y軸位置
          ???????self.is_running?=?True

          ???????self.bullet_list?=?pygame.sprite.Group()
          ???????self.last_time?=?time.time()

          ???def?move_level(self,?level):
          ???????#?防止飛機(jī)移出屏幕外,?增加判斷
          ???????add_level?=?self.rect.x?+?level
          ???????if?0?<=?add_level?<=?SCREEN_WIDTH?-?self.rect.width:
          ???????????self.rect.x?=?add_level
          ???????elif?add_level?0:
          ???????????self.rect.x?=?0
          ???????elif?add_level?>?SCREEN_WIDTH?-?self.rect.width:
          ???????????self.rect.x?=?SCREEN_WIDTH?-?self.rect.width

          ???def?move_vertical(self,?vertical):
          ???????add_vertical?=?self.rect.y?+?vertical
          ???????if?0?<=?add_vertical?<=?SCREEN_HEIGHT?-?self.rect.height:
          ???????????self.rect.y?=?add_vertical
          ???????elif?add_vertical?0:
          ???????????self.rect.y?=?0
          ???????elif?add_vertical?>?SCREEN_HEIGHT?-?self.rect.height:
          ???????????self.rect.y?=?SCREEN_HEIGHT?-?self.rect.height


          def?main():
          ???pygame.display.init()
          ???#?初始化顯示模塊
          ???#?pygame.display.init()
          ???#?創(chuàng)建窗口
          ???screen?=?pygame.display.set_mode((SCREEN_WIDTH,?SCREEN_HEIGHT))
          ???#?設(shè)置窗口標(biāo)題
          ???pygame.display.set_caption("python小demo?飛機(jī)大戰(zhàn)")
          ???#?設(shè)置窗口icon
          ???pygame.display.set_icon(pygame.image.load(os.path.join(IMG_PATH,?"icon.jpg")))
          ???#?加載背景圖片
          ???background?=?pygame.image.load(os.path.join(IMG_PATH,?"test_bj.png"))
          ???#?初始化英雄類
          ???hero?=?HeroPlane()

          ???def?update_hero():
          ???????hero.move_level(2)
          ???????screen.blit(hero.image,?(hero.rect.x,?hero.rect.y))

          ???while?True:

          ???????#?將背景圖片繪制到窗口上
          ???????screen.blit(background,?(0,?0))

          ???????#?更新英雄在屏幕上的位置
          ???????update_hero()

          ???????#?更新屏幕上內(nèi)容
          ???????pygame.display.update()
          ???????time.sleep(0.02)


          if?__name__?==?"__main__":
          ???main()

          執(zhí)行效果如下:

          飛機(jī)移動(dòng)

          上面加載英雄并且實(shí)現(xiàn)英雄移動(dòng),其實(shí)就是不斷改變圖片在屏幕中的繪制位置。主函數(shù)的time.sleep也可以替換成pygame.time.Clock.tick方法,但本例子中,效果偏差不遠(yuǎn),就沒有使用pygame.time(https://www.pygame.org/docs/ref/time.html)提供的時(shí)間模塊

          上面代碼雖然能夠?qū)崿F(xiàn)英雄的移動(dòng),但是無(wú)法根據(jù)玩家操作控制英雄的移動(dòng),這時(shí)候我們就需要提供特定的鍵盤或者鼠標(biāo)事件控制英雄移動(dòng),下面示例按住鼠標(biāo)實(shí)現(xiàn)飛機(jī)移動(dòng)

          import?os
          import?sys
          import?time
          import?pygame

          #?屏幕寬度
          SCREEN_WIDTH?=?500
          #?屏幕高度
          SCREEN_HEIGHT?=?250
          #?圖片絕對(duì)路徑
          IMG_PATH?=?os.path.join(os.getcwd(),?"img")
          #?鼠標(biāo)按鍵標(biāo)識(shí)
          MOUSE_MOVE?=?False


          class?HeroPlane(object):
          ???def?__init__(self):
          ???????super(HeroPlane,?self).__init__()
          ???????self.image?=?pygame.image.load(os.path.join(IMG_PATH,?"hero_show_1.png"))
          ???????self.rect?=?self.image.get_rect()
          ???????self.rect.x?=?0??#?飛機(jī)x軸位置
          ???????self.rect.y?=?int(SCREEN_HEIGHT?-?self.rect.height)?/?2??#?飛機(jī)y軸位置
          ???????self.is_running?=?True

          ???????self.bullet_list?=?pygame.sprite.Group()
          ???????self.last_time?=?time.time()

          ???def?move_level(self,?level):
          ???????#?防止飛機(jī)移出屏幕外,?增加判斷
          ???????if?0?<=?level?<=?SCREEN_WIDTH?-?self.rect.width:
          ???????????self.rect.x?=?level
          ???????elif?level?0:
          ???????????self.rect.x?=?0
          ???????elif?level?>?SCREEN_WIDTH?-?self.rect.width:
          ???????????self.rect.x?=?SCREEN_WIDTH?-?self.rect.width

          ???def?move_vertical(self,?vertical):
          ???????if?0?<=?vertical?<=?SCREEN_HEIGHT?-?self.rect.height:
          ???????????self.rect.y?=?vertical
          ???????elif?vertical?0:
          ???????????self.rect.y?=?0
          ???????elif?vertical?>?SCREEN_HEIGHT?-?self.rect.height:
          ???????????self.rect.y?=?SCREEN_HEIGHT?-?self.rect.height


          def?main():
          ???pygame.init()
          ???#?初始化顯示模塊
          ???pygame.display.init()
          ???#?創(chuàng)建窗口
          ???screen?=?pygame.display.set_mode((SCREEN_WIDTH,?SCREEN_HEIGHT))
          ???#?設(shè)置窗口標(biāo)題
          ???pygame.display.set_caption("python小demo?飛機(jī)大戰(zhàn)")
          ???#?設(shè)置窗口icon
          ???pygame.display.set_icon(pygame.image.load(os.path.join(IMG_PATH,?"icon.jpg")))
          ???#?加載背景圖片
          ???background?=?pygame.image.load(os.path.join(IMG_PATH,?"test_bj.png"))
          ???#?初始化英雄類
          ???hero?=?HeroPlane()

          ???def?event_check():
          ???????"""
          ???????事件檢測(cè),這邊做了一個(gè)簡(jiǎn)單的示例
          ???????return:
          ???????"
          ""
          ???????global?MOUSE_MOVE
          ???????for?event?in?pygame.event.get():
          ???????????if?event.type?==?pygame.QUIT:
          ???????????????#?接收到退出事件后退出程序
          ???????????????pygame.quit()
          ???????????????sys.exit()
          ???????????elif?event.type?==?pygame.MOUSEBUTTONDOWN:
          ???????????????MOUSE_MOVE?=?True
          ???????????elif?event.type?==?pygame.MOUSEBUTTONUP:
          ???????????????MOUSE_MOVE?=?False

          ???????if?MOUSE_MOVE:
          ???????????x,?y?=?pygame.mouse.get_pos()
          ???????????hero.move_level(x)
          ???????????hero.move_vertical(y)

          ???def?update_hero():
          ???????screen.blit(hero.image,?(hero.rect.x,?hero.rect.y))

          ???while?True:
          ???????#?事件檢測(cè)
          ???????event_check()

          ???????#?將背景圖片繪制到窗口上
          ???????screen.blit(background,?(0,?0))

          ???????#?更新英雄在屏幕上的位置
          ???????update_hero()

          ???????#?更新屏幕上內(nèi)容
          ???????pygame.display.update()
          ???????time.sleep(0.02)


          if?__name__?==?"__main__":
          ???main()

          執(zhí)行效果如下:

          所需函數(shù)簡(jiǎn)要說(shuō)明

          • pygame.event用于監(jiān)聽玩家事件,如按下鍵盤、點(diǎn)擊鼠標(biāo)等

            https://www.pygame.org/docs/ref/event.html

          event.get(eventtype=None)?->?Eventlist
          event.get(eventtype=None,?pump=True)?->?Eventlist
          #?獲取事件隊(duì)列
          #?參數(shù):
          #???eventtype?可以傳入你想要監(jiān)聽到的事件列表,如果不傳,會(huì)把所有用戶觸發(fā)的事件返回
          #???如上面示例中只監(jiān)聽了三個(gè)事件,也可以:
          #???????pygame.event.get([pygame.QUIT,?pygame.MOUSEBUTTONDOWN,?pygame.MOUSEBUTTONUP])
          #???但如果設(shè)置了指定類型事件,其他事件將不會(huì)被獲取,存在了事件隊(duì)列中中,有可能導(dǎo)致事件隊(duì)列被堆滿
          #???pump?默認(rèn)為False,如果設(shè)置為True,event.pump()將會(huì)被調(diào)用
          #?返回事件列表
          #?常見事件類型:
          #???事件??????????????????產(chǎn)生途徑????????????參數(shù)
          #???QUIT?????????????????用戶按下關(guān)閉按鈕???????none
          #???KEYDOWN??????????????鍵盤被按下????????????unicode,?key,?mod
          #???KEYUP????????????????鍵盤被放開????????????key,?mod
          #???MOUSEMOTION??????????鼠標(biāo)移動(dòng)?????????????pos,?rel,?buttons
          #???MOUSEBUTTONDOWN??????鼠標(biāo)按下?????????????pos,?button
          #???MOUSEBUTTONUP????????鼠標(biāo)放開?????????????pos,?button
          #???USEREVENT????????????用戶自定義事件????????code
          #?上面列舉了常見的事件,更多事件和方法可以點(diǎn)擊上面文檔鏈接查閱文檔
          • pygame.key用于處理鍵盤的模塊,當(dāng)鍵盤按下或者釋放時(shí),pygame.event.get()就能獲取pygame.KEYDOWN或pygame.KEYUP事件,這兩個(gè)事件都有key和mod屬性:key代表鍵盤上每個(gè)整數(shù)ID;mod代表事件發(fā)生時(shí)修飾建位掩碼。

            https://www.pygame.org/docs/ref/key.html
            上述例子中,如果想通過(guò)長(zhǎng)按鍵盤?、?、?、?控制英雄,可將事件處理函數(shù)修改為:

          def?event_check():
          ???"""
          ???事件檢測(cè),這邊做了一個(gè)簡(jiǎn)單的示例
          ???return:
          ???"""

          ???#?設(shè)置KEYDOWN標(biāo)志位,0代表鍵盤已釋放,1、2、3、4分別代表?、?、?、?
          ???global?KEYDOWN

          ???for?event?in?pygame.event.get():
          ???????if?event.type?==?pygame.QUIT:
          ???????????#?接收到退出事件后退出程序
          ???????????pygame.quit()
          ???????????sys.exit()
          ???????elif?event.type?==?pygame.KEYDOWN:
          ???????????if?event.key?==?pygame.K_LEFT:
          ???????????????KEYDOWN?=?1
          ???????????elif?event.key?==?pygame.K_UP:
          ???????????????KEYDOWN?=?2
          ???????????elif?event.key?==?pygame.K_DOWN:
          ???????????????KEYDOWN?=?3
          ???????????elif?event.key?==?pygame.K_RIGHT:
          ???????????????KEYDOWN?=?4
          ???????elif?event.type?==?pygame.KEYUP:
          ???????????KEYDOWN?=?0

          ???if?KEYDOWN:
          ???????if?KEYDOWN?==?1:
          ???????????hero.move_level(hero.rect.x?-?5)
          ???????elif?KEYDOWN?==?2:
          ???????????hero.move_vertical(hero.rect.y?-?5)
          ???????elif?KEYDOWN?==?3:
          ???????????hero.move_vertical(hero.rect.y?+?5)
          ???????else:
          ???????????hero.move_level(hero.rect.x?+?5)

          下面列舉常見的鍵盤常量(更多鍵盤常量可點(diǎn)擊上方連接查閱文檔):

          KeyASCII描述
          K_BACKSPACE退格鍵(Backspace)
          K_TAB制表鍵(Tab)
          K_CLEAR清除鍵(Clear)
          K_RETURN回車鍵(Enter)
          K_ESCAPE退出鍵(Escape)
          K_DELETE刪除鍵(delete)
          K_0 - K_90 - 9
          K_a - K_za - z
          K_KP0 - K_KP90 - 9(小鍵盤)
          K_UP向上箭頭(up arrow)
          K_DOWN向下箭頭(down arrow)
          K_RIGHT向右箭頭(right arrow)
          K_LEFT向左箭頭(left arrow)


          碰撞檢測(cè)及所需函數(shù)簡(jiǎn)要說(shuō)明
          上面代碼中,已經(jīng)實(shí)現(xiàn)創(chuàng)建英雄,并且能通過(guò)事件去控制英雄的移動(dòng),下面我們可以按照創(chuàng)建英雄的方法,創(chuàng)建一個(gè)敵機(jī),并通過(guò)讓英雄與敵機(jī)碰撞發(fā)生爆炸

          import?os
          import?sys
          import?time
          import?pygame

          #?屏幕寬度
          SCREEN_WIDTH?=?500
          #?屏幕高度
          SCREEN_HEIGHT?=?250
          #?圖片絕對(duì)路徑
          IMG_PATH?=?os.path.join(os.getcwd(),?"img")
          #?鼠標(biāo)按鍵標(biāo)識(shí)
          MOUSE_MOVE?=?False
          #?鍵盤長(zhǎng)按標(biāo)識(shí)位
          KEYDOWN?=?0


          class?HeroPlane(object):
          ????def?__init__(self):
          ????????super(HeroPlane,?self).__init__()
          ????????self.image?=?pygame.image.load(os.path.join(IMG_PATH,?"hero_show_1.png"))
          ????????self.rect?=?self.image.get_rect()
          ????????self.rect.x?=?0??#?飛機(jī)x軸位置
          ????????self.rect.y?=?int(SCREEN_HEIGHT?-?self.rect.height)?/?2??#?飛機(jī)y軸位置
          ????????self.is_running?=?True


          ????def?move_level(self,?level):
          ????????#?防止飛機(jī)移出屏幕外,?增加判斷
          ????????if?0?<=?level?<=?SCREEN_WIDTH?-?self.rect.width:
          ????????????self.rect.x?=?level
          ????????elif?level?0:
          ????????????self.rect.x?=?0
          ????????elif?level?>?SCREEN_WIDTH?-?self.rect.width:
          ????????????self.rect.x?=?SCREEN_WIDTH?-?self.rect.width

          ????def?move_vertical(self,?vertical):
          ????????if?0?<=?vertical?<=?SCREEN_HEIGHT?-?self.rect.height:
          ????????????self.rect.y?=?vertical
          ????????elif?vertical?0:
          ????????????self.rect.y?=?0
          ????????elif?vertical?>?SCREEN_HEIGHT?-?self.rect.height:
          ????????????self.rect.y?=?SCREEN_HEIGHT?-?self.rect.height


          class?EnemyPlane(pygame.sprite.Sprite):
          ????def?__init__(self):
          ????????super(EnemyPlane,?self).__init__()
          ????????self.image?=?pygame.image.load(os.path.join(IMG_PATH,?"mp_show_3.png"))
          ????????self.rect?=?self.image.get_rect()
          ????????self.rect?=?self.image.get_rect()
          ????????self.rect.x?=?int(SCREEN_WIDTH?-?self.rect.width)??#?飛機(jī)x軸位置
          ????????self.rect.y?=?int(SCREEN_HEIGHT?-?self.rect.height)?/?2??#?飛機(jī)y軸位置
          ????????self.is_running?=?True


          def?main():
          ????pygame.init()
          ????#?初始化顯示模塊
          ????pygame.display.init()
          ????#?創(chuàng)建窗口
          ????screen?=?pygame.display.set_mode((SCREEN_WIDTH,?SCREEN_HEIGHT))
          ????#?設(shè)置窗口標(biāo)題
          ????pygame.display.set_caption("python小demo?飛機(jī)大戰(zhàn)")
          ????#?設(shè)置窗口icon
          ????pygame.display.set_icon(pygame.image.load(os.path.join(IMG_PATH,?"icon.jpg")))
          ????#?加載背景圖片
          ????background?=?pygame.image.load(os.path.join(IMG_PATH,?"test_bj.png"))
          ????#?初始化英雄
          ????hero?=?HeroPlane()
          ????#?初始化敵機(jī)
          ????enemy?=?EnemyPlane()

          ????def?event_check():
          ????????"""
          ????????事件檢測(cè),這邊做了一個(gè)簡(jiǎn)單的示例
          ????????return:
          ????????"
          ""
          ????????global?MOUSE_MOVE

          ????????for?event?in?pygame.event.get():
          ????????????if?event.type?==?pygame.QUIT:
          ????????????????#?接收到退出事件后退出程序
          ????????????????pygame.quit()
          ????????????????sys.exit()
          ????????????elif?event.type?==?pygame.MOUSEBUTTONDOWN:
          ????????????????MOUSE_MOVE?=?True
          ????????????elif?event.type?==?pygame.MOUSEBUTTONUP:
          ????????????????MOUSE_MOVE?=?False

          ????????if?MOUSE_MOVE:
          ????????????x,?y?=?pygame.mouse.get_pos()
          ????????????hero.move_level(x)
          ????????????hero.move_vertical(y)

          ????#?def?event_check():
          ????#?????"""
          ????#?????事件檢測(cè),這邊做了一個(gè)簡(jiǎn)單的示例
          ????#?????return:
          ????#?????"""
          ????#?????#?設(shè)置KEYDOWN標(biāo)志位,0代表鍵盤已釋放,1、2、3、4分別代表?、?、?、?
          ????#?????global?KEYDOWN
          ????#
          ????#?????for?event?in?pygame.event.get():
          ????#?????????if?event.type?==?pygame.QUIT:
          ????#?????????????#?接收到退出事件后退出程序
          ????#?????????????pygame.quit()
          ????#?????????????sys.exit()
          ????#?????????elif?event.type?==?pygame.KEYDOWN:
          ????#?????????????if?event.key?==?pygame.K_LEFT:
          ????#?????????????????KEYDOWN?=?1
          ????#?????????????elif?event.key?==?pygame.K_UP:
          ????#?????????????????KEYDOWN?=?2
          ????#?????????????elif?event.key?==?pygame.K_DOWN:
          ????#?????????????????KEYDOWN?=?3
          ????#?????????????elif?event.key?==?pygame.K_RIGHT:
          ????#?????????????????KEYDOWN?=?4
          ????#?????????elif?event.type?==?pygame.KEYUP:
          ????#?????????????KEYDOWN?=?0
          ????#
          ????#?????if?KEYDOWN:
          ????#?????????if?KEYDOWN?==?1:
          ????#?????????????hero.move_level(hero.rect.x?-?5)
          ????#?????????elif?KEYDOWN?==?2:
          ????#?????????????hero.move_vertical(hero.rect.y?-?5)
          ????#?????????elif?KEYDOWN?==?3:
          ????#?????????????hero.move_vertical(hero.rect.y?+?5)
          ????#?????????else:
          ????#?????????????hero.move_level(hero.rect.x?+?5)

          ????def?update_hero():
          ????????screen.blit(hero.image,?(hero.rect.x,?hero.rect.y))

          ????def?update_enemy():
          ????????screen.blit(enemy.image,?(enemy.rect.x,?enemy.rect.y))

          ????def?check_crash():
          ????????is_crash?=?pygame.sprite.collide_rect(hero,?enemy)
          ????????if?is_crash:
          ????????????#?先展示飛機(jī)爆炸,然后在屏幕中間寫下game?over提示
          ????????????screen.blit(pygame.image.load(os.path.join(IMG_PATH,?"ex_2.png")),?(hero.rect.x,?hero.rect.y))
          ????????????screen.blit(pygame.image.load(os.path.join(IMG_PATH,?"ex_2.png")),?(enemy.rect.x,?enemy.rect.y))

          ????????????game_over?=?pygame.font.Font(None,?100)
          ????????????game_over?=?game_over.render("game?over",?True,?(220,?20,?60))
          ????????????screen.blit(game_over,?[int(SCREEN_WIDTH?/?2?-?game_over.get_width()?/?2),?int(SCREEN_HEIGHT?/?2)])

          ????while?True:
          ????????#?事件檢測(cè)
          ????????event_check()
          ????????#?將背景圖片繪制到窗口上
          ????????screen.blit(background,?(0,?0))
          ????????#?更新英雄在屏幕上的位置
          ????????update_hero()
          ????????#?更新敵機(jī)在屏幕上位置
          ????????update_enemy()
          ????????#?碰撞檢測(cè)
          ????????check_crash()
          ????????#?更新屏幕上內(nèi)容
          ????????pygame.display.update()
          ????????time.sleep(0.02)


          if?__name__?==?"__main__":
          ????main()

          執(zhí)行效果如下:

          所需函數(shù)簡(jiǎn)要說(shuō)明

          • pygame.sprite 基本游戲?qū)ο箢悾厦胬又校覀冇⑿鄹鷶硻C(jī)都繼承了pygame.sprite.Sprite,這是方便我們省略了造輪子的步驟,比如碰撞檢測(cè)。

            https://www.pygame.org/docs/ref/sprite.html

          sprite.collide_rect(left,?right)?->?bool
          #?檢測(cè)兩個(gè)繼承了pygame.sprite.Sprite且具有矩形區(qū)域?qū)傩缘膶?duì)象是否發(fā)生了碰撞
          #?該方法會(huì)根據(jù)對(duì)象的rect屬性判斷是否發(fā)生了碰撞
          #?參數(shù):
          #???left?第一個(gè)對(duì)象,如hero
          #???right?第二個(gè)對(duì)象,如hero
          #?返回bool值,?真為發(fā)生碰撞,假為沒有碰撞

          #?該示例中,只有一架敵機(jī)和一架英雄,但如果需要英雄與多架敵機(jī)發(fā)生碰撞
          #?或者英雄發(fā)出的子彈是否擊中了敵機(jī),這就產(chǎn)生了一對(duì)多、多對(duì)多的檢測(cè)
          #?這種情況可以使用sprite.Group來(lái)完成該方法

          sprite.Group()?->?Group
          #?用于保存和管理多個(gè)?Sprite?對(duì)象的容器類
          #?返回一個(gè)組對(duì)象
          sprite.Group.add(*sprites)?->?None
          #?增加一個(gè)sprites到該組中

          sprite.spritecollide(sprite,?group,?dokill,?collided?=?None)?->?Sprite_list
          #?查找一個(gè)sprite是否與sprite.Group()中的sprite發(fā)生碰撞
          #?用于一對(duì)多的碰撞檢測(cè)
          #?參數(shù):
          #???sprite?單個(gè)sprite對(duì)象
          #???group?一個(gè)包含多個(gè)sprite對(duì)象的組對(duì)象
          #???dokill?bool值,如果為真,發(fā)生碰撞時(shí),將碰撞的sprite對(duì)象從組中移除
          #???collided?是一個(gè)判斷碰撞的函數(shù),參數(shù)為兩個(gè)sprite對(duì)象,并且需要返回bool值,如果你的
          #???sprite對(duì)象也有像例子中設(shè)置了rect屬性,可以不傳
          #?返回所有和sprite發(fā)生碰撞的對(duì)象,如果沒有,返回空Sprite_list

          sprite.groupcollide(group1,?group2,?dokill1,?dokill2,?collided?=?None)?->?Sprite_dict
          #?查找兩組中所有碰撞的Sprite對(duì)象
          #?用于實(shí)現(xiàn)多對(duì)多碰撞檢測(cè)
          #?參數(shù):
          #???group1?第一個(gè)sprite對(duì)象的組對(duì)象
          #???group2?第二個(gè)sprite對(duì)象的組對(duì)象
          #???dokill1?bool值,如果為真,發(fā)生碰撞時(shí),將碰撞的sprite對(duì)象從第一個(gè)組中移除
          #???dokill2?bool值,如果為真,發(fā)生碰撞時(shí),將碰撞的sprite對(duì)象從第二個(gè)組中移除
          #???collided?是一個(gè)判斷碰撞的函數(shù),參數(shù)為兩個(gè)sprite對(duì)象,并且需要返回bool值,如果你的
          #???sprite對(duì)象也有像例子中設(shè)置了rect屬性,可以不傳
          #?返回一個(gè)Sprite_dict對(duì)象,類似于:
          #???{:?[]}
          #???key?是group1?碰撞列表,?value是group2碰撞列表

          #?上面列舉了本例需要的函數(shù),更多使用方法可以點(diǎn)擊上面文檔鏈接查閱文檔
          • pygame.font 用于加載和渲染字體

            https://www.pygame.org/docs/ref/font.html

          font.Font(filename,?size)?->?Font
          font.Font(object,?size)?->?Font
          #?從給定的文件名或者python的文件對(duì)象加載新字體
          #?參數(shù):
          #???filename?文件路徑字符串,如os.path.join('fonts',?'ziti.ttf')
          #???object?python文件對(duì)象
          #???如果第一個(gè)參數(shù)傳None,會(huì)使用默認(rèn)字體
          #???size?整數(shù)類型,字體大小
          #?返回一個(gè)Font對(duì)象

          font.Font.render(text,?antialias,?color,?background=None)?->?Surface
          #?創(chuàng)建一個(gè)新的?Surface,其上呈現(xiàn)了指定的文本,該方法只能寫一行文字,不呈現(xiàn)換行,空字符串會(huì)引發(fā)異常
          #?參數(shù):
          #???text?要展示的文本
          #???antialias?bool值,如果為真,字符將有平滑的邊緣
          #???color?字體顏色?RGB值
          #???background?用于文本背景顏色,如果沒有傳遞,背景色是透明色

          #?上面列舉了本例需要的函數(shù),更多使用方法可以點(diǎn)擊上面文檔鏈接查閱文檔


          音頻加載及所需函數(shù)簡(jiǎn)要說(shuō)明

          import?os
          import?sys
          import?time
          import?pygame

          #?屏幕寬度
          SCREEN_WIDTH?=?500
          #?屏幕高度
          SCREEN_HEIGHT?=?250
          #?圖片絕對(duì)路徑
          IMG_PATH?=?os.path.join(os.getcwd(),?"img")
          #?鼠標(biāo)按鍵標(biāo)識(shí)
          MOUSE_MOVE?=?False
          #?鍵盤長(zhǎng)按標(biāo)識(shí)位
          KEYDOWN?=?0
          #?背景音樂(lè)路徑
          MUSIC_PATH?=?os.path.join(os.getcwd(),?"sound")


          class?HeroPlane(pygame.sprite.Sprite):
          ????def?__init__(self):
          ????????super(HeroPlane,?self).__init__()
          ????????self.image?=?pygame.image.load(os.path.join(IMG_PATH,?"hero_show_1.png"))
          ????????self.rect?=?self.image.get_rect()
          ????????self.rect.x?=?0??#?飛機(jī)x軸位置
          ????????self.rect.y?=?int(SCREEN_HEIGHT?-?self.rect.height)?/?2??#?飛機(jī)y軸位置
          ????????self.is_running?=?True


          ????def?move_level(self,?level):
          ????????#?防止飛機(jī)移出屏幕外,?增加判斷
          ????????if?0?<=?level?<=?SCREEN_WIDTH?-?self.rect.width:
          ????????????self.rect.x?=?level
          ????????elif?level?0:
          ????????????self.rect.x?=?0
          ????????elif?level?>?SCREEN_WIDTH?-?self.rect.width:
          ????????????self.rect.x?=?SCREEN_WIDTH?-?self.rect.width

          ????def?move_vertical(self,?vertical):
          ????????if?0?<=?vertical?<=?SCREEN_HEIGHT?-?self.rect.height:
          ????????????self.rect.y?=?vertical
          ????????elif?vertical?0:
          ????????????self.rect.y?=?0
          ????????elif?vertical?>?SCREEN_HEIGHT?-?self.rect.height:
          ????????????self.rect.y?=?SCREEN_HEIGHT?-?self.rect.height


          class?EnemyPlane(pygame.sprite.Sprite):
          ????def?__init__(self):
          ????????super(EnemyPlane,?self).__init__()
          ????????self.image?=?pygame.image.load(os.path.join(IMG_PATH,?"mp_show_3.png"))
          ????????self.rect?=?self.image.get_rect()
          ????????self.rect?=?self.image.get_rect()
          ????????self.rect.x?=?int(SCREEN_WIDTH?-?self.rect.width)??#?飛機(jī)x軸位置
          ????????self.rect.y?=?int(SCREEN_HEIGHT?-?self.rect.height)?/?2??#?飛機(jī)y軸位置
          ????????self.is_running?=?True


          def?main():
          ????pygame.init()
          ????#?初始化顯示模塊
          ????pygame.display.init()
          ????#?創(chuàng)建窗口
          ????screen?=?pygame.display.set_mode((SCREEN_WIDTH,?SCREEN_HEIGHT))
          ????#?設(shè)置窗口標(biāo)題
          ????pygame.display.set_caption("python小demo?飛機(jī)大戰(zhàn)")
          ????#?設(shè)置窗口icon
          ????pygame.display.set_icon(pygame.image.load(os.path.join(IMG_PATH,?"icon.jpg")))
          ????#?加載背景圖片
          ????background?=?pygame.image.load(os.path.join(IMG_PATH,?"test_bj.png"))
          ????#?初始化英雄
          ????hero?=?HeroPlane()
          ????#?初始化敵機(jī)
          ????enemy?=?EnemyPlane()
          ????#?加載背景音樂(lè)并播放
          ????pygame.mixer.init()
          ????pygame.mixer.music.load(os.path.join(MUSIC_PATH,?"game_music.ogg"))
          ????pygame.mixer.music.play(loops=-1)


          ????def?event_check():
          ????????"""
          ????????事件檢測(cè),這邊做了一個(gè)簡(jiǎn)單的示例
          ????????return:
          ????????"
          ""
          ????????global?MOUSE_MOVE

          ????????for?event?in?pygame.event.get():
          ????????????if?event.type?==?pygame.QUIT:
          ????????????????#?接收到退出事件后退出程序
          ????????????????pygame.quit()
          ????????????????sys.exit()
          ????????????elif?event.type?==?pygame.MOUSEBUTTONDOWN:
          ????????????????MOUSE_MOVE?=?True
          ????????????elif?event.type?==?pygame.MOUSEBUTTONUP:
          ????????????????MOUSE_MOVE?=?False

          ????????if?MOUSE_MOVE:
          ????????????x,?y?=?pygame.mouse.get_pos()
          ????????????hero.move_level(x)
          ????????????hero.move_vertical(y)

          ????#?def?event_check():
          ????#?????"""
          ????#?????事件檢測(cè),這邊做了一個(gè)簡(jiǎn)單的示例
          ????#?????return:
          ????#?????"""
          ????#?????#?設(shè)置KEYDOWN標(biāo)志位,0代表鍵盤已釋放,1、2、3、4分別代表?、?、?、?
          ????#?????global?KEYDOWN
          ????#
          ????#?????for?event?in?pygame.event.get():
          ????#?????????if?event.type?==?pygame.QUIT:
          ????#?????????????#?接收到退出事件后退出程序
          ????#?????????????pygame.quit()
          ????#?????????????sys.exit()
          ????#?????????elif?event.type?==?pygame.KEYDOWN:
          ????#?????????????if?event.key?==?pygame.K_LEFT:
          ????#?????????????????KEYDOWN?=?1
          ????#?????????????elif?event.key?==?pygame.K_UP:
          ????#?????????????????KEYDOWN?=?2
          ????#?????????????elif?event.key?==?pygame.K_DOWN:
          ????#?????????????????KEYDOWN?=?3
          ????#?????????????elif?event.key?==?pygame.K_RIGHT:
          ????#?????????????????KEYDOWN?=?4
          ????#?????????elif?event.type?==?pygame.KEYUP:
          ????#?????????????KEYDOWN?=?0
          ????#
          ????#?????if?KEYDOWN:
          ????#?????????if?KEYDOWN?==?1:
          ????#?????????????hero.move_level(hero.rect.x?-?5)
          ????#?????????elif?KEYDOWN?==?2:
          ????#?????????????hero.move_vertical(hero.rect.y?-?5)
          ????#?????????elif?KEYDOWN?==?3:
          ????#?????????????hero.move_vertical(hero.rect.y?+?5)
          ????#?????????else:
          ????#?????????????hero.move_level(hero.rect.x?+?5)

          ????def?update_hero():
          ????????screen.blit(hero.image,?(hero.rect.x,?hero.rect.y))

          ????def?update_enemy():
          ????????screen.blit(enemy.image,?(enemy.rect.x,?enemy.rect.y))

          ????def?check_crash():
          ????????is_crash?=?pygame.sprite.collide_rect(hero,?enemy)
          ????????if?is_crash:
          ????????????#?先展示飛機(jī)爆炸,然后在屏幕中間寫下game?over提示
          ????????????screen.blit(pygame.image.load(os.path.join(IMG_PATH,?"ex_2.png")),?(hero.rect.x,?hero.rect.y))
          ????????????screen.blit(pygame.image.load(os.path.join(IMG_PATH,?"ex_2.png")),?(enemy.rect.x,?enemy.rect.y))
          ????????????pygame.mixer.Sound(os.path.join(MUSIC_PATH,?"enemy1_down.wav")).play()

          ????????????game_over?=?pygame.font.Font(None,?100)
          ????????????game_over?=?game_over.render("game?over",?True,?(220,?20,?60))
          ????????????screen.blit(game_over,?[int(SCREEN_WIDTH?/?2?-?game_over.get_width()?/?2),?int(SCREEN_HEIGHT?/?2)])

          ????while?True:
          ????????#?事件檢測(cè)
          ????????event_check()
          ????????#?將背景圖片繪制到窗口上
          ????????screen.blit(background,?(0,?0))
          ????????#?更新英雄在屏幕上的位置
          ????????update_hero()
          ????????#?更新敵機(jī)在屏幕上位置
          ????????update_enemy()
          ????????#?碰撞檢測(cè)
          ????????check_crash()
          ????????#?更新屏幕上內(nèi)容
          ????????pygame.display.update()
          ????????time.sleep(0.02)


          if?__name__?==?"__main__":
          ????main()

          執(zhí)行效果:


          所需函數(shù)簡(jiǎn)要說(shuō)明

          • pygame.mixer 用于加載和播放音頻

            https://www.pygame.org/docs/ref/mixer.html

          mixer.init(
          ????frequency=44100,
          ????size=-16,
          ????channels=2,
          ????buffer=512,
          ????devicename=None,
          ????allowedchanges=AUDIO_ALLOW_FREQUENCY_CHANGE?|?AUDIO_ALLOW_CHANNELS_CHANGE
          )?->?None
          #?初始化mixer模塊以進(jìn)行聲音加載和播放。可以重寫默認(rèn)參數(shù)以提供特定的音頻混合
          #?參數(shù):
          #???frequency??pygame?2.0.0+時(shí),范圍44100-22050
          #?? size 表示每個(gè)音頻樣本使用了多少位。如果是負(fù)值,則使用帶符號(hào)的樣本值,無(wú)效值會(huì)觸發(fā)異常,2.0.0后可以是32
          #???channels?指定使用單聲道還是立體音,1為單聲道,2為立體音,?2.0.0后可以是4或者6
          #???buffer?控制聲音混合器mixer中使用的內(nèi)部樣本數(shù),默認(rèn)值應(yīng)適用于大多數(shù)情況
          #?? allowedchanges 當(dāng)allowedchanges=0,將在運(yùn)行時(shí)轉(zhuǎn)換示例以匹配硬件支持的內(nèi)容,allowedchanges也支持:
          #???????AUDIO_ALLOW_FREQUENCY_CHANGE
          #???????AUDIO_ALLOW_FORMAT_CHANGE
          #???????AUDIO_ALLOW_CHANNELS_CHANGE
          #???????AUDIO_ALLOW_ANY_CHANGE

          mixer.music.load(filename)?->?None
          mixer.music.load(object)?->?None
          #?將加載音樂(lè)文件/或者音樂(lè)文件對(duì)象并準(zhǔn)備播放,如果音樂(lè)已經(jīng)播放,調(diào)用則會(huì)停止

          mixer.music.play(loops=0,?start=0.0,?fade_ms?=?0)?->?None
          #?播放已經(jīng)加載的音樂(lè)流,如果已經(jīng)在播放時(shí)調(diào)用,則會(huì)重新播放
          #?參數(shù):
          #???loops?可選整數(shù)參數(shù),表示重復(fù)播放次數(shù),設(shè)置為-1表示無(wú)限重復(fù)
          #???start?可選浮點(diǎn)數(shù),表示開始播放音樂(lè)時(shí)間的位置,起始位置決定于音樂(lè)格式
          #???fade_ms?可選整數(shù)參數(shù),大于0時(shí),在給定的fade_ms內(nèi)逐漸加大音量

          pygame.mixer.Sound(filename)?->?Sound
          pygame.mixer.Sound(buffer)?->?Sound
          #?從文件或者緩沖區(qū)創(chuàng)建一個(gè)新的文件對(duì)象
          pygame.mixer.Sound.play(loops=0,?maxtime=0,?fade_ms=0)?->?Channel
          #?開始在可用的頻道上播放聲音,播放時(shí)可能在必要時(shí)切斷正在播放的聲音
          #?在本例中,調(diào)用該方法產(chǎn)生爆炸音效并不會(huì)影響背景音樂(lè)的播放
          #?參數(shù):
          #???loops?可選整數(shù)參數(shù),表示重復(fù)播放次數(shù),設(shè)置為-1表示無(wú)限重復(fù)
          #???maxtime?大于零時(shí),在給定的maxtime停止播放(毫秒)
          #???fade_ms?可選整數(shù)參數(shù),大于0時(shí),在給定的fade_ms內(nèi)逐漸加大音量
          #?返回所選的通道對(duì)象

          #?上面列舉了本例需要的函數(shù),更多使用方法可以點(diǎn)擊上面文檔鏈接查閱文檔


          python小demo 飛機(jī)大戰(zhàn)完整例子

          在上面,大致示范了使用pygame寫一個(gè)飛機(jī)大戰(zhàn)所需模塊及函數(shù),本人也寫了一個(gè)示例,包括本推文中所使用的代碼都提交至github,在本公眾號(hào)中回復(fù)“飛機(jī)大戰(zhàn)”即可獲取源碼地址,及圖片素材、音頻素材,下面看下我例子效果:


          ?小伙伴們,快快用實(shí)踐一下吧!如果在學(xué)習(xí)過(guò)程中,有遇到任何問(wèn)題,歡迎加我好友,我拉你進(jìn)Python學(xué)習(xí)交流群共同探討學(xué)習(xí)。

          -------------------?End?-------------------

          往期精彩文章推薦:

          歡迎大家點(diǎn)贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持

          想加入Python學(xué)習(xí)群請(qǐng)?jiān)诤笈_(tái)回復(fù)【入群

          萬(wàn)水千山總是情,點(diǎn)個(gè)【在看】行不行

          /今日留言主題/

          隨便說(shuō)一兩句吧~~

          瀏覽 38
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  99精品视频在线播放免费 | 亚洲天堂久久 | 欧美日韩高 | 久久亚洲综合色 | 国产一级a一级a看免费视频 |