2022-08-24 14:12:23 +02:00
import bge # Blender Game Engine (UPBGE)
2022-08-30 03:25:36 +02:00
import bpy # Blender
2022-08-14 08:03:07 +02:00
import aud # Sounds
import threading # Multithreading
import trace
import sys
import time
import math
import mathutils
import random
###############################################################################
2022-08-19 15:43:20 +02:00
# rp_lib.py
2022-08-26 12:41:18 +02:00
# @title: Bibliothèque du Rover Ropy (rp_*)
2022-08-14 08:03:07 +02:00
# @project: Ropy (Blender-EduTech)
# @lang: fr
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2020-2022 Philippe Roy
# @license: GNU GPL
#
# Bibliothèque des actions du robot
#
# 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
purple = ( 0.202 , 0.114 , 0.521 , 1 )
turquoise = ( 0.051 , 0.270 , 0.279 , 1 )
magenta = ( 0.799 , 0.005 , 0.314 , 1 )
orange = ( 0.799 , 0.130 , 0.063 , 1 )
yellow = ( 0.799 , 0.617 , 0.021 , 1 )
green = ( 0.246 , 0.687 , 0.078 , 1 )
red = ( 0.799 , 0.031 , 0.038 , 1 )
blue = ( 0.127 , 0.456 , 1.000 , 1 )
black = ( 0 , 0 , 0 , 1 )
color_text = ( 0 , 0 , 0 , 1 ) # Noir
color_text_red = ( 0.799 , 0.031 , 0.038 , 1 )
color_text_orange = ( 0.799 , 0.176 , 0.054 , 1 )
color_text_yellow = ( 0.799 , 0.617 , 0.021 , 1 )
# ray_yellow = (0.799, 0.617, 0.021, 1) # [0.8, 0.619, 0.021])
# ray_blue = (0.127, 0.456, 1.000, 1)
# ray_black = (0, 0, 0, 1)
color_kaykit_black = ( 0.019 , 0.032 , 0.037 , 1 )
# Sounds
# audiodev = aud.Device()
# snd_build = aud.Sound('asset/sounds/build.wav')
# sndbuff_build = aud.Sound.cache(snd_build)
# snd_archer = aud.Sound('asset/sounds/archer.wav')
# sndbuff_archer = aud.Sound.cache(snd_archer)
# snd_mage = aud.Sound('asset/sounds/mage.wav')
# sndbuff_mage = aud.Sound.cache(snd_mage)
# snd_life = aud.Sound('asset/sounds/life.ogg')
# sndbuff_life = aud.Sound.cache(snd_life)
threads_cmd = [ ]
2022-08-24 14:12:23 +02:00
debug_thread = scene . objects [ ' Terrain ' ] [ ' debug_thread ' ]
2022-08-14 08:03:07 +02:00
# 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
###############################################################################
# Méthode kill pour les tâches (threads)
###############################################################################
class thread_with_trace ( threading . Thread ) :
def __init__ ( self , * args , * * keywords ) :
threading . Thread . __init__ ( self , * args , * * keywords )
self . killed = False
def start ( self ) :
self . __run_backup = self . run
self . run = self . __run
threading . Thread . start ( self )
def __run ( self ) :
sys . settrace ( self . globaltrace )
self . __run_backup ( )
self . run = self . __run_backup
def globaltrace ( self , frame , event , arg ) :
if event == ' call ' :
return self . localtrace
else :
return None
def localtrace ( self , frame , event , arg ) :
if self . killed :
if event == ' line ' :
raise SystemExit ( )
return self . localtrace
def kill ( self ) :
self . killed = True
###############################################################################
# Start et stop des tâches (threads)
###############################################################################
def thread_start ( threads , type_txt , fct ) :
threads . append ( thread_with_trace ( target = fct ) )
threads [ len ( threads ) - 1 ] . start ( )
2022-08-24 14:12:23 +02:00
if ( debug_thread ) :
print ( " Thread " , type_txt , " # " , len ( threads ) - 1 , " open. " )
2022-08-14 08:03:07 +02:00
def thread_stop ( threads , type_txt ) :
i = 0
zombie_flag = False
for t in threads :
if not t . is_alive ( ) :
2022-08-24 14:12:23 +02:00
if ( debug_thread ) :
print ( " Thread " , type_txt , " # " , i , " closed. " )
2022-08-14 08:03:07 +02:00
else :
2022-08-24 14:12:23 +02:00
if ( debug_thread ) :
print ( " Thread " , type_txt , " # " , i , " still open ... " )
2022-08-14 08:03:07 +02:00
t . kill ( )
t . join ( )
if not t . is_alive ( ) :
2022-08-24 14:12:23 +02:00
if ( debug_thread ) :
print ( " Thread " , type_txt , " # " , i , " killed. " )
2022-08-14 08:03:07 +02:00
else :
2022-08-24 14:12:23 +02:00
if ( debug_thread ) :
print ( " Thread " , type_txt , " # " , i , " zombie... " )
2022-08-14 08:03:07 +02:00
zombie_flag = True
i + = 1
if zombie_flag == False :
2022-08-24 14:12:23 +02:00
if ( debug_thread ) :
print ( " All threads " , type_txt , " are closed. " )
2022-08-23 03:39:37 +02:00
scene . objects [ ' Terrain ' ] [ ' thread_cmd ' ] = False
2022-08-14 08:03:07 +02:00
return True
else :
2022-08-24 14:12:23 +02:00
if ( debug_thread ) :
print ( " There are zombies threads " , type_txt , " . " )
2022-08-14 08:03:07 +02:00
return False
def thread_cmd_start ( fct ) :
thread_start ( threads_cmd , " commands " , fct )
def thread_cmd_stop ( ) :
thread_stop ( threads_cmd , " commands " )
2022-08-23 03:39:37 +02:00
def rp_end ( ) :
2022-08-24 14:12:23 +02:00
if ( debug_thread ) :
print ( " Thread commands is arrived. " )
2022-08-23 03:39:37 +02:00
scene . objects [ ' Terrain ' ] [ ' thread_cmd ' ] = False
def rp_fin ( ) :
rp_end ( )
def rp_quit ( ) :
rp_end ( )
2022-08-14 08:03:07 +02:00
###############################################################################
# Sounds
###############################################################################
# FIXME : Sound crash in Windows (very strange : blender, UPBGE, python ?), no music for Bill
def sound_play ( sound ) :
if scene . objects [ ' Commands ' ] [ ' sound ' ] and sys . platform != " win32 " :
audiodev . play ( sound )
2022-08-22 04:41:22 +02:00
###############################################################################
# Rover fonction élèves
###############################################################################
##
# Avancer le rover
##
def rp_avancer ( ) :
2022-08-26 01:58:49 +02:00
print ( " rp_avancer() " )
2022-08-26 12:41:18 +02:00
scene . objects [ ' Points ' ] [ ' step ' ] + = 1
2022-08-22 04:41:22 +02:00
obj = scene . objects [ ' Rover ' ]
2022-08-30 03:25:36 +02:00
# Rapide
if scene . objects [ ' Commands ' ] [ ' speed ' ] == 10 :
x0 = obj . worldPosition . x
y0 = obj . worldPosition . y
z0 = obj . worldPosition . z
if round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == 0.00 : # Sud
obj . worldPosition = [ x0 , y0 - 1 , z0 ]
if round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == round ( math . pi , 2 ) or round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == - round ( math . pi , 2 ) : # Nord
obj . worldPosition = [ x0 , y0 + 1 , z0 ]
if round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == round ( math . pi / 2 , 2 ) or round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == - round ( 3 * ( math . pi / 2 ) , 2 ) : # Est
obj . worldPosition = [ x0 + 1 , y0 , z0 ]
if round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == round ( - math . pi / 2 , 2 ) or round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == round ( 3 * ( math . pi / 2 ) , 2 ) : # Ouest
obj . worldPosition = [ x0 - 1 , y0 , z0 ]
rp_tempo ( 0.1 )
return True
# FIXME : Animation sacadée
# step =1/100
2022-08-22 04:41:22 +02:00
# print (obj.worldOrientation.to_euler().z)
2022-08-30 03:25:36 +02:00
# x0 = obj.worldPosition.x
# y0 = obj.worldPosition.y
# z0 = obj.worldPosition.z
# for i in range (100) :
# if round(obj.worldOrientation.to_euler().z, 2) == 0.00: # Sud
# obj.worldPosition=[x0, y0-step*i, z0]
# if round(obj.worldOrientation.to_euler().z, 2) == round(math.pi,2) or round(obj.worldOrientation.to_euler().z, 2) == - round(math.pi,2) : # Nord
# obj.worldPosition=[x0, y0+step*i, z0]
# if round(obj.worldOrientation.to_euler().z, 2) == round(math.pi/2,2) or round(obj.worldOrientation.to_euler().z, 2) == -round(3*(math.pi/2),2) : # Est
# obj.worldPosition=[x0+step*i, y0, z0]
# if round(obj.worldOrientation.to_euler().z, 2) == round(-math.pi/2,2) or round(obj.worldOrientation.to_euler().z, 2) == round(3*(math.pi/2),2) : # Ouest
# obj.worldPosition=[x0-step*i, y0, z0]
# rp_tempo (0.1*step)
# Animation
# obj['avancer_anim']=True
start = 1
end = 100
layer = 0
priority = 1
blendin = 1.0
mode = bge . logic . KX_ACTION_MODE_PLAY
layerWeight = 0.0
ipoFlags = 0
speed = scene . objects [ ' Commands ' ] [ ' speed ' ] * 4
2022-08-22 04:41:22 +02:00
if round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == 0.00 : # Sud
2022-08-30 03:25:36 +02:00
scene . objects [ ' Rover ' ] . playAction ( ' Rover-Avancer-Y- ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
# obj.worldPosition=[x0, y0-step*i, z0]
2022-08-22 04:41:22 +02:00
if round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == round ( math . pi , 2 ) or round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == - round ( math . pi , 2 ) : # Nord
2022-08-30 03:25:36 +02:00
scene . objects [ ' Rover ' ] . playAction ( ' Rover-Avancer-Y+ ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
# obj.worldPosition=[x0, y0+step*i, z0]
2022-08-22 04:41:22 +02:00
if round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == round ( math . pi / 2 , 2 ) or round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == - round ( 3 * ( math . pi / 2 ) , 2 ) : # Est
2022-08-30 03:25:36 +02:00
scene . objects [ ' Rover ' ] . playAction ( ' Rover-Avancer-X+ ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
# obj.worldPosition=[x0+step*i, y0, z0]
2022-08-22 04:41:22 +02:00
if round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == round ( - math . pi / 2 , 2 ) or round ( obj . worldOrientation . to_euler ( ) . z , 2 ) == round ( 3 * ( math . pi / 2 ) , 2 ) : # Ouest
2022-08-30 03:25:36 +02:00
scene . objects [ ' Rover ' ] . playAction ( ' Rover-Avancer-X- ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
# obj.worldPosition=[x0-step*i, y0, z0]
scene . objects [ ' Wheel-right-front ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-right-mid ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-right-rear ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-left-front ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-left-mid ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-left-rear ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
while scene . objects [ ' Wheel-right-front ' ] . isPlayingAction ( ) : # Forçage du redraw
# scene.objects['Camera'].applyMovement((0, 0, 0), True)
scene . objects [ ' Sun ' ] . applyMovement ( ( 0 , 0 , 0 ) , True )
2022-08-26 01:58:49 +02:00
rp_tempo ( 0.1 )
2022-08-30 03:25:36 +02:00
return True
2022-08-22 04:41:22 +02:00
##
# Tourner à gauche
##
def rp_gauche ( ) :
2022-08-26 01:58:49 +02:00
print ( " rp_gauche() " )
2022-08-26 12:41:18 +02:00
scene . objects [ ' Points ' ] [ ' step ' ] + = 1
2022-08-22 04:41:22 +02:00
step = math . pi / 2 # Pas angulaire
obj = scene . objects [ ' Rover ' ]
2022-08-30 03:25:36 +02:00
# Rapide
if scene . objects [ ' Commands ' ] [ ' speed ' ] == 10 :
obj . applyRotation ( ( 0 , 0 , step ) , True )
rp_tempo ( 0.1 )
return True
# Animation
start = 1
end = 100
layer = 0
priority = 1
blendin = 1.0
mode = bge . logic . KX_ACTION_MODE_PLAY
layerWeight = 0.0
ipoFlags = 0
speed = scene . objects [ ' Commands ' ] [ ' speed ' ] * 4
scene . objects [ ' Rover ' ] . playAction ( ' Rover-Gauche ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-right-front ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-right-mid ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-right-rear ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-left-front ' ] . playAction ( ' Wheel-Reculer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-left-mid ' ] . playAction ( ' Wheel-Reculer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-left-rear ' ] . playAction ( ' Wheel-Reculer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
while scene . objects [ ' Wheel-right-front ' ] . isPlayingAction ( ) : # Forçage du redraw
# scene.objects['Camera'].applyMovement((0, 0, 0), True)
scene . objects [ ' Sun ' ] . applyMovement ( ( 0 , 0 , 0 ) , True )
2022-08-26 01:58:49 +02:00
rp_tempo ( 0.1 )
2022-08-30 03:25:36 +02:00
return True
2022-08-22 04:41:22 +02:00
##
# Tourner à droite
##
def rp_droite ( ) :
2022-08-26 01:58:49 +02:00
print ( " rp_droite() " )
2022-08-26 12:41:18 +02:00
scene . objects [ ' Points ' ] [ ' step ' ] + = 1
2022-08-22 04:41:22 +02:00
step = math . pi / 2 # Pas angulaire
obj = scene . objects [ ' Rover ' ]
2022-08-30 03:25:36 +02:00
# Rapide
if scene . objects [ ' Commands ' ] [ ' speed ' ] == 10 :
obj . applyRotation ( ( 0 , 0 , - step ) , True )
rp_tempo ( 0.1 )
return True
# Animation
start = 1
end = 100
layer = 0
priority = 1
blendin = 1.0
mode = bge . logic . KX_ACTION_MODE_PLAY
layerWeight = 0.0
ipoFlags = 0
speed = scene . objects [ ' Commands ' ] [ ' speed ' ] * 4
scene . objects [ ' Rover ' ] . playAction ( ' Rover-Droite ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-right-front ' ] . playAction ( ' Wheel-Reculer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-right-mid ' ] . playAction ( ' Wheel-Reculer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-right-rear ' ] . playAction ( ' Wheel-Reculer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-left-front ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-left-mid ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
scene . objects [ ' Wheel-left-rear ' ] . playAction ( ' Wheel-Avancer ' , start , end , layer , priority , blendin , mode , layerWeight , ipoFlags , speed )
while scene . objects [ ' Wheel-right-front ' ] . isPlayingAction ( ) : # Forçage du redraw
# scene.objects['Camera'].applyMovement((0, 0, 0), True)
scene . objects [ ' Sun ' ] . applyMovement ( ( 0 , 0 , 0 ) , True )
2022-08-26 01:58:49 +02:00
rp_tempo ( 0.1 )
2022-08-30 03:25:36 +02:00
return True
2022-08-22 04:41:22 +02:00
##
# Marquer
##
def rp_marquer ( ) :
2022-08-26 01:58:49 +02:00
print ( " rp_marquer() " )
2022-08-26 12:41:18 +02:00
scene . objects [ ' Points ' ] [ ' step ' ] + = 1
rp_tempo ( 0.1 )
2022-08-26 01:58:49 +02:00
obj = scene . objects [ ' Rover ' ]
x = obj . worldPosition . x
y = obj . worldPosition . y
z = obj . worldPosition . z
# Vérification de l'absence de balise sur la tuile
if [ x , y ] in scene . objects [ ' Terrain ' ] [ ' map_tile_beacon ' ] :
print ( " Case déjà marquée ! " )
return False
for i in range ( 100 ) :
beacon = scene . objects [ " Beacon- " + str ( i ) ]
if beacon [ ' activated ' ] == False :
beacon . worldPosition = [ x , y , 0.2 ]
beacon [ ' activated ' ] = True
beacon . setVisible ( True , True )
break
if i == 99 :
print ( " Plus de balise disponible ! " )
# beacon= scene.addObject("Beacon", scene.objects['Terrain'])
# beacon.worldPosition=[x,y,0.2]
scene . objects [ ' Terrain ' ] [ ' map_tile_beacon ' ] . append ( [ x , y ] )
rp_tempo ( 0.1 )
return True
2022-08-22 04:41:22 +02:00
##
# Détecter
##
def rp_detect ( ) :
print ( " rp_detect " )
# FIXME
##
# Prendre
##
def rover_prendre ( ) :
print ( " rp_prendre " )
# FIXME
##
# Radar
##
def rover_radar ( ) :
print ( " rp_radar " )
# FIXME
###############################################################################
# Rover
###############################################################################
##
# Colision
##
def rover_colision ( ) :
pass
2022-08-24 14:12:23 +02:00
###############################################################################
# Temporisation
###############################################################################
2022-08-30 03:25:36 +02:00
# Temporisation basée sur l'horloge de l'OS
2022-08-24 14:12:23 +02:00
def rp_sleep ( duration ) :
time . sleep ( duration )
2022-08-30 03:25:36 +02:00
# Temporisation basée par l'horloge de UPBGE
2022-08-26 01:58:49 +02:00
def rp_tempo ( duration ) :
# time.sleep(duration*(1/scene.objects['Commands']['speed']))
scene . objects [ ' Commands ' ] [ ' time ' ] = 0
while scene . objects [ ' Commands ' ] [ ' time ' ] < duration * ( 1 / scene . objects [ ' Commands ' ] [ ' speed ' ] ) :
# print("Temporization commands :",scene.objects['Terrain']['delay_cmd'])
time . sleep ( 0.001 )
# # pass
###############################################################################
# Map
###############################################################################
def map_aim_near ( cont ) :
obj = cont . owner
sensor = obj . sensors [ ' Near ' ]
if sensor . positive :
print ( " Goall !! " )