ropy/rp_map1.py

358 lines
15 KiB
Python
Raw Normal View History

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
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()
###############################################################################
# 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
###############################################################################
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"]
# 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"
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)
missions_card_description.update({"mission_1-card" : [mission_1_title, mission_1_text]})
missions_conf.update({"1" : [mission_1_init, mission_1_aim]})
# Mission 2
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]
missions_card_description.update({"mission_2-card" : [mission_2_title, mission_2_text]})
missions_conf.update({"2" : [mission_2_init, mission_2_aim]})
# Mission 3
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"
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
missions_card_description.update({"mission_3-card" : [mission_3_title, mission_3_text]})
missions_conf.update({"3" : [mission_3_init, mission_3_aim]})
# Mission 4
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]
missions_card_description.update({"mission_4-card" : [mission_4_title, mission_4_text]})
missions_conf.update({"4" : [mission_4_init, mission_4_aim]})
# Mission 5
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 :"
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]
missions_card_description.update({"mission_5-card" : [mission_5_title, mission_5_text]})
missions_conf.update({"5" : [mission_5_init, mission_5_aim]})
# Mission 6
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
missions_card_description.update({"mission_6-card" : [mission_6_title, mission_6_text]})
missions_conf.update({"6" : [mission_6_init, mission_6_aim]})
# Mission 7
# 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]})
# Mission 8
# 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]})
# 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
##
# 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-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']= []
# 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
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
# 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']
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
###############################################################################
# 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
##
# 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)