2022-08-14 08:03:07 +02:00
import bge # Bibliothèque Blender Game Engine (UPBGE)
import bpy # Blender
2022-09-24 04:53:54 +02:00
import random
2022-08-22 04:41:22 +02:00
from rp_lib import * # Bibliothèque Ropy
2022-08-14 08:03:07 +02:00
import os
###############################################################################
# rp_map1.py
# @title: Carte 1 pour Ropy
# @project: Ropy (Blender-EduTech)
# @lang: fr
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2020-2022 Philippe Roy
# @license: GNU GPL
#
###############################################################################
scene = bge . logic . getCurrentScene ( )
2022-08-24 14:12:23 +02:00
###############################################################################
# Missions
###############################################################################
missions_card_description = { }
missions_conf = { }
2022-09-20 06:40:11 +02:00
###############################################################################
# Initialisation du niveau :
# Niveau 1 : Les premiers pas de Ropy
# Niveau 2 : Ma première fonction
# Niveau 3 : Sécuriser Ropy
# Niveau 4 : Partir au bout du monde
# Niveau 5 : Faire face à l'inconnu
# Niveau 6 : Se rendre utile
###############################################################################
2022-08-24 14:12:23 +02:00
2022-09-14 21:58:33 +02:00
missions_card = [ " mission_1-card " , " mission_2-card " , " mission_3-card " , " mission_4-card " , " mission_5-card " , " mission_6-card " ]
# missions_card=["mission_1-card", "mission_2-card", "mission_3-card", "mission_4-card", "mission_5-card", "mission_6-card", "mission_7-card", "mission_8-card"]
2022-08-24 14:12:23 +02:00
# Mission 1
mission_1_title = " Mission 1 \n Premiers pas "
2022-09-18 16:13:32 +02:00
mission_1_text = " \n \n Il faut aider Ropy à atteindre la case \n de l ' objectif (à l ' est de la station). \n "
mission_1_text = mission_1_text + " -> Voir onglet Rover, page \" Avancer \" \n "
mission_1_text = mission_1_text + " -> Voir onglet Rover, page \" Tourner \" \n \n "
mission_1_text = mission_1_text + " Afin de visualiser le trajet, il faudra \n marquer les cases. \n "
mission_1_text = mission_1_text + " -> Voir onglet Rover, page \" Baliser \" \n "
2022-08-24 14:12:23 +02:00
mission_1_init = [ - 11.0 , 3.0 , " e " ] # Rover init position (x,y), orientation ("n|s|e|w")
mission_1_aim = [ - 7.0 , 2.0 ] # Aim position (x,y)
2022-09-14 21:58:33 +02:00
missions_card_description . update ( { " mission_1-card " : [ mission_1_title , mission_1_text ] } )
2022-08-24 14:12:23 +02:00
missions_conf . update ( { " 1 " : [ mission_1_init , mission_1_aim ] } )
# Mission 2
2022-09-14 21:58:33 +02:00
mission_2_title = " Mission 2 \n Ma première fonction "
2022-09-22 06:44:37 +02:00
mission_2_text = " \n \n La case à atteindre est toujours la \n même (à l ' est de la station). \n \n "
mission_2_text = mission_2_text + " Pour faciliter le codage, vous devez \n créer et utiliser la fonction \n \" mrp_avancer() \" regroupant avancer \n et marquer. \n -> Voir onglet Python, page \" Fonction \" . \n \n \n \n \n "
2022-09-21 07:00:44 +02:00
mission_2_init = [ - 11.0 , 3.0 , " e " ]
mission_2_aim = [ - 7.0 , 2.0 ]
2022-08-24 14:12:23 +02:00
missions_card_description . update ( { " mission_2-card " : [ mission_2_title , mission_2_text ] } )
2022-09-14 21:58:33 +02:00
missions_conf . update ( { " 2 " : [ mission_2_init , mission_2_aim ] } )
2022-08-24 14:12:23 +02:00
# Mission 3
2022-09-14 21:58:33 +02:00
mission_3_title = " Mission 3 \n Apprendre le danger "
mission_3_text = " \n \n Tout d ' abords, il faut provoquer une \n collision avec un obstacle (pente \n ou station) et observer ce qui se \n passe. \n \n "
2022-09-22 06:44:37 +02:00
mission_3_text = mission_3_text + " Il faut donc sécuriser Ropy en \n utilisant une structure alternative. \n -> Voir onglet Python, page \" Si alors \" \n -> Voir onglet Rover, page \" Détecter \" \n \n "
2022-09-14 21:58:33 +02:00
mission_3_init = [ - 11.0 , 3.0 , " e " ] # Rover init position (x,y), orientation ("n|s|e|w")
2022-09-24 04:53:54 +02:00
mission_3_aim = [ 100.0 , 100.0 ] # Aim caché -> pas de de position objectif
2022-08-24 14:12:23 +02:00
missions_card_description . update ( { " mission_3-card " : [ mission_3_title , mission_3_text ] } )
2022-09-14 21:58:33 +02:00
missions_conf . update ( { " 3 " : [ mission_3_init , mission_3_aim ] } )
2022-08-24 14:12:23 +02:00
# Mission 4
2022-09-14 21:58:33 +02:00
mission_4_title = " Mission 4 \n Partir au bout du monde "
2022-09-24 04:53:54 +02:00
mission_4_text = " \n \n Ropy est maintenant prêt pour \n l ' aventure soit atteindre la case \n du nouvel objectif (loin, très loin ...). \n \n Pour un tel voyage, l ' utilisation \n d ' une boucle du type \" for \" s ' impose. \n "
2022-09-18 16:13:32 +02:00
mission_4_text = mission_4_text + " -> Voir onglet Python, page \" Boucle \" \n \n \n \n \n "
2022-09-24 04:53:54 +02:00
mission_4_init = [ - 7.0 , 4.0 , " e " ]
2022-09-21 07:00:44 +02:00
mission_4_aim = [ 12.0 , 9.0 ]
2022-08-24 14:12:23 +02:00
missions_card_description . update ( { " mission_4-card " : [ mission_4_title , mission_4_text ] } )
2022-09-14 21:58:33 +02:00
missions_conf . update ( { " 4 " : [ mission_4_init , mission_4_aim ] } )
2022-08-24 14:12:23 +02:00
# Mission 5
2022-09-14 21:58:33 +02:00
mission_5_title = " Mission 5 \n Faire face à l ' inconnu "
2022-09-18 16:13:32 +02:00
mission_5_text = " \n \n La case à atteindre est toujours la \n même, mais le lieu de départ change \n à chaque fois. \n \n "
2022-09-24 04:53:54 +02:00
mission_5_text = mission_5_text + " Pour pallier à l \' aléatoire, vous \n utiliserez les pentes comme obstacle. \n "
mission_5_text = mission_5_text + " Il faut alors créer une fonction \n avec une boucle \" while \" (tant que) \n qui permet d ' avancer jusqu ' à un \n obstacle : "
2022-09-14 21:58:33 +02:00
mission_5_text = mission_5_text + " \" mrp_avancer_mur() \" . \n \n \n "
2022-09-24 04:53:54 +02:00
mission_5_init = [ 0.0 , 0.0 , " e " ] # Position aléatoire tourné vers l'est -> défini dans le reset
2022-09-21 07:00:44 +02:00
mission_5_aim = [ 12.0 , 9.0 ]
2022-08-24 14:12:23 +02:00
missions_card_description . update ( { " mission_5-card " : [ mission_5_title , mission_5_text ] } )
2022-09-14 21:58:33 +02:00
missions_conf . update ( { " 5 " : [ mission_5_init , mission_5_aim ] } )
2022-08-24 14:12:23 +02:00
# Mission 6
2022-09-14 21:58:33 +02:00
mission_6_title = " Mission 6 \n Se rendre utile "
2022-09-22 06:44:37 +02:00
mission_6_text = " \n \n Une zone précise du terrain présente \n des pierres à analyser. \n \n Elles apparaissent de manière \n aléatoire (encore !), pour les \n ramasser, Ropy doit passer sur \n toutes les cases de la zone. \n \n \n \n \n \n \n "
2022-09-24 04:53:54 +02:00
mission_6_init = [ 0.0 , 0.0 , " e " ] # Position aléatoire tourné vers l'est -> défini dans le reset
mission_6_aim = [ 100.0 , 100.0 ] # Aim caché -> rammassage de pierre
2022-08-24 14:12:23 +02:00
missions_card_description . update ( { " mission_6-card " : [ mission_6_title , mission_6_text ] } )
2022-09-14 21:58:33 +02:00
missions_conf . update ( { " 6 " : [ mission_6_init , mission_6_aim ] } )
2022-08-24 14:12:23 +02:00
# Mission 7
2022-09-14 21:58:33 +02:00
# mission_7_title="Mission 7\n FIXME"
# mission_7_text="\n \n FIXME"
# missions_card_description.update({"mission_7-card" : [mission_7_title, mission_7_text]})
# missions_conf.update({"7" : [mission_7_init, mission_7_aim]})
2022-08-24 14:12:23 +02:00
# Mission 8
2022-09-14 21:58:33 +02:00
# mission_8_title="Mission 8\n FIXME"
# mission_8_text="\n \n FIXME"
# missions_card_description.update({"mission_8-card" : [mission_8_title, mission_8_text]})
# missions_conf.update({"8" : [mission_8_init, mission_8_aim]})
2022-08-24 14:12:23 +02:00
# Description des cartes missions
def get_missions_card ( ) :
return missions_card
def get_card_description ( ) :
return missions_card_description
2022-08-14 08:03:07 +02:00
###############################################################################
# Map
###############################################################################
2022-09-24 04:53:54 +02:00
##
2022-08-14 08:03:07 +02:00
# Initialization
2022-09-24 04:53:54 +02:00
##
2022-08-14 08:03:07 +02:00
def map_init ( ) :
2022-09-18 16:13:32 +02:00
scene . objects [ ' Terrain ' ] [ ' size ' ] = [ - 15 , - 11 , 15 , 10 ] # Map size
scene . objects [ ' Terrain ' ] [ ' map_tile_montain ' ] = [ ]
scene . objects [ ' Terrain ' ] [ ' map_tile_station ' ] = [ [ - 9 , 2 ] , [ - 9 , 3 ] ]
for obj_i in scene . objects :
if " terrain_sideCliff " in obj_i . name or " terrain_sideCorner " in obj_i . name or " terrain_sideCornerInner " in obj_i . name :
scene . objects [ ' Terrain ' ] [ ' map_tile_montain ' ] . append ( [ round ( obj_i . worldPosition . x ) , round ( obj_i . worldPosition . y ) ] )
2022-09-24 04:53:54 +02:00
# Cacher les zones
scene . objects [ ' Aim ' ] . setVisible ( False , True )
scene . objects [ ' Initzone-mission-5 ' ] . setVisible ( False , True )
scene . objects [ ' Aimzone-mission-6 ' ] . setVisible ( False , True )
2022-09-18 16:13:32 +02:00
# print (scene.objects['Terrain']['map_tile_montain'])
# i=0
# for i_xy in scene.objects['Terrain']['map_tile_montain']:
# beacon= scene.addObject("Beacon", scene.objects['Terrain'])
# beacon.worldPosition=[i_xy[0],i_xy[1],0.2]
# beacon.setVisible(True, True)
# i+=1
2022-08-14 08:03:07 +02:00
# Landscape
# file_path = 'asset/map/map1-landscape.blend'
# inner_path = 'Object'
# object_name = 'Landscape'
# bpy.ops.wm.append(
# filepath=os.path.join(file_path, inner_path, object_name),
# directory=os.path.join(file_path, inner_path),
# filename=object_name)
2022-09-24 04:53:54 +02:00
##
2022-08-24 14:12:23 +02:00
# Reset de la map
2022-09-24 04:53:54 +02:00
##
2022-08-14 08:03:07 +02:00
def map_reset ( ) :
scene . objects [ ' Points ' ] [ ' step ' ] = 0
scene . objects [ ' Points ' ] [ ' nbligne ' ] = 0
2022-09-20 06:40:11 +02:00
mission_init = missions_conf [ str ( scene . objects [ ' Points ' ] [ ' mission ' ] ) ] [ 0 ]
mission_aim = missions_conf [ str ( scene . objects [ ' Points ' ] [ ' mission ' ] ) ] [ 1 ]
2022-08-22 04:41:22 +02:00
2022-08-26 01:58:49 +02:00
# Cacher les balises
for i in range ( 100 ) :
beacon = scene . objects [ " Beacon- " + str ( i ) ]
beacon . worldPosition = [ 29 , 1 + i , 0.2 ]
beacon . setVisible ( False , True )
beacon [ ' activated ' ] = False
scene . objects [ ' Terrain ' ] [ ' map_tile_beacon ' ] = [ ]
2022-08-24 14:12:23 +02:00
# Initialisation du rover
obj = scene . objects [ ' Rover ' ]
obj . worldPosition . x = mission_init [ 0 ]
obj . worldPosition . y = mission_init [ 1 ]
2022-09-18 16:13:32 +02:00
obj . worldPosition . z = 0.2
2022-08-24 14:12:23 +02:00
applyRotationTo ( obj , 0 , 0 , 0 , True )
if mission_init [ 2 ] == " n " :
obj . applyRotation ( ( 0 , 0 , math . pi ) , True )
if mission_init [ 2 ] == " e " :
obj . applyRotation ( ( 0 , 0 , math . pi / 2 ) , True )
if mission_init [ 2 ] == " w " :
obj . applyRotation ( ( 0 , 0 , - math . pi / 2 ) , True )
2022-09-24 04:53:54 +02:00
# Initialisation du rover pour les missions 5 et 6 : position aléatoire entre -3.0 ; 5.0 et 1.0 ; -10.0
if scene . objects [ ' Points ' ] [ ' mission ' ] == 5 or scene . objects [ ' Points ' ] [ ' mission ' ] == 6 :
position_ok = False
while position_ok == False : # Exclusion de certaines cases
obj . worldPosition . x = random . randint ( - 3 , 1 )
obj . worldPosition . y = random . randint ( - 10 , 5 )
position_ok = True
if obj . worldPosition . x == 0 and obj . worldPosition . y == - 10 :
position_ok = False
if obj . worldPosition . x == 1 and obj . worldPosition . y == - 8 :
position_ok = False
if obj . worldPosition . x == 1 and obj . worldPosition . y == - 9 :
position_ok = False
if obj . worldPosition . x == 1 and obj . worldPosition . y == - 10 :
position_ok = False
2022-08-24 14:12:23 +02:00
# Initialisation des objectifs
2022-09-18 16:13:32 +02:00
scene . objects [ ' Terrain ' ] [ ' map_aim ' ] = [ [ mission_aim [ 0 ] , mission_aim [ 1 ] ] ]
2022-09-24 04:53:54 +02:00
obj_aim = scene . objects [ ' Aim ' ]
2022-08-24 14:12:23 +02:00
obj_aim . worldPosition . x = mission_aim [ 0 ]
obj_aim . worldPosition . y = mission_aim [ 1 ]
obj_aim . worldPosition . z = 0.5
2022-09-20 06:40:11 +02:00
###############################################################################
# Objectif
###############################################################################
2022-09-21 07:00:44 +02:00
##
# Afficher l'objectif
##
2022-09-20 06:40:11 +02:00
def aim_show ( ) :
2022-09-24 04:53:54 +02:00
# Zone de départ
if scene . objects [ ' Points ' ] [ ' mission ' ] == 5 or scene . objects [ ' Points ' ] [ ' mission ' ] == 6 :
scene . objects [ ' Initzone-mission-5 ' ] . setVisible ( True , True )
else :
scene . objects [ ' Initzone-mission-5 ' ] . setVisible ( False , True )
# Cible
if scene . objects [ ' Points ' ] [ ' mission ' ] == 3 or scene . objects [ ' Points ' ] [ ' mission ' ] == 6 :
scene . objects [ ' Aim ' ] . setVisible ( False , True )
2022-09-20 06:40:11 +02:00
else :
2022-09-24 04:53:54 +02:00
scene . objects [ ' Aim ' ] . setVisible ( True , True )
# Zone cible
if scene . objects [ ' Points ' ] [ ' mission ' ] == 6 :
scene . objects [ ' Aimzone-mission-6 ' ] . setVisible ( True , True )
else :
scene . objects [ ' Aimzone-mission-6 ' ] . setVisible ( False , True )
2022-09-20 06:40:11 +02:00
2022-09-21 07:00:44 +02:00
##
# Cacher l'objectif
##
2022-09-20 06:40:11 +02:00
def aim_hide ( ) :
2022-09-24 04:53:54 +02:00
scene . objects [ ' Aim ' ] . setVisible ( False , True )
scene . objects [ ' Aimzone-mission-6 ' ] . setVisible ( False , True )
scene . objects [ ' Initzone-mission-5 ' ] . setVisible ( False , True )
2022-09-21 07:00:44 +02:00
##
# Validation de l'objectif atteint
##
2022-09-20 06:40:11 +02:00
def objectif_control ( x , y ) :
2022-09-21 07:00:44 +02:00
# Mission 1
if scene . objects [ ' Points ' ] [ ' mission ' ] == 1 :
if [ x , y ] in scene . objects [ ' Terrain ' ] [ ' map_aim ' ] : # Aim
if len ( scene . objects [ ' Terrain ' ] [ ' map_tile_beacon ' ] ) > = 6 : # 6 balises posées mini
return True
# Mission 2 (fonction)
if scene . objects [ ' Points ' ] [ ' mission ' ] == 2 :
if [ x , y ] in scene . objects [ ' Terrain ' ] [ ' map_aim ' ] : # Aim
if len ( scene . objects [ ' Terrain ' ] [ ' map_tile_beacon ' ] ) > = 6 : # 6 balises posées mini
if scene . objects [ ' Points ' ] [ ' nbligne ' ] < = 40 : # 40 lignes de code maxi
2022-09-22 06:44:37 +02:00
txt = [ " def mrp_avancer(): " , " def mrp_avancer() : " , " def mrp_avancer (): " , " def mrp_avancer () : " ] # Présence de "def mrp_avancer():"
2022-09-24 04:53:54 +02:00
if rp_cmd_txtcount ( txt , 1 ) :
2022-09-21 07:00:44 +02:00
return True
# Mission 3 (structure alternative)
2022-09-22 06:44:37 +02:00
# Le controle de l'objectif est dans la fonction rp_detect().
2022-09-21 07:00:44 +02:00
# Mission 4 (boucle en for)
if scene . objects [ ' Points ' ] [ ' mission ' ] == 4 :
2022-09-22 06:44:37 +02:00
if [ x , y ] in scene . objects [ ' Terrain ' ] [ ' map_aim ' ] : # Aim
if scene . objects [ ' Points ' ] [ ' nbligne ' ] < = 40 : # 40 lignes de code maxi
2022-09-24 04:53:54 +02:00
txt = [ " for " ] # Présence de "for i in range" 2x
if rp_cmd_txtcount ( txt , 2 ) :
txt = [ " in range " ]
if rp_cmd_txtcount ( txt , 2 ) :
return True
else :
txt = [ " def mrp_avancer_nbpas " ] # Présence de "def mrp_avancer_nbpas"
if rp_cmd_txtcount ( txt , 1 ) :
return True
2022-09-21 07:00:44 +02:00
# Mission 5 (boucle en while)
if scene . objects [ ' Points ' ] [ ' mission ' ] == 5 :
2022-09-24 04:53:54 +02:00
if [ x , y ] in scene . objects [ ' Terrain ' ] [ ' map_aim ' ] : # Aim
if scene . objects [ ' Points ' ] [ ' nbligne ' ] < = 40 : # 40 lignes de code maxi
txt = [ " while " ] # Présence de "while" 2x
if rp_cmd_txtcount ( txt , 2 ) :
return True
else :
txt = [ " def mrp_avancer_mur(): " , " def mrp_avancer_mur() : " , " def mrp_avancer_mur (): " , " def mrp_avancer_mur () : " ] # Présence de "def mrp_avancer_mur():"
if rp_cmd_txtcount ( txt , 1 ) :
return True
2022-09-21 07:00:44 +02:00
# Mission 6 (passer sur tout le terrain)
if scene . objects [ ' Points ' ] [ ' mission ' ] == 6 :
2022-09-24 04:53:54 +02:00
# FIXME
2022-09-21 07:00:44 +02:00
return False
2022-09-20 06:40:11 +02:00
return False
2022-08-24 14:12:23 +02:00
###############################################################################
# Fonction bas niveau
###############################################################################
2022-09-21 07:00:44 +02:00
##
# Recherche de texte dans le script
##
2022-09-24 04:53:54 +02:00
def rp_cmd_txtcount ( text_list , n ) :
2022-09-21 07:00:44 +02:00
# print (os.getcwd())
file = open ( ' rp_cmd.py ' , ' r ' )
file_txt = file . read ( )
for text in text_list :
2022-09-24 04:53:54 +02:00
if file_txt . count ( text ) > = n :
2022-09-21 07:00:44 +02:00
file . close ( )
return True
file . close ( )
return False
2022-08-24 14:12:23 +02:00
##
# Atteindre une orientation
##
def applyRotationTo ( obj , rx = None , ry = None , rz = None , Local = True ) :
rres = 0.001 # resolution rotation
# x
if rx is not None :
while ( abs ( rx - obj . worldOrientation . to_euler ( ) . x ) > rres ) :
if obj . worldOrientation . to_euler ( ) . x - rx > rres :
obj . applyRotation ( ( - rres , 0 , 0 ) , Local )
if rx - obj . worldOrientation . to_euler ( ) . x > rres :
obj . applyRotation ( ( rres , 0 , 0 ) , Local )
# print ("delta x ",rx-obj.worldOrientation.to_euler().x)
# y
if ry is not None :
while ( abs ( ry - obj . worldOrientation . to_euler ( ) . y ) > rres ) :
if obj . worldOrientation . to_euler ( ) . y - ry > rres :
obj . applyRotation ( ( 0 , - rres , 0 ) , Local )
if ry - obj . worldOrientation . to_euler ( ) . y > rres :
obj . applyRotation ( ( 0 , rres , 0 ) , Local )
# print ("delta y ",ry-obj.worldOrientation.to_euler().y)
# z
if rz is not None :
while ( abs ( rz - obj . worldOrientation . to_euler ( ) . z ) > rres ) :
if obj . worldOrientation . to_euler ( ) . z - rz > rres :
obj . applyRotation ( ( 0 , 0 , - rres ) , Local )
if rz - obj . worldOrientation . to_euler ( ) . z > rres :
obj . applyRotation ( ( 0 , 0 , rres ) , Local )
# print ("delta z ",rz-obj.worldOrientation.to_euler().z)