Maison > développement back-end > Tutoriel Python > Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

王林
Libérer: 2023-05-12 16:16:14
avant
1358 Les gens l'ont consulté

Cette fois, l'effet que nous voulons obtenir est le suivant

Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

Tout d'abord, envoyez-nous les ressources dont nous avons besoin cette fois

Earth.jpg

Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

Jupiter.jpg

Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

Mars.j p.

Uranus.jpgComment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

Venus.jpgComment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

Maintenant, commencez à écrire du code ! Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

Tout d'abord, importez les modules dont nous avons besoin, importez le moteur 3D ursina, la bibliothèque mathématique math, la première personne, le système et les bibliothèques aléatoires fournies avec ursina

from ursina import *
from math import *
from ursina.prefabs.first_person_controller import FirstPersonController
import sys
import random as rd
Copier après la connexion

Ensuite, créez l'application

app=Ursina()
Copier après la connexion
Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en PythonRéglez la fenêtre en mode plein écran et définissez la couleur d'arrière-plan

window.fullscreen=True
window.color=color.black
Copier après la connexion

Définissez une liste pour stocker les étoiles générées

planets=[]
Copier après la connexion

Introduisez les matériaux de toutes les planètesComment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

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")
Copier après la connexion

Créez une classe Planet, héritée de Entity, le _type entrant est le type de l'étoile, pos est la position et l'échelle sont Mise à l'échelle

angle : L'arc dans lequel la planète tourne autour du soleil à chaque fois qu'il est mis à jour

Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python La valeur de fastMode est 1 ou 0, indiquant s'il faut augmenter la vitesse de révolution de la planète autour du soleil à 200 times

rotation : L'inclinaison de la planète, ici nous la générons aléatoirement

rotspeed : la vitesse de rotation de la planète Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

rotMode : indique la rotation le long d'un des axes xyz, sélectionne automatiquement

_type pour stocker le type de planète

la texture est le matériau, obtenez cette variable via eval

puis effectuez une initialisation de super classe, le modèle est une sphère, qui est la forme d'une sphère, la texture représente la texture, la couleur est définie sur blanc, la position est transmise en coordonnées

Définir la méthode de virage, passez en angle, tant que ce n'est pas le soleil, l'opération de rotation et de révolution sera effectuée si c'est le mode rapide, alors la vitesse augmente jusqu'à 200 fois, puis les nouvelles coordonnées xy sont calculées et exécutées. est utilisé pour effectuer l'opération d'autotransmission

Enfin, définissez la méthode de saisie pour accepter la saisie de l'utilisateur. Notez que le nom de la méthode doit être saisi ici, car il est automatiquement appelé par le système. Un paramètre lui sera toujours transmis. le nom du bouton enfoncé. Nous porterons un jugement. Si nous appuyons sur Entrée, nous basculerons entre le mode rapide et le mode normal

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
Copier après la connexion

Ensuite, nous définissons la classe Player, héritée de FirstPersonController

Pourquoi ne pas utiliser directement FirstPersonController ?

Étant donné que le FirstPersonController fourni avec ursina a sa propre gravité, nous l'utilisons ici uniquement comme perspective à la première personne et ne nécessite pas de gravité. Il existe également certaines fonctions que nous n'avons pas besoin d'utiliser, nous allons donc écrire une classe. pour en hériter puis le réécrire. Juste une partie du code. Tout d'abord, introduisez les planètes variables globales, initialisez la super classe, définissez le champ de vision sur 90, définissez la position initiale sur la position de la terre, définissez la gravité sur 0, ce qui signifie qu'il n'y a pas de gravité, vspeed signifie la vitesse de montée. et tomber, et speed signifie se déplacer dans la direction horizontale. La vitesse, mouse_sensitivity est la sensibilité de la souris, qui doit être sous la forme de Vec2. Notez qu'à l'exception de la variable vspeed ci-dessus, qui peut être nommée par vous-même, les autres ne le peuvent pas. être modifié. Ensuite, réécrivez l'entrée pour recevoir uniquement les informations de la touche esc. Lorsque nous appuyons sur esc, si la souris est verrouillée, elle sera relâchée. Si elle a été relâchée, le programme se terminera. Créez ensuite la méthode _update. Ici, nous ne remplaçons pas la méthode update appelée automatiquement par ursina, car dans le code système, la méthode update a encore de nombreuses opérations. Si nous voulons la réécrire, nous devrons peut-être également copier le code système. Le code est également compliqué. Ici, nous définissons nous-mêmes un nom et l'appelons nous-mêmes dans le code qui sera discuté ensuite. Dans cette méthode, nous surveillons les événements du bouton gauche de la souris, du décalage gauche et de l'espace. , ici nous l'avons réglé pour qu'il augmente. Le code système reçoit les informations de clé d'espace dans l'entrée. Nous l'avons réécrit, donc la méthode de saut du code système ne sera pas déclenchée ici.

这里讲一下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
Copier après la connexion

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

def update():
    global planets,player
    for planet in planets:
        planet.turn(planet.angle)
    player._update()
Copier après la connexion

接下来,我们定义两个列表,分别表示星球名称和星球的大小,其实在实际的大小比例中,和这个相差很多,如果地球是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
Copier après la connexion

最后实例化player,并运行app

player=Player()
 
if __name__ == '__main__':
    app.run()
Copier après la connexion

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

Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

Comment utiliser le moteur 3D pour créer un simulateur de planète du système solaire en Python

最后,附上代码

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()
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal