展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > 使用Python和3D引擎制作一个太阳系行星模拟器的教程

使用Python和3D引擎制作一个太阳系行星模拟器的教程

这一次,我们要实现的效果如下首先,送上本次需要用到的资源Earth.jpgJupiter.jpgMars.jpgMercury.jpgNeptune.jpgSaturn.jpgSun.jpgUranus.jpgVenus.jpg现在,就开始写代码吧!首先,导入我们需要的模块,导入3D引擎ursina,数学库math,ursina中自带的第一人称,sys,random随机库fromursinaimport*frommathimport*fromursina.prefabs.first_person_cont

这一次,我们要实现的效果如下

使用Python和3D引擎制作一个太阳系行星模拟器的教程

使用Python和3D引擎制作一个太阳系行星模拟器的教程

首先,送上本次需要用到的资源

Earth.jpg

使用Python和3D引擎制作一个太阳系行星模拟器的教程

Jupiter.jpg

使用Python和3D引擎制作一个太阳系行星模拟器的教程

Mars.jpg

使用Python和3D引擎制作一个太阳系行星模拟器的教程

Mercury.jpg

使用Python和3D引擎制作一个太阳系行星模拟器的教程

Neptune.jpg

使用Python和3D引擎制作一个太阳系行星模拟器的教程

Saturn.jpg

使用Python和3D引擎制作一个太阳系行星模拟器的教程

Sun.jpg

使用Python和3D引擎制作一个太阳系行星模拟器的教程

Uranus.jpg

使用Python和3D引擎制作一个太阳系行星模拟器的教程

Venus.jpg

使用Python和3D引擎制作一个太阳系行星模拟器的教程

现在,就开始写代码吧!

首先,导入我们需要的模块,导入3D引擎ursina,数学库math,ursina中自带的第一人称,sys,random随机库

from ursina import *
from math import *
from ursina.prefabs.first_person_controller import FirstPersonController
import sys
import random as rd

然后,创建app

app=Ursina()

将窗口设置为全屏,并设置背景颜色

window.fullscreen=True
window.color=color.black

定义一个列表,来储存生成的星

planets=[]

引入所有星球的材质

sun_texture=load_texture("texture/Sun.png")
mercury_texture=load_texture("texture/Mercury.png")
venus_texture=load_texture("texture/Venus.png")
earth_texture=load_texture("texture/Earth.png")
mars_texture=load_texture("texture/Mars.png")
jupiter_texture=load_texture("texture/Jupiter.png")
saturn_texture=load_texture("texture/Saturn.png")
uranus_texture=load_texture("texture/Uranus.png")
neptune_texture=load_texture("texture/Neptune.png")

创建一个类Planet,继承自实体Entity,传入_type是星的类型,pos是位置,scale是缩放

angle:每次更新的时候行星围绕太阳转的弧度

fastMode的值为1或0,表示是否让行星围绕太阳公转速度增加到200倍

rotation:星球倾斜度,这里我们随机生成

rotspeed:星球自转的速度

rotMode:表示沿着xyz轴的其中一条进行旋转,自动选择

_type存储星球类型

texture则是材质,通过eval获得该变量

然后进行超类的初始化,model是sphere,也就是球体形状,texture表示贴图,color颜色设置为white,position传入坐标

定义turn方法,传入angle,只要不是太阳,就进行自转公转操作,如果是快速模式,则速度增加到200倍,然后计算得出新的xy坐标,并用exec进行自传操作

最后定义input方法,接受用户输入,注意,这里方法名必须用input,因为它是系统自动调用的,它总会向其传入一个参数,为按下的按键名字,我们就进行判断,如果按下回车,则进行快速模式和普通模式间的切换

class Planet(Entity):
    def __init__(self,_type,pos,scale=2):
        self.angle=rd.uniform(0.0005,0.01)
        self.fastMode=0
        self.rotation=(rd.randint(0,360) for i in range(3))
        self.rotspeed=rd.uniform(0.25,1.5)
        self.rotMode=rd.choice(["x","y","z"])
        self._type=_type
        texture=eval(f"{_type}_texture")
        super().__init__(model="sphere",
                         scale=scale,
                         texture=texture,
                         color=color.white,
                         position=pos)
 
    def turn(self,angle):
        if self._type!="sun":
            if self.fastMode:
                angle*=200
            self.x=self.x*cos(radians(angle))-self.y*sin(radians(angle))
            self.y=self.x*sin(radians(angle))+self.y*cos(radians(angle))
            exec(f"self.rotation_{self.rotMode}+=self.rotspeed")
 
    def input(self,key):
        if key=="enter":
            self.fastMode=1-self.fastMode

接下来,我们定义Player类,继承自FirstPersonController

为什么不直接用FirstPersonController呢?

因为ursina自带的FirstPersonController自带重力,我们这里只是作为第一人称的视角使用,不需要重力,然后还有一些功能我们不需要用到,所以我们就写一个类继承下来,然后重写它的一部分代码即可。首先,引入全局变量planets,超类初始化,视野设置为90,将初始位置设置为地球的位置,重力(gravity)设置为0,表示没有重力,vspeed表示上升下降时的速度,speed表示水平方向移动的速度,mouse_sensitivity是鼠标灵敏度,需要用Vec2的形式,注意,上面除了vspeed变量可以自己命名,其它的都不可以修改。接下来,重写input,只接收esc按键的信息,当我们按下esc时,如果鼠标为锁定,则释放,如果已经释放,则退出程序。然后创建_update方法,这里我们不重写ursina自动调用的update方法,因为系统代码里面,update方法还有很多操作,如果我们要重写的话,可能还要加上把系统代码复制过来,代码过于繁琐,这里我们自己定义一个名字,在接下来会讲到的代码中自己调用它,在该方法中,监听鼠标左键、左shift和空格的事件,空格原本是跳跃,这里我们设置为上升,系统代码是在input中接收空格键的信息的,我们已经重写过了,所以这里不会触发系统代码的跳跃方法。

这里讲一下input和update中进行按键事件监听操作的不同,input每次只接收一个按键,而且,如果我们一个按键一直按下,它不会一直触发,只会触发一次,然后等到该按键释放,才会重新对该按键进行监听;update相当于主循环,在任何于ursina有关的地方(比如继承自Entity、Button这样的类,或者是主程序)写update方法,ursina都会进行自动调用,我们不需要手动调用它,在update方法中监听事件,我们用到了held_keys,不难发现,held_keys有多个元素,只要按下就为True,所以每次运行到这里,只要按键按下,就执行,而input传入的key本身就是一个元素,所以只有一个,我们按下esc的操作不能连续调用,所以用input,其它移动玩家的代码时可以重复执行的,所以写在update(应该说是用held_keys)中。

class Player(FirstPersonController):
    def __init__(self):
        global planets
        super().__init__()
        camera.fov=90
        self.position=planets[3].position
        self.gravity=0
        self.vspeed=2
        self.speed=600
        self.mouse_sensitivity=Vec2(160,160)
        self.on_enable()
 
    def input(self,key):
        if key=="escape":
            if mouse.locked:
                self.on_disable()
            else:
                sys.exit()
 
    def _update(self):
        if held_keys["left mouse"]:
            self.on_enable()
        if held_keys["left shift"]:
            self.y-=self.vspeed
        if held_keys["space"]:
            self.y+=self.vspeed

然后在主程序中写update方法,并在其中调用我们刚刚写的player中的_update方法,再对星球进行自转公转操作

def update():
    global planets,player
    for planet in planets:
        planet.turn(planet.angle)
    player._update()

接下来,我们定义两个列表,分别表示星球名称和星球的大小,其实在实际的大小比例中,和这个相差很多,如果地球是1,太阳则大约为130000,木星和图形分别为1500多和700多,这样相差太大,做在程序里看起来很不寻常,所以我们这里对大多数星球的大小进行放大缩小,把它们大小的相差拉近点。然后遍历并绘制,每颗星球的间隔为前一个的10倍

