效果图:

开始界面:

游戏中:

gameover!

文件结构:

  • game_file:所有游戏逻辑相关的源码;
  • rec:游戏相关的图片、音乐资源;
  • main.py: 游戏的启动文件;

所用到的图片:

源码和文件我会放到文末,感兴趣的自取。

源码及注释:

game_windows.py 游戏运行的主函数模块,所有的顶层函数

# coding=utf-8import time
import math
import sysimport 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 = 0fps5 = 0f = 0time1 = 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:passfps += 1if 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 += 1if 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 += 1if st.GAME_MOSHI:  # 判断目前的游戏模式ps = st.ENEMY_CREATE1else:ps = st.ENEMY_CREATE2if 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 += 1if time2 - time1 >= 1:time1 = time2print(fps4 - f)f = fps4loop()  # 元素循环显示和清空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_controldef 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_controldef 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 = Truepasselif 350 <= mouse_y <= 435:  # 按下了重新开始按钮bc(k2=True)  # 打开登陆界面开关cls()  # 清空子弹、删除、界面元素列表# 将敌机死亡的数量重新设置为0EnemyPlane.set_enemy_die(True)buttons = game_load(screen)  # 加载登陆界面元素return buttonselif 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 = Trueelif 400 <= mouse_y <= 440:  # 按下了困难模式按钮st.GAME_MOSHI = Falseelif 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 downelif event.key == pygame.K_s or event.key == pygame.K_DOWN:# 打开向下移动的开关st.KEY_DOWN = True# 是否按下a or leftelif event.key == pygame.K_a or event.key == pygame.K_LEFT:# 打开向左移动的开关st.KEY_LEFT = True# 是否按下d or rightelif 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()  # 清空子弹、删除、界面元素列表# 将敌机死亡的数量重新设置为0EnemyPlane.set_enemy_die(True)buttons = game_load(screen)  # 加载登陆界面元素return buttonselif event.type == pygame.KEYUP:  # 是否放开了键盘if event.key == pygame.K_w or event.key == pygame.K_UP:# 关闭开关st.KEY_UP = Falseelif event.key == pygame.K_s or event.key == pygame.K_DOWN:# 关闭向下移动的开关st.KEY_DOWN = Falseelif event.key == pygame.K_a or event.key == pygame.K_LEFT:# 关闭向左移动的开关st.KEY_LEFT = Falseelif event.key == pygame.K_d or event.key == pygame.K_RIGHT:# 关闭向右移动的开关st.KEY_RIGHT = Falseif event.type == pygame.MOUSEBUTTONDOWN:  # 判断是否按下了鼠标if hero_me.get_fire():  # 如果发射子弹的开关是打开的hero_me.fire()  # 将子弹列表的元素加入显示列表def go_game_end(screen):"""游戏结束的界面控制"""global fps6if 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 buttonsdef 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_6def 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 = Nonestony = Nonetry:# 若未达到敌机死亡的上限if EnemyPlane.get_enemy_die() < st.ENEMY_NUM:enemy_plane = next(EnemyCreate)  # 敌机生成stony = stony_creat(screen)  # 陨石生成else:st.BOSS_CREAT = Truest.ENEMY_MAKE = False  # 关闭生成器的开关except StopIteration:enemy_plane = Nonestony = Nonetry: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 fps2if st.BOSS_CREAT:  # 创建bossfps2 += 1# print(fps2)if fps2 == 100:for i in range(st.BOSS_NUM):Factory.enemy_act(300, -200, screen, dict_enemy['2'])fps2 = 0st.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 = Falseif boss_button:  # 如果没有boss飞机了st.BOSS_DIE = Truereturn st.BOSS_DIEdef buff_make():"""各种buff子弹有效时间计数函数"""if st.GOD_BUFF:  # 金币子弹buff出现,大于500帧数后消失st.BUFF_TIME += 1if st.BUFF_TIME >= 500:st.GOD_BUFF = Falseif st.LASER_BUFF:  # 激光子弹buff出现,大于500帧数后消失st.LASER_TIME += 1if st.LASER_TIME >= 500:st.LASER_BUFF = Falseif st.RAN_BUFF:  # 随机子弹buff出现st.RAN_TIME += 1if st.RAN_TIME >= 500:st.RAN_BUFF = Falsedef move_make(dict_key, hero_me):"""控制飞机移动的方法"""global numfor item in dict_key.items():  # 通过开关控制我方飞机移动if item[0]:# print(item[0])num += 1if num > 2:hero_me.hreo_move(item[1])num = 0def clear_list():"""清除相关列表中的元素函数"""bullet_list.clear()  # 清除发射出的列表bullet_del.clear()  # 清空该删除的列表screen_list.clear()  # 清空界面元素cls = clear_listdef 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, button3def 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 scriptdef 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_medef enemy_create(screen):"""敌机的生成器,使用了迭代器的方式"""i = 0while i < 500:ran1 = random.randint(0, 2)  # 生成敌机的 出生位置ranx = random.randint(0, 20)  # 调整敌机生成的概率if ranx <= 14:ran2 = 0else:ran2 = 1# 创建敌方飞机enemy_plane = EnemyPlane(100 + ran1 * 200, -100, screen, dict_enemy[str(ran2)])yield enemy_planei += 1# st.BOSS_CREAT = Truedef 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_oneelse:return Falsedef delay_time(delay, time0=time.time()):"""一个延时函数"""time1 = time.time()if time1 - time0 >= delay:return Trueelse:return Falseif __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 = xself.y = yself.screen = screenself.name = filenameself.image_1 = pygame.image.load_extended(self.name)  # 加载背景图片self.rect = self.image_1.get_rect()  # 获取图片的外接矩形def draw(self):  # 设置绘制的功能passclass 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 = xself.y = yself.screen = screenself.script = scriptself.size = sizeself.name = filenameself.color = colorself.bool_sc = bool_scself.bg_script = bg_scriptdef 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_surfacedef draw(self):text = self.sc_act()# 显示创建的文字对象self.screen.blit(text, (self.x, self.y))def change_size(self):"""文字的效果,如大小闪烁,移动变化等"""passdef change_color(self):passclass 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 += 1if self.fps % 20 == 0:  # 每隔5帧数显示一个文字try:self.t = next(self.it)except StopIteration:passif 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 += 1super().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 -= 2self.x += 1self.y += 1# if self.size <= self.least:  # 达到最小时还原大小#     self.size = self.maxdef 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 = 0def change_size(self):if self.fps % 2 == 0 and self.size < 180:  # 每过5帧数执行一次self.size += 3self.x -= 1self.y -= 1def draw(self):self.fps += 1super().draw()self.change_size()class ButtonGame(Obj):"""创建一个游戏开始按钮"""def __init__(self, x, y, screen, list_image):self.x = xself.y = yself.screen = screenself.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 += 1if self.fps % 10 == 0:  # 每过15帧显示一张按钮图片self.ran += 1if self.ran > 3:self.ran = 0self.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.numself.num += st.BEIJING_SPEED  # 使得背景图移动if self.num > -10:self.num = -2000self.screen.blit(self.image_1, (self.x, self.y))  # 循环显示背景图片class Factory(object):""""创建一个万能的工厂,能够生产并自动将其添加到显示列表"""@staticmethoddef beijing_act(x, y, screen, filename):"""创造并显示静态的图片"""beijing = Beijing(x, y, screen, filename)screen_list.append(beijing)  # 将背景添加到显示列表return beijing@staticmethoddef 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@staticmethoddef button1_act(x, y, screen, list_image):"""创建普通按钮"""button = ModeButton(x, y, screen, list_image)screen_list.append(button)return button@staticmethoddef button_act(x, y, screen, list_image):"""按钮生成器"""button = ButtonGame(x, y, screen, list_image)screen_list.append(button)@staticmethoddef star_act(x, y, screen, filename):"""流星雨生成器"""show = Star(x, y, screen, filename)screen_list.append(show)@staticmethoddef hreo_act(x, y, screen, filename):"""生产我方的飞机"""my_plane = Hreo(x, y, screen, filename)screen_list.append(my_plane)return my_plane@staticmethoddef 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)  # 将爆炸效果添加到显示列表@staticmethoddef 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)@staticmethoddef buff_act(ele, prob):"""buff生成方法"""ran = random.randint(0, 10)   # 有一定概率出现buffif ran < prob:  # 调整概率buff = BuffBullet1(ele.x, ele.y, ele.screen, random.choice(st.LIST_BUFF))screen_list.append(buff)  # 添加到显示列表@staticmethoddef music_act(name):"""音乐播放方法"""music1 = MusicThis(name)music1.play_music()del music1@staticmethoddef 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@staticmethoddef 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  # 一个控制开火的开关@propertydef blood(self):"""创建血量访问方法"""return self.__blood@blood.setterdef blood(self, new_blood):"""血量设置方法"""self.__blood = new_blooddef __del__(self):self.button_fire = False  # 关闭开火print("hero删除执行了")def get_fire(self):  # 设置类方法访问和修改类属性return self.button_firedef set_fire(self, bools):self.button_fire = boolsdef fire(self):"""发射子弹"""Factory.music_act(st.FIRE_MUSIC)  # 播放音乐Factory.bullet_act(self)  # 调用工厂产生子弹并发射出去def hreo_move(self, strx):"""飞机移动的方法"""if strx == 'up':  # 向上移动self.y -= self.speedelif strx == 'down':  # 向下移动self.y += self.speedelif strx == 'left':  # 向左移动self.x -= self.speedelif strx == 'right':  # 向右移动self.x += self.speedelse:passdef ishit(self, ele):"""飞机的碰撞检测执行函数"""# 忽略所有子弹、背景、爆炸图、本身、文字if isinstance(ele, (Beijing, Blast, Hreo, Bullet, ScriptBase)):# print("这是背景或本身")return Falseresult = 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血量减少5if isinstance(ele, BuffBullet1):  # 如果碰到的是buffbullet_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 = 0elif self.x >= 540:self.x = 540if self.y <= 0:self.y = 0elif self.y >= 600:self.y = 600class Bullet(Obj):"""创建子弹类"""def __init__(self, element):self.screen = element.screenself.ele = elementself.name = Noneself.image_bullet = Noneself.bullet_speed = Noneself.__blood = 50  # 设置血量def bullet_init(self, x1, y1, speed):"""不同子弹初始化参数的函数"""self.x = self.ele.x + x1self.y = self.ele.y + y1self.image_bullet = pygame.image.load_extended(self.name)  # 加载背景图片self.rect = self.image_bullet.get_rect()   # 获得图片的尺寸self.bullet_speed = speed  # 设置子弹的速度@propertydef blood(self):"""创建血量访问方法"""return self.__blood@blood.setterdef blood(self, new_blood):"""血量设置方法"""self.__blood = new_blooddef 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_speedelse:self.y += self.bullet_speedself.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 Falseelse: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 Falseelse: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.bloodele.blood = -1else:ele.blood -= self.bloodself.__blood = 0bullet_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):  # 如果是敌机被打爆,则敌机死亡计数器加1ele.set_enemy_die()if not isinstance(ele, Bullet):  # 如果对方不是子弹才能产生buffif 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 += 1if self.fps % 10 == 0:  # 每10帧数改变方向self.ran = random.randint(0, 1)if self.ran == 0:self.x -= self.bullet_speed - 5else:self.x += self.bullet_speed - 5self.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 = Truedef __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.__button1def draw(self):if st.SHOWER_BUFF:self.fps += 1if self.fps % 60 == 0:self.num_shower += 1for i in range(10):bullet_new = EneBullet(self, i * 64, -32)screen_list.append(bullet_new)  # 添加到显示列表# 五次后关闭流星雨if self.num_shower > 3:self.fps = 0self.num_shower = 0st.SHOWER_BUFF = Falseclass Blast(Obj):"""创建一个爆炸效果类"""def __init__(self, ele, name):self.num1 = 0self.screen = ele.screenself.name = nameself.image_blast = []# 如果是敌机的子弹爆炸if isinstance(ele, Bullet) and not isinstance(ele.ele, Hreo):self.x = ele.x - 56self.y = ele.y - 32# 如果是敌方的小飞机爆炸elif ele.name == st.ENEMY_1 and isinstance(ele, EnemyPlane):self.x = ele.x - 40self.y = ele.y - 40# 如果是敌方的中型飞机爆炸elif ele.name == st.ENEMY_2 and isinstance(ele, EnemyPlane):self.x = ele.x - 32self.y = ele.y - 32# 如果是敌方的boss飞机爆炸elif ele.name == st.ENEMY_3 and isinstance(ele, BossEnemy):self.x = ele.x + 16self.y = ele.y + 150# 如果是我方飞机爆炸elif ele.name == st.HREO_1 and isinstance(ele, Hreo):self.x = ele.x - 14self.y = ele.y# 如果是文字elif isinstance(ele, ScriptBase):self.x = ele.xself.y = ele.yelse:self.x = ele.x - 32self.y = ele.y - 32Factory.music_act(st.BLAST_MUSIC)  # 播放音乐def draw(self):passdef numx(self, n):"""改变爆炸的大小"""if self.num1 > n:self.num1 = 0bullet_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 += 1if 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 += xself.y += yfor 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 += 1if self.name == 'xiao':self.numx(7)elif self.name == 'big':self.numx(13)class EnemyPlane(Obj):"""创建一个敌方的飞机类1"""__enemy_die = 0  # 创建一个类属性记录杀死的敌机数量@classmethoddef get_enemy_die(cls):  # 访问类属性方法return cls.__enemy_die@classmethoddef set_enemy_die(cls, num=False):  # 设置类属性方法if num:cls.__enemy_die = 0  # 重新设置为0else:cls.__enemy_die += 1def __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_Bloodself.enemy_speed1 = st.ENEMY_DOWN_SPEED  # 小飞机设置成快速elif self.name == st.ENEMY_2:self.__blood = st.Middle_Bloodself.enemy_speed1 = st.ENEMY_DOWN_SPEED1  # 中型飞机设置成中速elif self.name == st.ENEMY_3:self.__blood = st.Boss_Bloodself.enemy_speed1 = st.ENEMY_DOWN_SPEED  # boss飞机设置成慢速@propertydef blood(self):"""创建血量访问方法"""return self.__blood@blood.setterdef blood(self, new_blood):"""血量设置方法"""self.__blood = new_blooddef __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 = time1self.derc = random.randint(0, 3)  # 获取敌机移动的方向self.y += self.enemy_speed1  # 使得敌机保持向下,左右随机移动if self.derc == 0:self.x += st.ENEMY_LR_SPEEDelif self.derc == 1:self.x -= st.ENEMY_LR_SPEEDself.out_screen()  # 防止敌机左右出界self.go_screen()  # 防止敌机下出界def out_screen(self):"""防止敌机左右出界"""if self.x <= 0:self.x = 0elif self.name == st.ENEMY_1 and self.x >= 592:  # 小飞机self.x = 592elif self.name == st.ENEMY_2 and self.x >= 576:  # 中飞机self.x = 576elif self.name == st.ENEMY_3 and self.x >= 480:  # boss飞机self.x = 480def 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_speed1else:  # 大于6秒开始左右移动self.button_fire = True  # 打开开火的开关if time3 - self.time3 >= 2:self.time3 = time3while True:derc = random.randint(0, 6)  # 获取敌机移动的方向if self.derc != derc:self.derc = dercbreakif self.derc == 0:  # 向右边移动self.x += st.ENEMY_LR_SPEED + 3elif self.derc == 1:  # 向左移动self.x -= st.ENEMY_LR_SPEED + 3elif self.derc == 2:  # 向右弧形移动self.x += st.ENEMY_LR_SPEED + 3self.y += st.ENEMY_LR_SPEED + 3elif self.derc == 3:  # 向右边移动self.x += st.ENEMY_LR_SPEED + 3self.y -= st.ENEMY_LR_SPEED + 3elif self.derc == 4:  # 向左边移动self.x -= st.ENEMY_LR_SPEED + 3self.y += st.ENEMY_LR_SPEED + 3elif self.derc == 5:  # 向左上移动self.x -= st.ENEMY_LR_SPEED + 3self.y -= st.ENEMY_LR_SPEED + 3self.go_screen1()  # 防止上出界self.out_screen()  # 防止敌机左右出界self.go_screen()  # 防止敌机下出界def go_screen1(self):"""防止敌机上出界"""if self.y <= 0:self.y = 0def go_screen(self):"""防止敌机下出界"""if self.y >= 448:self.y = 448def 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 = filenameself.count = countdef 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:  # 如果是流星雨buffst.SHOWER_BUFF = True  # 打开开关,在主函数中显示Factory.star_act(0, 0, self.screen, st.MY_BULLET)elif self.name == st.BUFF_2:  # 如果是金币子弹buffself.buff_control(n2=True)st.BUFF_TIME = 0  # 将金币buff时间计数器设为0elif self.name == st.BUFF_3:  # 如果是激光子弹buffself.buff_control(n3=True)st.LASER_TIME = 0  # 将buff时间计数器设为0elif self.name == st.BUFF_4:  # 如果是随机弹# 随机弹开关打开,其他的关闭BuffBullet1.buff_control(n1=True)st.RAN_TIME = 0  # 将时间计数器设为0@staticmethoddef 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 += 1if self.time > 400:  # buff超过6秒后自动删除bullet_del.append(self)self.time = 0if 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  # 设置血量@propertydef blood(self):"""创建血量访问方法"""return self.__blood@blood.setterdef blood(self, new_blood):"""血量设置方法"""self.__blood = new_blooddef draw(self):# 循环显示背景图self.screen.blit(self.image_1, (self.x, self.y))if self.__blood <= 0:  # 血量小于0bullet_del.append(self)self.y += st.STONY_SPEED  # 移动if self.drec == 0:self.x += st.STONY_SPEED - 4.2else: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 timedef any_hit(target, element):""""检测两个物体发生碰撞函数"""# 定义四个开关button1 = Falsebutton2 = Falsebutton3 = Falsebutton4 = False# 获取传入的类的尺寸ele_rect = element.rectx1 = element.xy1 = element.yw1 = ele_rect.wh1 = ele_rect.h# 碰撞判断if x1 < target.x + target.rect.w < x1 + w1 or x1 < target.x < x1 + w1:button1 = Trueif y1 < target.y < y1 + h1 or y1 < target.y + target.rect.h < y1 + h1:button2 = Trueif target.x < x1 + w1 < target.x + target.rect.w or target.x < x1 < target.x + target.rect.w:button3 = Trueif target.y < y1 < target.y + target.rect.h or target.y < y1 + h1 < target.y + target.rect.h:button4 = Trueif (button1 and button2) or (button3 and button4):return Trueelse:return Falsedef delays(delay, time0=time.time()):class MyDelay(object):"""创建一个带参数的类装饰器,用来对函数进行延时执行,每过delay时间执行一次"""def __init__(self, fun):self.sec = delayself.time = time0self.__fun = fundef __call__(self, *args, **kwargs):time1 = time.time()if time1 - self.time >= self.sec:self.__fun(*args, **kwargs)self.time = time1return MyDelaydef delay_fps(fps, fps0=0):class FpsDelay(object):"""创建一个根据固定帧数延时执行的类装饰器,每过fps帧数执行一次"""def __init__(self, fun):self.fps = fpsself.fps0 = fps0self.__fun = fundef __call__(self, *args, **kwargs):self.fps0 += 1# print(self.fps0)if self.fps0 % self.fps == 0:self.__fun(*args, **kwargs)return FpsDelaydef delay_run(fps, fps0=0):"""创建一个帧数 延时执行的装饰器"""def delay(func):def new_run(*args, **kwargs):nonlocal fps0fps0 += 1if fps0 % fps == 0:res = func(*args, **kwargs)return resreturn new_runreturn delaydef delay_time(time1, time0=time.time()):"""创建一个延时间的装饰器"""def delay(func):def new_run(*args, **kwargs):nonlocal time0time2 = time.time()if time2 - time0 >= time1:time0 = time2res = func(*args, **kwargs)return resreturn new_runreturn delaydef print_say():__a = 0print(locals())if __name__ == "__main__":class Person(object):def __init__(self, name, age, taste):self.name = nameself._age = ageself.__taste = tasteprint(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 mainif __name__ == '__main__':main()

