2022-02-24 11:48:12 +01:00
import bge # Bibliothèque Blender Game Engine (BGE)
import math
import time
###############################################################################
# ropy_lib.py
# @title: Bibliothèque du Robot Ropy (rp_*)
# @project: Blender-EduTech
# @lang: fr
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
2022-04-21 14:06:16 +02:00
# @copyright: Copyright (C) 2020-2022 Philippe Roy
2022-02-24 11:48:12 +01:00
# @license: GNU GPL
#
# Bibliothèque des actions du robot
# Bibliothèque pour la construction des murs
#
# Ropy est destiné à la découverte de la programmation procédurale et du language Python.
2022-04-21 14:06:16 +02:00
# A travers plusieurs challenges, donc de manière graduée, les élèves vont apprendre à manipuler les structures algorithmiques de base et à les coder en Python.
2022-02-24 11:48:12 +01:00
#
###############################################################################
# Récupérer l'objet robot
cont = bge . logic . getCurrentController ( )
obj = cont . owner
scene = bge . logic . getCurrentScene ( )
nb_objets_fixes = len ( scene . objects )
# print ("Nombre d'objets fixes de la scene : ", nb_objets_fixes)
print ( " Objets de la scene : " , scene . objects )
# Configuration des mouvements
pas = 3 # Pas linéaire
pas_rot = math . pi / 2 # Pas angulaire
###############################################################################
# Initialisation de la position du robot
###############################################################################
# Position initiale du robot
def rp_init_position ( ) :
x = obj [ ' x_init ' ]
y = obj [ ' y_init ' ]
obj . worldPosition . x = - ( ( y - 4.5 ) * 3 ) + 3
obj . worldPosition . y = ( x - 5.5 ) * 3
obj . worldPosition . z = 1.25
print ( ' \x1b [6;30;47m ' , " Placer le robot case (X,Y) : " , x , y , ' \x1b [0m ' )
# Pile des mouvements
# obj['mvts'] = ""
# obj['mvt_i'] = 0
# Répérer le robot détruit
if obj [ ' detruit ' ] :
start = 300
end = start + 75
layer = 0
priority = 1
blendin = 1.0
mode = bge . logic . KX_ACTION_MODE_PLAY
layerWeight = 0.0
ipoFlags = 0
speed = 3
scene . objects [ ' Armature ' ] . playAction ( ' ArmatureAction.Saut.001 ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
# scene.objects['Body'].playAction('BodyAction.Saut', start, end, layer, priority, blendin, mode, layerWeight, ipoFlags, speed)
# scene.objects['Eyes_glass'].playAction('Eyes_glassAction.Saut', start, end, layer, priority, blendin, mode, layerWeight, ipoFlags, speed)
# scene.objects['Mouth'].playAction('MouthAction.Saut', start, end, layer, priority, blendin, mode, layerWeight, ipoFlags, speed)
# scene.objects['Jetpack'].playAction('JetpackAction.Saut', start, end, layer, priority, blendin, mode, layerWeight, ipoFlags, speed)
scene . objects [ ' poignee1 ' ] . playAction ( ' poignee1Action.Saut ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' poignee2 ' ] . playAction ( ' poignee2Action.Saut ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' poignee3 ' ] . playAction ( ' poignee3Action.Saut ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' poignee4 ' ] . playAction ( ' poignee4Action.Saut ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
obj [ ' detruit ' ] = False
###############################################################################
# Affichage
###############################################################################
#Afficher position
def rp_print_position ( ) :
print ( ' \x1b [6;30;42m ' , " Position case (X,Y) : " , round ( - obj . worldPosition . x / 3 + 5.5 ) , round ( obj . worldPosition . y / 3 + 5.5 ) , ' \x1b [0m ' )
###############################################################################
# Moteur physique
# Détection des colisions aves les murs
###############################################################################
# Détection d'une colision
# rpcore_ : fonction bas niveau
def rpcore_detect_mur ( debug_flag = False ) :
# Vecteur du mouvement
init_x = round ( obj . worldPosition . y / 3 + 5.5 )
init_y = round ( - obj . worldPosition . x / 3 + 5.5 )
obj . applyMovement ( ( 0 , - pas , 0 ) , True )
final_x = round ( obj . worldPosition . y / 3 + 5.5 )
final_y = round ( - obj . worldPosition . x / 3 + 5.5 )
obj . applyMovement ( ( 0 , pas , 0 ) , True )
# Calcul du centre du mouvement
mov_xc = init_x + ( final_x - init_x ) / 2 - 0.5
mov_yc = init_y + ( final_y - init_y ) / 2 - 0.5
if debug_flag :
print ( ' \x1b [6;30;47m ' , " Mouvement (X_init,Y_init,X_final,Y_final) : " , init_x , init_y , final_x , final_y , ' \x1b [0m ' )
print ( ' \x1b [6;30;47m ' , " Mouvement (xc,yc) : " , mov_xc , mov_yc , ' \x1b [0m ' )
# Test sur les murs exterieurs (10x10)
if ( ( final_x < 1 ) or ( final_y < 1 ) or ( final_x > 10 ) or ( final_y > 10 ) ) :
if debug_flag :
print ( " Détection de mur : mur détecté " )
return True
# Test sur les murs intéreurs
else :
i = 0
for mur in scene . objects :
i + = 1
if mur . name == " Mur " :
# Mur en X : calcul du centre du mur
if ( round ( mur . worldOrientation . to_euler ( ) . z , 2 ) == round ( math . pi , 2 ) ) or ( round ( mur . worldOrientation . to_euler ( ) . z , 2 ) == round ( - math . pi , 2 ) ) :
mur_xc = mur [ ' x1 ' ]
mur_yc = mur [ ' y1 ' ] + 0.5
# Mur en Y : calcul du centre du mur
elif ( round ( mur . worldOrientation . to_euler ( ) . z , 2 ) == round ( math . pi / 2 , 2 ) ) or ( round ( mur . worldOrientation . to_euler ( ) . z , 2 ) == round ( - math . pi / 2 , 2 ) ) :
mur_xc = mur [ ' x1 ' ] + 0.5
mur_yc = mur [ ' y1 ' ]
# Trace de debug
if debug_flag :
print ( ' \x1b [6;30;47m ' , " Mur " , mur [ ' murId ' ] , " X (x1,y1,x2,y2) : " , mur [ ' x1 ' ] , mur [ ' y1 ' ] , mur [ ' x2 ' ] , mur [ ' y2 ' ] , ' \x1b [0m ' )
print ( ' \x1b [6;30;47m ' , " Mur " , mur [ ' murId ' ] , " Y (xc,yc) : " , mur_xc , mur_yc , ' \x1b [0m ' )
# Même centre -> mouvement pas possible
if ( mov_xc == mur_xc ) and ( mov_yc == mur_yc ) :
if debug_flag :
print ( " Détection de mur : mur détecté " )
return True
# Mouvement possible
if debug_flag :
print ( " Détection de mur : pas de mur " )
return False
# Fonction pour l'élève
def rp_detect_mur ( ) :
if rpcore_detect_mur ( ) == True :
print ( ' \x1b [6;30;45m ' , " Détection de mur : mur devant ! : Position case (X,Y): " , round ( - obj . worldPosition . x / 3 + 5.5 ) , round ( obj . worldPosition . y / 3 + 5.5 ) , ' \x1b [0m ' )
return True
else :
print ( ' \x1b [6;30;45m ' , " Détection de mur : voie libre : Position case (X,Y): " , round ( - obj . worldPosition . x / 3 + 5.5 ) , round ( obj . worldPosition . y / 3 + 5.5 ) , ' \x1b [0m ' )
return False
###############################################################################
# Mouvements
###############################################################################
# Avancer
def rp_avancer ( debug_flag = False ) :
obj . visible = False
if obj [ ' detruit ' ] != True :
# Vecteur du mouvement
init_x = round ( obj . worldPosition . y / 3 + 5.5 )
init_y = round ( - obj . worldPosition . x / 3 + 5.5 )
obj . applyMovement ( ( 0 , - pas , 0 ) , True )
final_x = round ( obj . worldPosition . y / 3 + 5.5 )
final_y = round ( - obj . worldPosition . x / 3 + 5.5 )
obj . applyMovement ( ( 0 , pas , 0 ) , True )
# Test des murs
if rpcore_detect_mur ( debug_flag ) == True :
print ( ' \x1b [6;30;41m ' , " Avancer case (X,Y) -> case (X,Y) : " , init_x , " , " , init_y , " -> " , final_x , " , " , final_y , ' \x1b [0m ' )
print ( ' \x1b [6;30;41m ' , " Bling, blang ... L ' aventure de Ropy s ' arrête donc ici ... " , ' \x1b [0m ' )
obj [ ' mvts ' ] = obj [ ' mvts ' ] + " c "
obj [ ' detruit ' ] = True
else :
obj . applyMovement ( ( 0 , - pas , 0 ) , True )
obj [ ' mvts ' ] = obj [ ' mvts ' ] + " a "
print ( ' \x1b [6;30;42m ' , " Avancer case (X,Y) -> case (X,Y) : " , init_x , " , " , init_y , " -> " , final_x , " , " , final_y , ' \x1b [0m ' )
# Test de l'objectif
i = 0
for objectif in scene . objects :
i + = 1
if objectif . name == " Objectif " :
if objectif [ ' x ' ] == final_x and objectif [ ' y ' ] == final_y :
print ( ' \x1b [6;30;42m ' , " Objectif atteint " , ' \x1b [0m ' )
obj [ ' mvts ' ] = obj [ ' mvts ' ] + " o "
# Tourner à droite
def rp_droite ( ) :
# obj.visible=False
if obj [ ' detruit ' ] != True :
# scene.objects['Robot'].applyRotation((0, 0, -pas_rot), True)
obj . applyRotation ( ( 0 , 0 , - pas_rot ) , True )
obj [ ' mvts ' ] = obj [ ' mvts ' ] + " d "
print ( ' \x1b [6;30;42m ' , " Tourner à droite " , ' \x1b [0m ' )
# print("Orientation : ", obj.worldOrientation.to_euler().z)
# Tourner à gauche
def rp_gauche ( ) :
# obj.visible=False
if obj [ ' detruit ' ] != True :
# scene.objects['Robot'].applyRotation((0, 0, pas_rot), True)
obj . applyRotation ( ( 0 , 0 , pas_rot ) , True )
obj [ ' mvts ' ] = obj [ ' mvts ' ] + " g "
print ( ' \x1b [6;30;42m ' , " Tourner à gauche " , ' \x1b [0m ' )
# print("Orientation : ", obj.worldOrientation.to_euler().z)
# Orienter
def rp_orientation ( orientation ) :
if orientation == " nord " :
obj . applyRotation ( ( 0 , 0 , - obj . worldOrientation . to_euler ( ) . z - math . pi / 2 ) , True )
if orientation == " sud " :
obj . applyRotation ( ( 0 , 0 , - obj . worldOrientation . to_euler ( ) . z + math . pi / 2 ) , True )
if orientation == " est " :
obj . applyRotation ( ( 0 , 0 , - obj . worldOrientation . to_euler ( ) . z + math . pi ) , True )
if orientation == " ouest " :
obj . applyRotation ( ( 0 , 0 , - obj . worldOrientation . to_euler ( ) . z ) , True )
# print("Orientation : ", obj.worldOrientation.to_euler().z)
###############################################################################
# Marquage du sol
###############################################################################
# Marquer une case
def rp_marquer ( ) :
if obj [ ' detruit ' ] != True :
obj [ ' mvts ' ] = obj [ ' mvts ' ] + " m "
if obj [ ' mvts_start ' ] == False : # à condition d'avoir terminé le mouvement
marque1 = scene . addObject ( " Marque " , obj )
marque1 . worldPosition . x = obj . worldPosition . x
marque1 . worldPosition . y = obj . worldPosition . y
marque1 . worldPosition . z = 0.2
# print('\x1b[6;30;43m', "Marquer case (X,Y) :", round(obj.worldPosition.y/3+5.5),",",round(-obj.worldPosition.x/3+5.5), '\x1b[0m')
# Enlever l'ensemble des murs et des marques
def rp_enlever_marques ( ) :
print ( " " )
print ( " Table rase ! " )
for i in range ( nb_objets_fixes , len ( scene . objects ) ) :
scene . objects [ i ] . endObject ( )
###############################################################################
# Construction du niveau
###############################################################################
# Définition du niveau
def rp_niveau ( niveau = 0 ) :
obj [ ' level ' ] = niveau
# Construire les murs
# Longueur : fixe d' une case
# Position des murs : liste imbriquée : [[mur1_x1,mur1_y1,mur1_x2,mur1_y2],[mur2_x1,mur2_y1,mur2_x2,mur2_y2], ...]
# FIXME : verifier si les murs sont dans la zone 10x10
# FIXME : intervertir l'ordre des coordonnéees
# FIXME : verifier si le mur est d'une case
def rp_construire_murs ( def_murs ) :
# print("Objets de la scene : ", scene.objects)
i = 0
for def_mur in def_murs :
i + = 1
# print (def_mur)
# Mur en X
if def_mur [ 0 ] == def_mur [ 2 ] :
mur1 = scene . addObject ( " Mur " , obj )
mur1 [ ' murId ' ] = i
mur1 [ ' x1 ' ] = def_mur [ 0 ]
mur1 [ ' y1 ' ] = def_mur [ 1 ]
mur1 [ ' x2 ' ] = def_mur [ 2 ]
mur1 [ ' y2 ' ] = def_mur [ 3 ]
# print ("mur ", 0)
# mur1.applyRotation((0, 0, -obj.worldOrientation.to_euler().z), True)
# mur1.applyRotation((0, 0, -math.pi/2), True)
# mur1.applyRotation((0, 0, -obj.worldOrientation.to_euler().z), True)
# mur1.worldOrientation.to_euler().z = 0
mur1 . worldPosition . x = - ( ( def_mur [ 1 ] - 4.5 ) * 3 )
mur1 . worldPosition . y = ( ( def_mur [ 0 ] - 5.5 ) * 3 ) + 1.5
mur1 . worldPosition . z = 1.5
print ( ' \x1b [6;30;47m ' , " Construire mur X " , mur1 [ ' murId ' ] , " coordonnées (x1,y1,x2,y2) : " , def_mur [ 0 ] , def_mur [ 1 ] , def_mur [ 2 ] , def_mur [ 3 ] , ' \x1b [0m ' )
# Mur en Y
elif def_mur [ 1 ] == def_mur [ 3 ] :
mur2 = scene . addObject ( " Mur " , obj )
mur2 [ ' murId ' ] = i
mur2 [ ' x1 ' ] = def_mur [ 0 ]
mur2 [ ' y1 ' ] = def_mur [ 1 ]
mur2 [ ' x2 ' ] = def_mur [ 2 ]
mur2 [ ' y2 ' ] = def_mur [ 3 ]
# print ("mur ", -obj.worldOrientation.to_euler().z-math.pi/2)
mur2 . applyRotation ( ( 0 , 0 , - obj . worldOrientation . to_euler ( ) . z - math . pi / 2 ) , True )
# print ("mur ", math.pi/2)
# mur2.applyRotation((0, 0, -math.pi), True)
# mur2.worldOrientation.to_euler().z = math.pi/2
mur2 . worldPosition . x = - ( ( def_mur [ 1 ] - 5.5 ) * 3 ) - 1.5
mur2 . worldPosition . y = ( ( def_mur [ 0 ] - 4.5 ) * 3 )
mur2 . worldPosition . z = 1.5
print ( ' \x1b [6;30;47m ' , " Construire mur Y " , mur2 [ ' murId ' ] , " coordonnées (x1,y1,x2,y2) : " , def_mur [ 0 ] , def_mur [ 1 ] , def_mur [ 2 ] , def_mur [ 3 ] , ' \x1b [0m ' )
else :
print ( ' \x1b [6;30;41m ' , " Mur ni sur X ni sur Y ! " , ' \x1b [0m ' )
# Marquer l'objectif
def rp_marquer_objectif ( x , y ) :
objectif1 = scene . addObject ( " Objectif " , obj )
objectif1 . worldPosition . x = - ( ( y - 4.5 ) * 3 ) + 3
objectif1 . worldPosition . y = ( x - 5.5 ) * 3
objectif1 . worldPosition . z = 0.2
objectif1 [ ' x ' ] = x
objectif1 [ ' y ' ] = y
print ( ' \x1b [6;30;47m ' , " Marquer l ' objectif case (X,Y) : " , x , y , ' \x1b [0m ' )