Vpython et l'animation : jeux

Description

La guerre des étoiles en environ de 200 lignes de code. Ce source vous montre toute la puissance de Vpython pour réaliser des animations aussi fluides que réalistes. A vous d'ajouter le contrôle du joystick...

Source / Exemple :


#!/usr/bin/env python
# -*- coding: ISO-8859-15 -*-
#Utiliser au moins Python 2.5 et Vpython 2.5-3.2.11
from visual import *
from random import Random, randint, sample, uniform
from math import radians, degrees

sourceRandom = Random()
scene.fullscreen = True
scene.scale =(.01, .01, .01)

class TieWing(object):
    """
    Aile du chasseur
    """
    def __init__( self, center = ( 0., 0., 0. ) ,
                        dimension = ( 1., 2., 3.),
                        objColor = color.white, 
                        frame = None ):
        """
        center = center of the wing ( x, y, z )
        dimension = dimension of the wing ( thickness, size, height )
        objColor = ( R, G, B )
        """
        [ self.x0, self.y0, self.z0 ] = center
        [ self.thickness, self.size, self.height ] = dimension
        self.vObj = convex( color = objColor , frame = frame)
        self.Tir_1 = sphere(frame = frame,
                            pos=(self.x0,self.y0, self.z0 +0.7 ),
                            radius = 0.1)
    def draw( self ):
        """
        Drawing of the wing.
        """
        y1 = self.y0 + self.size * 0.5
        z1 = self.z0 + self.height * 0.25
        y2 = self.y0
        z2 = self.z0 + self.height * 0.5
        y3 = self.y0 - self.size * 0.5
        z3 = self.z0 + self.height * 0.25
        y4 = self.y0 - self.size * 0.5
        z4 = self.z0 - self.height * 0.25
        y5 = self.y0
        z5 = self.z0 - self.height * 0.5
        y6 = self.y0 + self.size * 0.5
        z6 = self.z0 - self.height * 0.25
        self.vObj.pos =[ ( self.x0, y1, z1 ), ( self.x0, y2, z2 ), 
                        ( self.x0, y3, z3 ), ( self.x0, y4, z4 ),
                        ( self.x0, y5, z5 ),( self.x0, y6, z6 ) ]
 
class Etoile :
    """
    Represente une etoile qui scintille
    """
    def __init__(self, Position):
        """
        Position : position absolue de l'étoile dans le ciel
        """
        sphere (color = (1,1,1),  pos = Position, radius = 1)
        x,y,z = Position
        L = 1.5
        #Rayons etoiles
        self.curve = curve (pos =[(x,y,z),(L+x,y,z),(x,y,z),(-L+x,y,z), 
                                (x,y,z),(x,L+y,z),(x,y,z),(x,-L+y,z),
                                (x,y,z),(x,y,L+z),(x,y,z),(x,y,-L+z)])
            
    def move (self):
        """
        Modification de l'etoile dans le temps
        """
        #On fait clignoter chaque etoile
        self.curve.visible = 1 - self.curve.visible
     
class Tir:
    def __init__( self, position = ( 0., 0., 0. )):
        self.form = frame (pos=position)
        trait  = (position [0]*0.90,position [1]*0.90,position [2]*0.90)
        self.theCurve = curve (pos = [position,trait],
                                frame = self.form, color = (1,1,1))
        self.compteurVie = 0
    def move(self):
        self.form.pos = (self.form.pos[0]*0.55,
                        self.form.pos[1]*0.55,
                        self.form.pos[2]*0.55)
        self.compteurVie +=1
        if self.compteurVie > 10 :
            self.theCurve.visible = False
            del self
 
