【pygame】面向?qū)ο髮崿F(xiàn)飛機大戰(zhàn)(附完整代碼)

【寫在前面】:本人在網(wǎng)上裂明,似乎還沒有找到關(guān)于飛機大戰(zhàn)的完整程序。基本都是講了一些比較瑣碎的小知識點胜蛉。那么本篇文章呢,是使用pygame 通過面向?qū)ο蟮姆绞?/strong>實現(xiàn)的“飛機大戰(zhàn)”的完整程序的串講色乾。

【文章特點】主要是夠【硬核】誊册,夠【詳實】。文末附有完整的本項目所有內(nèi)容的GitHub地址...

【特點介紹】

  • 設(shè)置游戲背景暖璧;

  • 設(shè)置游戲背景音樂案怯;

  • 設(shè)置了游戲名稱“外星人入侵”;

  • 設(shè)置了積分裝置(左上角)澎办;

  • 設(shè)置了玩家的生命值(右上角)嘲碱;

  • 設(shè)置了兩種道具(powerup)和(liveup);

  • 設(shè)置了我方戰(zhàn)機三種攻擊模式(吃了道具后局蚀,模型轉(zhuǎn)變(持續(xù)時間:5秒))麦锯;

  • 設(shè)置了敵機的隨機產(chǎn)生,以及敵機子彈的隨機發(fā)射琅绅;

  • 我方戰(zhàn)機死亡后扶欣,游戲界面轉(zhuǎn)變;

  • 我方戰(zhàn)機死亡后,可選擇【重新游戲】和【游戲結(jié)束】

  • ......


【是否拭目以待了呢料祠?】
先來看一下游戲的運行結(jié)果吧骆捧!


游戲開始

火力升級【power up】


【power up】

火力升級【power up(MAX)】


【power up(MAX)】

【死亡后界面跳轉(zhuǎn)】


死亡后界面跳轉(zhuǎn)-圖例

看著醬紫的界面,是否有玩一局的沖動呢髓绽?

再一次游戲【once again】

再一次游戲-圖例

下面進(jìn)入正題

先提一下:什么是游戲循環(huán)?

每個游戲的核心都是一個循環(huán)凑懂,將其稱為“游戲循環(huán)”。這個循環(huán)一直在不斷運行梧宫,一遍又一遍地完成游戲工作所需的所有事情接谨。每次循環(huán)顯示一次游戲當(dāng)前畫面,稱為幀塘匣。


【本文主要有以下10個模塊】

  • App.py文件

  • hero.py文件

  • Npc.py文件

  • bullet.py文件

  • prop.py文件

  • hit.py文件

  • information.py文件

  • music.py文件

  • setting.py文件

  • setup.py文件


關(guān)于App.py文件

【作用如下】

  • 啟動pygame脓豪;

  • 確定游戲界面;

  • 設(shè)置幀率

  • 設(shè)置游戲名稱忌卤;

  • 設(shè)置游戲背景扫夜;

  • 設(shè)置游戲背景音樂;

  • 【調(diào)用各個模塊來豐富游戲功能】

  • 游戲關(guān)閉驰徊;

# @Author  : Zurich.Alcazar
# @Email   : 1178824808@qq.com
# @File    : App.py
# @Software: PyCharm

import pygame
import sys
import hero
import os.path as path
import setting
from information import DataBus
from Npc import EnermyFactory
from Npc import Button
from prop import PropFactory
import hit
# import music

