Python学习笔记42:游戏篇之外星人入侵(三)

前言

在之前我们已经创建好了目录,并且编写好了游戏入口的模块。今天的内容主要是讲讲需求的分析以及项目各模块的代码初步编写。

在正式编写代码前,碎碎念几句。在正式编写一个项目代码之前,实际是有很多工作要做的。就项目而言,简单的定项,需求对齐,项目架构设计,实际的代码编写,测试,上线等过程都是有的。

我们这个属于学习人家的项目,所有我们直接从代码编写开始,也可以从架构设计开始。直接从代码开始,就是直接按着书上的步骤来,直接写代码就好了,这个是最简单,有手就行,对于新手来说这样也做也不是大问题,但是如果是想从事编程工作或者想深入的学习下去,个人还是建议从架构设计开始,自己分析,自己设计。哪怕这个项目很简单,或者自己分析设计的有问题,也没关系,失败更能让人印象深刻。

之所以在这个时候讲这些,因为项目目录和main模块,是相对固定的内容,哪怕换一个项目,先把这两部分搞完也没关系,在实际业务代码的编写中查缺补漏也没问题。但是你不先根据需求设计项目的架构,写一点是一点,后面改起来麻烦就大了。

外星人入侵是个小项目,改改无所谓,而且这个项目网上一搜代码都能找到,但是实际遇到的项目,没有代码给你参考,项目代码量可能几十万行,写到后面发现设计得到不好,那怎么办?

这是设计思维的问题,哪怕我们前期是个螺丝钉,这种活不需要我们操心,写代码就行,但是人总是要成长的不是吗?目光要看向以后。

分析

先看看项目需求。

我们需要开发一个外星人入侵的小游戏,实际上就是简易版的雷霆战机,并且我们一期开发只需要实现基本的游戏功能就行,我们先大概整理一下:

  1. main模块。main模块是游戏入口,没入口怎么玩!
  2. 系统设置模块。主要用于设置游戏的一些信息,窗口大小,飞船移动速度,外星人移动速度等等。
  3. 飞船模块。没有飞船怎么打外星人!
  4. 子弹模块。没有子弹飞船只能和外星人一换一了!
  5. 外星人模块。游戏就叫外星人入侵,你和我说没有外星人?

main模块

main模块已经写好了,主要是项目启动模块,并且在该模块中,实现游戏窗口相关的功能代码。

import sys
import pygamedef run_game():"""启动游戏"""# 初始化pygamepygame.init()# 新建窗口screen = pygame.display.set_mode((1200, 800))# 窗口命名pygame.display.set_caption("alien_invasion")while True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()# 刷新屏幕pygame.display.flip()if __name__ == '__main__':run_game()

注意的是游戏窗口渲染的时候是在循环中监听事件,从而做出对应的响应。作为main模块,我们应该保持main模块代码的简洁性以及可读性,因此我们需要将窗口渲染的一些业务实现代码封装到一个单独的模块中,在main模块进行调用即可。

我们再单独建立一个game_function.py模块,后面都简称gf模块

注意这个时候我们这个模块啥也没有。看看main模块,窗口创建和命名就两行,够简洁了。

那么我们的目光看向事件监听。嗯~,竟然有四行,后面可能还会更多的,毕竟后面飞船移动和射击还要监听按键的按下和松开事件,封装,必须封装!

封装后的gf模块

import sys
import pygamedef check_event():for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()

封装好以后,再改造一下main模块,主要是导入gf模块和调用check_event函数

import pygame
import alien_invasion.game_functions as gfdef run_game():"""启动游戏"""# 初始化pygamepygame.init()# 新建窗口screen = pygame.display.set_mode((1200, 800))# 窗口命名pygame.display.set_caption("alien_invasion")while True:# 处理监听事件gf.check_event()# 刷新屏幕pygame.display.flip()if __name__ == '__main__':run_game()

目前为止,main模块的基础代码编写就改造好了,后续随着其他功能的实现,继续在gf模块编写函数,再由main模块调用即可。

展示一下当前的目录结构:

在这里插入图片描述

系统设置模块

这个模块简单点就是存储一些系统设置信息,比如游戏窗口的宽高,背景颜色,飞船和外星人的移动速度等等。

如果是想要复杂点的功能,我们可以另外编写函数修改这些信息即可。