源码及文件下载:

链接:https://pan.baidu.com/s/1f26Au3GMHO18OBYP1yMVpw
提取码:bi10

食用指南:进入the_war_of_sky目录,终端输入:python main.py

python之星河战争游戏相关推荐

  1. python经典小游戏五子棋,适合python编程的小游戏

    python入门可以做的小游戏 1.Python入门拼图小游戏简单介绍:将图像分为m×n个矩形块,并将图像右下角的矩形块替换为空白块后,将这些矩形块随机摆放成原图像的形状. 2.Python入门推箱子 ...

  2. python编的俄罗斯方块游戏下载_python写的俄罗斯方块游戏

    python写的俄罗斯方块游戏 功能包括:记录所花费时间;消去的总行数;总分;排行榜,最高记录查看等. 排行榜中包含一系列的统计功能,如单位时间消去的行数,单位时间得分等. from Tkinter ...

  3. 10行Python,搭建一个游戏AI | 视频教程

    昨天为大家推荐了三个Python视频,包含:<利用Python,用4分钟时间搭建一个情感分析系统>.<7行Python代码,搭建一个可以识花的机器学习APP>.<10行P ...

  4. python俄罗斯方块算法详解_用 Python 写一个俄罗斯方块游戏 (

    @@ -2,34 +2,34 @@ > * 原文作者:[Dr Pommes](https://medium.com/@pommes) > * 译文出自:[掘金翻译计划](https://g ...

  5. python 玩公众号游戏_Python入门太难?不如从玩塔防小游戏开始,玩通关就能学会编程...

    我一直认为,在python入门阶段学习基础理论,太枯燥.所以我们整理了很多有关python的项目案例,有详细教程还有源码,希望能帮助更多对python感兴趣的人. 这是其中一个适合入门的Python项 ...

  6. python抽奖游戏_python实现转盘效果 python实现轮盘抽奖游戏

    本文实例为大家分享了python实现转盘效果的具体代码,供大家参考,具体内容如下 #抽奖 面向对象版本 import tkinter import time import threading clas ...

  7. skype安卓手机版_危险的战争游戏安卓手机版下载-危险的战争下载v1.0.13

    危险的战争游戏安卓手机版是一款非常好玩的简约画风的手机战争策略游戏,在危险的战争游戏安卓手机版游戏中玩家将控制自己的军队进行战斗,游戏玩法简单有趣,感兴趣的朋友赶紧下载危险的战争游戏安卓手机版开始游戏 ...

  8. python手机版做小游戏代码大全-python简单小游戏代码 怎么用Python制作简单小游戏...

    1.Python猜拳小游戏代码: 2.import random #导入随机模块 3. 4.num = 1 5.yin_num = 0 6.shu_num = 0 7.while num <= ...

  9. python能做游戏吗-没有Python不能做的游戏,这些游戏都可以做

    简介:Python编程语言的强大,几乎是众所周知的!那么,下面我给大家介绍一下几个用Python实现的各种游戏吧.不仅能用来做web.爬虫.数据分析等,没想到还能用做这么多的游戏,实在令人惊讶不已.注 ...

最新文章

  1. Sprites实现翻页按钮,圆角,宽度不固定
  2. Win2000中活动目录的备份与恢复
  3. 【Vegas原创】获取远程数据库到本地
  4. 怎样查看mysql的安装路径
  5. 左操作数必须为左值_进入“左转弯待转区”被罚怎么回事?
  6. python中math模块函数_Python常用的一些内建函数和math模块函数
  7. The J2EE Architect's Handbook讀書筆記(一)
  8. matlab求根的原程序,MATLAB求根程序求帮助
  9. 松下plc安装序列号afpsgr7_《松下PLC 编程软件 FPWINGR7 操作手册 中文高清版》.pdf...
  10. Java单例模式双检锁原理
  11. phpdesigner(php开发工具) 注册码,php 开发工具 phpDesigner7 附注册机
  12. 【评测】常用免疫细胞培养基
  13. linux shell 未找到命令,未找到linux问题setenv命令(linux issue setenv command not found)
  14. MySql存储IP地址(兼容ipv4和ipv6)
  15. 安装/卸载微软鼠标和键盘中心1603和1612错误
  16. eSpeak与ekho交叉编译
  17. 三星a5000 android,三星SM-A5000是什么型号手机?
  18. 安徽外国语学院计算机信息管理,2021年安徽外国语学院录取结果查询网址入口及录取结果公布时间...
  19. Java SE\EE\ME区别-下载什么jdk
  20. Chinasec构建证券业数据安全防护体系

热门文章

  1. 01-HTML基础与进阶-day4-录像250
  2. 解决windows update失败,正在还原的问题
  3. 【AtCoder】ARC 081 E - Don't Be a Subsequence
  4. 工信部召开地方信息安全工作会议
  5. 精确的力量:完美SNES仿真器的一个3GHz追求
  6. 校内网脱胎“人人”能成大器
  7. Fizz Gateway API in Java
  8. Linux 笔记 :FHS目录笔记
  9. c++求矩阵的秩_利用Python矩阵求逆、特征值及特征向量
  10. 初一计算机第6单元,青岛出版社初中信息技术 七年级下册第二单元 第6课 海报设计 教学设计...