效果圖:
開始界面:

游戲中:

gameover!

檔案結構:

- game_file:所有游戲邏輯相關的原始碼;
- rec:游戲相關的圖片、音樂資源;
- main.py: 游戲的啟動檔案;
所用到的圖片:

原始碼和檔案我會放到文末,感興趣的自取,
原始碼及注釋:
game_windows.py 游戲運行的主函式模塊,所有的頂層函式
# coding=utf-8
import time
import math
import sys
import pygame
from pygame.locals import *
from .resource_game import *
from . import setting as st
# 創建一個敵機機型的字典
dict_enemy = {'0': st.ENEMY_1, '1': st.ENEMY_2, '2': st.ENEMY_3}
fps1 = 0 # 開始按鈕計數器
fps2 = 0
fps6 = 0
ran3 = 0
num = 0 # 減慢移動的計數器
num_shower = 0 # 創建流星雨的幀數計數器和回圈次數的計數器
def main(): # 定義一個游戲運行的主函式
fps = 0 # 創建幀數計數器
fps4 = 0
fps5 = 0
f = 0
time1 = time.time()
buttons = () # 登陸界面按鈕的元組
buttons1 = () # 用來放結束界面的按鈕
pygame.init() # 系統初始化
# 創建一個全屏的螢屏物件
screen = pygame.display.set_mode((st.SCREEN_WIDTH, st.SCREEN_HIGHT), 0, 32)
pygame.display.set_caption("星河戰爭-天宇之游")
screen.get_rect() # 獲取螢屏矩形
# 創建一個敵機生成器
EnemyCreate = enemy_create(screen)
# 創建一個文字顯示效果生成器
Chars = chars(screen)
game_before(screen) # 加入游戲界面元素
st.GAME_BEFORE = True # 打開游戲前言開關
while True: # 開始游戲主回圈
mouse_x, mouse_y = pygame.mouse.get_pos() # 獲取游標的位置
if st.GAME_BEFORE: # 游戲進入前言
key_quit() # 檢測退出按鍵
if fps % st.FRAMES == 0: # 每過幀數顯示一個字
try:
next(Chars)
except StopIteration:
pass
fps += 1
if fps == st.WIN_OVER_FRAMES:
fps = 0 # 計數器還原
cls() # 清空子彈、洗掉、界面元素串列
buttons = game_load(screen) # 加入登陸界面元素,回傳三個按鈕的元組
bc(k2=True) # 打開游戲界面控制開關
elif st.SCREEN_CHANGE: # 游戲界面控制開關
# 界面按鈕遍歷檢測
mc(buttons, mouse_x, mouse_y)
key_load(screen, mouse_x, mouse_y) # 按鍵的控制函式
elif st.GAME_SAY: # 游戲前言
key_quit() # 檢測視窗退出按鍵
fps5 += 1
if fps5 == st.WIN_FONT_FRAMES:
bc(k4=True) # 打開戰斗界面控制開關
fps5 = 0 # 計數器還原
cls() # 清空子彈、洗掉、界面元素串列
beijing_1, hero_me = game_fight(screen) # 加入游戲元素
elif st.GAME_FIGHT: # 進入戰斗界面
# 創建一個開關字典用來指示上下左右方向
dict_key = {st.KEY_UP: 'up',
st.KEY_DOWN: 'down',
st.KEY_LEFT: 'left',
st.KEY_RIGHT: 'right'
}
buttons = key_fight(screen, hero_me) # 戰斗界面的控制函式
# 創建敵機隨機生成器
fps += 1
if st.GAME_MOSHI: # 判斷目前的游戲模式
ps = st.ENEMY_CREATE1
else:
ps = st.ENEMY_CREATE2
if fps % ps == 0: # 每回圈ps次執行
enemy_make(screen, EnemyCreate) # 敵機的生產控制
boss_make(screen) # boss飛機的產生
buff_make() # buff有效時間控制
move_make(dict_key, hero_me) # 通過開關字典控制飛機的移動
if st.ENEMY_START: # 在boss飛機出現后才檢測
if boss_die(): # boss是否死光
buttons1 = go_game_end(screen) # 加載結束界面得到按鈕
elif st.GAME_END: # 進入結束界面
# 界面按鈕遍歷檢測
mc(buttons1, mouse_x, mouse_y)
# 按鈕控制
buttons = key_end(screen, mouse_x, mouse_y)
# 計算幀數的速度
time2 = time.time()
fps4 += 1
if time2 - time1 >= 1:
time1 = time2
print(fps4 - f)
f = fps4
loop() # 元素回圈顯示和清空
pygame.display.update() # 更新螢屏
time.sleep(0.01) # 休眠0.01秒
def buttons_control(k1=False, k2=False,
k3=False, k4=False, k5=False):
"""所有相關界面的開關管理,全部默認關閉"""
st.GAME_BEFORE = k1 # 游戲進入前的界面控制開關
st.SCREEN_CHANGE = k2 # 登陸界面開關
st.GAME_SAY = k3 # 游戲歷史背景開關
st.GAME_FIGHT = k4 # 戰斗界面控制開關
st.GAME_END = k5 # 游戲結束界面控制開關
bc = buttons_control
def mouse_control(buttons, mouse_x, mouse_y):
"""界面按鈕的檢測函式"""
try:
for button in buttons: # 將游標的坐標傳入物件檢測開關是否應該打開
button.mouse_make(mouse_x, mouse_y)
except Exception as re:
print(re)
mc = mouse_control
def key_quit():
"""檢測是否按了退出鍵"""
for event in pygame.event.get(): # 鍵盤和滑鼠事件的監聽
if event.type == pygame.QUIT: # 檢測是否按了視窗的退出按鍵
sys.exit()
def key_end(screen, mouse_x, mouse_y):
"""游戲結束后統計界面的按鍵控制函式"""
for event in pygame.event.get(): # 鍵盤和滑鼠事件的監聽
# 檢測是否按了視窗的退出按鍵
if event.type == pygame.QUIT:
sys.exit()
# 判斷是否按下了滑鼠并且游標在按鈕范圍內
elif event.type == pygame.MOUSEBUTTONDOWN:
if 20 <= mouse_x <= 620:
print(mouse_x)
print(mouse_y)
if 200 <= mouse_y <= 285: # 按下了下一關按鈕
# st.GAME_MOSHI = True
pass
elif 350 <= mouse_y <= 435: # 按下了重新開始按鈕
bc(k2=True) # 打開登陸界面開關
cls() # 清空子彈、洗掉、界面元素串列
# 將敵機死亡的數量重新設定為0
EnemyPlane.set_enemy_die(True)
buttons = game_load(screen) # 加載登陸界面元素
return buttons
elif 500 <= mouse_y <= 585: # 按下了退出按鈕
exit()
def key_load(screen, mouse_x, mouse_y):
"""游戲開始前的設定界面的按鍵控制函式"""
for event in pygame.event.get(): # 鍵盤和滑鼠事件的監聽
# 檢測是否按了視窗的退出按鍵
if event.type == pygame.QUIT:
sys.exit()
# 判斷是否按下了滑鼠并且游標在按鈕范圍內
elif event.type == pygame.MOUSEBUTTONDOWN:
if 220 <= mouse_x <= 420:
print(mouse_x)
print(mouse_y)
if 300 <= mouse_y <= 340: # 按下了標準模式按鈕
st.GAME_MOSHI = True
elif 400 <= mouse_y <= 440: # 按下了困難模式按鈕
st.GAME_MOSHI = False
elif 200 <= mouse_y <= 240: # 按下了退出按鈕
exit()
# 按下了進入游戲按鈕
if 230 <= mouse_x <= 412 and 500 <= mouse_y <= 695:
print("執行成功")
cls() # 清空子彈、洗掉、界面元素串列
game_say(screen) # 加入歷史背景界面
bc(k3=True) # 游戲歷史背景開關打開
st.ENEMY_MAKE = True # 重新打開敵機生成器的開關
def key_fight(screen, hero_me):
"""一個戰斗界面的按鍵檢測控制函式 """
for event in pygame.event.get(): # 鍵盤和滑鼠事件的監聽
if event.type == pygame.QUIT: # 檢測是否按了視窗的退出按鍵
sys.exit()
elif event.type == pygame.KEYDOWN: # 判斷是否按下了鍵盤
# 是否按下W鍵或up鍵
if event.key == pygame.K_w or event.key == pygame.K_UP:
st.KEY_UP = True # 打開開關
# 是否按下s or down
elif event.key == pygame.K_s or event.key == pygame.K_DOWN:
# 打開向下移動的開關
st.KEY_DOWN = True
# 是否按下a or left
elif event.key == pygame.K_a or event.key == pygame.K_LEFT:
# 打開向左移動的開關
st.KEY_LEFT = True
# 是否按下d or right
elif event.key == pygame.K_d or event.key == pygame.K_RIGHT:
# 打開向右移動的開關
st.KEY_RIGHT = True
# 判斷是否按下了Q鍵
elif event.key == pygame.K_q:
bc(k2=True) # 打開登陸界面開關
cls() # 清空子彈、洗掉、界面元素串列
# 將敵機死亡的數量重新設定為0
EnemyPlane.set_enemy_die(True)
buttons = game_load(screen) # 加載登陸界面元素
return buttons
elif event.type == pygame.KEYUP: # 是否放開了鍵盤
if event.key == pygame.K_w or event.key == pygame.K_UP:
# 關閉開關
st.KEY_UP = False
elif event.key == pygame.K_s or event.key == pygame.K_DOWN:
# 關閉向下移動的開關
st.KEY_DOWN = False
elif event.key == pygame.K_a or event.key == pygame.K_LEFT:
# 關閉向左移動的開關
st.KEY_LEFT = False
elif event.key == pygame.K_d or event.key == pygame.K_RIGHT:
# 關閉向右移動的開關
st.KEY_RIGHT = False
if event.type == pygame.MOUSEBUTTONDOWN: # 判斷是否按下了滑鼠
if hero_me.get_fire(): # 如果發射子彈的開關是打開的
hero_me.fire() # 將子彈串列的元素加入顯示串列
def go_game_end(screen):
"""游戲結束的界面控制"""
global fps6
if st.ENEMY_START and st.BOSS_DIE: # 如果boss產生了但又死光
fps6 += 1 # 計數器啟動
if fps6 == 300:
cls() # 清空子彈、洗掉、界面元素串列
buttons = game_end(screen) # 加載結束界面
bc(k5=True) # 打開結束界面開關
st.ENEMY_START = False # 關閉boss檢測開關
st.BOSS_DIE = False # 關閉boss死光開關
return buttons
def game_end(screen):
"""對方大boss死亡后出現結束界面"""
# 創建背景圖片
Factory.beijing_act(0, 0, screen, st.MY_TEXT)
# 創建退出游戲按鈕
button_4 = Factory.button1_act(20, 500, screen, st.BUTTON_D)
# 創建重新開始按鈕
button_5 = Factory.button1_act(20, 350, screen, st.BUTTON_E)
# 創建下一關按鈕
button_6 = Factory.button1_act(20, 200, screen, st.BUTTON_F)
# 創建積分界面畫布
Factory.beijing_act(640, 0, screen, st.IMAGE_BJ)
integ(screen) # 創建統計資訊標簽
return button_4, button_5, button_6
def game_say(screen):
"""顯示一段文字"""
# 創建一個星空背景
Factory.beijing_act(0, 0, screen, st.MY_TEXT)
text = "公元2300年,外星人入侵,這是人類的最后時刻!"
Factory.script_act(20, 300, screen, text, 30, num=3,
filename=st.SCRIPT, bg_script=(255, 255, 255))
def enemy_make(screen, EnemyCreate):
"""敵機生成控制函式"""
if st.ENEMY_MAKE: # 生成器開關默認是打開的
enemy_plane = None
stony = None
try:
# 若未達到敵機死亡的上限
if EnemyPlane.get_enemy_die() < st.ENEMY_NUM:
enemy_plane = next(EnemyCreate) # 敵機生成
stony = stony_creat(screen) # 隕石生成
else:
st.BOSS_CREAT = True
st.ENEMY_MAKE = False # 關閉生成器的開關
except StopIteration:
enemy_plane = None
stony = None
try:
if enemy_plane: # 如果不為空
screen_list.append(enemy_plane) # 加入顯示串列
if stony: # 如果不為空
screen_list.append(stony)
except Exception as re:
print(re)
def boss_make(screen):
"""敵機boss的生成控制"""
global fps2
if st.BOSS_CREAT: # 創建boss
fps2 += 1
# print(fps2)
if fps2 == 100:
for i in range(st.BOSS_NUM):
Factory.enemy_act(300, -200, screen, dict_enemy['2'])
fps2 = 0
st.BOSS_CREAT = False # 關閉創建boss的開關
st.ENEMY_START = True # 打開檢測boss飛機的開關
def boss_die():
"""所有的boss是否死亡檢測"""
boss_button = True # 開始默認打開的
for ele in screen_list: # 如果遍歷一次后發現還存在boss飛機,則關閉
if isinstance(ele, BossEnemy):
boss_button = False
if boss_button: # 如果沒有boss飛機了
st.BOSS_DIE = True
return st.BOSS_DIE
def buff_make():
"""各種buff子彈有效時間計數函式"""
if st.GOD_BUFF: # 金幣子彈buff出現,大于500幀數后消失
st.BUFF_TIME += 1
if st.BUFF_TIME >= 500:
st.GOD_BUFF = False
if st.LASER_BUFF: # 激光子彈buff出現,大于500幀數后消失
st.LASER_TIME += 1
if st.LASER_TIME >= 500:
st.LASER_BUFF = False
if st.RAN_BUFF: # 隨機子彈buff出現
st.RAN_TIME += 1
if st.RAN_TIME >= 500:
st.RAN_BUFF = False
def move_make(dict_key, hero_me):
"""控制飛機移動的方法"""
global num
for item in dict_key.items(): # 通過開關控制我方飛機移動
if item[0]:
# print(item[0])
num += 1
if num > 2:
hero_me.hreo_move(item[1])
num = 0
def clear_list():
"""清除相關串列中的元素函式"""
bullet_list.clear() # 清除發射出的串列
bullet_del.clear() # 清空該洗掉的串列
screen_list.clear() # 清空界面元素
cls = clear_list
def loop():
"""抽取主函式中回圈的代碼"""
screen_list.extend(bullet_list) # 將敵機產生的子彈加入顯示串列
# print(len(bullet_list))
bullet_list.clear() # 清除串列
for bu in bullet_del: # 從顯示串列中洗掉應該消失的子彈
if bu in screen_list:
screen_list.remove(bu)
bullet_del.clear() # 清空串列
for element in screen_list: # 回圈顯示所有物件,默認多型
element.draw()
# print(len(screen_list))
# print(screen_list)
def game_load(screen):
"""創建游戲登陸界面需要的影像"""
# 創建開始界面背景
Factory.beijing_act(0, 0, screen, st.BEIJING_2)
# 創建積分界面
Factory.beijing_act(640, 0, screen, st.IMAGE_BJ)
# 創建游戲操作說明
Factory.beijing_act(120, 50, screen, st.FUNCTION_1)
# 創建標準模式按鈕
button1 = Factory.button1_act(220, 300, screen, st.BUTTON_A)
# 困難模式按鈕
button2 = Factory.button1_act(220, 400, screen, st.BUTTON_B)
# 退出按鈕
button3 = Factory.button1_act(220, 200, screen, st.BUTTON_C)
# 生產一個開始按鈕并加入顯示串列
Factory.button_act(230, 500, screen, st.BUTTON_START)
integ(screen) # 創建統計資訊標簽
Factory.music_act(st.START_MUSIC) # 游戲的開始音樂
# print(len(screen_list))
# print(len(list_game))
return button1, button2, button3
def integ(screen):
"""創建游戲統計資訊的顯示文字"""
# 取得一個亂數
ran = random.randint(0, 4)
# 創建角色頭像標簽
Factory.beijing_act(640, 0, screen, st.BOY_IMAGE[ran])
# 創建分數標簽
Factory.script_act(655, 325, screen, "分數", 50,
filename=st.SCRIPT, bg_script=(0, 255, 255))
# 創建角色標簽
Factory.script_act(655, 150, screen, "角色", 50,
filename=st.SCRIPT, bg_script=(0, 255, 255))
# 創建排名標簽
Factory.script_act(655, 500, screen, "排名", 50,
filename=st.SCRIPT, bg_script=(0, 255, 255))
def game_before(screen):
"""創建游戲之前的界面影像"""
# 有主背景圖片、飛機大戰題目圖片、游戲發言圖片、作者圖片、積分界面圖片
beijing_before = [[0, 0, st.MY_XING],
[100, 200, st.MY_READ],
[450, 380, st.MY_SELF],
[640, 0, st.IMAGE_BJ]
]
# "保護地球人人有責"的坐標串列
script_before = ["保", "護", "地", "球", "人", "人", "有", "責"]
for i, bj in enumerate(beijing_before):
# 創建所有界面元素并添加
Factory.beijing_act(bj[0], bj[1], screen, bj[2])
for j, sb in enumerate(script_before):
# 創建文字物件
Factory.script_act(660, 10 + j * 83, screen, sb, 80, filename=st.SCRIPT1)
Factory.music_act(st.START_MUSIC) # 創建并播放音樂
def chars(screen):
"""顯示“星河戰爭“四個字的動態效果生成器"""
list_char = [(120, "星"), (220, "河"), (320, "戰"), (420, "爭")]
for tp in list_char:
# 創建一個文字
script = Factory.script_act(tp[0], 100, screen, tp[1], 120, num=1, color=(0, 0, 255))
# 創建一個爆炸
Factory.any_blast(script, "big", 2)
yield script
def game_fight(screen):
"""創建游戲戰斗需要的影像并加載"""
# 創建一個戰斗界面背景
beijing_1 = Factory.beijing_act(0, 0, screen, st.BEIJING_1)
# 創建積分界面
Factory.beijing_act(640, 0, screen, st.IMAGE_BJ)
integ(screen) # 創建統計資訊標簽
# 創建我方飛機并設定初始位置
hero_me = Factory.hreo_act(270, 600, screen, st.HREO_1)
hero_me.button_fire = True # 將我方飛機的開火開關打開
return beijing_1, hero_me
def enemy_create(screen):
"""敵機的生成器,使用了迭代器的方式"""
i = 0
while i < 500:
ran1 = random.randint(0, 2) # 生成敵機的 出生位置
ranx = random.randint(0, 20) # 調整敵機生成的概率
if ranx <= 14:
ran2 = 0
else:
ran2 = 1
# 創建敵方飛機
enemy_plane = EnemyPlane(100 + ran1 * 200, -100, screen, dict_enemy[str(ran2)])
yield enemy_plane
i += 1
# st.BOSS_CREAT = True
def stony_creat(screen):
"""隕石生成器"""
ran1 = random.randint(0, 2) # 生成出生位置
ran2 = random.randint(0, 10) # 設定出生概率
if ran2 <= 2: # 20%的出生概率
stony_one = Stony(250 + ran1 * 100, -100, screen, st.STONY_BUFF)
return stony_one
else:
return False
def delay_time(delay, time0=time.time()):
"""一個延時函式"""
time1 = time.time()
if time1 - time0 >= delay:
return True
else:
return False
if __name__ == '__main__':
pass
resource_game.py 所有的元素類和功能類模塊
import random
import pygame
from . import setting as st
from game_file.tool import *
screen_list = [] # 創建一個顯示串列全域
bullet_list = [] # 創建一個顯示子彈的全域串列
bullet_del = [] # 創建一個該洗掉的元素串列
num1 = 0 # 創建一個爆炸效果的計數器
class Obj(object):
"""創建一個父類1"""
# 構造位置屬性
def __init__(self, x, y, screen, filename):
self.x = x
self.y = y
self.screen = screen
self.name = filename
self.image_1 = pygame.image.load_extended(self.name) # 加載背景圖片
self.rect = self.image_1.get_rect() # 獲取圖片的外接矩形
def draw(self): # 設定繪制的功能
pass
class ScriptBase(Obj):
"""創建一個文字基類"""
def __init__(self, x, y, screen, script, size,
filename=st.SCRIPT, color=(255, 255, 255),
bool_sc=True, bg_script=None):
"""
建構式,初始化文字的位置x,y,顯示的視窗screen,文字script,
字體大小size,字體的TTF檔案filename,字體的顏色color,默認開啟抗鋸齒True,
不定長引數為是否設定字的背景bg_script
"""
self.x = x
self.y = y
self.screen = screen
self.script = script
self.size = size
self.name = filename
self.color = color
self.bool_sc = bool_sc
self.bg_script = bg_script
def sc_act(self):
"""創建文字的函式"""
# 創建一個文字物件
my_font = pygame.font.Font(self.name, self.size)
# 檔案物件的顯示引數
text_surface = my_font.render(self.script, self.bool_sc,
self.color, self.bg_script)
return text_surface
def draw(self):
text = self.sc_act()
# 顯示創建的文字物件
self.screen.blit(text, (self.x, self.y))
def change_size(self):
"""文字的效果,如大小閃爍,移動變化等"""
pass
def change_color(self):
pass
class ScriptNew(ScriptBase):
"""創建基本的文字"""
def __init__(self, x, y, screen, script, size, *args):
super().__init__(x, y, screen, script, size, *args)
# 創建一個文字物件
self.my_font = pygame.font.Font(self.name, self.size)
# 檔案物件的顯示引數
self.text_surface = self.my_font.render(self.script, self.bool_sc,
self.color, self.bg_script)
def draw(self):
# 顯示創建的文字物件
self.screen.blit(self.text_surface, (self.x, self.y))
class ScriptLong(ScriptBase):
"""創建大段依次顯示的文字"""
def __init__(self, x, y, screen, script, size, *args):
super().__init__(x, y, screen, script, size, *args)
# 創建一個文字物件
self.my_font = pygame.font.Font(self.name, self.size)
self.fps = 0
# 單個文字物件
self.t = None
# 創建一個文字影像串列
self.text = []
for x in range(len(self.script)): # 創建單個的文字影像
t = self.my_font.render(self.script[:x+1], self.bool_sc,
self.color, self.bg_script)
self.text.append(t)
self.it = iter(self.text) # 獲得迭代器
def draw(self):
self.fps += 1
if self.fps % 20 == 0: # 每隔5幀數顯示一個文字
try:
self.t = next(self.it)
except StopIteration:
pass
if self.t: # 如果物件不為空
self.screen.blit(self.t, (self.x, self.y))
class ScriptMove(ScriptBase):
"""創建一個的大小變化和閃爍效果"""
def __init__(self, x, y, screen, script, size, *args):
super().__init__(x, y, screen, script, size, *args)
# 創建一個閃爍速度的計數器
self.fps = 0
# 字體尺寸最小
self.least = 80
# 字體最大
self.max = size
# 設定變化的顏色
self.list_color = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]
def draw(self):
self.fps += 1
super().draw()
if self.fps >= 20: # 20幀數后開始變化
self.change_size() # 改變文字大小
self.change_color() # 改變文字顏色
def change_size(self):
"""重寫父類的方法"""
# print("change執行了")
if self.fps % 2 == 0 and self.size > self.least: # 每過5幀數執行一次
self.size -= 2
self.x += 1
self.y += 1
# if self.size <= self.least: # 達到最小時還原大小
# self.size = self.max
def change_color(self):
"""文字顏色紅綠藍三色變化"""
if self.fps % 5 == 0:
ran = random.randint(0, 2)
self.color = self.list_color[ran]
class ScriptEnd(ScriptBase):
"""創建一個文字由小到大的效果"""
def __init__(self, x, y, screen, script, size, *args):
super().__init__(x, y, screen, script, size, *args)
# 創建一個閃爍速度的計數器
self.fps = 0
def change_size(self):
if self.fps % 2 == 0 and self.size < 180: # 每過5幀數執行一次
self.size += 3
self.x -= 1
self.y -= 1
def draw(self):
self.fps += 1
super().draw()
self.change_size()
class ButtonGame(Obj):
"""創建一個游戲開始按鈕"""
def __init__(self, x, y, screen, list_image):
self.x = x
self.y = y
self.screen = screen
self.images = [] # 按鈕的圖片群
self.fps = 0 # 按鈕顯示的計數器
self.ran = 0 # 圖片下標
for image in list_image: # 所有圖片全部加載
self.images.append(pygame.image.load_extended(image))
def draw(self):
self.fps += 1
if self.fps % 10 == 0: # 每過15幀顯示一張按鈕圖片
self.ran += 1
if self.ran > 3:
self.ran = 0
self.screen.blit(self.images[self.ran], (self.x, self.y)) # 回圈顯示背景圖片
class ModeButton(ButtonGame):
"""創建各種功能按鈕"""
def __init__(self, x, y, screen, list_image):
super().__init__(x, y, screen, list_image)
self.image_size = []
self.button_make = False # 創建一個按鈕圖片替換的開關
for image1 in self.images:
self.image_size.append(image1.get_rect()) # 獲取圖片的外接矩形
def mouse_make(self, mouse_x, mouse_y):
"""根據游標位置控制顯示的方法"""
# 如果游標的坐標在圖片按鈕的范圍之內
if self.x <= mouse_x <= self.x + self.image_size[0].w \
and self.y <= mouse_y <= self.y + self.image_size[0].h:
self.button_make = True # 顯示黃色的圖片
else:
self.button_make = False # 顯示綠色的圖片
def draw(self): # 重寫顯示方法
try:
if not self.button_make: # 如果替換開關是關閉的
self.screen.blit(self.images[0], (self.x, self.y)) # 顯示綠色的圖片
else:
self.screen.blit(self.images[1], (self.x, self.y)) # 顯示黃色的圖片
except Exception as re:
print(re)
class Beijing(Obj):
"""創建一個背景類"""
def __init__(self, x, y, screen, filename):
super().__init__(x, y, screen, filename)
self.num = -2000 # 設定圖片最初位置
def draw(self): # 重寫父類的方法
if self.name == st.BEIJING_1: # 如果是游戲戰斗背景圖
self.y = self.num
self.num += st.BEIJING_SPEED # 使得背景圖移動
if self.num > -10:
self.num = -2000
self.screen.blit(self.image_1, (self.x, self.y)) # 回圈顯示背景圖片
class Factory(object):
""""創建一個萬能的工廠,能夠生產并自動將其添加到顯示串列"""
@staticmethod
def beijing_act(x, y, screen, filename):
"""創造并顯示靜態的圖片"""
beijing = Beijing(x, y, screen, filename)
screen_list.append(beijing) # 將背景添加到顯示串列
return beijing
@staticmethod
def script_act(x, y, screen, script, size,
filename=st.SCRIPT2, num=0, color=(255, 0, 0),
bool_sc=True, bg_script=None):
"""創建一個柔性化制造各種效果文字的工廠"""
ls = [x, y, screen, script, size,
filename, color, bool_sc, bg_script
]
if num == 0: # 如果選擇為0則創建基本的文字
script = ScriptNew(*ls)
elif num == 1: # 如果選擇為1則創建大小變化的文字
script = ScriptMove(*ls)
elif num == 2:
script = ScriptEnd(*ls) # 創建小變大的文字
elif num == 3:
script = ScriptLong(*ls) # 創建長文字
screen_list.append(script) # 添加文字到顯示串列
return script
@staticmethod
def button1_act(x, y, screen, list_image):
"""創建普通按鈕"""
button = ModeButton(x, y, screen, list_image)
screen_list.append(button)
return button
@staticmethod
def button_act(x, y, screen, list_image):
"""按鈕生成器"""
button = ButtonGame(x, y, screen, list_image)
screen_list.append(button)
@staticmethod
def star_act(x, y, screen, filename):
"""流星雨生成器"""
show = Star(x, y, screen, filename)
screen_list.append(show)
@staticmethod
def hreo_act(x, y, screen, filename):
"""生產我方的飛機"""
my_plane = Hreo(x, y, screen, filename)
screen_list.append(my_plane)
return my_plane
@staticmethod
def any_blast(target1, blast_name, btitem=1):
"""爆炸的公共方法"""
if btitem == 1: # 如果選擇短爆炸
bst = SmallBlast(target1, blast_name) # 創建一個爆炸的物件
else: # 長爆炸
bst = LongBlast(target1, blast_name) # 創建一個爆炸的物件
screen_list.append(bst) # 將爆炸效果添加到顯示串列
@staticmethod
def boss_blast(element):
"""boss飛機爆炸的公共方法"""
for i in range(0, 4):
ran = random.randint(0, 4) # 隨機生成位置
bst = LongBlast(element, 'big', -16 + 40*ran, -150 + i*40)
screen_list.append(bst)
@staticmethod
def buff_act(ele, prob):
"""buff生成方法"""
ran = random.randint(0, 10) # 有一定概率出現buff
if ran < prob: # 調整概率
buff = BuffBullet1(ele.x, ele.y, ele.screen, random.choice(st.LIST_BUFF))
screen_list.append(buff) # 添加到顯示串列
@staticmethod
def music_act(name):
"""音樂播放方法"""
music1 = MusicThis(name)
music1.play_music()
del music1
@staticmethod
def enemy_act(x, y, screen, filename):
"""創建一個敵方飛機的生產線"""
if filename == st.ENEMY_3: # 如果生產的是敵方boss飛機
enemy = BossEnemy(x, y, screen, filename)
else: # 如果是其他的飛機
enemy = EnemyPlane(x, y, screen, filename)
screen_list.append(enemy) # 添加到顯示串列
return enemy
@staticmethod
def bullet_act(element):
bullets = [] # 子彈初始值為空
"""生產子彈"""
if isinstance(element, Hreo): # 如果發射子彈的是我方
if st.GOD_BUFF: # 如果金幣buff開關打開
bullet = GodBullet(element, 0, 0)
bullets.append(bullet)
elif st.LASER_BUFF: # 如果是激光子彈開關打開
for i in range(-1, 2): # 創建3顆子彈
bullet = LaserBullet(element, i*40, 0)
bullets.append(bullet)
elif st.RAN_BUFF: # 如果是隨機運動的子彈
for i in range(0, 2):
bullet = RanBullet(element, -32 + i*64, 0)
bullets.append(bullet)
else: # 螺旋子彈
bullet = LuoXBullet(element)
bullets.append(bullet)
elif isinstance(element, EnemyPlane): # 若果放射子彈的是敵方
if isinstance(element, BossEnemy): # 如果是boss飛機
for i in range(-1, 2): # 創建3顆子彈
bullet = EneBullet(element, i*32, 0)
bullets.append(bullet)
else: # 如果是普通飛機
bullet = EneBullet(element, 0, 0)
bullets.append(bullet)
else:
bullet = EneBullet(element, 0, 0)
bullets.append(bullet)
if bullets: # 如果不為空
bullet_list.extend(bullets)
class Hreo(Obj):
"""創建一個我方飛機類"""
def __init__(self, x, y, screen, filename):
super().__init__(x, y, screen, filename)
self.speed = st.HERO_SPEED # 飛機的速度
self.__blood = st.HERO_BLOOD # 設定血量
self.button_fire = False # 一個控制開火的開關
@property
def blood(self):
"""創建血量訪問方法"""
return self.__blood
@blood.setter
def blood(self, new_blood):
"""血量設定方法"""
self.__blood = new_blood
def __del__(self):
self.button_fire = False # 關閉開火
print("hero洗掉執行了")
def get_fire(self): # 設定類方法訪問和修改類屬性
return self.button_fire
def set_fire(self, bools):
self.button_fire = bools
def fire(self):
"""發射子彈"""
Factory.music_act(st.FIRE_MUSIC) # 播放音樂
Factory.bullet_act(self) # 呼叫工廠產生子彈并發射出去
def hreo_move(self, strx):
"""飛機移動的方法"""
if strx == 'up': # 向上移動
self.y -= self.speed
elif strx == 'down': # 向下移動
self.y += self.speed
elif strx == 'left': # 向左移動
self.x -= self.speed
elif strx == 'right': # 向右移動
self.x += self.speed
else:
pass
def ishit(self, ele):
"""飛機的碰撞檢測執行函式"""
# 忽略所有子彈、背景、爆炸圖、本身、文字
if isinstance(ele, (Beijing, Blast, Hreo, Bullet, ScriptBase)):
# print("這是背景或本身")
return False
result = any_hit(self, ele) # 呼叫公共方法檢測碰撞
if result:
if isinstance(ele, EnemyPlane): # 如果碰到敵方飛機
# print("撞上了!")
if ele.name == st.ENEMY_1:
self.__bloods(ele, 50, "big")
elif ele.name == st.ENEMY_2:
self.__bloods(ele, 100, "big", btm=2)
elif ele.name == st.ENEMY_3:
self.blood -= 5 # 自身血量減少
ele.blood -= 5 # boss血量減少5
if isinstance(ele, BuffBullet1): # 如果碰到的是buff
bullet_del.append(ele) # buff1消失
ele.buff_creat() # 呼叫方法產生效果
if isinstance(ele, Stony): # 如果碰到的是隕石
self.__bloods(ele, 500, "big", 2)
def __bloods(self, ele, blood_r, name, btm=1):
"""檢測血量"""
self.__blood -= blood_r # 自身血量減少
Factory.any_blast(ele, name, btm) # 敵方飛機爆炸并洗掉
bullet_del.append(ele) # 洗掉敵方飛機
def draw(self): # 重寫父類的方法
self.screen.blit(self.image_1, (self.x, self.y)) # 顯示我方飛機
for ele in screen_list: # 遍歷顯示串列檢測碰撞
# print(ele)
self.ishit(ele)
self.serc() # 越界和血量檢測
def serc(self):
"""血量和越界檢測"""
if self.__blood <= 0: # 如果血量少于0洗掉自己
Factory.any_blast(self, 'big', 2) # 產生爆炸
self.button_fire = False # 關閉開火開關
# 創建“你輸了”文字
Factory.script_act(70, 250, self.screen, "你輸了", 100, num=2)
bullet_del.append(self)
# 越界檢測
if self.x <= 0:
self.x = 0
elif self.x >= 540:
self.x = 540
if self.y <= 0:
self.y = 0
elif self.y >= 600:
self.y = 600
class Bullet(Obj):
"""創建子彈類"""
def __init__(self, element):
self.screen = element.screen
self.ele = element
self.name = None
self.image_bullet = None
self.bullet_speed = None
self.__blood = 50 # 設定血量
def bullet_init(self, x1, y1, speed):
"""不同子彈初始化引數的函式"""
self.x = self.ele.x + x1
self.y = self.ele.y + y1
self.image_bullet = pygame.image.load_extended(self.name) # 加載背景圖片
self.rect = self.image_bullet.get_rect() # 獲得圖片的尺寸
self.bullet_speed = speed # 設定子彈的速度
@property
def blood(self):
"""創建血量訪問方法"""
return self.__blood
@blood.setter
def blood(self, new_blood):
"""血量設定方法"""
self.__blood = new_blood
def draw(self):
"""
修改數字,不要使用計數器來降低子彈的速度,因為計數器作為一個公共變數,
不同的子彈資料會造成干擾,導致子彈移動出現問題
"""
self.screen.blit(self.image_bullet, (self.x, self.y)) # 繪制子彈
for ele in screen_list: # 遍歷顯示串列檢測碰撞
# print(ele)
self.ishit(ele)
self.bullet_move() # 子彈的移動
def bullet_move(self):
"""子彈移動的函式"""
if isinstance(self.ele, Hreo): # 判斷是那種飛機的子彈
self.y -= self.bullet_speed
else:
self.y += self.bullet_speed
self.bullet_out() # 子彈越界檢測
def bullet_out(self):
"""判斷子彈越界"""
if self.y < -30 or self.y > 704: # 判斷子彈是否越界
bullet_del.append(self)
def ishit(self, ele):
"""子彈的碰撞檢測函式"""
# 忽略掉子彈本身、背景、爆炸、buff子彈
if ele is self or isinstance(ele, (Beijing, Blast, BuffBullet1, ScriptBase)):
# print("這是背景或本身")
return False
# 若果是我方飛機產生的子彈或流星雨產生的子彈
if isinstance(self.ele, (Hreo, Star)):
result = any_hit(self, ele)
# 忽略本類物件
if isinstance(ele, Bullet) and isinstance(ele.ele, (Hreo, Star)):
return False
else:
if result: # 發生了碰撞
# print("撞上了")
# 如果碰撞到敵方子彈
if isinstance(ele, Bullet) and isinstance(ele.ele, EnemyPlane):
self.hit_result(ele, "xiao") # 呼叫效果函式
# 如果碰到的是敵方小飛機
elif ele.name == st.ENEMY_1 and isinstance(ele, EnemyPlane):
self.hit_result(ele) # 呼叫效果函式
# 如果碰到的是敵方大飛機
elif ele.name == st.ENEMY_2 and isinstance(ele, EnemyPlane):
self.hit_result(ele, "big", 2)
# 如果是boss飛機
elif ele.name == st.ENEMY_3 and isinstance(ele, EnemyPlane):
self.hit_result(ele, 'big', 2)
# 如果碰到的是隕石
elif isinstance(ele, Stony):
self.hit_result(ele, "big", 2)
Factory.buff_act(ele, 1) # 每次碰撞爆buff概率為10%
else: # 如果是敵方飛機產生的子彈
result = any_hit(self, ele)
if not isinstance(ele, Hreo): # 忽略除了英雄飛機外的所有物件
return False
else:
if result: # 發生了碰撞
# print("撞上了")
self.hit_result(ele, "big", 2) # 呼叫效果函式
def hit_result(self, ele, blast_name="big", btm=1):
"""碰撞后產生的效果函式"""
if self.__blood >= ele.blood: # 如果子彈血量大于對方血量
self.__blood -= ele.blood
ele.blood = -1
else:
ele.blood -= self.blood
self.__blood = 0
bullet_del.append(self)
if ele.blood > 0: # 若果對方血量還大于0,產生小爆炸
Factory.any_blast(ele, 'xiao') # 產生一個小短爆炸效果
else: # 如果對方血量小于0,產生大爆炸,同時洗掉對方飛機
if isinstance(ele, BossEnemy): # 如果對方是boss飛機
# 創建“你贏了”文字
Factory.script_act(70, 250, self.screen, "你贏了", 100, num=2)
else:
Factory.any_blast(ele, blast_name, btm)
bullet_del.append(ele) # 將對方添加到洗掉串列
if isinstance(ele, EnemyPlane): # 如果是敵機被打爆,則敵機死亡計數器加1
ele.set_enemy_die()
if not isinstance(ele, Bullet): # 如果對方不是子彈才能產生buff
if isinstance(ele, Stony): # 對方隕石爆炸
Factory.buff_act(ele, 5) # 爆buff概率為30%
else: # 其他的爆炸
Factory.buff_act(ele, 3) # 爆buff概率為20%
class RanBullet(Bullet):
"""創建隨機跳彈"""
def __init__(self, element, x1, y1):
super().__init__(element)
self.name = st.RAN_BULLET # 得到子彈的圖片作為名字
self.__blood = 50 # 設定血量
self.fps = 0 # 子彈移動換方向的時間
self.ran = 0 # 子彈左右的方向
if isinstance(self.ele, Hreo): # 我方飛機
self.bullet_init(48 + x1, -64 + y1, st.BULLET_SPEED+2)
def bullet_move(self):
"""重寫子彈移動的函式"""
if isinstance(self.ele, Hreo): # 判斷是那種飛機的子彈
self.y -= self.bullet_speed # 向上運動
self.fps += 1
if self.fps % 10 == 0: # 每10幀數改變方向
self.ran = random.randint(0, 1)
if self.ran == 0:
self.x -= self.bullet_speed - 5
else:
self.x += self.bullet_speed - 5
self.bullet_out() # 子彈越界檢測
class GodBullet(Bullet):
"""創建一個金幣子彈類"""
def __init__(self, element, x1, y1):
super().__init__(element)
self.name = st.GOD_BULLET # 得到子彈的圖片作為名字
self.__blood = 200 # 設定血量
if isinstance(self.ele, Hreo): # 我方飛機
self.bullet_init(25 + x1, -30 + y1, st.BULLET_SPEED+2)
class LaserBullet(Bullet):
"""創建激光子彈"""
def __init__(self, element, x1, y1):
super().__init__(element)
self.name = st.LASER_BULLET # 得到子彈的圖片作為名字
self.__blood = 100 # 設定血量
if isinstance(self.ele, Hreo): # 我方飛機
self.bullet_init(40 + x1, -90 + y1, st.BULLET_SPEED)
class LuoXBullet(Bullet):
"""創建螺旋子彈"""
def __init__(self, element):
super().__init__(element)
self.name = st.LUOXUAN_BULLET # 得到子彈的圖片作為名字
self.__blood = 50 # 設定血量
if isinstance(self.ele, Hreo): # 我方飛機
self.bullet_init(42, -20, st.BULLET_SPEED)
class EneBullet(Bullet):
"""創建普通子彈"""
def __init__(self, element, x1, y1):
super().__init__(element)
self.name = st.MY_BULLET # 得到子彈的圖片作為名字
self.__blood = 50 # 設定血量
if isinstance(self.ele, EnemyPlane): # 如果是敵機
if self.ele.name == st.ENEMY_1: # 敵方小飛機
self.bullet_init(16 + x1, 32 + y1, st.BULLET_SPEED - 3)
elif self.ele.name == st.ENEMY_2: # 敵方中型飛機
self.bullet_init(24 + x1, 64 + y1, st.BULLET_SPEED - 3)
elif self.ele.name == st.ENEMY_3: # 敵方boss飛機
self.bullet_init(72 + x1, 220 + y1, st.BULLET_SPEED)
if isinstance(self.ele, Star): # 如果是流星雨
self.bullet_init(x1, y1, st.BULLET_SPEED)
class Star(Obj):
"""一個下流星雨的類"""
__button1 = None # 創建控制單例模式開關
__button2 = True
def __init__(self, x, y, screen, filename):
if self.__button2:
super().__init__(x, y, screen, filename)
self.fps = 0 # 創建時間計數
self.num_shower = 0 # 創建流星雨下的次數計數
# self.button_star = False # 下雨的開關
self.__button2 = False # 保證只有一次初始化
def __new__(cls, *args, **kwargs):
if not cls.__button1:
cls.__button1 = Obj.__new__(cls)
return cls.__button1
def draw(self):
if st.SHOWER_BUFF:
self.fps += 1
if self.fps % 60 == 0:
self.num_shower += 1
for i in range(10):
bullet_new = EneBullet(self, i * 64, -32)
screen_list.append(bullet_new) # 添加到顯示串列
# 五次后關閉流星雨
if self.num_shower > 3:
self.fps = 0
self.num_shower = 0
st.SHOWER_BUFF = False
class Blast(Obj):
"""創建一個爆炸效果類"""
def __init__(self, ele, name):
self.num1 = 0
self.screen = ele.screen
self.name = name
self.image_blast = []
# 如果是敵機的子彈爆炸
if isinstance(ele, Bullet) and not isinstance(ele.ele, Hreo):
self.x = ele.x - 56
self.y = ele.y - 32
# 如果是敵方的小飛機爆炸
elif ele.name == st.ENEMY_1 and isinstance(ele, EnemyPlane):
self.x = ele.x - 40
self.y = ele.y - 40
# 如果是敵方的中型飛機爆炸
elif ele.name == st.ENEMY_2 and isinstance(ele, EnemyPlane):
self.x = ele.x - 32
self.y = ele.y - 32
# 如果是敵方的boss飛機爆炸
elif ele.name == st.ENEMY_3 and isinstance(ele, BossEnemy):
self.x = ele.x + 16
self.y = ele.y + 150
# 如果是我方飛機爆炸
elif ele.name == st.HREO_1 and isinstance(ele, Hreo):
self.x = ele.x - 14
self.y = ele.y
# 如果是文字
elif isinstance(ele, ScriptBase):
self.x = ele.x
self.y = ele.y
else:
self.x = ele.x - 32
self.y = ele.y - 32
Factory.music_act(st.BLAST_MUSIC) # 播放音樂
def draw(self):
pass
def numx(self, n):
"""改變爆炸的大小"""
if self.num1 > n:
self.num1 = 0
bullet_del.append(self) # 爆炸完成后洗掉本身
class SmallBlast(Blast):
"""創建短爆炸"""
def __init__(self, ele, name):
super().__init__(ele, name)
for image in st.LIST_BLAST: # 加載爆炸圖片資源
self.image_blast.append(pygame.image.load_extended(image))
def draw(self): # 重寫爆炸繪制方法
self.screen.blit(self.image_blast[self.num1], (self.x, self.y))
self.num1 += 1
if self.name == "xiao":
self.numx(3)
elif self.name == "big":
self.numx(7)
class LongBlast(Blast):
"""創建長爆炸"""
def __init__(self, ele, name, x=0, y=0):
super().__init__(ele, name)
self.x += x
self.y += y
for image in st.LIST_BLAST_BIG: # 加載爆炸圖片資源
self.image_blast.append(pygame.image.load_extended(image))
def draw(self):
"""繪制長爆炸"""
self.screen.blit(self.image_blast[self.num1], (self.x, self.y))
self.num1 += 1
if self.name == 'xiao':
self.numx(7)
elif self.name == 'big':
self.numx(13)
class EnemyPlane(Obj):
"""創建一個敵方的飛機類1"""
__enemy_die = 0 # 創建一個類屬性記錄殺死的敵機數量
@classmethod
def get_enemy_die(cls): # 訪問類屬性方法
return cls.__enemy_die
@classmethod
def set_enemy_die(cls, num=False): # 設定類屬性方法
if num:
cls.__enemy_die = 0 # 重新設定為0
else:
cls.__enemy_die += 1
def __init__(self, x, y, screen, filename):
super().__init__(x, y, screen, filename)
self.button_fire = True # 設定一個是否可以開火的開關
self.derc = None # 初始方向為向右
self.time2 = time.time() # 時間變數
if self.name == st.ENEMY_1: # 如果是敵方小飛機
self.__blood = st.Small_Blood
self.enemy_speed1 = st.ENEMY_DOWN_SPEED # 小飛機設定成快速
elif self.name == st.ENEMY_2:
self.__blood = st.Middle_Blood
self.enemy_speed1 = st.ENEMY_DOWN_SPEED1 # 中型飛機設定成中速
elif self.name == st.ENEMY_3:
self.__blood = st.Boss_Blood
self.enemy_speed1 = st.ENEMY_DOWN_SPEED # boss飛機設定成慢速
@property
def blood(self):
"""創建血量訪問方法"""
return self.__blood
@blood.setter
def blood(self, new_blood):
"""血量設定方法"""
self.__blood = new_blood
def __del__(self):
self.button_fire = False # 關閉開火的開關
# print("敵機洗掉執行!")
def enemy_shoot(self): # 敵機發射子彈的方法
ran = random.randint(0, 100) # 敵機隨機發射子彈
if ran == 80:
Factory.bullet_act(self) # 呼叫工廠生產和裝填子彈
def draw(self):
# 繪制敵機
self.screen.blit(self.image_1, (self.x, self.y))
self.enemy_move() # 敵機移動
if self.button_fire: # 如果開火的開關是打開的
self.enemy_shoot() # 敵機發射子彈
if self.__blood <= 0: # 小于0洗掉自身
bullet_del.append(self)
def enemy_move(self): # 使得敵方飛機移動
"""敵機移動的方法"""
time1 = time.time() # 敵機每隔1.5秒改變方向
# print(timex)
# print(time1 - timex)
if time1 - self.time2 > 1.5:
self.time2 = time1
self.derc = random.randint(0, 3) # 獲取敵機移動的方向
self.y += self.enemy_speed1 # 使得敵機保持向下,左右隨機移動
if self.derc == 0:
self.x += st.ENEMY_LR_SPEED
elif self.derc == 1:
self.x -= st.ENEMY_LR_SPEED
self.out_screen() # 防止敵機左右出界
self.go_screen() # 防止敵機下出界
def out_screen(self):
"""防止敵機左右出界"""
if self.x <= 0:
self.x = 0
elif self.name == st.ENEMY_1 and self.x >= 592: # 小飛機
self.x = 592
elif self.name == st.ENEMY_2 and self.x >= 576: # 中飛機
self.x = 576
elif self.name == st.ENEMY_3 and self.x >= 480: # boss飛機
self.x = 480
def go_screen(self):
"""敵機下出界洗掉"""
if self.y > 710:
bullet_del.append(self)
class BossEnemy(EnemyPlane):
"""創建敵方boss飛機類"""
def __init__(self, x, y, screen, filename):
super().__init__(x, y, screen, filename)
self.time3 = time.time() # 用來記錄換方向的初始時間
self.button_fire = False # 開火的開關初始狀態設為關閉
def enemy_shoot(self):
"""重寫父類發射子彈的方法"""
ran = random.randint(0, 100) # 敵機隨機發射子彈
if ran <= 10: # 10%的時間發射子彈
Factory.bullet_act(self) # 呼叫工廠生產和裝填子彈
def enemy_move(self):
"""boss移動"""
time1 = time.time() # 記錄boss移動的時間
time3 = time.time() # boss左右換方向的時間
# print(timex)
# print(time1 - timex)
if time1 - self.time2 < 6: # 如果小于六秒就一直向下移動
self.y += self.enemy_speed1
else: # 大于6秒開始左右移動
self.button_fire = True # 打開開火的開關
if time3 - self.time3 >= 2:
self.time3 = time3
while True:
derc = random.randint(0, 6) # 獲取敵機移動的方向
if self.derc != derc:
self.derc = derc
break
if self.derc == 0: # 向右邊移動
self.x += st.ENEMY_LR_SPEED + 3
elif self.derc == 1: # 向左移動
self.x -= st.ENEMY_LR_SPEED + 3
elif self.derc == 2: # 向右弧形移動
self.x += st.ENEMY_LR_SPEED + 3
self.y += st.ENEMY_LR_SPEED + 3
elif self.derc == 3: # 向右邊移動
self.x += st.ENEMY_LR_SPEED + 3
self.y -= st.ENEMY_LR_SPEED + 3
elif self.derc == 4: # 向左邊移動
self.x -= st.ENEMY_LR_SPEED + 3
self.y += st.ENEMY_LR_SPEED + 3
elif self.derc == 5: # 向左上移動
self.x -= st.ENEMY_LR_SPEED + 3
self.y -= st.ENEMY_LR_SPEED + 3
self.go_screen1() # 防止上出界
self.out_screen() # 防止敵機左右出界
self.go_screen() # 防止敵機下出界
def go_screen1(self):
"""防止敵機上出界"""
if self.y <= 0:
self.y = 0
def go_screen(self):
"""防止敵機下出界"""
if self.y >= 448:
self.y = 448
def draw(self):
super().draw()
if self.blood <= 0:
Factory.boss_blast(self) # 創建超極爆炸
bullet_del.append(self)
class MusicThis(object):
"""創建一個音樂類管理音樂"""
def __init__(self, filename, count=0):
self.filename = filename
self.count = count
def play_music(self):
"""播放音樂"""
pygame.mixer_music.load(self.filename) # 添加音樂
pygame.mixer_music.play(self.count) # 播放音樂
class BuffBullet1(Obj):
"""創建一個子彈外掛管理的類"""
def __init__(self, x, y, screen, filename):
super().__init__(x, y, screen, filename)
self.time = 0 # 設定一個計時器
def buff_creat(self):
"""buff的開關控制"""
if self.name == st.BUFF_1: # 如果是流星雨buff
st.SHOWER_BUFF = True # 打開開關,在主函式中顯示
Factory.star_act(0, 0, self.screen, st.MY_BULLET)
elif self.name == st.BUFF_2: # 如果是金幣子彈buff
self.buff_control(n2=True)
st.BUFF_TIME = 0 # 將金幣buff時間計數器設為0
elif self.name == st.BUFF_3: # 如果是激光子彈buff
self.buff_control(n3=True)
st.LASER_TIME = 0 # 將buff時間計數器設為0
elif self.name == st.BUFF_4: # 如果是隨機彈
# 隨機彈開關打開,其他的關閉
BuffBullet1.buff_control(n1=True)
st.RAN_TIME = 0 # 將時間計數器設為0
@staticmethod
def buff_control(n1=False, n2=False, n3=False):
"""創建管理子彈buff開關打開的函式"""
st.RAN_BUFF = n1 # 隨機彈開關
st.GOD_BUFF = n2 # 金幣子彈buff開關
st.LASER_BUFF = n3 # 激光子彈buff開關
def draw(self):
# 回圈顯示背景圖
self.screen.blit(self.image_1, (self.x, self.y))
self.y += st.BUFF_SPEED # buff移動
self.time += 1
if self.time > 400: # buff超過6秒后自動洗掉
bullet_del.append(self)
self.time = 0
if self.y < -30 or self.y > 704: # 判斷buff是否越界
bullet_del.append(self)
class Stony(Obj):
"""創建一個隕石類"""
def __init__(self, x, y, screen, filename):
"""定義構造屬性"""
super().__init__(x, y, screen, filename)
self.drec = random.randint(0, 1) # 創建一個移動的左右隨機方向
self.__blood = 500 # 設定血量
@property
def blood(self):
"""創建血量訪問方法"""
return self.__blood
@blood.setter
def blood(self, new_blood):
"""血量設定方法"""
self.__blood = new_blood
def draw(self):
# 回圈顯示背景圖
self.screen.blit(self.image_1, (self.x, self.y))
if self.__blood <= 0: # 血量小于0
bullet_del.append(self)
self.y += st.STONY_SPEED # 移動
if self.drec == 0:
self.x += st.STONY_SPEED - 4.2
else:
self.x -= st.STONY_SPEED - 4.2
# 判斷是否越界
if self.y < -150 or self.y > 750 or self.x < -100 or self.x > 640:
bullet_del.append(self)
tool.py提供一些公共使用的工具方法
# coding=utf-8
import time
def any_hit(target, element):
""""檢測兩個物體發生碰撞函式"""
# 定義四個開關
button1 = False
button2 = False
button3 = False
button4 = False
# 獲取傳入的類的尺寸
ele_rect = element.rect
x1 = element.x
y1 = element.y
w1 = ele_rect.w
h1 = ele_rect.h
# 碰撞判斷
if x1 < target.x + target.rect.w < x1 + w1 or x1 < target.x < x1 + w1:
button1 = True
if y1 < target.y < y1 + h1 or y1 < target.y + target.rect.h < y1 + h1:
button2 = True
if target.x < x1 + w1 < target.x + target.rect.w or target.x < x1 < target.x + target.rect.w:
button3 = True
if target.y < y1 < target.y + target.rect.h or target.y < y1 + h1 < target.y + target.rect.h:
button4 = True
if (button1 and button2) or (button3 and button4):
return True
else:
return False
def delays(delay, time0=time.time()):
class MyDelay(object):
"""創建一個帶引數的類裝飾器,用來對函式進行延時執行,每過
delay時間執行一次
"""
def __init__(self, fun):
self.sec = delay
self.time = time0
self.__fun = fun
def __call__(self, *args, **kwargs):
time1 = time.time()
if time1 - self.time >= self.sec:
self.__fun(*args, **kwargs)
self.time = time1
return MyDelay
def delay_fps(fps, fps0=0):
class FpsDelay(object):
"""創建一個根據固定幀數延時執行的類裝飾器,每過fps幀數執行一次"""
def __init__(self, fun):
self.fps = fps
self.fps0 = fps0
self.__fun = fun
def __call__(self, *args, **kwargs):
self.fps0 += 1
# print(self.fps0)
if self.fps0 % self.fps == 0:
self.__fun(*args, **kwargs)
return FpsDelay
def delay_run(fps, fps0=0):
"""創建一個幀數 延時執行的裝飾器"""
def delay(func):
def new_run(*args, **kwargs):
nonlocal fps0
fps0 += 1
if fps0 % fps == 0:
res = func(*args, **kwargs)
return res
return new_run
return delay
def delay_time(time1, time0=time.time()):
"""創建一個延時間的裝飾器"""
def delay(func):
def new_run(*args, **kwargs):
nonlocal time0
time2 = time.time()
if time2 - time0 >= time1:
time0 = time2
res = func(*args, **kwargs)
return res
return new_run
return delay
def print_say():
__a = 0
print(locals())
if __name__ == "__main__":
class Person(object):
def __init__(self, name, age, taste):
self.name = name
self._age = age
self.__taste = taste
print(locals())
print(dir(Person))
setting.py創建存盤所有游戲資源的模塊
# 設定螢屏
SCREEN_WIDTH = 768 # 螢屏的寬度
SCREEN_HIGHT = 704 # 螢屏的高度
# 設定背景
BEIJING_SPEED = 3 # 設定背景移動速度
# 設定游戲前言界面字體顯示引數
FRAMES = 40 # 每隔frames幀數顯示一個字
WIN_OVER_FRAMES = 200 # 多少幀數后界面切換
# 設定游戲背景訴說界面的引數
WIN_FONT_FRAMES = 500 # 多少幀數后界面結束
# 我方飛機的引數
HERO_SPEED = 10 # 設定我方飛機移動的速度
HERO_BLOOD = 2000 # 我方血量
# 我方子彈的引數
BULLET_SPEED = 10 # 設定我方子彈的速度
# 設定敵機的血量
Small_Blood = 100 # 小敵機
Middle_Blood = 200 # 中型飛機
Big_Blood = 500 # 大型
Boss_Blood = 3000 # 敵方boss
# 敵機的數目
ENEMY_NUM = 50 # 普通飛機的上限
BOSS_NUM = 1 # boss飛機的上限
'''流星雨的速度'''
SHOWER_SPEED = 20
'''設定小敵機的速度'''
ENEMY_DOWN_SPEED = 1
ENEMY_LR_SPEED = 1
'''設定中型敵機的速度'''
ENEMY_DOWN_SPEED1 = 0.8
ENEMY_LR_SPEED1 = 1
'''設定大敵機的速度'''
ENEMY_DOWN_SPEED2 = 0.5
ENEMY_LR_SPEED2 = 0.5
"""設定子彈的大小"""
BULLET_BIG = 16
"""敵方飛機產生速度調節器"""
ENEMY_CREATE1 = 80
ENEMY_CREATE2 = 40
"""游戲buff的移動速度"""
BUFF_SPEED = 5
"""隕石移動速度"""
STONY_SPEED = 5
"""金幣buff的時間計數器"""
BUFF_TIME = 0
"""激光buff時間計數器"""
LASER_TIME = 0
"""隨機子彈buff時間"""
RAN_TIME = 0
"""文字字體檔案"""
SCRIPT = './rec/font_file/songti.TTF'
SCRIPT1 = './rec/font_file/jingdian.TTF'
SCRIPT2 = './rec/font_file/kong.TTF'
# 圖片資源
"""背景圖片"""
BEIJING_1 = 'rec/images/beijing_3.jpg'
"""積分界面背景圖片"""
IMAGE_BJ = 'rec/images/image_bj2.jpg'
'''開始界面圖片'''
BEIJING_2 = 'rec/images/kong.jpg'
'''我方飛機'''
HREO_1 = 'rec/images/hero1.png'
'''我方普通子彈'''
MY_BULLET = 'rec/images/shot_bottom.gif'
"""buff子彈螺旋彈"""
LUOXUAN_BULLET = 'rec/images/bullets.png'
"""buff金幣彈"""
GOD_BULLET = 'rec/images/moneybullet.png'
"""buff激光子彈"""
LASER_BULLET = 'rec/images/buffbullet2.png'
"""隨機運動子彈"""
RAN_BULLET = 'rec/images/bzx.png'
'''敵方飛機1'''
ENEMY_1 = 'rec/images/enemy_1.gif'
''''敵方飛機2'''
ENEMY_2 = 'rec/images/enemy_2.png'
'''敵方飛機3'''
ENEMY_3 = 'rec/images/enemy_3.gif'
"""隕石圖片"""
STONY_BUFF = 'rec/images/buff3.png'
"""標準模式按鈕"""
BUTTON_1 = 'rec/images/moshi_2.PNG'
BUTTON_2 = 'rec/images/moshi2.PNG'
BUTTON_A = [BUTTON_2, BUTTON_1]
"""困難模式按鈕"""
BUTTON_3 = 'rec/images/moshi1.PNG'
BUTTON_4 = 'rec/images/moshi_1.PNG'
BUTTON_B = [BUTTON_4, BUTTON_3]
"""飛機大戰名字"""
PLANE_NAME = 'rec/images/name.png'
"""退出按鈕"""
BUTTON_5 = 'rec/images/goout1.png'
BUTTON_6 = 'rec/images/goout2.png'
BUTTON_C = [BUTTON_5, BUTTON_6]
"""結束界面退出游戲按鈕"""
BUTTON_7 = 'rec/images/outgame3.png'
BUTTON_8 = 'rec/images/outgame4.png'
BUTTON_D = [BUTTON_7, BUTTON_8]
"""結束界面重新開始按鈕"""
BUTTON_9 = 'rec/images/restart3.png'
BUTTON_10 = 'rec/images/restart4.png'
BUTTON_E = [BUTTON_9, BUTTON_10]
"""游戲下一關按鈕"""
BUTTON_11 = 'rec/images/next3.png'
BUTTON_12 = 'rec/images/next4.png'
BUTTON_F = [BUTTON_11, BUTTON_12]
"""游戲操作說明"""
FUNCTION_1 = 'rec/images/func.png'
"""游戲buff圖片"""
BUFF_1 = 'rec/images/buff1.png'
BUFF_2 = 'rec/images/moneybuff.png'
BUFF_3 = 'rec/images/bulletn.png'
BUFF_4 = 'rec/images/buff_random.png'
"""游戲進入界面的前言"""
MY_READ = 'rec/images/mylaung1.png'
MY_XING = 'rec/images/xing1.jpg'
MY_SELF = 'rec/images/me.png'
MY_TEXT = 'rec/images/bg.png'
"""創建一個BUFF串列"""
LIST_BUFF = [BUFF_1, BUFF_2, BUFF_3, BUFF_4]
"""游戲開始按鈕"""
BUTTON_START1 = 'rec/images/start.png'
BUTTON_START2 = 'rec/images/start1.png'
BUTTON_START3 = 'rec/images/start2.png'
BUTTON_START4 = 'rec/images/start3.png'
"""一個開始的按鈕串列"""
BUTTON_START = [BUTTON_START1,
BUTTON_START2,
BUTTON_START3,
BUTTON_START4]
"""爆炸效果圖1"""
LIST_BLAST = ['rec/images/blast_1.gif',
'rec/images/blast_2.gif',
'rec/images/blast_3.gif',
'rec/images/blast_4.gif',
'rec/images/blast_5.gif',
'rec/images/blast_6.gif',
'rec/images/blast_7.gif',
'rec/images/blast_8.gif' ]
"""超大爆炸效果圖"""
LIST_BLAST_BIG = ['rec/images/bz0.png',
'rec/images/bz1.png',
'rec/images/bz2.png',
'rec/images/bz3.png',
'rec/images/bz4.png',
'rec/images/bz5.png',
'rec/images/bz6.png',
'rec/images/bz7.png',
'rec/images/bz8.png',
'rec/images/bz9.png',
'rec/images/bz10.png',
'rec/images/bz11.png',
'rec/images/bz12.png',
'rec/images/bz13.png',
'rec/images/bz14.png']
"""男生角色圖片"""
BOY_IMAGE = ['rec/images/boy0.jpg',
'rec/images/boy1.jpg',
'rec/images/boy2.jpg',
'rec/images/boy3.jpg',
'rec/images/boy4.jpg'
]
"""女生角色圖片"""
GIRL_IMAGE = ['rec/images/girl0.jpg',
'rec/images/girl1.jpg',
'rec/images/girl2.jpg',
'rec/images/girl3.jpg',
'rec/images/girl4.jpg'
]
'''音樂資源'''
FIRE_MUSIC = 'rec/music/fire.wav'
"""爆炸音樂"""
BLAST_MUSIC = 'rec/music/blast.mp3'
"""游戲開始音樂"""
START_MUSIC = 'rec/music/chao.mp3'
# 開關資源
"""上按鍵開關"""
KEY_UP = False
"""下按鍵開關"""
KEY_DOWN = False
"""左按鍵開關"""
KEY_LEFT = False
"""右按鍵開關"""
KEY_RIGHT = False
"""游戲模式切換開關"""
GAME_MOSHI = True
"""創建按鈕顏色變化開關"""
BUTTON_COLOR = True
"""流星雨buff的打開開關"""
SHOWER_BUFF = False
"""金幣子彈buff的開關"""
GOD_BUFF = False
"""激光子彈buff開關"""
LASER_BUFF = False
"""隨機彈控制開關"""
RAN_BUFF = False
"""boss出現的開關"""
BOSS_CREAT = False
"""boss是否全部死亡"""
BOSS_DIE = False
"敵機是否可以生產開關"
ENEMY_START = False
"""敵方生成器的開關"""
ENEMY_MAKE = True
'''登陸界面開關'''
SCREEN_CHANGE = False
"""游戲進入前的界面控制開關"""
GAME_BEFORE = False
"""游戲歷史背景開關"""
GAME_SAY = False
"""戰斗界面控制開關"""
GAME_FIGHT = False
"""游戲結束界面控制開關"""
GAME_END = False
_init_.py
- _init_.py 檔案的作用是將檔案夾變為一個Python模塊,Python 中的每個模塊的包中,都有_init_.py檔案,
- 通常_init_.py檔案為空,但是我們還可以為它增加其他的功能,我們在匯入一個包時,實際上是匯入了它的_init_.py檔案,
__all__ = ["game_windows", "setting", "tool", "resource_game"]
main.py 游戲啟動模塊
# coding:utf-8
from game_file.game_windows import main
if __name__ == '__main__':
main()
原始碼及檔案下載:
鏈接:https://pan.baidu.com/s/1f26Au3GMHO18OBYP1yMVpw
提取碼:bi10
食用指南:進入the_war_of_sky目錄,終端輸入:python main.py


轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/260056.html
標籤:python
下一篇:手把手Python3爬蟲實戰(1)——requests與Beautifulsoup的使用之爬蟲獲取豆瓣電影top250