那么我们创建setting模块,并且简单的设置几个值。

class Setting:"""系统设置类"""def __init__(self):# 窗口宽self.screen_width = 1200# 窗口高self.screen_height = 800# 背景颜色self.bg_color = (230, 230, 230)# 窗口名self.caption = "Alien Invasion"

既然已经使用了系统设置模块并定义了窗口的一些属性,那么我们再对main模块改造一下,在创建窗口的时候使用设置类的值,而不是直接在代码中写死。

import pygame
import alien_invasion.game_functions as gf
from alien_invasion.setting import Settingdef run_game():"""启动游戏"""# 初始化pygamepygame.init()# 定义一个系统设置对象setting = Setting()# 新建窗口screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))# 窗口命名pygame.display.set_caption(setting.caption)while True:# 处理监听事件gf.check_event()# 刷新屏幕pygame.display.flip()if __name__ == '__main__':run_game()

main模块中,我们已经使用系统设置类中的值替换了原本写死的值,相比以前,可读性和可维护性是不是大大提高了。

当前的目录结构如下:

在这里插入图片描述

飞船模块

飞船模块其实就是对飞船的抽象与封装。因此我们需要根据飞船的特性和行为抽象出飞船的属性并封装飞船的一些函数。

飞船可以抽象出哪些属性?

  1. 飞船是有图片渲染的,那么飞船需要外接一个矩形,并且具备长宽等属性。
  2. 飞船是可以移动的,简单点就是左右移动,复杂点就是上下左右移动。
  3. 飞船是在游戏窗口中渲染的,那么我们需要在飞船中注入一个窗口对象。
  4. 飞船的属性比如图片,大小应该是可以修改的。我们通过系统设置模块进行设置,那么我们需要在飞船中注入一个设置模块。

飞船可以封装哪些行为?

  1. 移动。

ps:可能有人问飞船不是可以发射子弹吗?项目编写了子弹模块,子弹有自己的生成子弹函数,但是子弹的初始位置是根据飞船的位置定义的。

那么飞船模块简单的编写如下:

import pygameclass Ship:def __init__(self, setting, screen):"""初始化飞船"""self.screen = screenself.setting = setting# 加载图片并外接矩形self.image = pygame.transform.scale(pygame.image.load('E:/python_project/alien_invasion/assets/images/ship.bmp'), (50, 50))# 飞船外接的矩形self.rect = self.image.get_rect()# 窗口矩形self.screen_rect = screen.get_rect()def move(self):"""移动飞船"""pass

因为这里还是编写基础代码,所以移动函数的功能先不写,用pass占位。

当前的目录结构如下:

在这里插入图片描述
需要注意的是这里我上传了两张图片,是飞船和外星人的图片,我直接放上来,大家自己保存一下。

在这里插入图片描述
在这里插入图片描述
格式可能有点问题,我直接在pdf截图保存的,大家可以自行寻找资源替代,不嫌麻烦和慢的话私信我找我要也行,就是我不会实时看私信。。。

外星人模块

外星人模块其实和飞船模块差不多,起码基础代码时一致的,这里不过多描述,大家自己思考一下。

外星人基础模块代码如下:

import pygameclass Alien:"""外星人类"""def __init__(self, setting, screen):"""初始化外星人并设置其初始位置"""super(Alien, self).__init__()self.screen = screenself.setting = setting# 加载图片并外接矩形self.image = pygame.transform.scale(pygame.image.load('F:/python_project/AlienTrespass/src/main/xq/images/alien.bmp'), (50, 50))self.rect = self.image.get_rect()self.screen_rect = screen.get_rect()

可以看到,其实和飞船类大差不错,只不过在后面游戏业务代码编写中,会出现差异而已。

当前项目的目录结构如下:

在这里插入图片描述

子弹模块

子弹虽然是有飞船发射的,但是子弹自己会移动,必须作为单独的模块存在,既然存在单独的模块,那么生成子弹和移动子弹的函数,自然编写到子弹模块中去。

子弹模块的属性和飞船,外星人有点相似,无非就是子弹不是图片渲染的,我们把子弹当做实心矩形处理,那么子弹模块的基础代码编写如下:

import pygameclass Bullet:def __init__(self, setting, screen, ship):super(Bullet, self).__init__()self.screen = screen# 创建子弹矩形self.rect = pygame.Rect(0, 0, setting.bullet_width, setting.bullet_height)self.rect.centerx = ship.rect.centerxself.rect.top = ship.rect.topdef move(self):"""向上移动子弹"""pass

