类实例:飞机大战

简介: 一、子弹模块import pygameWINDOW_WIDTH = 512 # 根据实际需求调整窗口大小WINDOW_HEIGHT = 768class Bullet(object): def __init__(self): # 图片,矩形对象,速度 self.

一、子弹模块

import pygame
WINDOW_WIDTH = 512             # 根据实际需求调整窗口大小
WINDOW_HEIGHT = 768

class Bullet(object):
    def __init__(self):
        # 图片,矩形对象,速度
        self.bullet_img = pygame.image.load('res/bullet_11.png')           # 资源文件自己选择
        self.enemy_bullet_img = pygame.image.load('res/bullet_4.png')
        self.bullet_rect = self.bullet_img.get_rect()
        self.enemy_bullet_rect = self.enemy_bullet_img.get_rect()
        self.speed = 5
        self.enemy_speed = 3
        # 开关
        #开:表示可以移动可以绘制可以杀敌人
        # 关闭:当子弹移动到窗口外面的时候回:表示不移动不绘制也不杀敌人
        # 开关的默认状态:关:当用户发射子弹的时候才打开开关
        self.is_shot = False
        self.enemy_is_shot = False
    def move(self):
        self.bullet_rect.move_ip(0, -self.speed)
        self.enemy_bullet_rect.move_ip(0, self.enemy_speed)
        # 当子弹移动到窗口上面的外面,开关关闭
        if self.bullet_rect[1] < 0:
            self.is_shot = False
        if self.enemy_bullet_rect[1] > 600:
            self.enemy_is_shot = False

  

二、敌人模块

import pygame
import random
import bullet

WINDOW_WIDTH = 512              # 这里由于我电脑分辨率有问题,我把界面调小了。。
WINDOW_HEIGHT = 600
class Enemy(object):
    def __init__(self):
        # 图片、矩形对象(设置敌机的默认位置)、速度 img-plane_1.png
        num = str(random.randint(1, 7))
        self.enemy_img = pygame.image.load('res/img-plane_'+ num +'.png')
        self.enemy_rect = self.enemy_img.get_rect()
        # 默认位置水平是随机,垂直窗口外面
        self.enemy_rect[0] = random.randint(0, WINDOW_WIDTH-self.enemy_rect[2])
        self.enemy_rect[1] = -self.enemy_rect[3]  # 0, 0, 宽度,高
        self.speed = random.randint(2, 4)
        self.enemy_bullet_list = [bullet.Bullet() for _ in range(10)]


    def move(self):
        # 移动矩形对象move_ip (0,+speed)
        self.enemy_rect.move_ip(0, self.speed)
        # 因为敌机需要循环使用,判断如果移动到窗口下面的外面,把敌机放到初始位置
        if self.enemy_rect[1] > WINDOW_HEIGHT:
            self.reset()

    def reset(self):
        self.enemy_rect[0] = random.randint(0, WINDOW_WIDTH - self.enemy_rect[2])
        self.enemy_rect[1] = -self.enemy_rect[3]  # 0, 0, 宽度,高
        self.speed = random.randint(2, 3)

    def shot(self):
        # 摆子弹位置 -- 10 list
        for bullet in self.enemy_bullet_list:
            # 如果子弹是为发射状态的才摆位置 -- 开关false
            # if bullet.is_shot == False
            if not bullet.enemy_is_shot:
                #水平
                bullet.enemy_bullet_rect[0] = self.enemy_rect[0] + self.enemy_rect[2]/2 - bullet.enemy_bullet_rect[2]/2
                bullet.enemy_bullet_rect[1] = self.enemy_rect[1] + self.enemy_rect[3]
                # 之所以摆位置是因为要发射了
                bullet.enemy_is_shot = True
                break # 取一发子弹就可以了,当下次用户按j或者空格的时候再调用这个shot函数

  

三、游戏地图模块

import pygame
import random

WINDOW_WIDTH = 512
WINDOW_HEIGHT = 768

