Heim > Artikel > Backend-Entwicklung > So erstellen Sie mithilfe der 3D-Engine einen Planetensimulator für das Sonnensystem in Python
Der Effekt, den wir dieses Mal erzielen möchten, ist wie folgt:
Schicken Sie uns zunächst die Ressourcen, die wir dieses Mal benötigen:
Earth.jpg
Jupiter.jpg
Mars.j pg
Merkur.jpg
Neptun.jpg
Saturn.jpg
Sonne.jpg
Uranus.jpg
Venus.jpg
Jetzt beginnen Sie mit dem Schreiben von Code!
Importieren Sie zunächst die Module, die wir benötigen, importieren Sie die 3D-Engine Ursina, die Mathematikbibliothek Mathe, die First-Person-, Sys- und Zufallsbibliotheken, die mit Ursina geliefert werden Bildschirm und legen Sie die Hintergrundfarbe fest.
from ursina import * from math import * from ursina.prefabs.first_person_controller import FirstPersonController import sys import random as rd
Definieren Sie eine Liste zum Speichern der generierten Sterne.
app=Ursina()
Geben Sie die Materialien aller Planeten ein Die Position und der Maßstab sind Skalierung
Winkel: Der Bogen, in dem sich der Planet bei jeder Aktualisierung um die Sonne dreht
Der Wert von fastMode ist 1 oder 0 und gibt an, ob die Umlaufgeschwindigkeit des Planeten um die Sonne auf 200 erhöht werden soll mal
rotation: Die Neigung des Planeten, hier generieren wir sie zufällig
rotspeed: die Geschwindigkeit der Planetenrotation
rotMode: zeigt die Rotation entlang einer der xyz-Achsen an, wählt automatisch
_type aus, um den Planetentyp
zu speichern Textur ist das Material, erhalten Sie diese Variable durch Auswertung
und führen Sie dann die Initialisierung der Superklasse durch. Das Modell ist eine Kugel, die die Form einer Kugel darstellt, die Textur stellt die Textur dar, die Farbe wird auf Weiß gesetzt und die Position wird übergeben die Koordinaten
Definieren Sie die Drehmethode, geben Sie den Winkel ein, solange es sich nicht um die Sonne handelt, wird der Rotations- und Umdrehungsvorgang ausgeführt. Wenn es sich im Schnellmodus befindet, wird die Geschwindigkeit auf das 200-fache erhöht und dann Die neuen xy-Koordinaten werden berechnet und exec wird für den automatischen Übertragungsvorgang verwendet. Abschließend wird die Eingabemethode definiert, um Benutzereingaben zu akzeptieren, da sie vom System automatisch als Parameter aufgerufen wird Es wird immer der Name der gedrückten Schaltfläche übergeben. Wenn wir die Eingabetaste drücken, wechseln wir zwischen dem Schnellmodus und dem Normalmodus. Als nächstes definieren wir die Player-Klasse, die von FirstPersonController geerbt wurde
Warum nicht einfach FirstPersonController verwenden?
Da der mit Ursina gelieferte FirstPersonController eine eigene Schwerkraft hat, verwenden wir ihn hier nur als First-Person-Perspektive und benötigen keine Schwerkraft. Es gibt auch einige Funktionen, die wir nicht verwenden müssen, daher werden wir eine Klasse schreiben um es zu erben und dann neu zu schreiben. Nur ein Teil des Codes. Führen Sie zunächst die globalen variablen Planeten ein, initialisieren Sie die Superklasse, setzen Sie das Sichtfeld auf 90, setzen Sie die Anfangsposition auf die Position der Erde, setzen Sie die Schwerkraft auf 0, was bedeutet, dass es keine Schwerkraft gibt, und vspeed bedeutet die Geschwindigkeit beim Aufstieg und fallen, und Geschwindigkeit bedeutet, sich in horizontaler Richtung zu bewegen. Mouse_sensitivity ist die Mausempfindlichkeit, die in der Form von Vec2 vorliegen muss. Beachten Sie, dass dies mit Ausnahme der oben genannten vspeed-Variablen nicht der Fall ist geändert werden. Als nächstes schreiben Sie die Eingabe um, um nur die Informationen der Esc-Taste zu erhalten. Wenn wir die Esc-Taste drücken, wird sie freigegeben. Wenn sie losgelassen wurde, wird das Programm beendet. Dann erstellen wir die _update-Methode. Hier überschreiben wir nicht die von Ursina automatisch aufgerufene Update-Methode, da die Update-Methode noch viele Operationen enthält. Wenn wir sie neu schreiben möchten, müssen wir möglicherweise auch den Systemcode kopieren. Der Code ist zu umständlich. Hier definieren wir selbst einen Namen und nennen ihn im Code, der als nächstes besprochen wird. Bei dieser Methode überwachen wir die Ereignisse der linken Maustaste, der linken Umschalttaste und der Leertaste , hier stellen wir es so ein, dass der Systemcode die Leerzeicheninformationen in der Eingabe erhält, sodass die Sprungmethode des Systemcodes hier nicht ausgelöst wird.
这里讲一下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()
然后就能实现文章前面展示的效果啦~
最后,附上代码
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()
Das obige ist der detaillierte Inhalt vonSo erstellen Sie mithilfe der 3D-Engine einen Planetensimulator für das Sonnensystem in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!