这里稍微解释一下为什么需要注入一个飞船对象。因为我们子弹的生成这个功能的实现不是飞船的行为,而是新建一个子弹对象,但是这个子弹对象初始位置在飞船外接矩形的上方。

当前的项目目录结构如下:
在这里插入图片描述

至此,我们通过对项目的分析,已经将实现基础功能所需的模块一一分析完毕,并编写出了基础的代码,后面就是一步步根据游戏业务进行业务代码编写填充了。

结尾

今天内容有点多,但是重要,需要认真理解!

基本上整个项目基础已经打好,接下来的工作就是考验逻辑能力和代码编写了。

我的记录教程和书籍的教程不太一样。我是先总再分,书籍的内容是直接一个个模块功能开始的,两种方式没有谁好谁坏,我都是学人家的按书中来的,后面我再进行总结记录,这是属于我自己的学习方式而已。

大家喜欢哪种各自学习即可。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM 8 的优化指南:如何进行JVM调优,JVM调优参数有哪些

这篇文章将详细介绍如何进行JVM 8调优,包括JVM 8调优参数及其应用。此外,我将提供12个实用的代码示例,每个示例都会结合JVM启动参数和Java代码。 本文已收录于,我的技术网站 java-broke.site,有大厂完整面经&#xff…

ES中的数据类型学习之Aggregate metric(聚合计算)