class GameMap(object):
    def __init__(self):
        # 加载两个图片,设置图片的初始位置、移动的速度
        self.num = str(random.randint(1,5))  # 保证随机的是同一个数字
        self.bg_img1 = pygame.image.load('res/img_bg_level_' + self.num + '.jpg')
        self.bg_img2 = pygame.image.load('res/img_bg_level_' + self.num + '.jpg')
        self.bg_img1_y = -WINDOW_HEIGHT
        self.bg_img2_y = 0
        self.speed = 1

    def map_scroll(self):
        if self.bg_img1_y >= 0:
            self.bg_img1_y = -WINDOW_HEIGHT
        if self.bg_img2_y >= WINDOW_HEIGHT:
            self.bg_img2_y = 0
        self.bg_img1_y += self.speed
        self.bg_img2_y += self.speed

 

四、我方英雄战机模块

import pygame
import bullet
WINDOW_WIDTH = 512
WINDOW_HEIGHT = 600

class Hero(object):
    def __init__(self):
        # 图、矩形对象、速度、设置飞机初始位置
        self.hero_img = pygame.image.load('res/hero.png')
        self.hero_rect = self.hero_img.get_rect()  # (0, 0, 120, 78)
        self.hero_rect.move_ip(WINDOW_WIDTH/2-self.hero_rect[2]/2, WINDOW_HEIGHT-self.hero_rect[3])
        # (水平中间, 垂直底部, 120 ,78)
        self.speed = 2
        # 因为是飞机发射子弹,创建子弹对象:10 -- 创建一个子弹列表
        # self.bullet = bullet.Bullet()
        self.bullet_list = [bullet.Bullet() for _ in range(1000)]


    def move_up(self):
        # 上移动 -- y -speed -- >0
        if self.hero_rect[1] > 0:
            self.hero_rect.move_ip(0, -self.speed)

    def move_down(self): # y +speed  < 最低坐标
        if self.hero_rect[1] < WINDOW_HEIGHT-self.hero_rect[3]:
            self.hero_rect.move_ip(0, self.speed)
    def move_left(self):
        if self.hero_rect[0] > 0:
            self.hero_rect.move_ip(-self.speed, 0)
    def move_right(self):
        if self.hero_rect[0] < WINDOW_WIDTH- self.hero_rect[2]:
            self.hero_rect.move_ip(self.speed, 0)

    def shot(self):
        # 摆子弹位置 -- 10 list
        for bullet in self.bullet_list:
            # 如果子弹是为发射状态的才摆位置 -- 开关false
            # if bullet.is_shot == False
            if not bullet.is_shot:
                #水平
                bullet.bullet_rect[0] = self.hero_rect[0] + self.hero_rect[2]/2 - bullet.bullet_rect[2]/2
                bullet.bullet_rect[1] = self.hero_rect[1] - bullet.bullet_rect[3]
                # 之所以摆位置是因为要发射了
                bullet.is_shot = True
                break # 取一发子弹就可以了,当下次用户按j或者空格的时候再调用这个shot函数

  

五、飞机大战主模块

# 创建窗口对象,显示
import pygame
import sys  # 为了关闭游戏窗口
import game_map
import hero
import bullet
import enemy
# import time


# 经验:但凡变量名全都大写,表示的后期不做这个数据的修改了
WINDOW_WIDTH = 512
WINDOW_HEIGHT = 600


