外星人入侵(python)

前言

代码来源《python编程从入门到实践》Eric Matthes 署 袁国忠 译

使用软件:PyCharm Community Editor 2022

目的:记录一下按照书上敲的代码

alien_invasion.py

游戏的一些初始化设置,界面的大小,标题

import sys
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Group
from alien import Alien
from game_stats import  GameStats


def run_game():
    # 初始化游戏并创建一个屏幕对象
    pygame.init()
    ai_settigns = Settings()
    # 里面是一个元组
    screen = pygame.display.set_mode((ai_settigns.screen_width, ai_settigns.screen_height))
    # 窗口尺寸,宽高
    # screen=pygame.display.set_mode((1200,800))
    # 窗口标题
    pygame.display.set_caption("Alien Invasion")
    #创建一个用于存储游戏统计信息的实例
    stats=GameStats(ai_settigns)

    # 设置背景色
    # bg_color=(230,230,230)
    # 创建一艘飞船、一个子弹编组和一个外星人编组
    ship = Ship(ai_settigns, screen)
    # 创建一个用于存储子弹的编组
    bullets = Group()
    # 创建一个外星人
    # alien=Alien(ai_settigns,screen)
    aliens = Group()
    # 创建外星人群
    gf.create_fleet(ai_settigns, screen, ship, aliens)

    # 开始游戏的主循环
    while True:
        gf.check_events(ai_settigns, screen, ship, bullets)
        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settigns, screen, ship, aliens, bullets)
            gf.update_aliens(ai_settigns,stats,screen,ship, aliens,bullets)
        # print(len(bullets))

        gf.update_screen(ai_settigns, screen, ship, aliens, bullets)
        # 监视键盘和鼠标事件
        # for event in pygame.event.get():
        #     if event.type==pygame.QUIT:
        #         sys.exit()
        # 每次循环都重绘屏幕
        # screen.fill(bg_color)
        # screen.fill(ai_settigns.gb_color)
        # ship.blitme()
        # 让最近绘制的屏幕可见
        # pygame.display.flip()


run_game()

game_functions.py

 游戏主体


import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleep


def check_keydown_events(event, ai_settings, screen, ship, bullets):
    # 响应按键
    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
    elif event.key == pygame.K_SPACE:
        fire_bullet(ai_settings, screen, ship, bullets)
    # 按下键盘上的q键同样关闭游戏界面(需要是英文状态下)
    elif event.key == pygame.K_q:
        sys.exit()


def check_keyup_events(event, ship):
    # 响应松开
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    elif event.key == pygame.K_LEFT:
        ship.moving_left = False


def check_events(ai_settings, screen, ship, bullets):
    # 响应按键和鼠标事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            # if event.key == pygame.K_RIGHT:
            #     ship.moving_right = True
            # elif event.key == pygame.K_LEFT:
            #     ship.moving_left = True
            check_keydown_events(event, ai_settings, screen, ship, bullets)
        elif event.type == pygame.KEYUP:
            # if event.key == pygame.K_RIGHT:
            #     ship.moving_right = False
            # elif event.key == pygame.K_LEFT:
            #     ship.moving_left = False
            check_keyup_events(event, ship)


def update_screen(ai_settings, screen, ship, aliens, bullets):
    # 更新屏幕上的图像,并切换到新屏幕
    # 每次循环时都重绘屏幕
    screen.fill(ai_settings.gb_color)
    # 在飞船和外星人后面重绘所有子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    aliens.draw(screen)
    # 让最近绘制的屏幕可见
    pygame.display.flip()


def update_bullets(ai_settings, screen, ship, aliens, bullets):
    # 更新子弹的位置,并删除已经消失的子弹
    # 更新子弹的位置
    bullets.update()

    # 删除已经消失的子弹
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)

    # 检查是否有子弹击中了外星人
    # 如果是这样,就删除相应的子弹和外星人
    check_bullet_alien_collision(ai_settings, screen, ship, aliens, bullets)


def check_bullet_alien_collision(ai_settings, screen, ship, aliens, bullets):
    # 响应子弹和外星人的碰撞
    # 删除发生碰撞的子弹和外星人
    collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
    if len(aliens) == 0:
        # 删除现有的子弹并新建一群外星人
        bullets.empty()
        create_fleet(ai_settings, screen, ship, aliens)