class App:

    def start(self):
        pygame.init()    # 啟動pygame
        pygame.mixer.init()
        # 確定游戲界面
        screen = pygame.display.set_mode((400, 600))

        # 設(shè)置幀率
        clock = pygame.time.Clock()
        bus = DataBus()
        # 設(shè)置游戲名稱
        pygame.display.set_caption("外星人入侵")
        # 設(shè)置游戲背景
        # bg_img = pygame.image.load(path.join(setting.img_folder, "background.png")).convert()
        bg_img = pygame.image.load(path.join(setting.img_folder, "789.jpg")).convert()
        # bg_img = pygame.image.load(path.join(setting.img_folder, "888.png")).convert()
        screen.blit(bg_img,(0,0))

        # 設(shè)置游戲背景音樂
        bgm = pygame.mixer.Sound(path.join(setting.snd_folder,'game_music.ogg'))
        bgm.set_volume(0.5)
        bgm.play(loops = -1)
        # 調(diào)用

        ef = EnermyFactory()
        pp = PropFactory()
        transColor = pygame.Color(0, 0, 0)
        player_img = pygame.image.load(path.join(setting.img_folder, "me1.png")).convert()

        player_mini_img = pygame.transform.scale(player_img, (25, 30))
        player_mini_img.set_colorkey(transColor)

        game_font = pygame.font.SysFont('arial', 24, True)


        # 讓渲染結(jié)果一次顯示
        pygame.display.flip()

        while True:
            screen.blit(bg_img, (0, 0))
            clock.tick(30)
            if not bus.is_game_over:
                # 制造敵機
                ef.generate_enermy()
                # 制造道具
                pp.generate_bomb_prop()
                pp.generate_bullet_prop()

                # 更新坐標(biāo)(核心)
                bus.all_sprites.update()
                # 映射到屏幕
                bus.all_sprites.draw(screen)
                # 碰撞檢測: 玩家子彈和敵機
                bus.game_helper.collision()
                screen.blit(game_font.render(u'%d' % bus.score, True, [255, 0, 0]), [20, 20])
                hero.Hero.draw_lives(screen, 300, 20, 3, player_mini_img)

                # 讓渲染結(jié)果一次顯示
                pygame.display.flip()

            if bus.is_game_over:
                bg_img = pygame.image.load(path.join(setting.img_folder, "888.png")).convert()
                screen.blit(bg_img, (0, 0))
                bus.game_helper.draw_game_over_view()

            bus.all_sprites.draw(screen)
            pygame.display.flip()


            for event in pygame.event.get():
                if event.type == pygame.QUIT:  # 游戲關(guān)閉
                    sys.exit()

App().start()

關(guān)于hero.py文件

【作用】:定義英雄的各種功能(移動笤闯、發(fā)射子彈等等)

  • 定義初始位置;

  • 定義子彈發(fā)射音效棍厂;

  • 彈延時(效果)颗味;

  • 我方戰(zhàn)機生命值;

  • 是否觸碰游戲邊界【檢查】牺弹;

  • 等級提升浦马,火力升級【powerup】;

  • 戰(zhàn)機隱藏张漂;

  • 我方戰(zhàn)機爆炸(此功能尚未實現(xiàn))晶默;

# @Author  : Zurich.Alcazar
# @Email   : 1178824808@qq.com
# @File    : hero.py
# @Software: PyCharm
import pygame
from pygame.sprite import Sprite
import os.path as path
import setting
from bullet import HeroBullet
from bullet import HeroBullet2
import information as info

class Hero(Sprite):
    def __init__(self):
        super().__init__()

        image = pygame.image.load(path.join(setting.img_folder,"me1.png"))
        self.image = pygame.transform.scale(image,(51,60))
        # 定義初始位置
        self.rect = self.image.get_rect()
        self.rect.center = (setting.SCREEN_WIDTH - 200,setting.SCREEN_HEIGHT - 80)
        self.bus = info.DataBus()
        # 定義子彈發(fā)射音效
        self.shoot_sud = pygame.mixer.Sound(path.join(setting.snd_folder,"bullet.wav"))
        self.shoot_sud.set_volume(0.8)
        # self.clock = pygame.time.Clock()
        # 子彈延時(效果)
        self.shoot_delay = 500
        self.last_shoot_time = pygame.time.get_ticks()
        self.power = 1
        self.POWERUP_TIME = 5000
        self.power_time = pygame.time.get_ticks()
        # 我方戰(zhàn)機生命值
        self.lives = 3
        self.hidden = False
        self.hide_timer = pygame.time.get_ticks()

        player_img = pygame.image.load(path.join(setting.img_folder, "me1.png")).convert()
        player_mini_img = pygame.transform.scale(player_img, (25, 30))
        player_mini_img.set_colorkey()



    def update(self, *args):
        speed = 10
        keystate = pygame.key.get_pressed()
        if (keystate[pygame.K_LEFT] or keystate[pygame.K_a]):
            self.rect.x -= speed
        if keystate[pygame.K_RIGHT] or keystate[pygame.K_d]:
            self.rect.x += speed
        if keystate[pygame.K_UP] or keystate[pygame.K_w]:
            self.rect.y -= speed
        if keystate[pygame.K_DOWN] or keystate[pygame.K_s]:
            self.rect.y += speed
        # if keystate[pygame.K_SPACE]:  # 空格鍵 射擊
        if self.power == 1:
            self.shoot()
        if self.power == 2:
            self.powershoot()
        if self.power >= 3:
            self.superpower()
        # 戰(zhàn)機復(fù)活影藏
        if self.hidden and pygame.time.get_ticks() - self.hide_timer > 1000:
            self.hidden = False
            self.rect.centerx = setting.SCREEN_WIDTH / 2
            self.rect.bottom = setting.SCREEN_HEIGHT - 80


        # 邊界檢查
        if self.rect.right > setting.SCREEN_WIDTH:
            self.rect.right = setting.SCREEN_WIDTH
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.top < 0:
            self.rect.top = 0
        if self.rect.bottom > setting.SCREEN_HEIGHT:
            self.rect.bottom = setting.SCREEN_HEIGHT

        if self.power >= 2 and pygame.time.get_ticks() - self.power_time > self.POWERUP_TIME:
            self.power -= 1
            self.power_time = pygame.time.get_ticks()

    # 生命值減少
    def Lives(self):
        self.lives -= 1

    # 等級提升
    def powerup(self):
        self.power += 1
        self.power_time = pygame.time.get_ticks()

    # 戰(zhàn)機隱藏
    def hide(self):
        # hide the player temporarily

        self.hidden = True
        self.hide_timer = pygame.time.get_ticks()
        self.rect.center = (setting.SCREEN_WIDTH/ 2, setting.SCREEN_HEIGHT + 200)



    def shoot(self):
        now = pygame.time.get_ticks()
        if now - self.last_shoot_time > self.shoot_delay:
            self.last_shoot_time = now

            bullet = HeroBullet(self.rect.centerx, self.rect.top)
            self.shoot_sud.play()
            self.bus.add_sprite(bullet)
            self.bus.add_hero_bullet(bullet)

    # 火力升級
    def powershoot(self):
        now = pygame.time.get_ticks()
        if now - self.last_shoot_time > self.shoot_delay:
            self.last_shoot_time = now

            bullet1 = HeroBullet(self.rect.left + 15, self.rect.top)
            bullet2 = HeroBullet(self.rect.right - 15, self.rect.top)
            bullet3 = HeroBullet(self.rect.centerx, self.rect.top - 5)

            # 發(fā)射子彈時的音效
            self.shoot_sud.play()

            self.bus.add_sprite(bullet1)
            self.bus.add_sprite(bullet2)
            self.bus.add_sprite(bullet3)

            self.bus.add_hero_bullet(bullet1)
            self.bus.add_hero_bullet(bullet2)
            self.bus.add_hero_bullet(bullet3)

    def superpower(self):
        now = pygame.time.get_ticks()
        if now - self.last_shoot_time > 50:
            self.last_shoot_time = now

            bullet3 = HeroBullet2(self.rect.centerx - 32, self.rect.top)
            self.shoot_sud.play()
            self.bus.add_sprite(bullet3)
            self.bus.add_hero_bullet(bullet3)

    def draw_lives(surf, x, y, lives, img):
        for i in range(lives):
            img_rect = img.get_rect()
            img_rect.x = x + 30 * i
            img_rect.y = y
            surf.blit(img, img_rect)


class HeroLive(Sprite):
    """
    我方戰(zhàn)機爆炸
    """
    def __init__(self, name, num, center):
        super().__init__()
        self.animation = []

【解釋一下】:只要是與我方戰(zhàn)機掛鉤的功能,都可在此模塊添加航攒。


上面寫完了有關(guān)我方戰(zhàn)機的各種功能磺陡,下面就該【邪惡角色】外星人出場了..

關(guān)于Npc.py文件

【作用】:隨機生成敵機。

【小技巧介紹】:

class EnermyFactory:

【敵機工廠類】:來實現(xiàn)敵機的隨機產(chǎn)生

class Explosion(Sprite):

【爆炸效果類】:實現(xiàn)敵機與子彈碰撞后的爆炸效果漠畜。
【此代碼塊如下】

# @Author  : Zurich.Alcazar
# @Email   : 1178824808@qq.com
# @File    : Npc.py
# @Software: PyCharm

