中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python怎么用3D引擎做一個太陽系行星模擬器

發布時間:2023-01-09 10:55:45 來源:億速云 閱讀:147 作者:iii 欄目:開發技術

這篇文章主要介紹了Python怎么用3D引擎做一個太陽系行星模擬器的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Python怎么用3D引擎做一個太陽系行星模擬器文章都會有所收獲,下面我們一起來看看吧。

這一次,我們要實現的效果如下

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()

關于“Python怎么用3D引擎做一個太陽系行星模擬器”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Python怎么用3D引擎做一個太陽系行星模擬器”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

博白县| 英超| 三台县| 绥宁县| 洱源县| 临潭县| 海晏县| 麻栗坡县| 大冶市| 开封市| 申扎县| 克东县| 巴楚县| 德安县| 凉城县| 望都县| 淳安县| 宁安市| 舞钢市| 金寨县| 闽侯县| 嘉定区| 凌海市| 静乐县| 南宫市| 尼木县| 彭山县| 竹山县| 永济市| 灵台县| 沅江市| 廊坊市| 攀枝花市| 高青县| 汉沽区| 清流县| 兴山县| 石景山区| 浦江县| 长沙市| 桂阳县|