class GameWindow(object):
    def __init__(self):
        pygame.init()
        # 尺寸,标题。标志
        self.window = pygame.display.set_mode([WINDOW_WIDTH, WINDOW_HEIGHT])
        pygame.display.set_caption('飞机大战V1.1')
        self.ico = pygame.image.load('res/app.ico')
        pygame.display.set_icon(self.ico)
        # 创建地图对象
        self.map = game_map.GameMap()
        # 先有动画还是先绘制图片  --
        # 创建飞机对象
        self.hero = hero.Hero()
        # 创建敌机对象
        self.enemy_list = [enemy.Enemy() for _ in range(5)]
        # 加载背景音乐
        pygame.mixer.music.load("./res/bg2.ogg")
        # 循环播放背景音乐
        pygame.mixer.music.play(-1)


    def run(self):
        while True:
            self.action()
            self.draw()
            self.event()
            self.bullet_hit_enemy()
            if self.enemy_hit_hero():
                break
            self.update()

    # 函数 -- 做动画
    def action(self):
        # 地图动画调进来
        self.map.map_scroll()
        # 调用子弹移动动画
        for bullet in self.hero.bullet_list:
            if bullet.is_shot:
                bullet.move()
        for enemy in self.enemy_list:
            for bullet in enemy.enemy_bullet_list:
                if bullet.enemy_is_shot:
                    bullet.move()
        for enemy in self.enemy_list:
            enemy.move()

    # 函数 -- 绘制图片
    def draw(self):
        self.window.blit(self.map.bg_img1, (0,self.map.bg_img1_y))
        self.window.blit(self.map.bg_img2, (0,self.map.bg_img2_y))
        # 绘制飞机
        self.window.blit(self.hero.hero_img, (self.hero.hero_rect[0], self.hero.hero_rect[1]))
        # 绘制子弹:开关是true的
        for bullet in self.hero.bullet_list:
            if bullet.is_shot is True:
                self.window.blit(bullet.bullet_img, (bullet.bullet_rect[0], bullet.bullet_rect[1]))
        for enemy in self.enemy_list:
            for bullet in enemy.enemy_bullet_list:
                if bullet.enemy_is_shot is True:
                    self.window.blit(bullet.enemy_bullet_img, (bullet.bullet_rect[0], bullet.bullet_rect[1]))
        # 绘制敌机
        for enemy in self.enemy_list:
            self.window.blit(enemy.enemy_img, (enemy.enemy_rect[0], enemy.enemy_rect[1]))

    # 碰撞检测 -- 子弹碰撞敌机
    def bullet_hit_enemy(self):
        # 取每个子弹,看所有敌机,到底看哪个子弹(必须是发射状态开关是True)碰撞了哪个敌机
        for bullet in self.hero.bullet_list:
            if bullet.is_shot == True:
                for enemy in self.enemy_list:
                    if pygame.Rect.colliderect(bullet.bullet_rect, enemy.enemy_rect):
                        # 加载音效
                        boom_sound = pygame.mixer.Sound("./res/baozha.ogg")
                        # 播放音效
                        boom_sound.play()
                        # 敌机消失 -- 放到顶部 等下次向下移动reset
                        enemy.reset()
                        # 子弹消失-- false
                        bullet.is_shot = False
                        break

    # 碰撞检测 -- 敌机碰撞英雄飞机
    def enemy_hit_hero(self):
        for enemy in self.enemy_list:
            if pygame.Rect.colliderect(enemy.enemy_rect, self.hero.hero_rect):
                # 退出主循环
                return True
        return False



    # 英雄飞机人为控制移动,添加事件(event)函数
    def event(self):
        # 单次事件 -- 返回的是列表
        self.event_list = pygame.event.get()
        for event in self.event_list:
            # 叉号
            if event.type == pygame.QUIT:
                # 关闭游戏窗口
                # sys.exit()
                # # 退出pygame
                # pygame.quit()
                self.gameOver()
            # 判断键盘按下类型
            if event.type == pygame.KEYDOWN:
                # 判断按下的到底是哪个键
                if event.key == pygame.K_ESCAPE:
                    self.gameOver()
                if event.key == pygame.K_r:
                    for enemy in self.enemy_list:
                        enemy.shot()

        # 连续、多次事件  连续按键 -- 判断按下的是哪个key
        # time.sleep(3)
        self.pressed = pygame.key.get_pressed()
        if self.pressed[pygame.K_SPACE] or self.pressed[pygame.K_j]:
            self.hero.shot()
        # print(self.pressed)  (0,0,0,1,0,0)
        if self.pressed[pygame.K_UP]:
            self.hero.move_up()
        if self.pressed[pygame.K_DOWN]:
            self.hero.move_down()
        if self.pressed[pygame.K_LEFT]:
            self.hero.move_left()
        if self.pressed[pygame.K_RIGHT]:
            self.hero.move_right()

    def gameOver(self):
        pygame.quit()
        sys.exit()
    # 函数更新
    def update(self):
        pygame.display.update()

