codetower/ct.py

574 lines
26 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 importlib
import bge # Bibliothèque Blender Game Engine (UPBGE)
import math
import time
import sys
import webbrowser
import threading # Multithreading
###############################################################################
# ct.py
# @title: Commandes pour le jeu codetower
# @project: Blender-EduTech
# @lang: fr
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL
#
# Ce simulateur est un jeu du type tower defense où les tours sont à piloter par la programmation Python.
#
###############################################################################
# Import dynamique du fichier Python élève
# sys.setrecursionlimit(10**5) # Limite sur la récursivité (valeur par défaut : 1000) -> segfault de Blender
# importlib.invalidate_caches()
# ct_cmd = importlib.import_module('ct_cmd')
# Récupérer la scène UPBGE
scene = bge.logic.getCurrentScene()
# print("Objets de la scene : ", scene.objects)
# Couleurs
# couleur_magenta = [0.800, 0.005, 0.315,1] # bouton non activable : magenta
# couleur_orange = [0.799, 0.130, 0.063,1] # bouton activable : orange
# couleur_blanc = [0.8, 0.8, 0.8, 1] # bouton focus : blanc
# couleur_jaune = [0.8, 0.619, 0.021, 1] # bouton activé : jaune
couleur_cmd = [0.8, 0.8, 0.8, 1] # blanc
couleur_cmd_hl = [0.8, 0.619, 0.021, 1] # jaune
couleur_lien = [0.024, 0.006, 0.8, 1] # bleu
couleur_lien_hl = [0.8, 0.005, 0.315, 1] # majenta
# Constantes UPBGE
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
# ###############################################################################
# # Actionneurs
# ###############################################################################
# # Action du simulateur pour le clignotant
# def sml_clignotant (cont):
# if scene.objects['Systeme']['run']:
# obj = cont.owner
# if obj['actif'] and scene.objects['Led allumee'].visible == False:
# scene.objects['Led allumee'].setVisible(True,False)
# scene.objects['Led'].setVisible(False,False)
# # print ("Clignotant allumée")
# if obj['actif']==False and scene.objects['Led allumee'].visible == True:
# scene.objects['Led'].setVisible(True,False)
# scene.objects['Led allumee'].setVisible(False,False)
# # print ("Clignotant éteint")
# # Action du simulateur pour le moteur
# def sml_moteur (cont):
# if scene.objects['Systeme']['run']:
# obj = cont.owner
# pas_rot = math.pi/7 # z = 14
# pas = 2.35619/0.3 # pas echelle 1:1 = 2.35619 -> pas à l'échelle de la maquette (0,3) : 2.35619/0.3 = 7,85396
# vitesse = 0.05
# engrenage_obj = scene.objects['Engrenage']
# portail_obj = scene.objects['Portail']
# if obj['actif_ouvrir']:
# # print (scene.objects['Portail'].worldPosition.x)
# engrenage_obj.applyRotation((0, 0, -pas_rot*vitesse), True)
# portail_obj.applyMovement((-pas*vitesse, 0, 0), True)
# # else:
# if obj['actif_fermer']:
# # print (scene.objects['Portail'].worldPosition.x)
# engrenage_obj.applyRotation((0, 0, pas_rot*vitesse), True)
# portail_obj.applyMovement((pas*vitesse, 0, 0), True)
# ###############################################################################
# # Capteurs fin de course
# ###############################################################################
# # Etat capteur fin de course portail ouvert
# def sml_fdc_ouvert (cont):
# if scene.objects['Systeme']['run'] :
# obj = cont.owner
# obj_etat=obj['actif']
# obj_microrupteur=scene.objects['Microrupteur fdc ouvert']
# # Etat capteur en fonction de la grille : worldPosition.x : 0 -> 65.5 et localPosition.x : 0 -> 218
# if scene.objects['Portail'].localPosition.x <= 0 and obj['actif'] == False :
# obj['actif'] = True
# if scene.objects['Portail'].localPosition.x > 0 and obj_microrupteur['actif'] == False and obj['actif'] == True :
# obj['actif'] = False
# #Forçage
# if obj_microrupteur['actif'] == True:
# obj['actif'] = True
# #Couleurs
# if obj['actif'] == True and obj_microrupteur.color !=couleur_jaune:
# obj_microrupteur.color =couleur_jaune
# if obj['actif'] == False :
# if obj_microrupteur['MO'] == True and obj_microrupteur.color !=couleur_blanc:
# obj_microrupteur.color =couleur_blanc
# if obj_microrupteur['MO'] == False and obj_microrupteur.color !=couleur_orange:
# obj_microrupteur.color =couleur_orange
# # Etat capteur fin de course portail fermé
# def sml_fdc_ferme (cont):
# if scene.objects['Systeme']['run'] :
# obj = cont.owner
# obj_etat=obj['actif']
# obj_microrupteur=scene.objects['Microrupteur fdc ferme']
# # Etat capteur en fonction de la grille : worldPosition.x : 0 -> 65.5 et localPosition.x : 0 -> 218
# if scene.objects['Portail'].localPosition.x >= 218 and obj['actif'] == False :
# obj['actif'] = True
# if scene.objects['Portail'].localPosition.x < 218 and obj_microrupteur['actif'] == False and obj['actif'] == True :
# obj['actif'] = False
# #Forçage
# if obj_microrupteur['actif'] == True:
# obj['actif'] = True
# #Couleurs
# if obj['actif'] == True and obj_microrupteur.color !=couleur_jaune:
# obj_microrupteur.color =couleur_jaune
# if obj['actif'] == False :
# if obj_microrupteur['MO'] == True and obj_microrupteur.color !=couleur_blanc:
# obj_microrupteur.color =couleur_blanc
# if obj_microrupteur['MO'] == False and obj_microrupteur.color !=couleur_orange:
# obj_microrupteur.color =couleur_orange
# # Forçage capteur fin de course avec la souris
# def sml_microrupteur (cont):
# if scene.objects['Systeme']['run'] :
# sml_click(cont, cont.owner)
# ###############################################################################
# # Capteurs barrage
# ###############################################################################
# # Emetteur IR
# def sml_emet_ir (cont):
# if scene.objects['Systeme']['run'] :
# obj = cont.owner
# obj_emetteur_ir=scene.objects['Emetteur IR']
# obj_recepteur_ir=scene.objects['Recepteur IR']
# if obj['actif'] and scene.objects['Emetteur IR Led allumee'].visible == False:
# scene.objects['Emetteur IR Led allumee'].setVisible(True,False)
# scene.objects['Emetteur IR Led'].setVisible(False,False)
# obj_emetteur_ir.color = couleur_orange
# obj_recepteur_ir.color = couleur_orange
# if obj['actif']==False and scene.objects['Emetteur IR Led allumee'].visible == True:
# scene.objects['Emetteur IR Led'].setVisible(True,False)
# scene.objects['Emetteur IR Led allumee'].setVisible(False,False)
# obj_emetteur_ir.color = couleur_magenta
# obj_recepteur_ir.color = couleur_magenta
# # Recepteur IR
# def sml_recep_ir (cont):
# if scene.objects['Systeme']['run'] and scene.objects['Module emetteur IR']['actif'] :
# obj = cont.owner
# sml_click(cont, scene.objects['Module recepteur IR'])
# if scene.objects['Module recepteur IR']['actif']==True :
# scene.objects['Emetteur IR'].color = couleur_jaune
# scene.objects['Recepteur IR'].color = couleur_jaune
# ###############################################################################
# # Boutons poussoirs
# ###############################################################################
# # Gestion du click sur les éléments cliquables
# def sml_click(cont, obj_activation):
# obj = cont.owner
# if cont.sensors['MO'].status == JUST_ACTIVATED :
# obj.color = couleur_blanc
# obj['MO']=True
# if cont.sensors['Click'].status == JUST_ACTIVATED and scene.objects['Systeme']['manip_mode']==0:
# if obj['MO']:
# obj_activation['actif'] = True
# obj.color = couleur_jaune
# if cont.sensors['MO'].status == JUST_RELEASED :
# obj['MO']=False
# if cont.sensors['Click'].status == ACTIVATE :
# obj.color = couleur_jaune
# else:
# obj.color = couleur_orange
# if cont.sensors['Click'].status == JUST_RELEASED:
# obj_activation['actif'] = False
# obj.color = couleur_blanc
# if cont.sensors['MO'].status != ACTIVATE :
# obj.color = couleur_orange
# # Bouton pousssoir coté rue
# def sml_bp_rue (cont):
# if scene.objects['Systeme']['run'] :
# sml_click(cont, scene.objects['Module bouton cote rue'])
# # Bouton pousssoir coté cour
# def sml_bp_cour (cont):
# if scene.objects['Systeme']['run'] :
# sml_click(cont, scene.objects['Module bouton cote cour'])
###############################################################################
# Cycle
###############################################################################
# Initialisation du cycle de fonctionnement normal
# Le moteur est géré en continue.
def cycle_init (cont):
# Clignotant
scene.objects['Module led']['actif']=False
scene.objects['Led allumee'].setVisible(False,False)
scene.objects['Led'].setVisible(True,False)
# Emetteur IR
scene.objects['Module emetteur IR']['actif']=False
scene.objects['Emetteur IR Led allumee'].setVisible(False,False)
scene.objects['Emetteur IR Led'].setVisible(True,False)
scene.objects['Emetteur IR'].color = couleur_magenta
scene.objects['Recepteur IR'].color = couleur_magenta
# Mise en route et pause du cycle
def cycle_run (cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['Terrain']['manip_mode']==0:
# Pause
if scene.objects['Terrain']['run'] == True:
scene.objects['Terrain']['run']=False
scene.objects['Pause'].setVisible(False,False)
scene.objects['Pause-Hl'].setVisible(False,False)
scene.objects['Run-Hl'].setVisible(True,False)
else:
# Run
scene.objects['Terrain']['run']=True
scene.objects['Run'].setVisible(False,False)
scene.objects['Run-Hl'].setVisible(False,False)
scene.objects['Pause-Hl'].setVisible(True,False)
if scene.objects['Terrain']['thread_run']==False: # Lancement du thread utilisateur
scene.objects['Stop'].setVisible(True,False)
# importlib.reload(porcou_cmd) # Lecture dynamique du script python (risque de Segfault de Blender)
# porcou_cmd.start()
# Arrêt et réinitialisation du cycle
def cycle_stop (cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['Terrain']['manip_mode']==0:
# Arrêt du thread utilisateur
scene.objects['Terrain']['run']=False
scene.objects['Terrain']['thread_run']=False
# porcou_cmd.stop()
# Commandes
scene.objects['Pause'].setVisible(False,False)
scene.objects['Run'].setVisible(True,False)
scene.objects['Stop'].setVisible(False,False)
scene.objects['Stop-Hl'].setVisible(False,False)
# Fin naturelle du cycle
def cycle_fin (cont):
# Arrêt du thread utilisateur
scene.objects['Terrain']['run']=False
scene.objects['Terrain']['thread_run']=False
# porcou_cmd.stop()
# Commandes
scene.objects['Pause'].setVisible(False,False)
scene.objects['Run'].setVisible(True,False)
scene.objects['Stop'].setVisible(False,False)
scene.objects['Stop-Hl'].setVisible(False,False)
###############################################################################
# Commandes
###############################################################################
# Init
def cmd_init():
# scene.objects['Terrain']['run']=False
scene.objects['Run-Hl'].setVisible(False,False)
scene.objects['Pause'].setVisible(False,False)
scene.objects['Pause-Hl'].setVisible(False,False)
scene.objects['Stop'].setVisible(False,False)
scene.objects['Stop-Hl'].setVisible(False,False)
# scene.objects['Raz-vue-Hl'].setVisible(False,False)
# scene.objects['Aide-cmd-Hl'].setVisible(False,False)
# Le highlight des commandes
def cmd_hl(cont):
obj = cont.owner
print ("ok 1")
# Activation
if cont.sensors['MO'].status == JUST_ACTIVATED and scene.objects['Terrain']['manip_mode']==0:
print ("ok 2")
if obj.name!="Run" and obj.name!="Pause" and obj.name!="Run-Hl" and obj.name!="Pause-Hl" and obj.name!="Stop" and obj.name!="Stop-Hl":
obj.setVisible(False,True)
scene.objects[obj.name+'-Hl'].setVisible(True,True)
# Run et pause
if obj.name=="Pause" or obj.name=="Run":
if scene.objects['Terrain']['run'] == True:
scene.objects['Pause'].setVisible(False,False)
scene.objects['Pause-Hl'].setVisible(True,False)
else:
scene.objects['Run'].setVisible(False,False)
scene.objects['Run-Hl'].setVisible(True,False)
# Stop
if obj.name=="Stop":
if scene.objects['Terrain']['thread_run']==True:
scene.objects['Stop'].setVisible(False,False)
scene.objects['Stop-Hl'].setVisible(True,False)
# Désactivation
if cont.sensors['MO'].status == JUST_RELEASED and scene.objects['Terrain']['manip_mode']==0:
if obj.name!="Run" and obj.name!="Pause" and obj.name!="Run-Hl" and obj.name!="Pause-Hl" and obj.name!="Stop" and obj.name!="Stop-Hl":
scene.objects[obj.name+'-Hl'].setVisible(False,True)
obj.setVisible(True,True)
# Run et pause
if obj.name=="Pause" or obj.name=="Run":
if scene.objects['Terrain']['run'] == True:
scene.objects['Pause-Hl'].setVisible(False,False)
scene.objects['Pause'].setVisible(True,False)
else:
scene.objects['Run-Hl'].setVisible(False,False)
scene.objects['Run'].setVisible(True,False)
# Stop
if obj.name=="Stop":
if scene.objects['Terrain']['thread_run']==True:
scene.objects['Stop-Hl'].setVisible(False,False)
scene.objects['Stop'].setVisible(True,False)
###############################################################################
# Gestion du clavier
###############################################################################
# Mode : Pan(1) avec Shift, Zoom (2) avec Ctrl, Orbit (0),
def mode(cont):
obj = cont.owner
keyboard = bge.logic.keyboard
# Shift -> mode 1 : Pan (clic milieu)
if JUST_ACTIVATED in keyboard.inputs[bge.events.LEFTSHIFTKEY].queue:
obj['manip_mode']=1
if JUST_ACTIVATED in keyboard.inputs[bge.events.RIGHTSHIFTKEY].queue:
obj['manip_mode']=1
# Ctrl -> mode 2 : Zoom (clic milieu)
if JUST_ACTIVATED in keyboard.inputs[bge.events.LEFTCTRLKEY].queue:
obj['manip_mode']=2
if JUST_ACTIVATED in keyboard.inputs[bge.events.RIGHTCTRLKEY].queue:
obj['manip_mode']=2
# Pas de modificateur -> mode 0 : Pas de Orbit (mode 0) ici
if JUST_RELEASED in keyboard.inputs[bge.events.LEFTSHIFTKEY].queue:
obj['manip_mode']=0
if JUST_RELEASED in keyboard.inputs[bge.events.RIGHTSHIFTKEY].queue:
obj['manip_mode']=0
if JUST_RELEASED in keyboard.inputs[bge.events.LEFTCTRLKEY].queue:
obj['manip_mode']=0
if JUST_RELEASED in keyboard.inputs[bge.events.RIGHTCTRLKEY].queue:
obj['manip_mode']=0
# Touche Home -> Reset de la vue
if JUST_ACTIVATED in keyboard.inputs[bge.events.HOMEKEY].queue:
scene.objects['Camera'].worldPosition.x = scene.objects['Camera']['init_lx']
scene.objects['Camera'].worldPosition.y = scene.objects['Camera']['init_ly']
scene.objects['Camera'].worldPosition.z = scene.objects['Camera']['init_lz']
applyRotationTo(scene.objects['Terrain'], 0, 0, 0)
# Touche F5 -> Run et Pause
if JUST_ACTIVATED in keyboard.inputs[bge.events.F5KEY].queue:
if scene.objects['Terrain']['run'] == True:
scene.objects['Terrain']['run']=False
scene.objects['Pause'].setVisible(False,False)
scene.objects['Run'].setVisible(True,False)
else:
scene.objects['Terrain']['run']=True
scene.objects['Run'].setVisible(False,False)
scene.objects['Pause'].setVisible(True,False)
if scene.objects['Terrain']['thread_run']==False: # Lancement du thread utilisateur
scene.objects['Stop'].setVisible(True,False)
# importlib.reload(porcou_cmd) # Lecture dynamique du script python
# porcou_cmd.start()
# Touche F6 -> Stop / Init
if JUST_ACTIVATED in keyboard.inputs[bge.events.F6KEY].queue:
if scene.objects['Terrain']['thread_run']==True:
# Arrêt du thread utilisateur
scene.objects['Terrain']['run']=False
scene.objects['Terrain']['thread_run']=False
# porcou_cmd.stop()
# Commandes
scene.objects['Pause'].setVisible(False,False)
scene.objects['Run'].setVisible(True,False)
scene.objects['Stop'].setVisible(False,False)
scene.objects['Stop-Hl'].setVisible(False,False)
###############################################################################
# Manipulation 3D du système
###############################################################################
# Mémorisation de la position et orientation initiales du modèle 3D et de la caméra
def manip_init(cont):
scene.objects['Camera']['init_lx']=scene.objects['Camera'].worldPosition.x
scene.objects['Camera']['init_ly']=scene.objects['Camera'].worldPosition.y
scene.objects['Camera']['init_lz']=scene.objects['Camera'].worldPosition.z
scene.objects['Terrain']['init_lx']=scene.objects['Terrain'].worldPosition.x
scene.objects['Terrain']['init_ly']=scene.objects['Terrain'].worldPosition.y
scene.objects['Terrain']['init_lz']=scene.objects['Terrain'].worldPosition.z
scene.objects['Terrain']['init_rx']=scene.objects['Terrain'].worldOrientation.to_euler().x
scene.objects['Terrain']['init_ry']=scene.objects['Terrain'].worldOrientation.to_euler().y
scene.objects['Terrain']['init_rz']=scene.objects['Terrain'].worldOrientation.to_euler().z
# Atteindre une orientation (bas niveau)
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)
# Reset de la manipulation de la vue
def manip_reset(cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['Terrain']['manip_mode']==0:
scene.objects['Camera'].worldPosition.x = scene.objects['Camera']['init_lx']
scene.objects['Camera'].worldPosition.y = scene.objects['Camera']['init_ly']
scene.objects['Camera'].worldPosition.z = scene.objects['Camera']['init_lz']
applyRotationTo(scene.objects['Terrain'], 0, 0, 0)
# Position de départ pour la manipulation de la vue
def manip_start(cont):
obj = cont.owner
obj['click_x']=cont.sensors['ClickM'].position[0]
obj['click_y']=cont.sensors['ClickM'].position[1]
# Cacher le cercle de la manipulation Orbit
def manip_stop(cont):
# scene.objects['Orbit'].setVisible(False,False)
pass
# Manipulation du modèle ou de la caméra
def manip(cont):
obj = cont.owner
sensibilite_orbit=0.00005 # Base : 0.0005
sensibilite_pan=0.001 # Base : 0.005
sensibilite_zoom=0.005 # Base : 0.01
delta_x=cont.sensors['DownM'].position[0]-obj['click_x']
delta_y=cont.sensors['DownM'].position[1]-obj['click_y']
# Orbit (1280 * 720 px) Pas de Orbit ici
# if obj['manip_mode']==0:
# scene.objects['Orbit'].color=couleur_cmd
# scene.objects['Orbit'].setVisible(True,False)
# dist_orbit = math.sqrt(((1280/2)-obj['click_x'])**2+((720/2)-obj['click_y'])**2)
# if dist_orbit<235 : # Orbit sur x et z
# n=10
# pas_x=(delta_x*40*sensibilite_orbit)/n
# pas_y=(((1280/2)-cont.sensors['DownM'].position[0])+((720/2)-cont.sensors['DownM'].position[1]))*0.005
# pas_z=(delta_y*40*sensibilite_orbit)/n
# for i in range (n):
# bge.render.drawLine([scene.objects['Orbit'].worldPosition.x+pas_x*i, scene.objects['Orbit'].worldPosition.y+abs(pas_y*math.sin((3.14*i)/n)), scene.objects['Orbit'].worldPosition.z-pas_z*i],
# [scene.objects['Orbit'].worldPosition.x+pas_x*(i+1), scene.objects['Orbit'].worldPosition.y+abs(pas_y*math.sin((3.14*(i+1))/n)), scene.objects['Orbit'].worldPosition.z-pas_z*(i+1)],
# [0.8, 0.619, 0.021])
# scene.objects['Terrain'].applyRotation((delta_y*sensibilite_orbit, 0, delta_x*sensibilite_orbit), True)
# else: # Orbit sur y
# scene.objects['Orbit'].color=couleur_cmd_hl
# if abs(delta_x) >= abs(delta_y):
# scene.objects['Terrain'].applyRotation((0, delta_x*sensibilite_orbit, 0), True)
# else:
# scene.objects['Terrain'].applyRotation((0, delta_y*sensibilite_orbit, 0), True)
# Pan
if obj['manip_mode']==1: # Shift
scene.objects['Camera'].applyMovement((delta_x*-sensibilite_pan, delta_y*sensibilite_pan, 0), True)
# Zoom
if obj['manip_mode']==2: # Ctrl
scene.objects['Camera'].applyMovement((0, 0, (delta_x+delta_y)*sensibilite_zoom), True)
# Manipulation du modèle ou de la caméra
def manip_wheel(cont):
obj = cont.owner
sensibilite_wheel = 5 # Base : 20
if cont.sensors['WheelUp'].positive:
scene.objects['Camera'].applyMovement((0, 0, -sensibilite_wheel), True)
if cont.sensors['WheelDown'].positive:
scene.objects['Camera'].applyMovement((0, 0, sensibilite_wheel), True)
###############################################################################
# Aide
###############################################################################
# # Ouvrir la page d'aide
# def aide(cont):
# if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
# # scene.replace('Scene-Aide') # Bug Eevee -> même scene mais camera différente
# scene.active_camera=scene.objects['Aide-Camera']
# scene.objects['Apropos-Lien_projet'].color= couleur_lien
# scene.objects['Apropos-Lien_maquette'].color= couleur_lien
# scene.objects['Apropos-Lien_a4'].color= couleur_lien
# scene.objects['Apropos-Lien_blender'].color= couleur_lien
# scene.objects['Apropos-Lien_upbge'].color= couleur_lien
# scene.objects['Apropos-Lien_cc'].color= couleur_lien
# scene.objects['Apropos-Lien_gpl'].color= couleur_lien
# # Fermer la page d'aide
# def aide_fermer(cont):
# if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
# # bge.logic.addScene('Scene') # Bug Eevee -> même scene mais camera différente
# scene.active_camera=scene.objects['Camera']
# # Aller sur les liens
# def aide_apropos(cont):
# if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
# obj = cont.owner
# if obj.name == "Apropos-Lien_maquette" :
# webbrowser.open('https://www.a4.fr/wiki/')
# if obj.name == "Apropos-Lien_projet" :
# webbrowser.open('https://gitlab.com/blender-edutech')
# if obj.name == "Apropos-Lien_a4" :
# webbrowser.open('https://www.a4.fr')
# if obj.name == "Apropos-Lien_blender" :
# webbrowser.open('https://blender.org')
# if obj.name == "Apropos-Lien_upbge" :
# webbrowser.open('https://upbge.org')
# if obj.name == "Apropos-Lien_cc" :
# webbrowser.open('https://creativecommons.org/licenses/by-sa/4.0/')
# if obj.name == "Apropos-Lien_gpl" :
# webbrowser.open('https://www.gnu.org/licenses/gpl-3.0.html')
# # Le highlight des liens
# def aide_apropos_hl(cont):
# if cont.sensors['MO'].status == JUST_ACTIVATED :
# obj = cont.owner
# obj.color = couleur_lien_hl
# if cont.sensors['MO'].status == JUST_RELEASED :
# obj = cont.owner
# obj.color = couleur_lien