Soya/Python base 4
< Soya
# -*- indent-tabs-mode: t -*-
# Soya 3D tutorial
# Copyright (C) 2004 Jean-Baptiste LAMY
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# basic-4: Gestion du temps : un mouvement aléatoire de chenille.
# Dans cette leçon, nous allons créer une chenille composée d'une tête (Nous avons déjà vu ça
# dans une précédente leçon ; maintenant vous comprenez pourquoi j'ai appelé ça 'head' (= tête))
# et 10 sphères d'un corps. Chaque pièce du corps suit le précédent, ou le head pour
# première pièce.
# Démarrez le tutorial si vous ne comprennez pas ce qu'est la chenille.
# Importation du module de Soya.
import sys, os, os.path, random, soya
soya.init()
soya.path.append(os.path.join(os.path.dirname(sys.argv[0]), "data"))
# Création de la scène.
scene = soya.World()
# CaterpillarHead est la classe pour la tête de la chenille.
# C'est identique à la classe Head de la leçon base 3, excepté le nom de la classe.
# Alors je ne commente pas !
class CaterpillarHead(soya.Body):
def __init__(self, parent):
soya.Body.__init__(self, parent, soya.Model.get("caterpillar_head"))
self.speed = soya.Vector(self, 0.0, 0.0, -0.2)
def begin_round(self):
soya.Body.begin_round(self)
self.rotate_y((random.random() - 0.5) * 50.0)
def advance_time(self, proportion):
soya.Body.advance_time(self, proportion)
self.add_mul_vector(proportion, self.speed)
# Une CaterpillarPiece est une pièce du corps de la chenille.
# Ça suit d'autres objets -- la pièce précédente, ou là tête pour la première.
class CaterpillarPiece(soya.Body):
# Le constructeur prend 2 arguments : le parent et la précédente pièce du corps
# que nous devons suivre.
# Similaire à la tête, nous définissons un vecteur de vitesse.
def __init__(self, parent, previous):
soya.Body.__init__(self, parent, soya.Model.get("caterpillar"))
self.previous = previous
self.speed = soya.Vector(self, 0.0, 0.0, -0.2)
def begin_round(self):
soya.Body.begin_round(self)
# Nous tournons une pièce de la chenille pour qu'il regarde le morceau précédent.
self.look_at(self.previous)
# La méthode distance_to retourne une distance entre 2 positions.
# Si nous sommes trop près du morceau précédent du corps, nous paramétrons la vitesse à Z = 0.0,
# et ainsi la vitesse du vecteur est nulle : cette pièce n'a pas de longs mouvements.
# Sinon, nous remettons la vitesse à Z = -0.2.
if self.distance_to(self.previous) < 1.5: self.speed.z = 0.0
else: self.speed.z = -0.2
# advance_time est identique a CaterpillarHead.
def advance_time(self, proportion):
soya.Body.advance_time(self, proportion)
self.add_mul_vector(proportion, self.speed)
# Création de la tête de la chenille.
caterpillar_head = CaterpillarHead(scene)
caterpillar_head.rotate_y(90.0)
# Création de 10 pièces de corps de la chenille.
previous_caterpillar_piece = caterpillar_head
for i in range(10):
previous_caterpillar_piece = CaterpillarPiece(scene, previous_caterpillar_piece)
previous_caterpillar_piece.x = i + 1
# Création de la lampe.
light = soya.Light(scene)
light.set_xyz(2.0, 5.0, 0.0)
# Création de la caméra.
camera = soya.Camera(scene)
camera.set_xyz(0.0, 15.0, 15.0)
camera.look_at(caterpillar_head)
soya.set_root_widget(camera)
soya.MainLoop(scene).main_loop()
# Pour information, la texture de la chenille à été réalisée avec Gimp et le modèle a été généré
# avec ce code (regardez le tutoriel sur le modelage pour le comprendre) :
# import soya.sphere
# caterpillar_material = soya.Material(soya.Image.get("chenille.png"))
# caterpillar_head_material = soya.Material(soya.Image.get("chenille_tete.png"))
# caterpillar_material .filename = "caterpillar"
# caterpillar_head_material.filename = "caterpillar_head"
# caterpillar_material .save()
# caterpillar_head_material.save()
# caterpillar = soya.sphere.Sphere(slices = 12, stacks = 12, material = caterpillar_material)
# caterpillar_head = soya.sphere.Sphere(slices = 12, stacks = 12, material = caterpillar_head_material)
# caterpillar_head.scale(1.2, 1.2, 1.2)
# caterpillar .filename = "caterpillar"
# caterpillar_head.filename = "caterpillar_head"
# caterpillar .save()
# caterpillar_head.save()
# XXX put this elsewhere
# Lots of Soya methods have also an operator :
#
# Position + Vector => Point
# Position += Vector Position.add_vector(Vector)
# Position >> Position Position.vector_to (Position) => Vector
# Position %= CoordSyst Position.convert_to(CoordSyst)
# Vector * float
# Position + Vector => Point
# Position += Vector
# Position.add_vector(Vector)
# Translation or vectorial addition (if the Position is a Vector).
# Position >> Position => Vector
# Position.vector_to (Position) => Vector
# Creates a vector from a strating and an ending position.
# Position %= CoordSyst Position.convert_to(CoordSyst)
# Vector * float