【寫在前面】:本人在網(wǎng)上,似乎還沒有找到關于飛機大戰(zhàn)的完整程序。基本都是講了一些比較瑣碎的小知識點。那么本篇文章呢,是使用pygame 通過面向對象的方式實現(xiàn)的“飛機大戰(zhàn)”的完整程序的串講。
【文章特點】主要是夠【硬核】,夠【詳實】。文末附有完整的本項目所有內容的GitHub地址...
【特點介紹】
設置游戲背景;
設置游戲背景音樂;
設置了游戲名稱“外星人入侵”;
設置了積分裝置(左上角);
設置了玩家的生命值(右上角);
設置了兩種道具(powerup)和(liveup);
設置了我方戰(zhàn)機三種攻擊模式(吃了道具后,模型轉變(持續(xù)時間:5秒));
設置了敵機的隨機產(chǎn)生,以及敵機子彈的隨機發(fā)射;
我方戰(zhàn)機死亡后,游戲界面轉變;
我方戰(zhàn)機死亡后,可選擇【重新游戲】和【游戲結束】
......
【是否拭目以待了呢?】
先來看一下游戲的運行結果吧!
火力升級【power up】
火力升級【power up(MAX)】
【死亡后界面跳轉】
看著醬紫的界面,是否有玩一局的沖動呢?
再一次游戲【once again】
下面進入正題
先提一下:什么是游戲循環(huán)?
每個游戲的核心都是一個循環(huán),將其稱為“游戲循環(huán)”。這個循環(huán)一直在不斷運行,一遍又一遍地完成游戲工作所需的所有事情。每次循環(huán)顯示一次游戲當前畫面,稱為幀。
【本文主要有以下10個模塊】
App.py文件
hero.py文件
Npc.py文件
bullet.py文件
prop.py文件
hit.py文件
information.py文件
music.py文件
setting.py文件
setup.py文件
關于App.py文件
【作用如下】
啟動pygame;
確定游戲界面;
設置幀率
設置游戲名稱;
設置游戲背景;
設置游戲背景音樂;
【調用各個模塊來豐富游戲功能】
游戲關閉;
# @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))
# 設置幀率
clock = pygame.time.Clock()
bus = DataBus()
# 設置游戲名稱
pygame.display.set_caption("外星人入侵")
# 設置游戲背景
# 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))
# 設置游戲背景音樂
bgm = pygame.mixer.Sound(path.join(setting.snd_folder,'game_music.ogg'))
bgm.set_volume(0.5)
bgm.play(loops = -1)
# 調用
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)
# 讓渲染結果一次顯示
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()
# 更新坐標(核心)
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)
# 讓渲染結果一次顯示
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: # 游戲關閉
sys.exit()
App().start()
關于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)機復活影藏
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)機掛鉤的功能,都可在此模塊添加。
上面寫完了有關我方戰(zhà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
# 可設計其他軌跡
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
那么敵軍和我方英雄都存在了,接下來,我們介紹一下關于【子彈發(fā)射的問題】
bullet.py
【作用】:導入子彈、定義子彈初始位置、以及移動軌跡。
【代碼塊】
# @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__()
# 導入子彈
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__()
# 導入子彈
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__()
# 導入敵機子彈
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()
【解釋】:關于子彈這一塊,其實是最簡單的啦。子彈能發(fā)射了,那接下來就可以加載以下道具了。
關于prop.py文件
【分類】
- 火力提升道具
class Bulletprop(Sprite):
- 加血道具
class Bombprop(Sprite):
【小技巧】
class PropFactory:
通過調用【道具工廠類】來實現(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
【注意事項】:在設置道具產(chǎn)生時,會很容易出現(xiàn)滿屏的道具問題,如果自己在編程中有遇到,(請自行百度解決,或者參考本篇文章)。
【插播小廣告,嘻嘻】
【關于爆炸效果】:其實游戲設置中的爆炸效果,是由幾張圖片在極短的時間內閃過產(chǎ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
關于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" % self.score)
def draw_text(self, screen):
font1 = pygame.font.Font(16, True)
screen.blit(font1.render(u'當前得分:%d' % self.score, True,'red'), [20, 20])
【解釋一下】:這個文件就是拿來存儲數(shù)據(jù)的。
關于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()
關于setting.py文件
【作用】:設置工程目錄,并且設置游戲的邊界。
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)
總結一下
本篇文章主要是理一下使用pygame面向對象編程的思路,說一下本文中程序的缺點吧,此程序其實部分功能沒有實現(xiàn),例如:關于加血道具那一塊、以及我方戰(zhàn)機的爆炸效果等。不把這個做的盡善盡美,也是為了看這篇文章的你能夠有自己的【Idea】。能夠學著自己去實現(xiàn)一種小小的功能。
github地址:https://github.com/Alacazar99/Power_Plane
【如果簡書的朋友們有什么想法或者建議】歡迎留言。
【關于所使用的一些圖片素材】,歡迎留言。