素材
main.py
# 游戏的主文件,使用该文件来启动游戏
import pygame
import sys
import time
from game_config import GameConfig
from ship import Ship
# 从 X模块中引入X类
from bullet import Bullet
from alien import Alien
from pygame.sprite import Group
import game_function as gf
# 创建配置对象
gc = GameConfig()
# 编写基础代码
pygame.init()
# # 设置子弹连发,存在些隐患的
# pygame.key.set_repeat(True)
# 设置窗口大小
screen = pygame.display.set_mode(gc.size)
# 设置窗口标题
pygame.display.set_caption(gc.title)
# 创建一个飞船对象
ship = Ship(screen, gc)
# 创建外星人
# aliens.add(Alien(screen, gc))
# 创建一个列表来保存子弹
bullets = Group()
# 创建一个group来保存外星人
aliens = Group()
# 创建外星人
gf.create_aliens(screen, gc, aliens)
# 创建主循环
while 1:
gf.check_event(screen, gc, ship, bullets)
gf.show_screen(screen, gc, ship, bullets, aliens)
# time.sleep(0.5)
game_function.py
import pygame
import sys
import time
from ship import Ship
# 从 X模块中引入X类
from bullet import Bullet
from alien import Alien
from pygame.sprite import Group
# pygame.sprite.groupcollide(groupa, groupb, dokilla, dokillb, collided=None)
# 碰撞检测的方法
# groupa 第一个图层的群组
# groupb 第二图层的群组
def check_bullets_aliens(bullets, aliens):
result = pygame.sprite.groupcollide(bullets, aliens, False, True)
print(result)
# pygame.sprite.spritecollideany(sprite, group)
def check_ship_aliens(screen, gc, ship, aliens):
result = pygame.sprite.spritecollide(ship, aliens, True)
if result:
# 如果result 有值,则证明发生了碰撞,生命减少
gc.life -= 1
# 重置游戏,将外星人全部删除
aliens.empty()
# print('撞上了~~~')
# 创建一组外星人
create_aliens(screen, gc, aliens)
else:
# 检查外星人是否到达底部
for alien in aliens.sprites():
if alien.rect.bottom >= screen.get_rect().bottom:
# 如果result 有值,则证明发生了碰撞,生命减少
gc.life -= 1
# 重置游戏,将外星人全部删除
aliens.empty()
# print('撞上了~~~')
# 创建一组外星人
create_aliens(screen, gc, aliens)
break
# 检查外星人是否死光
def check_aliens_empty(screen, gc, aliens):
if len(aliens) == 0:
# 外星人死光了,进入下一关,速度提升
gc.alien_speed += 1
# 创建外星人
create_aliens(screen, gc, aliens)
# pygame.sprite.groupcollide(groupa, groupb, dokilla, dokillb, collided=None)
# 碰撞检测的方法
# groupa 第一个图层的群组
# groupb 第二个图层的群组
def check_bullets_aliens(bullets, aliens):
result = pygame.sprite.groupcollide(bullets, aliens, True, True)
# print(result)
def check_aliens(gc, aliens):
'''
检查外星人是否移动到边界
:param gc:
:param aliens:
:return:
'''
for alien in aliens.sprites():
# 检查外星人是否移动到了边界
if alien.check_edge():
# print('hello')
gc.alien_dir = -gc.alien_dir
# print(gc.alien_dir)
# 修改外星人的y值
for al in aliens.sprites():
al.rect.y += 3
break
def show_life(screen, gc):
# 根据生命,来创建飞船
for i in range(gc.life):
ship = Ship(screen, gc)
ship.rect.x = ship.rect.width * i
ship.rect.y = 0
ship.blitme()
def check_game_over(gc, screen):
if gc.life <= 0:
# 创建字体的对象
font = pygame.font.SysFont('fangsong', 60)
# pygame.font.get_fonts() 获取系统中的字体的名字
print(pygame.font.get_fonts())
# 使用字体对象,创建字体的图层
font_sur = font.render('GAME OVER&游戏结束', True, (255, 255, 255), (0, 0, 0))
# 获取字体的矩形
font_rect = font_sur.get_rect()
font_rect.centerx = screen.get_rect().centerx
font_rect.centery = screen.get_rect().centery
# 将字体显示在屏幕中
screen.blit(font_sur, font_rect)
# 刷新屏幕
pygame.display.flip()
# 游戏结束
time.sleep(2)
# 退出游戏
sys.exit()
# 定义游戏运行中需要的一些函数
def show_screen(screen, gc, ship, bullets, aliens):
# 检查游戏是否结束
check_game_over(gc, screen)
# 检查外星人是否死光
check_aliens_empty(screen, gc, aliens)
# 设置背景颜色
screen.fill(gc.bg_color)
# 显示飞船
show_life(screen, gc)
# 更新外星人的位置
aliens.update()
# 绘制外星人
aliens.draw(screen)
# 检查外星人是否移动到屏幕边缘
check_aliens(gc, aliens)
# 更新飞船位置
ship.update()
# 遍历子弹
# for bt in bullets:
# bt.update()
# # 显示
# bt.draw_bullet()
# 更新子弹的位置
bullets.update()
# 检查子弹是否打中外星人
check_bullets_aliens(bullets, aliens)
# 检查外星人是否撞上飞船
check_ship_aliens(screen, gc, ship, aliens)
# print(len(bullets))
# 显示飞船
ship.blitme()
# 对窗口进行重绘
pygame.display.flip()
# time.sleep(0.05)
def create_aliens(screen, gc, aliens):
'''
创建外星人
'''
# 计算外星人的生存空间
# 获取屏幕的宽度
screen_width = gc.width
screen_height = gc.height
# 获取外星人宽度
a1 = Alien(screen, gc)
a1_width = a1.rect.width
a1_height = a1.rect.height
# 计算外星人数量
col_count = int((screen_width - a1_width * 2) / (a1_width * 2))
# 计算外星人的行数
row_count = int((screen_height - a1_height * 3) / (a1_height * 2))
# print(row_count)
# 创建一个外层循环,控制外星人行数
for j in range(row_count):
# 创建外星人
for i in range(col_count):
alien = Alien(screen, gc)
alien.rect.x = a1_width * (1 + 2 * i)
alien.rect.y = a1_height * (1 + 2 * j)
# \
# ---外星人---外星人---外星人---外星人
# \
# ---外星人---外星人---外星人---外星人
# \
# ---外星人---外星人---外星人---外星人
# width*(1+2*0) width*(1+2*1) width*(1+2*2) width*(1+2*3)
aliens.add(alien)
# 创建一个处理事件的函数
def check_event(screen, gc, ship, bullets):
# 处理事件
for event in pygame.event.get():
# 处理退出的事件
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
# 键盘按下
check_keydown(event, screen, gc, ship, bullets)
elif event.type == pygame.KEYUP:
# 何时将ship_dir 设置为0
# 当向左移动松开左键,向右移动松开右键,此时应该设置为0
check_keyup(event, gc)
# 处理键盘按下的事件
def check_keydown(event, screen, gc, ship, bullets):
if event.key == pygame.K_LEFT:
# 向左移动,设置飞船的移动方向 -1
gc.ship_dir = -1
elif event.key == pygame.K_RIGHT:
# 向右移动,设置飞船的移动方向 +1
gc.ship_dir = 1
elif event.key == pygame.K_SPACE:
# 检查子弹的数量
if len(bullets) < gc.bullet_count:
# 点击空格,开炮
# 创建子弹对象
bullets.add(Bullet(screen, gc, ship))
def check_keyup(event, gc):
if gc.ship_dir == -1 and event.key == pygame.K_LEFT or \
gc.ship_dir == 1 and event.key == pygame.K_RIGHT:
gc.ship_dir = 0
game_config.py
# 该模块用来存储游戏的配置信息
class GameConfig:
def __init__(self):
# 直接将配置信息,存储到config对象中
self.width = 800 # 宽度
self.height = 600 # 高度
self.title = '外星人入侵' # 游戏的标题
self.bg_color = (230, 230, 230) # 背景颜色
self.ship_dir = 0 # 飞船的移动方向
self.ship_speed =1 # 飞船的速度
self.bullet_color = (0,0,0) # 子弹的颜色
self.bullet_width = 3 # 子弹的宽度
self.bullet_height = 15 # 子弹的长度
self.bullet_speed = 1 # 子弹的速度
self.bullet_count = 3 # 限制子弹的最大数量
self.alien_dir = 1 # 外星人的移动方向,1向右,-1向左
self.alien_speed = 1 # 外星人的移动速度
self.life = 3 # 默认飞船三条命
@property
def size(self):
return self.width, self.height
alien.py
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
'''
表示外星人的类
'''
def __init__(self, screen, gc):
super().__init__()
self.screen = screen # 屏幕
self.gc = gc
# sprite 中需要image 和 rect
# 当指定这两个属性时,调用group的draw方法会自动对图层进行配置
# 约定优于配置
self.image = pygame.image.load('./data/alien.bmp') # 图片
self.rect = self.image.get_rect() # 矩形
def update(self):
'''
更新外星人的位置
'''
self.rect.x += self.gc.alien_speed * self.gc.alien_dir
# if self.check_edge():
# # 有外星人移动到了屏幕边缘
# self.gc.alien_dir = -self.gc.alien_dir
def check_edge(self):
'''
检查外星人是否移动到屏幕边缘
:return:
到边缘,返回true
没到,返回False
'''
return self.rect.x <= 0 or \
self.rect.right >= self.screen.get_rect().right
bullet.py
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
'''
表示子弹的类
'''
def __init__(self, screen, gc, ship):
# 调用父类的init
super().__init__()
# fill (color, rect=None) -> Rect
self.color = gc.bullet_color# 子弹的颜色
self.rect = pygame.Rect(0, 0, gc.bullet_width, gc.bullet_height) # 表示矩形的大小和位置
# 设置子弹的位置
self.rect.centerx = ship.rect.centerx
self.rect.centery = ship.rect.centery
self.gc = gc # 存储配置对象
self.screen = screen # 屏幕的对象
def draw_bullet(self):
'''
在屏幕中绘制子弹
'''
self.screen.fill(self.color, self.rect)
def update(self):
'''
修改子弹位置
'''
self.rect.y -= self.gc.bullet_speed
# 将没用的子弹销毁,飞出屏幕就需要进行销毁
if self.rect.bottom < 0:
# 销毁子弹,将子弹从列表中移除
# 要从列表中删除子弹,必须先获取到列表的对象
# lst.remove(...)
self.kill()
self.draw_bullet()
ship.py
import pygame
from pygame.sprite import Sprite
# 保存飞船类的模块
class Ship(Sprite):
'''
表示飞船(玩家)
image 飞船的样子
rect 飞船的大小和位置
'''
def __init__(self, screen, gc):
super().__init__()
self.image = pygame.image.load('./data/ship.bmp') # 加载飞船的图片
self.rect = self.image.get_rect() # 设置飞船的默认矩形
self.screen = screen # 设置游戏主窗口
self.scr_rect = screen.get_rect()
self.gc = gc # 设置配置文件
# 设置飞船的位置,底部 居中
self.rect.bottom = self.scr_rect.bottom
self.rect.centerx = self.scr_rect.centerx
def update(self):
'''
修改飞船的位置
'''
# 判断移动的方向
# if self.gc.ship_dir == 1:
# # # 向右移动
# # self.rect.x += self.gc.ship_speed
# #
# # elif self.gc.ship_dir == -1:
# # # 向左移动
# # self.rect.x -= self.gc.ship_speed
self.rect.x += self.gc.ship_speed * self.gc.ship_dir
# self.rect.y += self.gc.ship_speed * self.gc.ship_dir
# 判断飞船是移出画面
if self.rect.x < 0:
self.rect.x = 0
elif self.rect.right > self.scr_rect.right:
self.rect.right = self.scr_rect.right
def blitme(self):
# 将飞船在游戏窗口中显示
self.screen.blit(self.image ,self.rect)
打包setup.py
from cx_Freeze import setup, Executable
# win32的界面
base = 'Win32GUI'
# 设置打包的信息 "main.py" 打包的主文件名 base 打包的环境
executables = [Executable("main.py", base=base)]
# 要一起打包的包,一般不用指定,会自动搜索,如果有没有匹配到的则需要指定
packages = []
# 需要一起打包的资源文件
files = ['data']
# 打包的设置
options = {
'build_exe': {
'packages':packages, # 依赖的包
'include_files':files #依赖的资源
},
}
# 执行打包程序
setup(
name = "外星人入侵", #项目名
options = options, # 配置信息
version = "1.0", # 项目的版本
description = '打包测试,外星人入侵', #项目的描述
executables = executables #主文件环境信息
)