ropy/rp_doc.py

716 lines
36 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import bge # Bibliothèque Blender Game Engine (UPBGE)
import rp_map1 # Map definition
import webbrowser
###############################################################################
# rp_doc.py
# @title: Documentation du Rover Ropy
# @project: Ropy (Blender-EduTech)
# @lang: fr
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2020-2023 Philippe Roy
# @license: GNU GPL
#
# Ropy est destiné à la découverte de la programmation procédurale et du language Python.
# 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.
###############################################################################
scene = bge.logic.getCurrentScene()
# Colors
color_doc_chap = (0, 1, 0.857,1) # Turquoise
color_doc_fct = (0, 1, 0.857,1) # Turquoise
color_doc_hl = (0.799, 0.617, 0.021, 1) # Jaune
color_doc_activate = (0.936, 0.033, 1, 1) # Rose
color_doc_mission = (1, 0.192, 0.03, 1) # Orange
# UPBGE constants
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED
ACTIVATE = bge.logic.KX_INPUT_ACTIVE
# JUST_DEACTIVATED = bge.logic.KX_SENSOR_JUST_DEACTIVATED
# Cards description
card_description ={}
# Missions
card_description.update(rp_map1.get_missions_description())
missions_card=rp_map1.get_missions_card()
################################################################################
# Documentation Rover
################################################################################
rover_card=["forward-card", "turn-card", "delineate-card", "detect-card", "radar-card", "twins-card"]
rover_card=rover_card+["speed-card", "paint-card", "battery-card", "beacon-card"]
# Avancer et reculer
rp_forward_title="Avancer et reculer"
rp_forward_text=" rp_avancer() \n -> Avance d'un pas en avant. \n \n rp_reculer() \n -> Recule d'un pas."
rp_forward_type="standard"
card_description.update({"forward-card" : [rp_forward_title, rp_forward_text, rp_forward_type]})
# Tourner
rp_turn_title="Tourner"
rp_turn_text=" rp_gauche() \n -> Tourne à gauche (90°).\n \n rp_droite() \n -> Tourne à droite (90°)."
rp_turn_type="standard"
card_description.update({"turn-card" : [rp_turn_title, rp_turn_text, rp_turn_type]})
# Baliser
rp_delineate_title="Baliser"
rp_delineate_text=" rp_marquer() \n -> Place une balise sur la case. \n \n Ropy possède que 20 balises, il ne \n peut pas en poser une de plus.\n\n Avec l'amélioration \"Balise +\", le \n nombre de balise transportées est \n étendu à 200."
rp_delineate_type="standard"
card_description.update({"delineate-card" : [rp_delineate_title, rp_delineate_text, rp_delineate_type]})
# Détecter
rp_detect_title="Détecter"
rp_detect_text=" rp_detect() \n -> Détecte un obstacle.\n \n La fonction retourne : \n - \"True\" si il a un obstacle, \n - \"False\" si il n'y a pas d'obstacle."
rp_detect_type="standard"
card_description.update({"detect-card" : [rp_detect_title, rp_detect_text, rp_detect_type]})
# Radar
rp_radar_title="Radar"
rp_radar_text=" Le radar n'est toujours pas \n opérationnel ! \n \n Mais où est donc encore passé Thomas !"
rp_radar_type="mission"
card_description.update({"radar-card" : [rp_radar_title, rp_radar_text, rp_radar_type]})
# Jumeau numérique
rp_twins_title="Jumeau numérique"
rp_twins_text=""" Via une liaison série, Ropy peut être \n le jumeau numérique d'un robot réel. \n
rp_jumeau(port, vitesse=115200) \n -> Active le jumeau réel par la liaison \n série. Si le port n'est pas spécifié, il \n est recherché automatiquement. \n
rp_serie_msg(texte) \n -> Envoi un message \n \n texte=rp_serie_rcpt() \n -> Reçoit un message"""
# Message envoyé (asynchrone) : \n avancer : a, reculer : r, droite : d, \n gauche g, marquer : m et forer : f \n\n\n """
rp_twins_type="standard"
card_description.update({"twins-card" : [rp_twins_title, rp_twins_text, rp_twins_type]})
# Cards description pour le magasin
storecard_description ={}
# Speed - Vitesse
rp_speed_title="Vitesse"
rp_speed_text=" L'amélioration \"Vitesse\" permet de \n changer la vitesse des déplacements \n par l'interface (en bas à gauche).\n\n"
rp_speed_text=rp_speed_text + " La vitesse est modifiable par codage : \n"
rp_speed_text=rp_speed_text + " rp_vitesse(nouvelle_vitesse), où \n la vitesse est une valeur de 0,1 à 10.\n\n La fonction rp_vitesse() retourne la \n vitesse actuelle."
rp_speed_store="Permet de modifier\nla vitesse des \ndéplacements."
rp_speed_purchased="Je vois ... \n l'efficacité, hein ! \n Vous verrez avec \n ces moteurs,\n c'est autre vie."
rp_speed_type="upgrade"
card_description.update({"speed-card" : [rp_speed_title, rp_speed_text, rp_speed_store, rp_speed_purchased, rp_speed_type]})
# Paint - Peinture
rp_paint_title="Peinture"
rp_paint_text=" rp_couleur(objets, couleur) \n -> Change la couleur du groupe \n d'objets 3d. \n"
rp_paint_text=rp_paint_text + " - La couleur est un tuple au format \n (R,V,B,Alpha) avec des valeurs de 0 à 1.\n"
rp_paint_text=rp_paint_text + " - objets peut être : \"Rover 1\",\n \"Rover 2\", \"Rover 3\", \"Station 1\", \n \"Station 2\", \"Station 3\", \"Station 4\", \n \"Balises\" ou \"Balise 1\" à \"Balise 200\".\n\n"
rp_paint_text=rp_paint_text + " rp_couleur_init(objets) \n -> Réinitialise la couleur des objets.\n rp_couleur_init() réinitialise tout !"
rp_paint_store="On refait la déco ?"
rp_paint_purchased="Rien de tel qu'un \n peu de couleur \n dans ce monde \n de brute !"
rp_paint_type="upgrade"
card_description.update({"paint-card" : [rp_paint_title, rp_paint_text, rp_paint_store, rp_paint_purchased, rp_paint_type]})
# Battery + - Batterie +
rp_battery_title="Batterie +"
rp_battery_text=" L'amélioration \"Batterie +\" permet \n d'augmenter la capacité de la batterie \n du Rover à 200 pas (contre 20 pas). \n\n"
rp_battery_text=rp_battery_text + " La fonction rp_batterie() retourne \n la charge actuelle de la batterie \n (valeur de 0 à 100 %)."
rp_battery_store="Augmente la capacité \nde la batterie à 200 \nmouvements (contre \n20, plutôt faible ...).\n\n"
rp_battery_purchased="Très bon choix ! \n Cette batterie \n vous va comme \n un gant."
rp_battery_type="upgrade"
card_description.update({"battery-card" : [rp_battery_title, rp_battery_text, rp_battery_store, rp_battery_purchased, rp_battery_type]})
# Beacon + - Balise +
rp_beacon_title="Balise +"
rp_beacon_text=" L'amélioration \"Balise +\" permet \n d'augmenter le nombre de balises \n pouvant être posées à 200 (contre 20). \n\n"
rp_beacon_text=rp_beacon_text + " La fonction rp_balise() retourne \n le nombre de balises dejà posées \n lors du trajet."
rp_beacon_store="Porte le nombre de \nbalises transportées\nà 200 (contre 20)."
rp_beacon_purchased="Les colis viennent \n tout juste d'être \n livrés. Un vrai sapin de Noël, \nce terrain !"
rp_beacon_type="upgrade"
card_description.update({"beacon-card" : [rp_beacon_title, rp_beacon_text, rp_beacon_store, rp_beacon_purchased, rp_beacon_type]})
###############################################################################
# Documentation Python
###############################################################################
# python_card=["function-card", "alternative-card", "loop-card", "flow-card", "text-card", "list-card", "dict-card", "oop-card", "console-card", "sleep-card"]
python_card=["function-card", "alternative-card", "loop-card", "flow-card", "text-card", "list-card", "dict-card", "console-card", "sleep-card", "python-card"]
# Fonction
rp_function_title="Fonction"
rp_function_text=" La définition d'une fonction se fait \n avec \"def\". La fonction peut \n renvoyer une valeur avec \"return\". \n\n"
rp_function_text=rp_function_text + " def fonction_1 (arguments) : \n instruction_1 \n instruction_2 \n ....\n return valeurs_renvoyées \n\n"
rp_function_text=rp_function_text + " Les arguments sont des données \n transmises à la fonction."
rp_function_url=[["w3schools.com : functions","https://www.w3schools.com/python/python_functions.asp"]]
card_description.update({"function-card" : [rp_function_title, rp_function_text, rp_function_url]})
# Alternative
rp_alternative_title="Alternative"
rp_alternative_text=" L'alternative permet d'éxécuter des \n instructions en fonction d'un test. \n"
rp_alternative_text=rp_alternative_text + " Elle se programme en suivant la \n suite : si ... alors ... sinon ... où \n"
rp_alternative_text=rp_alternative_text + " \"si\" est \"if \" et \"sinon\" est \"else\". \n\n"
rp_alternative_text=rp_alternative_text + " if condition :\n"
rp_alternative_text=rp_alternative_text + " instruction_1\n"
rp_alternative_text=rp_alternative_text + " else : \n"
rp_alternative_text=rp_alternative_text + " instruction_2\n\n"
rp_alternative_text=rp_alternative_text + "Le sinon (\"else\") est facultatif."
rp_alternative_url=[["w3schools.com : if ... else","https://www.w3schools.com/python/python_conditions.asp"]]
card_description.update({"alternative-card" : [rp_alternative_title, rp_alternative_text, rp_alternative_url]})
# Boucles
rp_loop_title="Boucles"
rp_loop_text=" Il y a deux types de boucle : \n - avec \"for\" pour définir un nombre \n de répétition (ici N), \n - avec \"while\" (tant que) pour \n prendre en compte une condition. \n \n"
rp_loop_text=rp_loop_text + " for i in range (n) : \n instruction \n \n"
rp_loop_text=rp_loop_text + " while condition : \n instruction"
rp_loop_url=[["w3schools.com : for","https://www.w3schools.com/python/python_for_loops.asp"],
["w3schools.com : while","https://www.w3schools.com/python/python_while_loops.asp"]]
card_description.update({"loop-card" : [rp_loop_title, rp_loop_text, rp_loop_url]})
# Flux
rp_flow_title="Contrôle du flux"
rp_flow_text=" Les structures (if, while, for) peuvent \n être gérées plus finement par les \n fonctions \"break\", \"continue\" et \"pass\". \n\n"
rp_flow_text= rp_flow_text + "- \"break\" : Termine l'itération en cours \n et arrête la boucle.\n"
rp_flow_text= rp_flow_text + "- \"continue\" : Termine l'itération en \n cours et reprend la boucle.\n"
rp_flow_text= rp_flow_text + "- \"pass\" : Instruction vide."
rp_flow_url=[["w3schools.com : break","https://www.w3schools.com/python/ref_keyword_break.asp"],
["w3schools.com : continue","https://www.w3schools.com/python/ref_keyword_break.asp"],
["w3schools.com : pass","https://www.w3schools.com/python/ref_keyword_pass.asp"]]
card_description.update({"flow-card" : [rp_flow_title, rp_flow_text, rp_flow_url]})
# Chaîne de caractères
rp_text_title="Chaîne de caractères"
rp_text_text=""" Une chaîne de caractères correspond \n à un texte (mot, phrase). Elle est \n délimitée par " ou ' : texte = "Bonjour !" \n
- texte1 + texte2 : concaténe plusieurs \n chaînes.
- len(texte) : longueur du texte.
- "\\n" : caractère aller à la ligne.
- texte[i] : le caractère du rang i.
- texte[2:5] : les caractères du \n rang 2 au rang 5.
- texte.replace("a","b") : remplace les \n "a" par des "b". """
rp_text_url=[
["Doc. Python v3 Français : string","https://docs.python.org/fr/3/library/string.html"],
["w3schools.com : strings","https://www.w3schools.com/python/python_strings.asp"]]
card_description.update({"text-card" : [rp_text_title, rp_text_text, rp_text_url]})
# Liste
rp_list_title="Liste"
rp_list_text=""" Une liste est une séquence d'éléments. \n Elle est délimitée par des crochets :
liste = ["pomme", 7, "rouge", True] \n
- liste[i] : renvoie l'élément du rang i \n de la liste (commence à 0).
- liste.append("neige") : ajoute "neige" \n à la fin de la liste.
- len(liste) : nombre d'éléments.
- liste.sort() : classe par ordre \n croissant la liste.
- liste.remove("rouge") : enlève la \n première occurence de "rouge"."""
rp_list_url=[
["Doc. Python v3 Français : list","https://docs.python.org/fr/3/library/stdtypes.html#sequence-types-list-tuple-range"],
["w3schools.com : lists","https://www.w3schools.com/python/python_lists.asp"]]
card_description.update({"list-card" : [rp_list_title, rp_list_text, rp_list_url]})
# Dictionnaire
rp_dict_title="Dictionnaire"
rp_dict_text=""" Un dictionnaire est une collection \n d'éléments. Il est délimité par des \n accolades, chaque valeur est associée
à une clé unique : dct={'nom':"Haddock",\n 'prénom':"Archibald", 'année': 1940} \n
- dct[clé] : valeur liée à la clé.
- dct.update('domicile' : "Moulinsart") : \n met à jour les paires de clé/valeur.
- len(dct) : nombre d'éléments.
- list(dct) : liste des clés.
- dct.pop('année') : enlève la valeur \n associée à la clé (ici 1940)."""
rp_dict_url=[
["Doc. Python v3 Français : dict","https://docs.python.org/fr/3/library/stdtypes.html#mapping-types-dict"],
["w3schools.com : dictionaries","https://www.w3schools.com/python/python_dictionaries.asp"]]
card_description.update({"dict-card" : [rp_dict_title, rp_dict_text, rp_dict_url]})
# Objet (POO)
rp_oop_title="Programmation\norientée objet (POO)"
rp_oop_text="\nFIXME"
rp_oop_url=[["w3schools.com : classes & objects","https://www.w3schools.com/python/python_classes.asp"]]
card_description.update({"oop-card" : [rp_oop_title, rp_oop_text, rp_oop_url]})
# Console
rp_console_title="Console"
rp_console_text=" Si vous avez executé Ropy dans un \n terminal avec l'option \"-con\", vous \n pouvez utiliser le terminal comme \n console de debuggage.\n\n"
rp_console_text= rp_console_text + " print(\"Bonjour !\") \n -> Affiche le texte dans la console.\n\n"
rp_console_text= rp_console_text + " variable = input () \n -> Permet la saisie, par exemple : \n"
rp_console_text= rp_console_text + " entree = \"\"\n while entree == \"\" :\n entree = input ()"
rp_console_url=[["w3schools.com : print","https://www.w3schools.com/python/ref_func_print.asp"],
["w3schools.com : input","https://www.w3schools.com/python/ref_func_input.asp"]]
card_description.update({"console-card" : [rp_console_title, rp_console_text, rp_console_url]})
# Temps
rp_sleep_title="Gestion du temps"
rp_sleep_text=" Vous pouvez créer des temporisations \n dans le déroulement du script.\n\n"
rp_sleep_text= rp_sleep_text + " time.sleep(x) \n -> Marque d'un temps d'arrêt de \n x secondes.\n\n"
rp_sleep_text= rp_sleep_text + " Il faudra préalablement importer la \n bibliothèque \"time\" avec \"import time\"."
rp_sleep_url=[["docs.python.org : sleep","https://docs.python.org/fr/3/library/time.html#time.sleep"]]
card_description.update({"sleep-card" : [rp_sleep_title, rp_sleep_text, rp_sleep_url]})
# Python
rp_python_title="Langage Python"
rp_python_text=""" Python est un langage de \n programmation interprété open source.
Python vise à être visuellement épuré \n avec une syntaxe clairement séparée \n des mécanismes de bas niveau.\n
Python possède beaucoup de \n bibliothèques spécialisées.
Multiplateformes et multiparadigme,
il est utilisé dans de nombreux \n contextes : scriptage, prototypage, \n calcul numérique, enseignement, ou \n encore comme langage de commande."""
rp_python_url=[["python.org","https://python.org"], ["AFPy","https://www.afpy.org"]]
card_description.update({"python-card" : [rp_python_title, rp_python_text, rp_python_url]})
###############################################################################
# Interface
###############################################################################
##
# Initialisation de la tablette
##
def init():
# Mettre les couleurs sur les icones (chapitres et cartes)
chap=("general", "missions", "rover", "python")
for page in chap:
scene.objects["Doc-"+page].color = color_doc_chap
scene.objects["Doc-"+page+"-text"].color = color_doc_chap
for i in range(len(missions_card)):
scene.objects[missions_card[i]].color = color_doc_fct
scene.objects[missions_card[i]+"-icon"].color = color_doc_fct
scene.objects[missions_card[i]+"-text"].color = color_doc_fct
for i in range(len(rover_card)):
scene.objects[rover_card[i]].color = color_doc_fct
scene.objects[rover_card[i]+"-icon"].color = color_doc_fct
scene.objects[rover_card[i]+"-text"].color = color_doc_fct
for i in range(len(python_card)):
scene.objects[python_card[i]].color = color_doc_fct
scene.objects[python_card[i]+"-icon"].color = color_doc_fct
scene.objects[python_card[i]+"-text"].color = color_doc_fct
scene.objects['Book_level_button'].color = color_doc_chap
scene.objects['Book_level_button'].setVisible(False,True)
scene.objects['Book_python_url_title'].setVisible(False,True)
scene.objects['Book_python_url0'].color = color_doc_chap
scene.objects['Book_python_url0'].setVisible(False,True)
scene.objects['Book_python_url1'].color = color_doc_chap
scene.objects['Book_python_url1'].setVisible(False,True)
scene.objects['Book_python_url2'].color = color_doc_chap
scene.objects['Book_python_url2'].setVisible(False,True)
scene.objects["mission_"+str(scene.objects['Points']['mission'])+"-card"].color = color_doc_mission
scene.objects["mission_"+str(scene.objects['Points']['mission'])+"-card-icon"].color = color_doc_mission
scene.objects["mission_"+str(scene.objects['Points']['mission'])+"-card-text"].color = color_doc_mission
# Chargement du texte
# text_load()
text_dynamic_load() # en dynamique
# Mémorisation de la position des pages
for page in chap:
scene.objects["Doc_chap-"+page]['init_lx']=scene.objects["Doc_chap-"+page].worldPosition.x
scene.objects["Doc_chap-"+page]['init_ly']=scene.objects["Doc_chap-"+page].worldPosition.y
scene.objects["Doc_chap-"+page]['init_lz']=scene.objects["Doc_chap-"+page].worldPosition.z
# Page par défaut
scene.objects['Doc']['page_chap'] = "general"
##
# Ouvrir la tablette
##
def open():
# Placer la tablette
# scene.objects['Doc'].worldPosition = [0, -21, 15.75]
scene.objects['Doc'].worldPosition = [0, -21, 15.8]
scene.objects['Doc_close'].color = color_doc_chap
scene.objects['Doc'].setVisible(True,True)
# text_hide()
text_dynamic_hide()
# Placer le nouveau chapitre
name_chap = scene.objects['Doc']['page_chap']
scene.objects['Doc-'+name_chap].color = color_doc_activate
scene.objects['Doc-'+name_chap+'-text'].color = color_doc_activate
scene.objects['Doc_chap-'+name_chap].worldPosition = scene.objects['Doc'].worldPosition
scene.objects['Doc_chap-'+name_chap].setVisible(True,True)
# Affichage ou pas du bouton de selection de la mission
if name_chap == "missions":
name_fct = scene.objects['Doc_chap-missions']['page_fct']
if name_fct !="":
if scene.objects[name_fct]['mission'] <= scene.objects['Points']['level'] and scene.objects[name_fct]['mission'] != scene.objects['Points']['mission']:
scene.objects['Book_level_button'].setVisible(True,True)
else:
scene.objects['Book_level_button'].setVisible(False,True)
else:
scene.objects['Book_level_button'].setVisible(False,True)
# Upgrade
if name_chap == "rover":
upgrade_card=("battery", "beacon", "paint", "speed")
for i in range(len(upgrade_card)):
if scene.objects['Points']['upgrade_'+upgrade_card[i]]==True:
scene.objects[upgrade_card[i]+'-card'].setVisible(True,True)
scene.objects[upgrade_card[i]+'-card-colbox'].restorePhysics()
else:
scene.objects[upgrade_card[i]+'-card'].setVisible(False,True)
scene.objects[upgrade_card[i]+'-card-colbox'].suspendPhysics()
# URL Python
if name_chap == "python":
name_fct = scene.objects['Doc_chap-python']['page_fct']
scene.objects['Book_python_url_title'].setVisible(False,True)
scene.objects['Book_python_url0'].setVisible(False,True)
scene.objects['Book_python_url1'].setVisible(False,True)
scene.objects['Book_python_url2'].setVisible(False,True)
if name_fct !="":
scene.objects['Book_python_url_title'].setVisible(True,True)
for i in range(len(card_description[name_fct][2])):
scene.objects['Book_python_url'+str(i)]['Text'] = card_description[name_fct][2][i][0]
scene.objects['Book_python_url'+str(i)].setVisible(True,True)
# Afficher le texte de la carte active
if name_chap != "general" and scene.objects['Doc_chap-'+name_chap]['page_fct'] !="":
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
scene.objects['Doc_title']['Text'] = card_description[name_fct][0]
scene.objects['Doc_title'].setVisible(True, False)
text_dynamic_show(name_fct)
# text_show(name_fct)
else:
scene.objects['Doc_title']['Text'] = " "
scene.objects['Doc_title'].setVisible(False,True)
text_dynamic_hide()
# text_hide()
##
# Fermeture du livre
##
def close():
# sound_play (sndbuff_book_close)
chap=("general", "missions", "rover", "python")
for page in chap:
scene.objects["Doc_chap-"+page].setVisible(False,True)
scene.objects["Doc_chap-"+page].worldPosition.x = scene.objects["Doc_chap-"+page]['init_lx']
scene.objects["Doc_chap-"+page].worldPosition.y = scene.objects["Doc_chap-"+page]['init_ly']
scene.objects["Doc_chap-"+page].worldPosition.z = scene.objects["Doc_chap-"+page]['init_lz']
scene.objects['Doc'].setVisible(False,True)
scene.objects['Doc'].worldPosition = [35, -2, 2]
##
# Highlight du livre
##
def hl (cont):
# Activation
if cont.sensors['MO'].status == JUST_ACTIVATED :
obj = cont.owner
name=obj.name[:-7]
name_text=name+"-text"
name_icon=name+"-icon"
# Close ou lien
if name == "Doc_close" or name == "Book_level_button":
scene.objects[name].color = color_doc_hl
elif name == "Book_python_url0" or name == "Book_python_url1" or name == "Book_python_url2":
scene.objects[name].color = color_doc_hl
else:
if "Doc-" in name : # Chapitre
if name[4:] == scene.objects['Doc']['page_chap']:
scene.objects[name].color = color_doc_activate
scene.objects[name_text].color = color_doc_activate
else:
scene.objects[name].color = color_doc_hl
scene.objects[name_text].color = color_doc_hl
else: # Carte
name_chap = scene.objects['Doc']['page_chap']
if name == scene.objects['Doc_chap-'+name_chap]['page_fct'] :
scene.objects[name].color = color_doc_activate
scene.objects[name_text].color = color_doc_activate
scene.objects[name_icon].color = color_doc_activate
else:
scene.objects[name].color = color_doc_hl
scene.objects[name_text].color = color_doc_hl
scene.objects[name_icon].color = color_doc_hl
# Désactivation
if cont.sensors['MO'].status == JUST_RELEASED :
obj = cont.owner
name=obj.name[:-7]
name_text=obj.name[:-7]+"-text"
name_icon=obj.name[:-7]+"-icon"
# Close
if name == "Doc_close" or name == "Book_level_button":
scene.objects[name].color = color_doc_fct
elif name == "Book_python_url0" or name == "Book_python_url1" or name == "Book_python_url2":
scene.objects[name].color = color_doc_fct
else:
if "Doc-" in name : # Chapitre
if name[4:] == scene.objects['Doc']['page_chap']:
scene.objects[name].color = color_doc_activate
scene.objects[name_text].color = color_doc_activate
else:
scene.objects[name].color = color_doc_fct
scene.objects[name_text].color = color_doc_fct
else: # Carte
name_chap = scene.objects['Doc']['page_chap']
if name == scene.objects['Doc_chap-'+name_chap]['page_fct'] :
scene.objects[name].color = color_doc_activate
scene.objects[name_text].color = color_doc_activate
scene.objects[name_icon].color = color_doc_activate
else:
if name == "mission_"+str(scene.objects['Points']['mission'])+"-card":
scene.objects[name].color = color_doc_mission
scene.objects[name_text].color = color_doc_mission
scene.objects[name_icon].color = color_doc_mission
else:
scene.objects[name].color = color_doc_fct
scene.objects[name_text].color = color_doc_fct
scene.objects[name_icon].color = color_doc_fct
##
# Afficher le chapitre
##
def chapter(cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and cont.sensors['Click'].positive:
# sound_play (sndbuff_book_flip)
obj = cont.owner
scene.objects['Doc_title']['Text'] = " "
# Enlever l'ancien chapitre
scene.objects['Doc-'+scene.objects['Doc']['page_chap']].color = color_doc_chap
scene.objects['Doc-'+scene.objects['Doc']['page_chap']+'-text'].color = color_doc_chap
scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']].worldPosition.x = scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']]['init_lx']
scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']].worldPosition.y = scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']]['init_ly']
scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']].worldPosition.z = scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']]['init_lz']
if scene.objects['Doc']['page_chap'] != "general" and scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']]['page_fct'] !="":
# text_hide(scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']]['page_fct'])
text_dynamic_hide(scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']]['page_fct'])
# Placer le nouveau chapitre
name_chap= obj.name[4:-7]
scene.objects['Doc-'+name_chap].color = color_doc_activate
scene.objects['Doc-'+name_chap+'-text'].color = color_doc_activate
scene.objects['Doc']['page_chap'] = name_chap
scene.objects['Doc_chap-'+name_chap].worldPosition = scene.objects['Doc'].worldPosition
scene.objects['Doc_chap-'+name_chap].setVisible(True,True)
# Bouton de selection de la mission
if name_chap == "missions":
name_fct = scene.objects['Doc_chap-missions']['page_fct']
if name_fct !="":
if scene.objects[name_fct]['mission'] <= scene.objects['Points']['level'] and scene.objects[name_fct]['mission'] != scene.objects['Points']['mission']:
scene.objects['Book_level_button'].setVisible(True,True)
else:
scene.objects['Book_level_button'].setVisible(False,True)
else:
scene.objects['Book_level_button'].setVisible(False,True)
# Upgrade
if name_chap == "rover":
upgrade_card=("battery", "beacon", "paint", "speed")
for i in range(len(upgrade_card)):
if scene.objects['Points']['upgrade_'+upgrade_card[i]]==True:
scene.objects[upgrade_card[i]+'-card'].setVisible(True,True)
scene.objects[upgrade_card[i]+'-card-colbox'].restorePhysics()
else:
scene.objects[upgrade_card[i]+'-card'].setVisible(False,True)
scene.objects[upgrade_card[i]+'-card-colbox'].suspendPhysics()
# URL Python
if name_chap == "python":
name_fct = scene.objects['Doc_chap-python']['page_fct']
scene.objects['Book_python_url_title'].setVisible(False,True)
scene.objects['Book_python_url0'].setVisible(False,True)
scene.objects['Book_python_url1'].setVisible(False,True)
scene.objects['Book_python_url2'].setVisible(False,True)
if name_fct !="":
scene.objects['Book_python_url_title'].setVisible(True,True)
for i in range(len(card_description[name_fct][2])):
scene.objects['Book_python_url'+str(i)]['Text'] = card_description[name_fct][2][i][0]
scene.objects['Book_python_url'+str(i)].setVisible(True,True)
# Afficher le texte de la carte active
if name_chap != "general" and scene.objects['Doc_chap-'+name_chap]['page_fct'] !="":
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
scene.objects['Doc_title']['Text'] = card_description[name_fct][0]
scene.objects['Doc_title'].setVisible(True, False)
text_dynamic_show(name_fct)
# text_show(name_fct)
else:
scene.objects['Doc_title']['Text'] = " "
scene.objects['Doc_title'].setVisible(False,True)
text_dynamic_hide()
# text_hide()
##
# Afficher les details de la fonction à partir d'une carte
##
def card (cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
# sound_play (sndbuff_book_flip)
obj = cont.owner
name_chap = scene.objects['Doc']['page_chap']
name_fct= obj.name[:-7]
scene.objects['Doc_title']['Text'] = " "
# Enlever l'ancienne carte
if scene.objects['Doc_chap-'+name_chap]['page_fct'] !="":
# text_dynamic_hide(name_old_fct)
# text_hide(scene.objects['Doc_chap-'+name_chap]['page_fct'])
text_dynamic_hide(scene.objects['Doc_chap-'+name_chap]['page_fct'])
# Placer la carte de la mission active
if scene.objects['Doc_chap-'+name_chap]['page_fct'] == "mission_"+str(scene.objects['Points']['mission'])+"-card":
scene.objects[scene.objects['Doc_chap-'+name_chap]['page_fct']].color = color_doc_mission
scene.objects[scene.objects['Doc_chap-'+name_chap]['page_fct']+'-text'].color = color_doc_mission
scene.objects[scene.objects['Doc_chap-'+name_chap]['page_fct']+'-icon'].color = color_doc_mission
else:
scene.objects[scene.objects['Doc_chap-'+name_chap]['page_fct']].color = color_doc_fct
scene.objects[scene.objects['Doc_chap-'+name_chap]['page_fct']+'-text'].color = color_doc_fct
scene.objects[scene.objects['Doc_chap-'+name_chap]['page_fct']+'-icon'].color = color_doc_fct
# Afficher le texte de la carte
scene.objects['Doc_chap-'+name_chap]['page_fct'] = name_fct
scene.objects[name_fct].color = color_doc_activate
scene.objects[name_fct+'-icon'].color = color_doc_activate
scene.objects[name_fct+'-text'].color = color_doc_activate
scene.objects['Doc_title']['Text'] = card_description[name_fct][0]
scene.objects['Doc_title'].setVisible(True, False)
# text_show(name_fct)
text_dynamic_show(name_fct)
# URL Python
if name_chap == "python":
scene.objects['Book_python_url_title'].setVisible(False,True)
scene.objects['Book_python_url0'].setVisible(False,True)
scene.objects['Book_python_url1'].setVisible(False,True)
scene.objects['Book_python_url2'].setVisible(False,True)
if name_fct !="":
scene.objects['Book_python_url_title'].setVisible(True,True)
for i in range(len(card_description[name_fct][2])):
scene.objects['Book_python_url'+str(i)]['Text'] = card_description[name_fct][2][i][0]
scene.objects['Book_python_url'+str(i)].setVisible(True,True)
# Sélection de la mission
if "mission_" in name_fct :
if scene.objects[name_fct]['mission'] <= scene.objects['Points']['level'] and scene.objects[name_fct]['mission'] != scene.objects['Points']['mission']:
scene.objects['Book_level_button'].setVisible(True,True)
else:
scene.objects['Book_level_button'].setVisible(False,True)
##
# Sélectionner le niveau
##
def level_button (cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
# sound_play (sndbuff_book_flip)
obj = cont.owner
name_fct = scene.objects['Doc_chap-missions']['page_fct']
if name_fct !="":
mission_select=scene.objects[name_fct]['mission']
if mission_select <= scene.objects['Points']['level'] and mission_select != scene.objects['Points']['mission']:
scene.objects["mission_"+str(scene.objects['Points']['mission'])+"-card"].color = color_doc_fct
scene.objects["mission_"+str(scene.objects['Points']['mission'])+"-card-icon"].color = color_doc_fct
scene.objects["mission_"+str(scene.objects['Points']['mission'])+"-card-text"].color = color_doc_fct
scene.objects['Points']['mission'] = mission_select
scene.objects['Points-Map-text']['Text']="Mission "+str(scene.objects['Points']['mission'])
scene.objects['Book_mission']['Text'] = "Mission en cours : "+str(scene.objects['Points']['mission'])
scene.objects['Book_level_button'].setVisible(False,True)
##
# Aller à la page Python externe
##
def python_link (cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
# sound_play (snd_click)
name_fct = scene.objects['Doc_chap-python']['page_fct']
if name_fct !="":
i= cont.owner.name[15:-7]
webbrowser.open(card_description[name_fct][2][int(i)][1])
###############################################################################
# Génération dynamique des pages
###############################################################################
##
# Cacher le texte
##
def text_dynamic_hide(card=None):
if card is None:
for card in card_description:
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)].setVisible(False, False)
else:
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-'+card].setVisible(False, False)
##
# Afficher le texte
##
def text_dynamic_show(card=None):
if card is None:
for card in card_description:
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)].setVisible(True, False)
else:
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-'+card].setVisible(True, False)
##
# Préchargement des textes
##
def text_dynamic_load():
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-ref']['Text'] = ""
# Création des objets 3D
for card in card_description:
lines = card_description[card][1].split("\n")
for i in range (13):
doc_text= scene.addObject('Doc_text-l'+str(i+1), None, 0.00, True)
doc_text.setParent(scene.objects['Doc'])
doc_text.name = 'Doc_text-l'+str(i+1)+'-'+str(card)
doc_text.worldPosition.x = scene.objects['Doc_text-l'+str(i+1)+'-ref'].worldPosition.x
doc_text.worldPosition.y = scene.objects['Doc_text-l'+str(i+1)+'-ref'].worldPosition.y
doc_text.worldPosition.z = scene.objects['Doc_text-l'+str(i+1)+'-ref'].worldPosition.z
doc_text.setVisible(False, False)
if i >= len(lines):
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)]['Text']=""
else:
if len(lines[i]) ==0:
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)]['Text']=""
else:
# scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)]['Text']=lines[i]
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)].blenderObject.data.body=lines[i] # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
###############################################################################
# Store
###############################################################################
##
# Texte pour le store
##
def upgrade_description (card):
name_fct =card[6:]
if name_fct in card_description:
return card_description[name_fct][2]
else:
return ""
def upgrade_talk (card):
name_fct =card[6:]
if name_fct in card_description:
return card_description[name_fct][3]
else:
return ""
###############################################################################
# Sounds
###############################################################################
def sound_play (sound):
pass # FIXME
# if scene.objects['Commands']['sound']:
# audiodev.play(sound)