Python Pygame實(shí)戰(zhàn)之飛機(jī)大戰(zhàn)的實(shí)現(xiàn)
導(dǎo)語(yǔ)
三月疫情原因,很多地方都封閉式管理了!
在回家無(wú)聊的打醬油,小編今天給大伙帶來(lái)了一波小游戲——全民左右飛機(jī)大戰(zhàn)!在這個(gè)快熬不下去的日子里,打打飛機(jī)消遣閑暇時(shí)間,也是蠻愜意的,這幾天小編必須全身心投入到飛機(jī)大戰(zhàn)中來(lái)!肝了幾天這款小游戲終于面市啦!
這次的游戲操作很簡(jiǎn)單,就是左右移動(dòng)飛機(jī),躲避敵人飛機(jī),打落敵機(jī)會(huì)隨機(jī)掉落金幣,我們
要打擊的敵人!每個(gè)玩家有五條命,被敵機(jī)撞到即掛掉一條命,所以要珍惜生命喲!這款是升
級(jí)版本的飛機(jī)大戰(zhàn)哦~還有更多不同的飛機(jī)類型等你來(lái)探索,看看你能闖過多少關(guān)吧!
小編才闖到第二個(gè)飛機(jī),相信你肯定會(huì)超過我滴!來(lái)試試呀~
一、環(huán)境安裝
1)各種素材(圖片、字體等)
2)運(yùn)行環(huán)境
小編使用的環(huán)境:Python3、Pycharm社區(qū)版、Pygame模塊部分自帶。
模塊安裝:pip install -i https://pypi.douban.com/simple/ pygame
二、代碼展示
1)文章思路
Plane 打飛機(jī)小游戲 ——
游戲說明: * 目前只做了一個(gè)關(guān)卡,有三種敵機(jī),自己飛機(jī)的子彈類型有四種 * 在游戲中空格鍵
是暫停,游戲結(jié)束后ESC鍵是重新開始 * 暫時(shí)沒有加入音效 * 游戲窗口尺寸為512*768
關(guān)卡內(nèi)元素介紹 ——
1. ENEMY_RED:紅色小敵機(jī),數(shù)量多,出現(xiàn)頻率高,擊落后有機(jī)率出現(xiàn)錢幣,可以加分。
2. ENEMY_BLUE:藍(lán)色中型敵機(jī),出現(xiàn)頻率低,需要多顆子彈擊落,擊落后有機(jī)率出現(xiàn)星星,可以加強(qiáng)火力 。
3. ENEMY_BOSS:綠色大型敵機(jī),出現(xiàn)頻率低,可以發(fā)射子彈,需要很多顆子彈擊落,擊落后得分較高 。
4. BULLET_BOSS: 綠色大型敵機(jī)發(fā)射的子彈
5. OWN: 自己的飛機(jī) 6. OWN_BULLET: 自己飛機(jī)發(fā)射的子彈
系統(tǒng)文件——
【start.py】:開始游戲的主文件 -
【level_01.py】:游戲第一關(guān) - 【sprites.py】:建立游戲精靈類文件
【initialize.py】:系統(tǒng)設(shè)置文件,包含各種游戲基本元素的設(shè)定值
- .\fonts\\...:游戲使用的字體
- .\images\\...:游戲使用的圖像文件
- .\screenshot\...:游戲畫面截屏 ## 游戲畫面
截屏 * 游戲載入圖片 ![游戲載入]
2)附代碼講解
配置的文件、窗口、圖片等設(shè)置。
import pygame SCREEN_RECT = pygame.Rect(0, 0, 512, 768) # 用一個(gè)常量來(lái)存儲(chǔ)屏幕的位置和大小,常量用全大寫表示 SCREEN_CENTER = [SCREEN_RECT.width/2, SCREEN_RECT.height/2] CREATE_ENEMY_EVENT = pygame.USEREVENT # 敵機(jī)事件定時(shí)器常量值 OWN_FIRE_EVENT = pygame.USEREVENT + 1 # 發(fā)射子彈定時(shí)器常量值 BONUS_ENEMY_EVENT = pygame.USEREVENT + 2 # 加分?jǐn)硻C(jī)的定時(shí)器常量值 STAR_ENEMY_EVENT = pygame.USEREVENT + 3 # 星星敵機(jī)的定時(shí)器常量值 BOSS_ENEMY_EVENT = pygame.USEREVENT + 4 # BOSS敵機(jī)的定時(shí)器常量值 BULLET_BOSS_EVENT = pygame.USEREVENT + 5 # BOSS敵機(jī)的子彈定時(shí)器常量值 ENEMY_TIMER = 600 # 敵機(jī)出現(xiàn)的時(shí)間頻率 BULLET_TIMER = 400 # 子彈出現(xiàn)的時(shí)間頻率 BONUS_TIMER = 5000 # 加分?jǐn)硻C(jī)出現(xiàn)的時(shí)間頻率 START_TIMER = 20000 # 星星敵機(jī)出現(xiàn)的時(shí)間頻率 BOSS_TIMER = 120000 # BOSS敵機(jī)出現(xiàn)的時(shí)間頻率 BULLET_BOSS_TIMER = 1500 # BOSS敵機(jī)子彈出現(xiàn)的時(shí)間頻率 LIFE_NUMS = 5 # 生命值 MOVE_SPEED = 5 # 已方飛機(jī)移動(dòng)速度 STAR_ENEMY_LIFE = 6 # 打掉星星敵機(jī)需要的子彈 BOSS_ENEMY_LIFE = 100 # 打掉BOSS敵機(jī)需要的子彈 BACKGROUND = r'.\images\background.png' GAME_OVER = r'.\images\gameover.png' OWN_IMAGE = r'.\images\own.png' OWN_DOWN_IMAGE = r'.\images\own_died.png' ENEMY_RED_IMAGE = r'.\images\enemy_red.png' ENEMY_BLUE_IMAGE = r'.\images\enemy_blue.png' ENEMY_DOWN_IMAGE = r'.\images\enemy_down.png' BULLET_IMAGE = r'.\images\bullet.png' BULLET_BOSS_IMAGE = r'.\images\bullet_boss.png' LIFE_IMAGE = r'.\images\life.png' GOLD_COIN_IMAGE = r'.\images\bonus.png' STAR_IMAGE = r'.\images\star.png' READY_IMAGE = r'.\images\ready.png' BOSS_IMAGE = r'.\images\boss.png' LOGO_IMAGE = r'.\images\logo.ico' SYS_FONT = r'.\fonts\BOLDER.ttf' GAME_NAME = '小飛機(jī)' FPS = 60 # 屏幕刷新頻率
3)主程序
import threading from sprites import * from initialize import * # noinspection PyPep8Naming # 主游戲類 class PlaneGame(object): def __init__(self): self.score = 0 self.bullet_grade = 1 # 初始的子彈等級(jí) self.boss_flag = 0 # 判斷BOSS是否出現(xiàn) self.ready_time = pygame.time.get_ticks() # 用來(lái)控制顯示ready畫面的時(shí)鐘 self.star_enemy_life = STAR_ENEMY_LIFE # 星星敵機(jī)需要幾顆子彈 self.boss_enemy_life = BOSS_ENEMY_LIFE # BOSS敵機(jī)需要幾顆子彈 self.bullet_type = {1: 'One', 2: 'Two', 3: 'Three', 4: 'Four'} self.screen = pygame.display.set_mode(SCREEN_RECT.size) logo = pygame.image.load(LOGO_IMAGE) # 設(shè)置游戲窗口圖標(biāo) pygame.display.set_icon(logo) pygame.display.set_caption(GAME_NAME) # 設(shè)置游戲窗口名稱 self.clock = pygame.time.Clock() # 創(chuàng)建游戲時(shí)鐘 self.__createSprite() # 調(diào)用私有方法, 創(chuàng)建精靈和組 pygame.time.set_timer(CREATE_ENEMY_EVENT, ENEMY_TIMER) # 設(shè)置定時(shí)器事件 pygame.time.set_timer(OWN_FIRE_EVENT, BULLET_TIMER) pygame.time.set_timer(BONUS_ENEMY_EVENT, BONUS_TIMER) pygame.time.set_timer(STAR_ENEMY_EVENT, START_TIMER) pygame.time.set_timer(BOSS_ENEMY_EVENT, BOSS_TIMER) pygame.time.set_timer(BULLET_BOSS_EVENT, BULLET_BOSS_TIMER) self.life_num = LIFE_NUMS def __createSprite(self): """ 私有方法,創(chuàng)建精靈和組 """ bg1 = BackGround(BACKGROUND) # 創(chuàng)建背景和組 bg2 = BackGround(BACKGROUND) bg2.rect.y = -bg2.rect.height # ??? self.back_group = pygame.sprite.Group(bg1, bg2) self.ready_go_group = pygame.sprite.Group() # 創(chuàng)建ready組 self.ready_go_group.add(ReadyGo()) self.enemy_red_group = pygame.sprite.Group() # 創(chuàng)建紅色敵機(jī)組 self.enemy_down_group = pygame.sprite.Group() # 創(chuàng)建被擊中敵機(jī)組 self.bonus_enemy_group = pygame.sprite.Group() # 創(chuàng)建加分?jǐn)硻C(jī)組 self.gold_coin_group = pygame.sprite.Group() # 創(chuàng)建金幣組 self.star_enemy_group = pygame.sprite.Group() # 創(chuàng)建星星敵機(jī)組 self.boss_enemy = EnemyBoss() # ??? self.boss_enemy_group = pygame.sprite.Group() # 創(chuàng)建BOSS敵機(jī)組 self.bullet_boss_group = pygame.sprite.Group() # 創(chuàng)建BOSS子彈組 self.star_coin_group = pygame.sprite.Group() # 創(chuàng)建星星組 self.own_died_group = pygame.sprite.Group() # 創(chuàng)建自己死亡飛機(jī)的組 self.__resetOwn() # 創(chuàng)建自己的飛機(jī)和組 def start(self): """ 游戲開始 """ while True: self.clock.tick(FPS) # 刷新幀率 self.__eventHandler() # 事件監(jiān)聽 self.__checkCollide() # 碰撞檢測(cè) self.__updateSprites() # 更新/繪制畫面 pygame.display.update() # 更新屏幕顯示 self.__gameOver() # 游戲結(jié)束 def __eventHandler(self): """ 事件監(jiān)聽(監(jiān)聽定時(shí)器常量) """ for event in pygame.event.get(): if event.type == pygame.QUIT: # 判斷是否退出游戲 PlaneGame.quit() elif event.type == CREATE_ENEMY_EVENT: # 當(dāng)事件值等于CREATE_ENEMY_EVENT時(shí),將敵機(jī)精靈添加到組 enemy = EnemyRed() self.enemy_red_group.add(enemy) elif event.type == BONUS_ENEMY_EVENT: # 當(dāng)事件值等于BONUS_ENEMY_EVENT時(shí),將加分?jǐn)硻C(jī)加入到組 bonus_enemy = EnemyRed() self.bonus_enemy_group.add(bonus_enemy) elif event.type == STAR_ENEMY_EVENT: # 當(dāng)事件值等于STAR_ENEMY_EVENT時(shí),將星星敵機(jī)加入到組 self.star_enemy_life = STAR_ENEMY_LIFE # 賦予新的星星敵機(jī)生命值 star_enemy = EnemyBlue() self.star_enemy_group.add(star_enemy) elif event.type == BOSS_ENEMY_EVENT: # 當(dāng)事件值等于BOSS_ENEMY_EVENT時(shí),將BOSS敵機(jī)加入到組 self.boss_enemy_life = BOSS_ENEMY_LIFE # 賦予新的BOSS敵機(jī)生命值 self.boss_enemy = EnemyBoss() # ???? self.boss_enemy_group.add(self.boss_enemy) self.boss_flag = 1 # 修改BOSS出現(xiàn)的flag elif event.type == OWN_FIRE_EVENT: # 當(dāng)事件值等于OWN_FIRE_EVENT時(shí),按子彈等級(jí)開火 for n in self.bullet_type: grade = 4 if self.bullet_grade > 4 else self.bullet_grade if grade == n: exec('self.own.fire{}()'.format(self.bullet_type[n])) if self.boss_flag == 1: # 如果BOSS出現(xiàn),則發(fā)射子彈 if event.type == BULLET_BOSS_EVENT: self.boss_enemy.fire() keys_pressed = pygame.key.get_pressed() # 使用鍵盤提供的方法獲取按鍵, 得到一個(gè)按鍵元組 if keys_pressed[pygame.K_RIGHT]: # 按右方向鍵時(shí)向右移動(dòng),水平速度為4 self.own.speed_y = 0 # 同時(shí)將垂直方向的速度變?yōu)? self.own.speed_x = MOVE_SPEED elif keys_pressed[pygame.K_LEFT]: # 按左方向鍵時(shí)向右移動(dòng),水平速度為4 self.own.speed_y = 0 self.own.speed_x = -MOVE_SPEED elif keys_pressed[pygame.K_UP]: # 按上方向鍵時(shí)向右移動(dòng),垂直速度為-4 self.own.speed_x = 0 # 同時(shí)將水平方向的速度變?yōu)? self.own.speed_y = -MOVE_SPEED elif keys_pressed[pygame.K_DOWN]: # 按下方向鍵時(shí)向右移動(dòng),垂直速度為4 self.own.speed_x = 0 self.own.speed_y = MOVE_SPEED elif keys_pressed[pygame.K_SPACE]: # 按空格鍵時(shí)暫停游戲 self.__gamePause(True) else: # 按其他鍵或不按時(shí)不移動(dòng) self.own.speed_x = 0 self.own.speed_y = 0 def __checkCollide(self): """ 碰撞檢測(cè) """ # 當(dāng)子彈和敵機(jī)碰撞,敵機(jī)爆炸,得分加1,groupcollide()是精靈基類中的方法,返回一個(gè)字典,子彈是鍵,敵機(jī)是值 killers = pygame.sprite.groupcollide(self.own.bullets, self.enemy_red_group, True, True) # 子彈摧毀敵機(jī) if len(killers) > 0: # 如果返回值長(zhǎng)度大于0時(shí),得分加1 self.score += 1 enemy_down = SpriteDown(ENEMY_DOWN_IMAGE, list(killers.keys())[0].rect, 0) # 取出碰撞字典中的鍵用來(lái)定位顯示爆炸 self.enemy_down_group.add(enemy_down) # 當(dāng)敵機(jī)和已機(jī)碰撞,飛機(jī)數(shù)量減1,1秒后重新顯示一架飛機(jī) died_1 = pygame.sprite.groupcollide(self.enemy_red_group, self.own_group, True, True) # 敵機(jī)撞毀自己飛機(jī) died_2 = pygame.sprite.groupcollide(self.bonus_enemy_group, self.own_group, True, True) # 加分?jǐn)硻C(jī)撞毀自己飛機(jī) died_3 = pygame.sprite.groupcollide(self.star_enemy_group, self.own_group, True, True) # 星星敵機(jī)撞毀自己飛機(jī) died_4 = pygame.sprite.groupcollide(self.boss_enemy.bullets, self.own_group, True, True) # BOSS敵機(jī)子彈擊毀已機(jī) died_5 = pygame.sprite.groupcollide(self.boss_enemy_group, self.own_group, True, True) # BOSS敵機(jī)撞毀已機(jī) died_owns = {**died_1, **died_2, **died_3, **died_4, **died_5} # 合并字典 if len(died_owns) > 0: # 列表有內(nèi)容代表發(fā)生碰撞了 self.life_num -= 1 # 飛機(jī)數(shù)量減1 own_died = SpriteDown(OWN_DOWN_IMAGE, list(died_owns.keys())[0].rect, 0) self.own_died_group.add(own_died) self.s = threading.Timer(1, self.__resetOwn) # 設(shè)置一個(gè)多線程定時(shí)調(diào)用函數(shù),1秒后開始執(zhí)行 self.s.start() # 當(dāng)子彈和加分?jǐn)硻C(jī)碰撞,出現(xiàn)金幣繼續(xù)下落 bonus_enemies = pygame.sprite.groupcollide(self.own.bullets, self.bonus_enemy_group, True, True) if len(bonus_enemies) > 0: self.score += 1 gold_coin = SpriteDown(GOLD_COIN_IMAGE, list(bonus_enemies.keys())[0].rect, 1) self.gold_coin_group.add(gold_coin) # 當(dāng)已機(jī)和硬幣碰撞,得分+5,金幣消失 gold = pygame.sprite.groupcollide(self.gold_coin_group, self.own_group, True, False) if len(gold) > 0: self.score += 5 # 當(dāng)子彈和星星敵機(jī)碰撞,子彈消失,超過n顆子彈后出現(xiàn)星星繼續(xù)下落 if self.star_enemy_life <= 0: star_enemy = pygame.sprite.groupcollide(self.own.bullets, self.star_enemy_group, True, True) if len(star_enemy) > 0: self.score += 5 star_coin = SpriteDown(STAR_IMAGE, list(star_enemy.keys())[0].rect, 1) self.star_coin_group.add(star_coin) else: star_enemies = pygame.sprite.groupcollide(self.own.bullets, self.star_enemy_group, True, False) if len(star_enemies) > 0: self.star_enemy_life -= 1 # 當(dāng)子彈和BOSS敵機(jī)碰撞,子彈消失,超過n顆子彈后BOSS敵機(jī)爆炸 if self.boss_enemy_life <= 0: boss_enemy = pygame.sprite.groupcollide(self.own.bullets, self.boss_enemy_group, True, True) if len(boss_enemy) > 0: self.score += 300 enemy_down = SpriteDown(ENEMY_DOWN_IMAGE, list(boss_enemy.keys())[0].rect, 1) self.enemy_down_group.add(enemy_down) self.boss_flag = 0 else: boss_enemies = pygame.sprite.groupcollide(self.own.bullets, self.boss_enemy_group, True, False) if len(boss_enemies) > 0: self.boss_enemy_life -= 1 # 當(dāng)已機(jī)和星星碰撞,得分+10,子彈等級(jí)+1 star = pygame.sprite.groupcollide(self.star_coin_group, self.own_group, True, False) if len(star) > 0: self.score += 10 self.bullet_grade += 1 def __resetOwn(self): """ 自己飛機(jī)重生 """ self.own = Own() # 創(chuàng)建自己的飛機(jī)精靈和精靈組 self.own_group = pygame.sprite.Group(self.own) self.bullet_grade = 1 # 初始的子彈等級(jí) def __infoDisplay(self, text, pos, angle): """ -- 顯示游戲信息 :param text: 文字內(nèi)容 :param pos: 位置[x, y] :param angle: 用來(lái)定位的角 :return: """ score_font = pygame.font.Font(SYS_FONT, 24) score_text = score_font.render(text, True, (255, 255, 255)) text_rect = score_text.get_rect() exec('text_rect.{}={}'.format(angle, pos)) self.screen.blit(score_text, text_rect) def __updateSprites(self): """ 更新/繪制精靈組 """ self.back_group.update() self.back_group.draw(self.screen) self.__infoDisplay('score ' + str(self.score), [20, 10], 'topleft') self.__infoDisplay('level 01', [492, 10], 'topright') self.__infoDisplay('life ' + str(self.life_num), [230, 10], 'topleft') if pygame.time.get_ticks() < self.ready_time + 3000: # 顯示ready畫面3秒 self.ready_go_group.update() self.ready_go_group.draw(self.screen) if pygame.time.get_ticks() > self.ready_time + 4000: # ready畫面1秒后開始顯示游戲元素 self.enemy_red_group.update() self.enemy_red_group.draw(self.screen) # 顯示敵機(jī) self.bonus_enemy_group.update() self.bonus_enemy_group.draw(self.screen) # 顯示加分?jǐn)硻C(jī) self.star_enemy_group.update() self.star_enemy_group.draw(self.screen) # 顯示星星敵機(jī) self.boss_enemy_group.update() self.boss_enemy_group.draw(self.screen) # 顯示BOSS敵機(jī) self.enemy_down_group.update() self.enemy_down_group.draw(self.screen) # 顯示敵機(jī)爆炸 self.own.bullets.update() self.own.bullets.draw(self.screen) # 顯示已方子彈 self.boss_enemy.bullets.update() self.boss_enemy.bullets.draw(self.screen) # 顯示BOSS子彈 self.own_died_group.update() self.own_died_group.draw(self.screen) # 顯示已方飛機(jī)爆炸 self.gold_coin_group.update() self.gold_coin_group.draw(self.screen) # 顯示金幣 self.star_coin_group.update() self.star_coin_group.draw(self.screen) # 顯示星星 self.own_group.update() self.own_group.draw(self.screen) # 顯示已方飛機(jī) def __gamePause(self, pause=False): """ 暫停游戲, 按任意鍵退出""" self.__infoDisplay('Any key to continue...', SCREEN_CENTER, 'center') pygame.display.update() # 更新屏幕顯示 while pause: for event in pygame.event.get(): if event.type == pygame.QUIT: PlaneGame.quit() elif event.type == pygame.KEYDOWN: pause = False def __gameOver(self): """ 游戲結(jié)束,按ESC重新開始 """ if self.life_num == 0: # 如果飛機(jī)數(shù)量為0,退出游戲 game_over = pygame.image.load(GAME_OVER) # 顯示GAMEOVER圖片 self.screen.blit(game_over, (50, 150)) self.__infoDisplay('press ESC play again...', SCREEN_CENTER, 'center') pygame.display.update() # 更新屏幕顯示 flag = True while flag: for event in pygame.event.get(): if event.type == pygame.QUIT: PlaneGame.quit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: # 按SPACE重新開始游戲 flag = False PlaneGame().start() @staticmethod def quit(): """ 靜態(tài)函數(shù),退出游戲 """ pygame.quit() exit()
三、效果展示
1)游戲界面
?2)運(yùn)行游戲
3)金幣掉落
4)游戲結(jié)束
總結(jié)
嘻嘻!打掉藍(lán)色戰(zhàn)機(jī)加星星之后玩起來(lái)特別爽的哦~以上沒截圖,大家可以自己試試的啦!
到此這篇關(guān)于Python Pygame實(shí)戰(zhàn)之飛機(jī)大戰(zhàn)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python Pygame飛機(jī)大戰(zhàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python項(xiàng)目127.0.0.1:5000訪問失敗問題解決
Windows環(huán)境下啟動(dòng)python項(xiàng)目,接口訪問失敗,本文給大家分享python項(xiàng)目127.0.0.1:5000訪問失敗問題解決方法,感興趣的朋友跟隨小編一起看看吧2023-09-09pandas 強(qiáng)制類型轉(zhuǎn)換 df.astype實(shí)例
這篇文章主要介紹了pandas 強(qiáng)制類型轉(zhuǎn)換 df.astype實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2020-04-04selenium框架中driver.close()和driver.quit()關(guān)閉瀏覽器
這篇文章主要介紹了selenium框架中driver.close()和driver.quit()關(guān)閉瀏覽器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Opencv實(shí)現(xiàn)傾斜圖片轉(zhuǎn)正示例
本文主要介紹了Opencv實(shí)現(xiàn)傾斜圖片轉(zhuǎn)正示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08Python實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之快速排序詳解
這篇文章主要介紹了Python實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之快速排序,詳細(xì)分析了快速排序的原理與Python實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-04-04Python數(shù)據(jù)可視化之Pyecharts使用詳解
Pyecharts是一個(gè)由百度開源的、用于生成Echarts圖表的類庫(kù),可以用來(lái)進(jìn)行數(shù)據(jù)可視化分析。本文將詳細(xì)講解一下Pyecharts的使用,需要的可以參考一下2022-04-04