import random
import pygame

from pygame.sprite import Sprite
import os.path as path

import setting
import information as info
from bullet import NpcBullet

class commonEnermy(Sprite):
    def __init__(self,x,y):
        super().__init__()
        image = pygame.image.load(path.join(setting.img_folder,"enemy1.png"))
        self.image = pygame.transform.scale(image,(40,30))
        self.bus = info.DataBus()
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = y
        self.shoot_time = pygame.time.get_ticks()
        self.delay_shoot = random.randint(500,3500)

    def update(self, *args):
        speed = 4
        self.rect.y += speed
        # 可設(shè)計其他軌跡
        self.shoot()
        if self.rect.y > setting.SCREEN_HEIGHT:
            self.kill()

    def shoot(self):
        now =  pygame.time.get_ticks()
        if now - self.shoot_time > self.delay_shoot:
            self.delay_shoot = random.randint(500, 3500)
            self.shoot_time = now
            bullet = NpcBullet(self.rect.centerx,self.rect.bottom)
            self.bus.add_sprite(bullet)
            self.bus.add_npc_bullet(bullet)

class EnermyFactory:
    def __init__(self):
        self.bus = info.DataBus()
        # 普通敵軍生成時間
        self.last_common_time = pygame.time.get_ticks()

    def generate_comon_enermy(self):
        x = random.randint(26,setting.SCREEN_WIDTH - 26)
        y = random.randint(-100,80)
        common_enermy = commonEnermy(x,y)
        self.bus.add_sprite(common_enermy)
        self.bus.add_enermy(common_enermy)

    def generate_enermy(self):
        now = pygame.time.get_ticks()
        if now - self.last_common_time > 800:
            self.generate_comon_enermy()
            self.last_common_time = now

class Explosion(Sprite):
    animations = dict()
    def __init__(self, who, center):
        super().__init__()
        self.aninmation = []
        self.load()

        if who == "enermy":
            self.animation = Explosion.animations['enemy_main']
        self.frame = 0
        self.image = self.animation[self.frame]
        self.rect = self.image.get_rect()
        self.rect.center = center
        # 上一幀圖片的顯示時間
        self.last_frame_time = pygame.time.get_ticks()

    def load(self):
        # 加載敵機爆炸資源
        if Explosion.animations.get("enemy_main") is None:
            enemy_explosion_res = []
            for i in range(0, 4):
                filename = "enemy1_down{}.png".format(i+1)
                img = pygame.image.load(path.join(setting.img_folder,filename))
                enemy_explosion_res.append(img)
            Explosion.animations["enemy_main"] = enemy_explosion_res

    def update(self, *args):
        now = pygame.time.get_ticks()
        if now - self.last_frame_time > 100:
            if self.frame == len(self.animation) - 1:
                self.kill()
            else:
                self.frame += 1
                self.image = self.animation[self.frame]

class HeroExplosion(Sprite):
    animations = dict()
    def __init__(self, who, center):
        super().__init__()
        self.aninmation = []
        self.load()

        if who == "hero":
            self.animation = Explosion.animations['enemy_main']
        self.frame = 0
        self.image = self.animation[self.frame]
        self.rect = self.image.get_rect()
        self.rect.center = center
        # 上一幀圖片的顯示時間
        self.last_frame_time = pygame.time.get_ticks()

    def load(self):
        # 加載爆炸資源
        if Explosion.animations.get("enemy_main") is None:
            enemy_explosion_res = []
            for i in range(0, 4):
                filename = "me_destroy_{}.png".format(i+1)
                img = pygame.image.load(path.join(setting.img_folder,filename))
                enemy_explosion_res.append(img)
            Explosion.animations["enemy_main"] = enemy_explosion_res

    def update(self, *args):
        now = pygame.time.get_ticks()
        if now - self.last_frame_time > 100:
            if self.frame == len(self.animation) - 1:
                self.kill()
            else:
                self.frame += 1
                self.image = self.animation[self.frame]


class Button(Sprite):
    def __init__(self,img_name,offset_y):
        super(Button, self).__init__()
        self.image = pygame.image.load(path.join(setting.img_folder,img_name))
        self.rect = self.image.get_rect()
        self.rect.center = setting.SCREEN_WIDTH / 2, (setting.SCREEN_HEIGHT/2) + offset_y

    @staticmethod
    def check_click(button):
        pressed = pygame.mouse.get_pressed()
        print(pressed)
        if pressed == (1, 0, 0):
            print("左鍵點擊")
            pos = pygame.mouse.get_pos()
            button_x = pos[0]
            button_y = pos[1]

            if button.rect.left < button_x < button.rect.right and button.rect.top < button_y < button.rect.bottom:
                return True
            return False

那么敵軍和我方英雄都存在了币他,接下來,我們介紹一下關(guān)于【子彈發(fā)射的問題】

bullet.py

【作用】:導(dǎo)入子彈盆驹、定義子彈初始位置圆丹、以及移動軌跡。

【代碼塊】

# @Author  : Zurich.Alcazar
# @Email   : 1178824808@qq.com
# @File    : bullet.py
# @Software: PyCharm

import pygame
import os.path as path
import setting
from pygame.sprite import Sprite

class HeroBullet(Sprite):
    def __init__(self,x,y):
        super(HeroBullet, self).__init__()
        # 導(dǎo)入子彈
        self.image = pygame.image.load(path.join(setting.img_folder,"bullet2.png"))
        # 定義子彈初始位置
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.bottom = y

    def update(self, *args):
        self.rect.y -= 10
        if self.rect.bottom < 0:
            self.kill()

class HeroBullet2(Sprite):
    def __init__(self,x,y):

        super(HeroBullet2, self).__init__()
        # 導(dǎo)入子彈
        self.image = pygame.image.load(path.join(setting.img_folder,"bullet2.png"))
        # 定義子彈初始位置
        self.rect = self.image.get_rect()
        # self.rect.center = center
        self.rect.centerx = x
        self.rect.bottom = y
        self.speedx = 0
        self.d = 6

    def update(self, *args):

        self.rect.y -= 4
        if self.speedx < -12:
            self.d = 3
        if self.speedx > 12:
            self.d = -3
        self.speedx += self.d
        self.rect.x += self.speedx

        if self.rect.bottom < 0:
            self.kill()

class NpcBullet(Sprite):
    def __init__(self,x,y):
        super(NpcBullet, self).__init__()
        # 導(dǎo)入敵機子彈
        image = pygame.image.load(path.join(setting.img_folder,"bullet1.png"))
        self.image = pygame.transform.scale(image, (4, 8))
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.bottom = y

    def update(self, *args):
        self.rect.y += 7
        if self.rect.centery < 0:
            self.kill()

【解釋】:關(guān)于子彈這一塊躯喇,其實是最簡單的啦辫封。子彈能發(fā)射了硝枉,那接下來就可以加載以下道具了。


關(guān)于prop.py文件

【分類】

  • 火力提升道具

class Bulletprop(Sprite):

  • 加血道具

class Bombprop(Sprite):

【小技巧】

class PropFactory:

通過調(diào)用【道具工廠類】來實現(xiàn)道具的生成倦微。
【代碼】

import random
import pygame
from pygame.sprite import Sprite
import os.path as path
import setting
import hit
import information as info
import math




class Bombprop(Sprite):
    # 定義加血道具
    def __init__(self,x,y):
        super().__init__()
        image = pygame.image.load(path.join(setting.img_folder,"bomb_supply.png"))
        self.image = pygame.transform.scale(image,(20,35))

        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = y

    def update(self, *args):
        speed = 2
        self.rect.y += speed
        if self.rect.y > setting.SCREEN_HEIGHT:
            self.kill()


class Bulletprop(Sprite):
    # 定義加火力道具
    def __init__(self,x,y):
        super(Bulletprop, self).__init__()
        prop_image = pygame.image.load(path.join(setting.img_folder,"bullet_supply.png"))
        self.image = pygame.transform.scale(prop_image, (20, 35))
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = y

    def update(self, *args):
        speed = 2
        self.rect.y += speed
        if self.rect.y > setting.SCREEN_HEIGHT:
            self.kill()

class PropFactory:
    def __init__(self):
        self.bus = info.DataBus()
        # 普通敵軍生成時間
        self.prop_time = pygame.time.get_ticks()
        self.bullet_time = pygame.time.get_ticks() - 500

    def generate_comon_prop(self):
        # 定義加血道具位置
        x = random.randint(26, setting.SCREEN_WIDTH - 26)
        y = random.randint(26, 180)
        bomb_supply = Bombprop(x, y)
        self.bus.add_sprite(bomb_supply)
        self.bus.add_bomb_prop(bomb_supply)

    def bullet_prop(self):
        # 定義火力道具位置
        x = random.randint(26, setting.SCREEN_WIDTH - 26)
        y = random.randint(26, 180)

        bullet_supply = Bulletprop(x, y)
        self.bus.add_sprite(bullet_supply)
        self.bus.add_bullet_prop(bullet_supply)

    # 加血道具出現(xiàn)時間間隔
    def generate_bomb_prop(self):
        now = pygame.time.get_ticks()
        if now - self.prop_time > 2000 :
            self.generate_comon_prop()
            self.prop_time  = now

    def generate_bullet_prop(self):
        it = pygame.time.get_ticks()
        if it - self.bullet_time > 3000:
            self.bullet_prop()
            self.bullet_time = it

【注意事項】:在設(shè)置道具產(chǎn)生時妻味,會很容易出現(xiàn)滿屏的道具問題,如果自己在編程中有遇到欣福,(請自行百度解決责球,或者參考本篇文章)。


【插播小廣告拓劝,嘻嘻】
【關(guān)于爆炸效果】:其實游戲設(shè)置中的爆炸效果雏逾,是由幾張圖片在極短的時間內(nèi)閃過產(chǎn)生的視覺效果。

下面來講一講碰撞檢測郑临。


關(guān)于hit.py文件

【碰撞檢測分類】

  • 子彈和敵軍碰撞檢測栖博;

  • 敵機與戰(zhàn)機碰撞檢測;

  • 敵機子彈和戰(zhàn)機碰撞檢測厢洞;

  • 戰(zhàn)機和火力道具碰撞檢測仇让;

  • 戰(zhàn)機和加血道具碰撞檢測;

