外星人入侵_python

素材

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述


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 #主文件环境信息
)

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯子@123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值