def fire_bullet(ai_settings, screen, ship, bullets):
    # 如果还没有到达限制,就发射一颗子弹
    # 创建一颗子弹,并将其加入到编组bullets中
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)


def create_fleet(ai_settings, screen, ship, aliens):
    # 创建一个外星人群
    # 创建一个外星人,并计算每行可容纳多少个外星人
    alien = Alien(ai_settings, screen)
    number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)
    number_rows = get_number_rows(ai_settings, ship.rect.height, alien.rect.height)

    # 创建外星人群
    for row_number in range(number_rows):
        for alien_number in range(number_aliens_x):
            # 创建一个外星人并将其加入当前行
            create_alien(ai_settings, screen, aliens, alien_number, row_number)


def get_number_aliens_x(ai_settings, alien_width):
    # 计算每行可容纳多少个外星人
    available_space_x = ai_settings.screen_width - 2 * alien_width
    number_aliens_x = int(available_space_x / (2 * alien_width))
    return number_aliens_x


def create_alien(ai_settings, screen, aliens, alien_number, row_number):
    # 创建一个外星人并将其放在当前行
    # 外星人间距为外星人的宽度
    alien = Alien(ai_settings, screen)
    alien_width = alien.rect.width
    alien.x = alien_width + 2 * alien_width * alien_number
    alien.rect.x = alien.x
    alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
    aliens.add(alien)


def get_number_rows(ai_settings, ship_height, alien_height):
    # 计算屏幕可容纳多少行外星人
    available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)
    number_rows = int(available_space_y / (2 * alien_height))
    return number_rows


def update_aliens(ai_settings, stats, screen, ship, aliens, bullets):
    # 检查是否有外星人位于屏幕边缘,更新外星人群中所有外星人的位置
    check_fleet_edges(ai_settings, aliens)
    aliens.update()

    # 检测外星人和飞船之间的碰撞
    if pygame.sprite.spritecollideany(ship, aliens):
        print("Ship hit!!!")
        ship_hit(ai_settings, stats, screen, ship, aliens, bullets)

    # 检查是否有外星人到达屏幕底端
    check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets)


def check_fleet_edges(ai_settings, aliens):
    # 有外星人到达边缘采取相应的措施
    for alien in aliens.sprites():
        if alien.check_edges():
            change_fleet_direction(ai_settings, aliens)
            break


def change_fleet_direction(ai_settings, aliens):
    # 将整群外星人下移,并改变他们的方向
    for alien in aliens.sprites():
        alien.rect.y += ai_settings.fleet_drop_speed
    ai_settings.fleet_direction *= -1


def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):
    # 响应被外星人撞到的飞船
    if stats.ships_left > 0:
        # 将ships_letf减1
        stats.ships_left -= 1

        # 清空外星人列表和子弹列表
        aliens.empty()
        bullets.empty()

        # 创建一群新的外星人,并将飞船放到屏幕底端中央
        create_fleet(ai_settings, screen, ship, aliens)
        ship.center_ship()

        # 暂停
        sleep(0.5)
    else:
        stats.game_active = False


def check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets):
    # 检查是否有外星人到达了屏幕底端
    screen_rect = screen.get_rect()
    for alien in aliens.sprites():
        if alien.rect.bottom >= screen_rect.bottom:
            # 向飞船被撞到一样进行处理
            ship_hit(ai_settings, stats, screen, ship, aliens, bullets)
            break

settings.py

游戏的一些初始化数据的储存,子弹的速度,大小,屏幕的大小

class Settings():
    # 储存《外星人入侵》所设置的类
    def __init__(self):
        # 初始化游戏的设置
        # 屏幕设置
        self.screen_width = 1200
        self.screen_height = 800
        self.gb_color = (230, 230, 230)

        # 飞船设置
        # 位置
        self.ship_speed_factor = 1.5
        self.ship_limit = 3

        # 子弹设置(宽高,颜色)
        self.bullet_speed_factor = 1  # 速度
        self.bullet_width = 3  # 宽度
        self.bullet_height = 15  # 高度
        self.bullet_color = 60, 60, 60  # 颜色
        self.bullets_allowed = 3

        # 外星人设置
        self.alien_speed_factor = 1
        self.fleet_drop_speed = 10
        # fleet_direction为1表示向右移,为-1表示向左移
        self.fleet_direction = 1