【代碼】:此塊代碼中有許多被 住掉的(#...)如果有興趣的話躺翻,可以嘗試嘗試丧叽。

import pygame
import sys
import setting
import os.path as path
import hero
from pygame.sprite import Sprite
# from Npc import EnermyFactory
import information as info
from Npc import Explosion
# from Npc import HeroExplosion
from Npc import Button


class Hit(Sprite):
    """
    碰撞類
    """
    def __init__(self):
        super(Hit, self).__init__()
        self.score = 0
        self.power = 1
        self.die_music = pygame.mixer.Sound(path.join(setting.snd_folder, "enemy1_down.wav"))
        self.get_bullet = pygame.mixer.Sound(path.join(setting.snd_folder,"get_bullet.wav"))
        self.bus = info.DataBus()


class GameHelper:
    def __init__(self):
        self.bus = info.DataBus()

    def collision(self):
        """
        全局碰撞檢測
        :return:
        """
        # 子彈和敵軍碰撞檢測
        hits = pygame.sprite.groupcollide(self.bus.hero_bullets, self.bus.enermys, True, True)
        if hits:
            self.handle_collision(hits)

        #  敵機與戰(zhàn)機碰撞
        enermys = self.bus.enermys.sprites()
        enermys_hit = pygame.sprite.spritecollide(self.bus.hero, self.bus.enermys, True, pygame.sprite.collide_circle_ratio(0.7))
        # for e in enermys:
        #     pygame.sprite.collide_circle_ratio(0.7)
        #     if pygame.sprite.collide_circle(self.bus.hero, e):

        if enermys_hit:
            # for b, e in hits.items():
            #     for eson in e:
            #         explosion = HeroExplosion('hero', eson.rect.center)
            #         self.bus.add_sprite(explosion)
            # hero.Hero.hide(self.bus.hero)
            # hero.Hero.Lives(self.bus.hero)
            # hero.Hero.shield = 100
                self.bus.is_game_over =True
                print("Game Over...")

        # 敵機子彈和戰(zhàn)機碰撞
        enermys_bullets = self.bus.enermy_bullets.sprites()
        for i in enermys_bullets:
            if pygame.sprite.collide_rect(self.bus.hero, i):
                # # 敵人爆炸動畫
                # for b, e in hits.items():
                #     for eson in e:
                #         explosion = HeroExplosion('hero', eson.rect.center)
                #         self.bus.add_sprite(explosion)
                # hero.Hero.hide(self.bus.hero)
                # hero.Hero.Lives(self.bus.hero)
                # hero.Hero.shield = 100
                self.bus.is_game_over = True
                print("Game Over...")


        # 戰(zhàn)機和火力道具碰撞
        bullet_prop = self.bus.bullet_props.sprites()
        bullet_hit = pygame.sprite.spritecollide(self.bus.hero, self.bus.bullet_props,True, pygame.sprite.collide_circle_ratio(0.7))
        # for k in bullet_prop:
        #     pygame.sprite.collide_circle_ratio(0.7)
        #     if pygame.sprite.collide_circle(self.bus.hero, k):
        #         hero.Hero.powerup(self.bus.hero)
        if bullet_hit:
            hero.Hero.powerup(self.bus.hero)


        # 戰(zhàn)機和加血道具碰撞
        bomb_prop = self.bus.bomb_props.sprites()
        bomb_hit = pygame.sprite.spritecollide(self.bus.hero, self.bus.bomb_props, pygame.sprite.collide_circle_ratio(0.8))
        # if bomb_hit:
        #     hero.Hero.(self.bus.hero)

    def handle_collision(self, hits):
        # 加分
        self.bus.add_score(10 * len(hits))
        # 敵人死亡聲音
        self.bus.m.play_die_music()

        # 敵人爆炸動畫
        for b, e in hits.items():
            for eson in e:
                explosion = Explosion('enermy', eson.rect.center)
                self.bus.add_sprite(explosion)

    def draw_game_over_view(self):
        self.bus.all_sprites.empty()

        game_over_button = Button("gameover.png", -40)
        begin_button = Button("again.png",40)
        self.bus.all_sprites.add(game_over_button)
        self.bus.all_sprites.add(begin_button)

        if Button.check_click(game_over_button):
            sys.exit()

        if Button.check_click(begin_button):
            self.bus.reset()
            self.bus.is_game_over = False

關(guān)于information.py文件

這個文件特別重要。
【作用】

  • 初始化英雄(...)公你;

  • 將游戲中的各個元素(敵機踊淳、子彈、道具等)分門別類的“存”起來省店;

【代碼】

# @Author  : Zurich.Alcazar
# @Email   : 1178824808@qq.com
# @File    : information.py
# @Software: PyCharm
import pygame
import hero
import music
import hit
import setting
# from Npc import Explosion

class DataBus:
   instance = None


   def __new__(cls, *args, **kwargs):
       if DataBus.instance is None:
           DataBus.instance = super().__new__(cls)
           DataBus.instance.reset()


       return DataBus.instance

   def reset(self):

       self.score = 0
       self.is_game_over = False

       self.all_sprites = pygame.sprite.Group()
       self.hero_bullets = pygame.sprite.Group()

       self.enermy_bullets = pygame.sprite.Group()
       self.heros = pygame.sprite.Group()
       self.enermys = pygame.sprite.Group()
       self.bomb_props = pygame.sprite.Group()
       self.bullet_props = pygame.sprite.Group()
       self.m = music.Music()
       self.game_helper = hit.GameHelper()
       # self.game_over_button = Npc.Button("gameover.png")
       # self.game_over_button_clicked = False

       # 初始化英雄
       self.__init_hero()

   def __init_hero(self):
       """
       初始化英雄
       :return:
       """
       self.hero = hero.Hero()
       self.add_sprite(self.hero)

   def add_sprite(self,sprite):
       self.all_sprites.add(sprite)

   def remove_sprite(self,sprite):
       self.all_sprites.remove(sprite)

   def add_hero_bullet(self,hero_bullet):
       self.hero_bullets.add(hero_bullet)

   def add_npc_bullet(self,npc_bullet):
       self.enermy_bullets.add(npc_bullet)

   def add_hero(self,hero):
       self.heros.add(hero)

   def add_enermy(self,enermy):
       self.enermys.add(enermy)

   def add_bomb_prop(self,prop):
       self.bomb_props.add(prop)

   def add_bullet_prop(self,prop):
       self.bullet_props.add(prop)

   def add_score(self,score):
       self.score += score
       num_score = self.score

       print("當(dāng)前得分:%d" % self.score)


   def draw_text(self, screen):
       font1 = pygame.font.Font(16, True)
       screen.blit(font1.render(u'當(dāng)前得分:%d' % self.score, True,'red'), [20, 20])

【解釋一下】:這個文件就是拿來存儲數(shù)據(jù)的嚣崭。


關(guān)于music.py文件

【作用】:配置音樂

【代碼】:

# @Author  : Zurich.Alcazar
# @Email   : 1178824808@qq.com
# @File    : music.py
# @Software: PyCharm
import pygame
import sys
import setting
import os.path as path


class Music:

    singleton = None
    def __new__(cls, *args, **kwargs):
        if Music.singleton is None:
            Music.singleton = super().__new__(cls, *args, **kwargs)
            Music.singleton.initial()

        return Music.singleton

    def initial(self):
        self.die_music = pygame.mixer.Sound(path.join(setting.snd_folder, "enemy1_down.wav"))
        self.bgm = pygame.mixer.Sound(path.join(setting.snd_folder, 'game_music.ogg'))
        self.shoot_sud = pygame.mixer.Sound(path.join(setting.snd_folder, "bullet.wav"))
        self.enermy_die_music = pygame.mixer.Sound(path.join(setting.snd_folder, "enemy1_down.wav"))

        self.set_config()

    def set_config(self):
        """
        配置音樂
        :return:
        """
        self.bgm.set_volume(0.6)

    def play_die_music(self):
        self.die_music.play()

    def play_bgm(self):
        self.bgm.play(loops=-1)

    def play_shoot_sud(self):
        self.shoot_sud.play()

    def play_enmery_die_music(self):
        self.enermy_die_music.play()


關(guān)于setting.py文件

【作用】:設(shè)置工程目錄,并且設(shè)置游戲的邊界懦傍。

import os.path as path
import pygame

SCREEN_WIDTH = 400
SCREEN_HEIGHT = 600

# 工程目錄
print(__file__)
project_folder = path.dirname(__file__)

img_folder = path.join(project_folder,"plane/images")
snd_folder = path.join(project_folder,"plane/sound")
print(img_folder)


總結(jié)一下

本篇文章主要是理一下使用pygame面向?qū)ο缶幊痰乃悸罚f一下本文中程序的缺點吧芦劣,此程序其實部分功能沒有實現(xiàn)粗俱,例如:關(guān)于加血道具那一塊、以及我方戰(zhàn)機的爆炸效果等虚吟。不把這個做的盡善盡美寸认,也是為了看這篇文章的你能夠有自己的【Idea】。能夠?qū)W著自己去實現(xiàn)一種小小的功能串慰。