Aggregate metric field type | Elasticsearch Guide [7.17] | Elastic 对于object类型的字段来说,可以存子字段为 min/max/sum/value_count PUT my-index {"mappings": {"properties": {"my-agg-metric-field": { -- 字段名"ty…

时序分解 | Matlab基于CEEMDAN-CPO-VMD的CEEMDAN结合冠豪猪优化算法(CPO)优化VMD二次分解

时序分解 | Matlab基于CEEMDAN-CPO-VMD的CEEMDAN结合冠豪猪优化算法(CPO)优化VMD二次分解 目录 时序分解 | Matlab基于CEEMDAN-CPO-VMD的CEEMDAN结合冠豪猪优化算法(CPO)优化VMD二次分解效果一览基本介绍程序设计参考资料 效果一览…

R的数据集读取和利用,如何高效地直接复制黏贴数据到R

​​​​​​R语言自带了许多内部数据集,这些数据集不仅为初学者提供了丰富的练习资源,还为研究人员和数据分析师提供了方便的数据测试和模型验证工具。在这篇文章中,我们将详细探讨如何读取和使用数据集。 一、认识数据集 1、数据和数据集 数据(Data)是指以某种形式表示…

SpringMVC中的注解驱动

文章目录 SpringMVC中的注解驱动一、注解驱动的作用二、注解驱动的使用场景1.注册Bean2.数据返回响应 SpringMVC中的注解驱动 &#xff1c;mvc:annotation-driven&#xff1e;就是注解驱动 一、注解驱动的作用 1.<mvc:annotation-driven> Spring MVC用来提供Controller请…

Taro中的坑

Taro什么玩意啊,文档文档不全,案例案例也不详细,为了绩效开源的东西用起来真的是如鲠在喉! 1 ScrollView自动撑开 视图内容(也就是ScrollView内部的视图) 在封装自己的弹框的时候用到ScrollView,如果给ScrollView一个固定的高度,他是肯定会滚动。 但是我们设计要求是…

软考:软件设计师 — 5.计算机网络

五. 计算机网络 1. OSI 七层模型 层次名称主要功能主要设备及协议7应用层实现具体的应用功能 POP3、FTP、HTTP、Telent、SMTP DHCP、TFTP、SNMP、DNS 6表示层数据的格式与表达、加密、压缩5会话层建立、管理和终止会话4传输层端到端的连接TCP、UDP3网络层分组传输和路由选择 三…

我的办公小助手——办公小浣熊

在当今快节奏的工作环境中&#xff0c;高效的办公室工作不再是锦上添花&#xff0c;而是专业人士必备的技能。近年来&#xff0c;随着人工智能技术的不断发展&#xff0c;越来越多的人工智能软件被引入办公领域。凭借其高效和智能的特点&#xff0c;他们已经成为我们的日常办公…

7. 聚类算法 KMeans

聚类算法 KMeans 1. 应用&#xff1a;大数据杀熟2. 迭代法3. 代码 1. 应用&#xff1a;大数据杀熟 618、双十一&#xff0c;平台要对用户进行分类&#xff1a;用户&#xff1a; 脑残粉&#xff08;不降价&#xff0c;或者涨点价&#xff09;墙头草&#xff08;给点小优惠券&am…

Day14 | 找树左下角的值 路径总和 从中序与后序遍历序列构造二叉树

语言 Java 找树左下角的值 题目链接&#xff1a;找树左下角的值 题目 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 思路 本题有两种做法我主要讲一下递归的思路&#xff0c;创建两个全局变量&…

二叉树精选面试题

&#x1f48e; 欢迎大家互三&#xff1a;2的n次方_ 1. 相同的树 100. 相同的树 同时遍历两棵树 判断结构相同&#xff1a;也就是在遍历的过程中&#xff0c;如果有一个节点为null&#xff0c;另一棵树的节点不为null&#xff0c;那么结构就不相同 判断值相同&#xff1a;只需…

Java写的简单卡券系统

以下是一个简单的Java卡券系统的示例代码&#xff1a; import java.util.ArrayList; import java.util.List;class Card {private String code;private double balance;public Card(String code, double balance) {this.code code;this.balance balance;}public String getC…

Android GlSurfaceView渲染YUV图形

OpenGL ES 2.0 的代码&#xff0c;用来显示YUV格式的视频数据。这个示例将包括初始化OpenGL环境、加载Shader程序、绘制纹理等步骤 import android.content.Context; import android.opengl.GLES20;import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.Fl…

Ubuntu22.04安装与卸载nginx

换源 如果是国内的就不用换 中科大的源&#xff0c;由于我这里是Ubuntu&#xff0c;所以我就直接选Ubuntu22.04就行 点击下载&#xff0c;或者你直接复制这个sources.list的内容到linux中的/etc/apt/sources.list也可以&#xff0c;把原来的sources.list备份一下&#xff0c;…

nfs和samba

​webserver 服务器&#xff1a;作用是发布nginx的web项目 1、安装nginx&#xff08;只下载不安装&#xff09; [rootweb_server ~]# yum -y install --downloadonly --downloaddir./soft/ nginx 2、配置一个本地的nginx仓库 [rootweb_server ~]# yum -y install createrepo …

『 Linux 』信号概念与信号的产生

文章目录 信号概念前台进程与后台进程信号的本质硬件理解信号的产生 信号概念 "信号"一词指用来传达信息或只是的各种形式的提示或标志; 在生活中常见的信号例如红绿灯,交通标志,短信通知等 在操作系统中,"信号"是一种用于异步通知进程发生特定事件的机制;…

数据库-练习

题目要求&#xff1a;按照要求建立数据库与表&#xff0c;并完成相应的查询操作 解题步骤如下代码所示&#xff1a; //建立相关的数据库mydb8_worker mysql> show databases; -------------------- | Database | -------------------- | information_schema | | …

C++:智能指针 [auto_ptr]

文章目录 0x1 基本使用0x11 初步使用0x12 get()函数【获取指针指向的内存地址】0x13 release()函数 【仅仅是释放所有权&#xff0c;但是并没有清空内存】0x14 reset()函数 【旧值析构,重新设置指针】 0x2 迷惑点0x21 迷惑点1 &#xff08;拷贝赋值&#xff09;0x22 迷惑点2 &a…

NMEA 2000航空插头插座选择

一、概述 NMEA 2000航空插头插座是船舶电子设备中不可或缺的部分&#xff0c;它们负责在船舶的各种电子系统间传输数据和电源信号。选择合适的NMEA 2000航空插头插座对于确保船舶电子系统的稳定性和可靠性至关重要。本文将详细探讨如何选择合适的NMEA 2000航空插头插座&#xf…

NodeJS系列面试题

大家好&#xff0c;我是有用就扩散&#xff0c;有用就点赞。 有没有写过Koa中间件&#xff0c;说一下中间件原理&#xff0c;介绍下自己写过的中间件 koa本来就是一个轻量级框架&#xff0c;本身支持的功能并不多&#xff0c;功能都是通过中间件来实现不同的需求。开发者可以通…