ship.py

 飞船的初始化信息和移动

import pygame


class Ship():

    def __init__(self, ai_settings, screen):
        # 初始化飞船并设置其初始位置
        self.screen = screen
        self.ai_settings = ai_settings
        # 加载飞船图像并获取外接矩形
        self.image = pygame.image.load('images/ship.png')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()
        # 将每艘新飞船放在屏幕底部中央
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom
        # 在飞船的属性center中存储小数值
        self.center = float(self.rect.centerx)

        # 移动标志
        self.moving_right = False
        self.moving_left = False

    def update(self):
        # 根据移动标志调整飞船的位置
        # 更新飞船的center值,而不是rect
        # if self.moving_right:
        # 增加不能越界的条件
        if self.moving_right and self.rect.right < self.screen_rect.right:
            # self.rect.centerx += 1
            self.center += self.ai_settings.ship_speed_factor
        # elif self.moving_left:
        if self.moving_left and self.rect.left > 0:
            # self.rect.centerx -= 1
            self.center -= self.ai_settings.ship_speed_factor

        # 根据self.center更新rect对象
        self.rect.centerx = self.center

    def blitme(self):
        # 在指定位置绘制飞船
        self.screen.blit(self.image, self.rect)

    def center_ship(self):
        # 让飞船在屏幕上居中
        self.center = self.screen_rect.centerx

alien.py

外星人的初始信息和移动

import pygame
from pygame.sprite import Sprite


class Alien(Sprite):
    # 表示单个外星人的类

    def __init__(self, ai_settings, screen):
        # 初始化外星人并设置起始位置
        super(Alien, self).__init__()
        self.screen = screen
        self.ai_settins = ai_settings

        # 加载外星人图像,并设置其rect属性
        self.image = pygame.image.load('images/alien.png')
        self.rect = self.image.get_rect()

        # 每个外星人最初都在屏幕左上角附近
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        # 存储外星人的准确位置
        self.x = float(self.rect.x)

    def blitme(self):
        # 在指定位置绘制外星人
        self.screen.blit(self.image, self.rect)

    def update(self):
        # 向右、左移动外星人
        # self.x += self.ai_settins.alien_speed_factor
        self.x += (self.ai_settins.alien_speed_factor * self.ai_settins.fleet_direction)
        self.rect.x = self.x

    def check_edges(self):
        # 如果外星人位于屏幕边缘,就返回True
        screen_rect = self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <= 0:
            return True

bullet.py

子弹的显示

import pygame
from pygame.sprite import Sprite


class Bullet(Sprite):
    # 一个对飞船发射的子弹进行管理的类

    def __init__(self, ai_settings, screen, ship):
        # 在飞船所处的位置创建一个子弹对象
        super(Bullet, self).__init__()
        self.screen = screen

        # 在(0,0)处创建一个表示子弹的矩形,在设置正确的位置
        self.rect = pygame.Rect(0, 0, ai_settings.bullet_width, ai_settings.bullet_height)
        self.rect.centerx = ship.rect.centerx
        self.rect.top = ship.rect.top

        # 存储用小数表示的子弹位置
        self.y = float(self.rect.y)
        self.color = ai_settings.bullet_color
        self.speed_factor = ai_settings.bullet_speed_factor

    def update(self):
        # 向上移动子弹
        # 更新表示子弹位置的小数值
        self.y -= self.speed_factor
        # 更新表示子弹的rect的位置
        self.rect.y = self.y

    def draw_bullet(self):
        # 在屏幕上绘制子弹
        pygame.draw.rect(self.screen, self.color, self.rect)

game_stats.py

游戏是否结束

class GameStats():
    # 跟踪游戏的统计信息

    def __init__(self, ai_settings):
        # 初始化统计信息
        self.ai_settings = ai_settings
        self.reset_stats()
        # 游戏刚启动时处于活动状态
        self.game_active=True

    def reset_stats(self):
        # 初始化在游戏运行期间可能变化的统计信息
        self.ships_left = self.ai_settings.ship_limit