github地址:https://github.com/Alacazar99/Power_Plane

【如果簡書的朋友們有什么想法或者建議】歡迎留言偏塞。
【關(guān)于所使用的一些圖片素材】,歡迎留言邦鲫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末灸叼,一起剝皮案震驚了整個濱河市神汹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌古今,老刑警劉巖屁魏,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捉腥,居然都是意外死亡氓拼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門抵碟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桃漾,“玉大人,你說我怎么就攤上這事拟逮∏送常” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵唱歧,是天一觀的道長宪摧。 經(jīng)常有香客問我,道長颅崩,這世上最難降的妖魔是什么几于? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮沿后,結(jié)果婚禮上沿彭,老公的妹妹穿的比我還像新娘。我一直安慰自己尖滚,他們只是感情好喉刘,可當(dāng)我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著漆弄,像睡著了一般睦裳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上撼唾,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天廉邑,我揣著相機與錄音,去河邊找鬼倒谷。 笑死蛛蒙,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的渤愁。 我是一名探鬼主播牵祟,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抖格!你這毒婦竟也來了诺苹?” 一聲冷哼從身側(cè)響起咕晋,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎筝尾,沒想到半個月后捡需,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡筹淫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年站辉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片损姜。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡饰剥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出摧阅,到底是詐尸還是另有隱情汰蓉,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布棒卷,位于F島的核電站顾孽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏比规。R本人自食惡果不足惜若厚,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜒什。 院中可真熱鬧测秸,春花似錦、人聲如沸灾常。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钞瀑。三九已至沈撞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雕什,已是汗流浹背关串。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留监徘,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓吧碾,卻偏偏與公主長得像凰盔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子倦春,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容