效果图:
开始界面:
游戏中:
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(