if __name__ == '__main__':
    game = GameWindow()
    game.run()

                                                                   -------  知识无价,汗水有情,如需搬运请注明出处,谢谢!

目录
相关文章
|
Prometheus 运维 监控
linux磁盘I/O监控
【4月更文挑战第1天】在Linux中监控磁盘I/O性能至关重要,工具如iostat(-d显示磁盘统计)、iotop(进程级I/O查看)、vmstat、/proc/diskstats(详细统计信息)、Node Exporter(Prometheus集成)和Zabbix(动态监控与LLD)提供关键指标,如IOPS、吞吐量、利用率和服务时间,助力系统优化和故障排查。
432 4
linux磁盘I/O监控
|
7月前
|
数据可视化 算法 数据挖掘
用傅里叶变换解码时间序列:从频域视角解析季节性模式
本文介绍了如何使用傅里叶变换和周期图分析来识别时间序列中的季节性模式,特别是在能源消耗数据中。通过Python实现傅里叶变换和周期图,可以有效提取并量化时间序列中的主要和次要频率成分,克服传统可视化分析的局限性。这对于准确捕捉时间序列中的季节性变化具有重要意义。文章以AEP能源消耗数据为例,展示了如何应用这些方法识别日、周、半年等周期模式。
291 3
用傅里叶变换解码时间序列:从频域视角解析季节性模式
|
8月前
|
人工智能 弹性计算 运维
OS Copilot
作为一名运维工程师,我发现OS Copilot安装便捷、文档详尽,适用于多种系统(如Debian)。其主要缺点是缺乏记忆性,无法记住之前的交互内容。然而,它能检测发行版并提出详细的解决方案,通过指令轻松执行,大大简化了日常运维工作。内嵌系统的优势使其对配置了解透彻,极大提升了工作效率。如果能改进记忆功能,将更有力地辅助甚至部分替代运维人员的工作。
OS Copilot
|
6月前
|
人工智能 自然语言处理 前端开发
【2025.3.04更新】wordpress AI智能插件|自动生成SEO文章/图片/视频+长尾词优化 内置DeepSeek多模型支持与API扩展
Linkreate WordPress AI插件提供自动化文章生成、关键词管理和内容采集等核心功能。支持根据关键词批量生成高质量文章,优化SEO并自动生成标签和摘要。插件还具备定时任务、API集成、前端AI客服窗口及媒体生成功能,帮助用户高效管理网站内容,提升SEO效果。简单配置即可实现多种定制化需求,极大简化了内容创作流程。
【2025.3.04更新】wordpress AI智能插件|自动生成SEO文章/图片/视频+长尾词优化 内置DeepSeek多模型支持与API扩展
|
9月前
|
人工智能 文字识别 API
|
9月前
|
机器学习/深度学习 人工智能 编解码
【AI系统】MobileVit 系列
MobileViT系列是基于Vision Transformer(ViT)架构设计的轻量级视觉模型,专为移动设备和嵌入式系统优化。MobileViT V1通过结合局部卷积和全局Transformer机制,实现了高性能与低资源消耗的平衡。V2进一步优化了Transformer中的多头自注意力机制,引入了线性复杂度的可分离自注意力,显著提升了计算效率。V3则对融合模块进行了简化,用1x1卷积替代3x3卷积,减少了参数量,同时引入了残差连接,进一步提升了模型性能。这些改进使MobileViT系列在保持高效的同时,能够在资源受限的设备上运行,表现出色。
383 8
【AI系统】MobileVit 系列
|
11月前
|
移动开发 前端开发 Android开发
开发指南059-App实现微信扫描登录
App是用uniapp开发的,打包为apk,上传到安卓平板中使用
|
11月前
|
存储 监控 安全
阿里云携手庆视互联数据迁云,助力全球业务升级
智能家居数据迁云,守护千万家庭安全
|
算法 Java BI
算法竞赛入门【码蹄集新手村600题】(MT1551-1600)
算法竞赛入门【码蹄集新手村600题】(MT1551、MT1552、MT1553、MT1554、MT1555......MT1600)
517 1
算法竞赛入门【码蹄集新手村600题】(MT1551-1600)

热门文章

最新文章