class TieFighter:
    """
    Represente un vaisseau
    """    
    def __init__( self, position = ( 0., 0., 0. )):
        self.CalculateurPosition = None
        self.tie = frame( name = "TIE" )
        self.tieColor =  (sourceRandom.random() ,
                            sourceRandom.random(),
                            sourceRandom.random())
        self.centerTieFighter = sphere( frame = self.tie, 
                                        pos = position,  
                                        radius = 0.5, 
                                        color = self.tieColor )
                                        
        leftWing = TieWing(frame = self.tie,
                            center = ( position[0] - 0.5, 
                                        position[1], 
                                        position[2] ),
                            dimension = ( 1., 3., 5.),
                            objColor = self.tieColor )

        leftWing.draw()
        rightWing = TieWing(frame     = self.tie,
                            center    = ( position[0] + 0.5, position[1], position[2] ),
                            dimension = ( 1., 3., 5.), 
                            objColor  = self.tieColor )
        rightWing.draw()
        self.tie.pos = position
        self.directionXPredilection = sourceRandom.choice([-1,1])
        self.SensZ = 1
        self.angleRotation  = 0.1*sourceRandom.random()*sourceRandom.choice([-1,1])
        self.angleRotationPropreY = 0.01*sourceRandom.random()*sourceRandom.choice([-1,1])
        self.Tirs = []
        
    def move(self,dt):
        X,Y,Z = self.tie.pos
        if Z > 0:
            newX = X + (.5*self.directionXPredilection)
        else:
            newX = X - (.5*self.directionXPredilection)    
        newY = Y
        newZ = Z - self.SensZ
        self.tie.pos =  (newX, newY, newZ)
        self.tie.rotate( angle = self.angleRotation )
        axeY = self.tie.axis [1] + self.directionXPredilection *self.angleRotationPropreY
        self.tie.axis = (self.tie.axis [0],axeY,self.tie.axis [2])
        NtotalTir = 100
        chance_Tir = sourceRandom.randint(0,NtotalTir) 
        if chance_Tir > NtotalTir-1:
            self.Tirs.append (Tir (self.tie.pos))
        for unTir in self.Tirs:
            unTir.move ()
       
class FighterSpace (object):
    ETOILES_NUMBER = 500
    def __init__(self,FighterNumber):
        self.FighterNumber = FighterNumber
        self.FighterList = []
        self.etoiles = []
    
    def drawEarth(self):
         L = []
         Color=[0.5*sourceRandom.random() ,
                0.5*sourceRandom.random(),
                0.5*sourceRandom.random()]
         c = convex(color=Color)
         for i in range(100):
             L.append(20*(vector(0,1) + norm((uniform(-1,1),uniform(-1,1),uniform(-1,1)))))
         c.pos = L
         L = []
         d = convex(color=(0,0.5,0.5))
         for i in range(100):
             L.append(20*(vector(0,1) + norm((uniform(-1,1),uniform(-1,1),uniform(-1,1)))))
         d.pos = L
         L = []
         Color=[0.5*sourceRandom.random() ,
             0.5*sourceRandom.random(),
             0.5*sourceRandom.random()]
         e = convex(color=Color)
         for i in range(100):
             L.append(20*(vector(0,1) + norm((uniform(-1,1),uniform(-1,1),uniform(-1,1)))))
         e.pos = L
         
    def create_Fighter (self):
        for aTieFighter in range(self.FighterNumber):
            Position = array((20*sourceRandom.random()*sourceRandom.choice([-1,1]),
                             20*sourceRandom.random()*sourceRandom.choice([-1,1]),
                             randint (10,200)))
            theTieFighter = TieFighter(position=Position)
            self.FighterList.append(theTieFighter)
            
    def goSimu (self):
        while True:
            framePerSecond = 50
            rate(framePerSecond)
            for aTieFighter in self.FighterList:
                aTieFighter.move(dt = 1.0/framePerSecond)
                
            # Selection de  10% des etoiles à faire clignoter: realisation d'un echantillonage
            nbEtoiles = len(self.etoiles)
            numeros_etoiles_a_faire_clignoter = sample(xrange(nbEtoiles), int(nbEtoiles*0.1))
            for numEtoiles in numeros_etoiles_a_faire_clignoter:
                self.etoiles[numEtoiles].move()
            
    def draw_space (self):
        #Dessin de beaucoup d'etoiles un peu partour dans l'espace
        RayonUnivers = 2000
        for i in range (FighterSpace.ETOILES_NUMBER):
            positionEtoile =array((RayonUnivers*sourceRandom.random()*sourceRandom.choice([-1,1]),
                                   RayonUnivers*sourceRandom.random()*sourceRandom.choice([-1,1]),
                                   RayonUnivers*sourceRandom.random()*sourceRandom.choice([-1,1])))
            self.etoiles.append(Etoile(positionEtoile))
            
if __name__ == '__main__':
    FighterNumber = 100
    theFighterSpace= FighterSpace(FighterNumber)
    theFighterSpace.create_Fighter()
    theFighterSpace.drawEarth()
    theFighterSpace.draw_space ()
    theFighterSpace.goSimu()

Conclusion :


Quelques classes et le tour est joué. Avec un peu d'imagination et de travail, on peut faire un vrai jeux.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.