ps=["sun","mercury","venus","earth","mars","jupiter","saturn","uranus","neptune"]
cp=[200,15,35,42,20,160,145,90,80]
x,y,z=0,0,0
for i,p in enumerate(ps):
    newPlanet=Planet(p,(x,y,z),cp[i])
    planets.append(newPlanet)
    x+=cp[i]*10

最后实例化player,并运行app

player=Player()
 
if __name__ == '__main__':
    app.run()

然后就能实现文章前面展示的效果啦~

使用Python和3D引擎制作一个太阳系行星模拟器的教程

使用Python和3D引擎制作一个太阳系行星模拟器的教程

最后,附上代码

from ursina import *
from math import *
from ursina.prefabs.first_person_controller import FirstPersonController
import sys
import random as rd
 
app=Ursina()
window.fullscreen=True
window.color=color.black
 
planets=[]
 
class Planet(Entity):
    def __init__(self,_type,pos,scale=2):
        self.angle=rd.uniform(0.0005,0.01)
        self.fastMode=0
        self.rotation=(rd.randint(0,360) for i in range(3))
        self.rotspeed=rd.uniform(0.25,1.5)
        self.rotMode=rd.choice(["x","y","z"])
        self._type=_type
        texture=eval(f"{_type}_texture")
        super().__init__(model="sphere",
                         scale=scale,
                         texture=texture,
                         color=color.white,
                         position=pos)
 
    def turn(self,angle):
        if self._type!="sun":
            if self.fastMode:
                angle*=200
            self.x=self.x*cos(radians(angle))-self.y*sin(radians(angle))
            self.y=self.x*sin(radians(angle))+self.y*cos(radians(angle))
            exec(f"self.rotation_{self.rotMode}+=self.rotspeed")
 
    def input(self,key):
        if key=="enter":
            self.fastMode=1-self.fastMode
 
class Player(FirstPersonController):
    def __init__(self):
        global planets
        super().__init__()
        camera.fov=90
        self.position=planets[3].position
        self.gravity=0
        self.vspeed=2
        self.speed=600
        self.mouse_sensitivity=Vec2(160,160)
        self.on_enable()
 
    def input(self,key):
        if key=="escape":
            if mouse.locked:
                self.on_disable()
            else:
                sys.exit()
 
    def _update(self):
        if held_keys["left mouse"]:
            self.on_enable()
        if held_keys["left shift"]:
            self.y-=self.vspeed
        if held_keys["space"]:
            self.y+=self.vspeed
 
def update():
    global planets,player
    for planet in planets:
        planet.turn(planet.angle)
    player._update()
 
sun_texture=load_texture("texture/Sun.png")
mercury_texture=load_texture("texture/Mercury.png")
venus_texture=load_texture("texture/Venus.png")
earth_texture=load_texture("texture/Earth.png")
mars_texture=load_texture("texture/Mars.png")
jupiter_texture=load_texture("texture/Jupiter.png")
saturn_texture=load_texture("texture/Saturn.png")
uranus_texture=load_texture("texture/Uranus.png")
neptune_texture=load_texture("texture/Neptune.png")
 
ps=["sun","mercury","venus","earth","mars","jupiter","saturn","uranus","neptune"]
cp=[200,15,35,42,20,160,145,90,80]
x,y,z=0,0,0
for i,p in enumerate(ps):
    newPlanet=Planet(p,(x,y,z),cp[i])
    planets.append(newPlanet)
    x+=cp[i]*10
 
player=Player()
 
if __name__ == '__main__':
    app.run()
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
作者最新文章
编程开发 Python
相关文章 更多
精品专题 更多
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

macOS软件

正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

IOS软件

正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

AI

正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

Mac软件 更多
WPS Office macOS版
WPS Office macOS版

WPS Office是一款面向macOS用户的综合办公套件,将文字处理、电子表格、演示文稿、PDF工具、模板与云协作整合在同一应用中。它兼容常见Microsoft Office格式,支持Intel及Apple芯片Mac,基础功能可免费使用,

Shapr3D macOS版
Shapr3D macOS版

Shapr3D是一款面向工业设计、机械工程、建筑概念和三维打印工作流的CAD软件。Mac版采用Parasolid建模内核,支持草图约束、实体建模、工程图、可视化渲染及常见CAD格式交换,并可通过账户在多台设备之间同步项目。

REAPER macOS版
REAPER macOS版

REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。

Ableton Live macOS版
Ableton Live macOS版

Ableton Live 是面向音乐制作人与现场表演者的数字音频工作站,提供编曲视图、独具特色的现场视图、音频录制、MIDI创作、实时变速、乐器及效果器。Mac版原生支持Apple芯片,并可连接音频接口、MIDI控制器和第三方插件。

Adobe After Effects macOS版
Adobe After Effects macOS版

Adobe After Effects 是面向动态图形、影视特效与视频合成的专业创作软件。它提供关键帧动画、遮罩抠像、运动跟踪、三维空间、文字动画和表达式等工具,并可与 Premiere Pro、Photoshop、Illustrator

Adobe Audition macOS版
Adobe Audition macOS版

Adobe Audition 是面向播客、影视后期、音乐制作及内容创作者的专业音频工作站,提供波形精修、多轨录制与混音、频谱编辑、降噪修复、响度匹配和效果处理工具,并可与 Adobe Premiere 协同完成视频声音制作。

Adobe Bridge macOS版
Adobe Bridge macOS版

Adobe Bridge 是面向摄影师、设计师及内容团队的免费数字资产管理工具,可集中预览照片、视频和 Adobe 项目文件,并利用评级、标签、关键词、元数据、筛选与收藏集完成分类检索。它还支持批量重命名、格式导出、相机导入及 Camera

Adobe Illustrator macOS版
Adobe Illustrator macOS版

Adobe Illustrator 是 Adobe 推出的专业矢量图形设计软件,适合在 Mac 上制作标志、图标、插画、包装、信息图及印刷版面。它以路径和锚点构建可无损缩放的图形,并提供钢笔、形状、文字、图像描摹、渐变、画板及生成式功能。

Adobe InDesign macOS版
Adobe InDesign macOS版

Adobe InDesign 是面向印刷品与数字出版物的专业版面设计软件,可在 Mac 上制作书籍、杂志、宣传册、海报、报告及交互式文档。它提供精细的文字样式、网格、母版、长文档管理和印前输出能力。

Adobe Lightroom Classic macOS版
Adobe Lightroom Classic macOS版

Adobe Lightroom Classic 是面向桌面摄影工作流的照片管理与后期处理软件,可将原始照片保存在本地硬盘,通过目录、关键词、评分和收藏夹高效整理图库,并提供 RAW 冲印、蒙版、镜头校正、批量同步及多格式导出等功能。

Adobe Media Encoder macOS版
Adobe Media Encoder macOS版

Adobe Media Encoder 是 Adobe 推出的专业音视频编码与转码工具,可通过队列、预设和监视文件夹批量完成格式转换、代理文件创建及多平台成片输出,并与 Premiere Pro、After Effects 等软件紧密协作。

Adobe Photoshop macOS版
Adobe Photoshop macOS版

Adobe Photoshop 是面向摄影师、设计师和内容创作者的专业图像处理软件,提供图层、蒙版、选区、修复、调色、文字排版、智能对象及生成式编辑等能力。Mac 版支持 Intel 与 Apple Silicon 处理器。

WINDOWS 更多
Adobe InDesign Windows版
Adobe InDesign Windows版