我们的飞船和下面的飞船相撞或者撞到下面的墙都会输出:“Ship hit!!!”

 

总结

主要是记录一下这个,毕竟敲了这么久了,不过还是要理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/361903.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

spring boot 项目中的异常处理

出现异常&#xff1a; 怎样定义全局异常处理器 新建一个类&#xff0c;加上注释两个 ControllerAdvice(basePackages"com.example.controller") public class GlobalExceptionHandler {private static final Log log LogFactory.get();//统一异常处理ExceptionHandl…

SOLIDWORKS Simulation 2024增强新功能

SOLIDWORKS 2024 新功能前瞻| SOLIDWORKS Simulation 功能增强 • 性能增强功能 • 壳体的接合交互 • 网格性能 • 欠约束实体检测 • 增强型轴承接头 • 收敛检查图解 • 去耦合混合自由体模式 • 复制算例时排除网格和结果 • 新增在网格化后及分析完成后自动保存模…

【Tomcat与网络10】Tomcat I/O和线程池的并发调优

前面我们看了提高Tomcat启动速度的措施&#xff0c;这里我们看一下如何提高Tomcat的性能。 Tomcat 的调优涉及 I/O 模型和线程池调优、JVM 内存调优以及网络优化等&#xff0c;今天我们来聊聊 I/O 模型和线程池调优&#xff0c;由于 Web 应用程序跑在 Tomcat 的工作线程中&…

给定n个结点的树,u,v两个结点可以配对当且仅当u不是v的祖先且v不是u的祖先,每个结点最多与一个结点配对,求最大配对个数

题目 思路: #include <bits/stdc++.h> using namespace std; #define int long long typedef long long ll; #define pb push_back #define lson p << 1 #define rson p << 1 | 1 #define fi first #define se second const int maxn = 1e6 + 5, maxm = 5e…

【破事水】Java Gradle 无法引入同名不同版本的两个包

此问题水于 2024 年 01 月&#xff0c;假如后面 gradle 出了什么好方法能解决这个问题&#xff0c;家祭无忘告乃翁&#xff0c;提前谢过看到这篇的各位大佬了。 结论 先说结论&#xff0c;Java 因为包名定义等原因&#xff0c;对同名包在编译时只能编译一个版本&#xff0c;具…

Linux 内核学习1. 编译并启动一个最小化系统

Linux 内核学习1. 编译并启动一个最小化系统 一、Linux内核简介1. Linux 内核介绍2. Linux内核主要的作用 二、编译内核主要的步骤三、编译过程1. 准备环境2. 安装编译工具和依赖项3. 下载源码4. 配置内核配置功能选项命令行配置图形化配置默认配置 5. 编译内核6. 构建轻量化工…

有什么办法保护网站安全

随着互联网的快速发展&#xff0c;随着品牌效应的加大&#xff0c;企业网站已经成为了企业对外展示的明信片&#xff0c;以及宣传获取私有流量的重要渠道&#xff0c;网站的安全性也越来越受到用户的重视&#xff0c;保护网站安全是运维人员非常重要的任务。德迅云安全深耕网络…

Qt 5.9.4 转 Qt 6.6.1 遇到的问题总结(三)

1.QSet: toList 中的toList 函数已不存在&#xff0c;遇到xx->toList改成直接用&#xff0c;如下&#xff1a; 2.开源QWT 图形库中QwtDial中的 setPenWidth 变成 setPenWidthF函数。 3.QDateTime 中无setTime_t 改为了setSecsSinceEpoch函数。 4.QRegExp 类已不存在 可以用Q…

Node.js Express 框架 2024版 笔记

1.0 操作命令 Node.js express 框架 https://www.expressjs.com.cn/ npm install -g express-generator expressexpress --pug --git // --pug 添加对 pug 模板引擎的支持 // --git 添加 .gitignore 代码仓库排除 //无法直接安装新版pug模板 npm i npm …

SqueezeNet模型详解

简介 SqueezeNet是一种轻量级卷积神经网络架构&#xff0c;旨在保持较高性能的同时减少模型的参数数量和计算复杂度。由于其小尺寸和高效性能&#xff0c;SqueezeNet适用于在资源受限的环境中部署&#xff0c;如移动设备和嵌入式系统。 SqueezeNet是通过使用一种"Fire M…

AI的安全应答之道

作者&#xff1a;统信UOS技术团队 2023,随着各种大语言模型的爆发&#xff0c;整个AI生态正处于从决策式AI进化到生成式AI的进程中。各类AI模型和AI应用层出不穷&#xff0c;也随之带来了与AI相关的各类潜在风险。AI开发和使用过程中的风险防范和治理&#xff0c;成为了不可忽…

神经网络的一些常规概念

epoch&#xff1a;是指所有样本数据在神经网络训练一次&#xff08;单次epoch(全部训练样本/batchsize)/iteration1&#xff09;或者&#xff08;1个epochiteration数 batchsize数&#xff09; batch-size&#xff1a;顾名思义就是批次大小&#xff0c;也就是一次训练选取的样…

力扣hot100 前 K 个高频元素 小根堆 流 IntStream

Problem: 347. 前 K 个高频元素 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 参考 小根堆&#xff08;维护k个高频元素&#xff09;遍历所有元素&#xff0c;当前堆大小 < k 或者 当前元素出现次数大于堆顶元素出现次数&#xff1a;替换掉堆顶元素 复杂…

2024Node.js零基础教程(小白友好型),nodejs新手到高手,(三)NodeJS入门——http协议

033_HTTP协议_初识HTTP协议 hello&#xff0c;大家好&#xff0c;这个小节我们来认识一下 http协议。 http是几个单词的首字母拼写&#xff0c;全称为Hypertext Transfer Protocol 译为超文本传输协议&#xff0c;那么这个http协议是互联网上应用最广泛的协议之一。顺便说一下…

使用 axios 请求库,设置请求拦截

什么是 axios&#xff1f; 基于promise网络请求库&#xff0c;可以同构&#xff08;同一套代码可以运行在浏览器&#xff09;&#xff0c;在服务端&#xff0c;使用原生node.js的http模块&#xff0c;在客户端&#xff08;浏览器&#xff09;中&#xff0c;使用XMLHttpRequests…

【Godot4自学手册】第十节将场景添加到TileSet绘制背景,主人公走到房子后面房子变得半透明

这节主要学习将场景添加到TileSet作为TileMap来搭建背景。同时&#xff0c;主人公进入房子后面&#xff0c;房子变得半透明&#xff0c;离开房子后房子变的不透明。 一、创建新场景 首先导入房子素材&#xff0c;最终文件系统内容如下&#xff1a; 点击新建场景按钮&#x…

【Qt学习笔记】(一)初识Qt

Qt学习笔记 1 使用Qt Creator 新建项目2 项目代码解释3 创建第一个 Hello World 程序4 关于内存泄漏问题5 Qt 中的对象树6 关于 qDebug&#xff08;&#xff09;的使用7 使用其他方式创建一个 Hello World 程序&#xff08;编辑框和按钮方式&#xff09;8 关于 Qt 中的命名规范…

阿里云智能集团副总裁安筱鹏:企业数字化的终局是什么?

以下文章来源于数字化企业 &#xff0c;作者安筱鹏博士 回答数字化终局追问的起点是&#xff0c;企业需要重新定义我是谁。成为有竞争力的行业领导厂商&#xff0c;你应当成为一个客户运营商&#xff0c;即能够实时洞察、实时满足客户需求&#xff0c;追求极致的客户体验。而要…

使用 Docker 部署扫雷小游戏

1&#xff09;源码 介绍&#xff1a;扫雷游戏是一款经典的单人益智游戏&#xff0c;旨在通过揭示方块和避开地雷来展示玩家的逻辑思维和推理能力。 源码&#xff1a;saolei.zip 个人文件站&#xff1a;https://share.wuhanjiayou.cn/ 2&#xff09;部署 2.1&#xff09;安装…

SpringBoot中处理校验逻辑的两种方式:Hibernate Validator+全局异常处理

最近正在开发一个知识库学习网站编程喵&#x1f431;&#xff0c;需要对请求参数进行校验&#xff0c;比如说非空啊、长度限制啊等等&#xff0c;可选的解决方案有两种&#xff1a; 一种是用 Hibernate Validator 来处理一种是用全局异常来处理 两种方式&#xff0c;我们一一…