Adobe InDesign 是面向印刷与数字出版的专业页面排版工具,可制作书籍、杂志、宣传册、海报、交互式 PDF 和电子书。它提供精细的文字样式、多页面管理、印前检查及多格式输出能力,并能与 Photoshop、Illustrator

Adobe Illustrator Windows版
Adobe Illustrator Windows版

Adobe Illustrator 是用于绘制矢量图形、插画、图标、徽标和版式的专业设计工具。它以路径和锚点为核心,作品放大后仍能保持清晰,并提供画板、文字、渐变、图像描摹及精确变换等功能,适合品牌视觉、印刷物料、数字界面和商业插画创作。

Adobe Bridge Windows版
Adobe Bridge Windows版

Adobe Bridge 是 Adobe 推出的创意资产管理工具,可集中预览、分类和查找照片、视频、PDF及多种设计文件,并支持元数据、关键词、评级、批量重命名和格式导出。它可与 Photoshop、Illustrator 等应用衔接,

Affinity Photo Windows版
Affinity Photo Windows版

Affinity Photo 是一款面向摄影师、修图师和视觉设计人员的桌面图像编辑工具,提供 RAW 显影、多图层合成、蒙版、实时滤镜、批处理和色彩管理等功能。原独立产品已停止销售,其照片编辑能力已延续至免费的新 Affinity 应用;

Adobe Lightroom Classic Windows版
Adobe Lightroom Classic Windows版

Adobe Lightroom Classic 是面向 Windows 桌面摄影工作流的照片管理与无损编辑工具,可通过目录集中整理大型图库,并完成 RAW 显影、局部蒙版、批量调整、打印和多格式导出。它强调本地文件管理与精细控制,

Figma Windows版
Figma Windows版

Figma 是面向产品设计与开发团队的云端协作平台,可在 Windows 桌面客户端中完成界面绘制、组件管理、交互原型、评论评审和开发交付。文件保存在云端,多名成员能够同步编辑并共享设计系统;官方同时提供免费 Starter 方案及按席位计

Affinity Designer Windows版
Affinity Designer Windows版

Affinity Designer 是面向矢量图形、数字插画和界面设计的专业创作工具,可在矢量、像素与导出工作区之间快速切换。它提供曲线编辑、形状构建、画板、排版、图层和专业色彩管理,并支持常见设计文件的导入及多种印刷、网页格式输出。

Capture One Pro Windows版
Capture One Pro Windows版

Capture One Pro 是面向摄影师和影像团队的专业桌面照片处理工具,提供相机定制色彩配置、RAW转换、图层与蒙版、联机拍摄、目录及会话管理等功能。它适合棚拍、人像、商业产品、婚礼和风光摄影,

Adobe Acrobat Pro Windows版
Adobe Acrobat Pro Windows版

Adobe Acrobat Pro 是面向专业 PDF 工作的综合解决方案,可在 Windows 中创建、编辑、转换、比较、整理和保护文档,并支持表单、电子签名、扫描件文字识别及敏感信息永久遮盖。订阅还包含网页、移动服务和云端协作能力,

Adobe After Effects Windows版
Adobe After Effects Windows版

Adobe After Effects 是面向动态图形、动画与影视视觉特效制作的专业工具,可完成关键帧动画、图层合成、遮罩跟踪、抠像、文字动画和二维三维元素整合。Windows 版通过 Adobe Creative Cloud 安装及更新,

DaVinci Resolve Windows版
DaVinci Resolve Windows版

DaVinci Resolve是Blackmagic Design推出的一体化影视后期工具,将素材管理、非线性剪辑、专业调色、Fusion视觉特效、Fairlight音频处理和成片交付整合在统一工程中。免费版已覆盖多数个人创作需求,

Adobe Media Encoder Windows版
Adobe Media Encoder Windows版

Adobe Media Encoder 是 Adobe 面向视频与音频制作流程提供的专业编码和转码工具,可批量处理媒体文件、创建代理、套用输出预设并监控文件夹自动执行任务。它与 Premiere、After Effects、Audition