ropy/rp_lib.py

941 lines
39 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 # Blender Game Engine (UPBGE)
import aud # Sounds
import threading # Multithreading
import trace
import sys
import time
import math
import mathutils
import random
###############################################################################
# rp_lib.py
# @title: Bibliothèque du Robot Ropy (rp_*)
# @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
# Bibliothèque pour la construction des murs
#
# 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=[]
# 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()
print ("Thread",type_txt, "#", len(threads)-1, "open.")
def thread_stop(threads, type_txt):
i=0
zombie_flag=False
for t in threads:
if not t.is_alive():
print ("Thread",type_txt, "#",i,"closed.")
else:
print ("Thread",type_txt, "#",i,"still open ...")
t.kill()
t.join()
if not t.is_alive():
print ("Thread",type_txt, "#",i,"killed.")
else:
print ("Thread",type_txt, "#",i,"zombie...")
zombie_flag=True
i +=1
if zombie_flag==False:
print ("All threads",type_txt, "are closed.")
return True
else:
print ("There are zombies threads",type_txt, ".")
return False
def thread_cmd_start(fct):
thread_start(threads_cmd, "commands", fct)
def thread_cmd_stop():
thread_stop(threads_cmd, "commands")
###############################################################################
# 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)
###############################################################################
# Rover fonction élèves
###############################################################################
##
# Avancer le rover
##
def rp_avancer ():
print ("rp_avancer")
step =1
obj=scene.objects['Rover']
# print (obj.worldOrientation.to_euler().z)
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-step, 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, 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, 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, y0, z0]
##
# Tourner à gauche
##
def rp_gauche ():
print ("rp_gauche")
step=math.pi/2 # Pas angulaire
obj=scene.objects['Rover']
obj.applyRotation((0, 0, step), True)
##
# Tourner à droite
##
def rp_droite ():
print ("rp_droite")
step=math.pi/2 # Pas angulaire
obj=scene.objects['Rover']
obj.applyRotation((0, 0, -step), True)
##
# Marquer
##
def rp_marquer ():
print ("rp_marquer")
# FIXME
##
# 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
# ###############################################################################
# # Waves (minions)
# ###############################################################################
# ##
# # Création d'un minion
# #
# # Minion caracteristics : category (class), level, hp, speed, armor, bounty, lifes_damage
# # Minion 3d body : body (male,female,old, ...), variante (A,B,C,D, ...), level
# ##
# def ct_minion_create(x,y,cat,level):
# category=cat+"-lv"+str(level)
# minion_3d= scene.objects['Terrain']['minion_3d']
# body = random.choice(minion_3d[category][0])+"_"+random.choice(minion_3d[category][1])+"_"+random.choice(minion_3d[category][2])
# return (ct_minion_create_details(x,y,cat,level,body))
# # Création d'un minion détaillée
# def ct_minion_create_details(x,y,cat,level,body="Knight_m_A_common"):
# category=cat+"-lv"+str(level)
# # Pause
# while scene.objects['Terrain']['run'] == False:
# time.sleep(0.01)
# # Synchronisation des threads : attente de la création d'une tour
# while scene.objects['Terrain']['thread_cmd_lock'] == True:
# # print ("ct_minion : thread_cmd_lock =True")
# time.sleep(0.01)
# # Blocage des autres threads pendant l'apparition du minion
# scene.objects['Terrain']['thread_cmd_lock'] = True
# # Object 3D
# minion= scene.addObject(body, scene.objects['Terrain'])
# minion.worldScale=[0.25,0.25,0.25]
# minion.worldPosition=[x,y,0.1]
# minion.suspendPhysics (True)
# minion.setVisible(False)
# scene.objects['Terrain']['idm']=scene.objects['Terrain']['idm']+1
# minion['id']=scene.objects['Terrain']['idm']
# minion.name="wm("+str(minion['id'])+")" # Wave minion (wm), identifier minion (idm)
# scene.objects['Points']['minions'] +=1
# scene.objects['Points']['minions_run'] +=1
# # Gestion de la distance et des minions zombis
# minion['dist']=0.0
# minion['dist_old']=0.0
# minion['dist_last_x']=minion.worldPosition.x
# minion['dist_last_y']=minion.worldPosition.y
# minion['dist_new']=True
# # Caracteristics
# minion_carac= scene.objects['Terrain']['minion_carac']
# minion['cat']=minion_carac[category][0]
# minion['level']=minion_carac[category][1]
# minion['hp']=minion_carac[category][2]
# minion['speed']=minion_carac[category][3]
# minion['speed_base']=minion_carac[category][3]
# minion['armor']=minion_carac[category][4]
# minion['bounty']=minion_carac[category][5]
# minion['lifes_damage']=minion_carac[category][6]
# minion['buff']=[]
# minion['resist']=[]
# # Actuator Steering
# minion.actuators['Steering'].navmesh=scene.objects[scene.objects['Terrain']['navmesh']]
# minion.actuators['Steering'].target=scene.objects[scene.objects['Terrain']['endtile']]
# minion.actuators['Steering'].distance=2
# # minion.actuators['Steering'].distance=0.5
# minion.actuators['Steering'].velocity=minion['speed_base']*scene.objects['Terrain']['speed']
# # Déblocage des autres threads après l'apparition du minion
# scene.objects['Terrain']['thread_cmd_lock'] = False
# return minion.name
# ##
# # Activation du minion (steering)
# ##
# def ct_minion_go(minion_name):
# minion=scene.objects[minion_name]
# minion.restorePhysics()
# minion.setVisible(True)
# ##
# # Destruction d'un minion
# ##
# def scn_minion_dead(cont):
# obj = cont.owner
# scene.objects['Points']['minions'] -=1
# scene.objects['Points']['minions_run'] -=1
# scene.objects['Points']['kills'] +=1
# scene.objects['Points']['coins']= scene.objects['Points']['coins']+obj['bounty']
# obj.setVisible(False)
# obj.suspendPhysics (True)
# # obj.endObject()
# ###############################################################################
# # Spells / Casts
# ###############################################################################
# ##
# # Buff/debuff Minion
# ##
# def scn_minion_affect(cont):
# if scene.objects['Terrain']['run'] == False: # Pause
# return
# obj = cont.owner
# # print (obj.name, obj['buff'])
# slow_state=False
# # Distance parcourue
# obj['dist']=obj['dist']+ math.sqrt((obj.worldPosition.x-obj['dist_last_x'])**2+(obj.worldPosition.y-obj['dist_last_y'])**2)
# obj['dist_last_x']=obj.worldPosition.x
# obj['dist_last_y']=obj.worldPosition.y
# # Lod
# # print(obj.currentLodLevel)
# # Etats actif
# for debuff_i in obj['buff']:
# if debuff_i[1] <= 0:
# obj['buff'].remove(debuff_i)
# continue
# if debuff_i[0] == "slow":
# slow_state=True
# debuff_i[1] -= scene.objects['Terrain']['speed']
# # Effets
# if slow_state:
# obj.actuators['Steering'].velocity =(obj['speed_base']*scene.objects['Terrain']['speed'])/3
# # obj.actuators['Steering'].velocity =(obj['speed_base']*scene.objects['Terrain']['speed'])/2
# else:
# obj.actuators['Steering'].velocity = obj['speed_base']*scene.objects['Terrain']['speed']
# ###############################################################################
# # Towers
# ###############################################################################
# ##
# # Création d'une tour
# #
# # Tower caracteristics : category (class), damage, speed, range
# ##
# def ct_build(x,y, cat='Archer tower', tower_name="Tower", color=tower_purple, building="square-A"):
# tower_minion_3d= scene.objects['Terrain']['tower_minion_3d']
# if cat=='Archer tower': # Archer
# category="Archer-lv1"
# if cat=='Mage tower': # Mage
# category="Mage-lv1"
# body = random.choice(tower_minion_3d[category][0])+"_"+random.choice(tower_minion_3d[category][1])+"_"+random.choice(tower_minion_3d[category][2])
# return (ct_build_details(x,y, cat, tower_name, color, building, body))
# ##
# # Création d'une tour détaillée
# ##
# def ct_build_details(x,y, cat='Archer tower', tower_name="Tower", color=tower_purple, building="square-A", body="Archer_m_A_common"):
# # Vérification de la place
# if [x,y] in scene.objects['Terrain']['scene_tile_noncontruct'] or [x,y] in scene.objects['Terrain']['scene_tile_tower']:
# return False
# # Vérification du niveau
# scene.objects['Points']['level']= scene.objects['Points']['level'] + 1
# if scene.objects['Points']['level'] > scene.objects['Points']['level_max'] :
# tour= scene.addObject("Tower_error", scene.objects['Terrain'])
# tour.worldPosition=[x,y,0.2]
# tour.worldScale=[1,1,1]
# scene.objects['Terrain']['scene_tile_tower'].append([x,y])
# return False
# # Blocage des autres threads pendant la construction
# scene.objects['Terrain']['thread_cmd_lock'] = True
# # Objets 3D
# time.sleep(0.02)
# tour= scene.addObject('Tower-'+building, scene.objects['Terrain'])
# time.sleep(0.02)
# tour.color = color
# tour.worldPosition=[x,y,0.2]
# tour.worldScale=[1,1,1]
# tour.name="tower("+str(x)+','+str(y)+")"
# scene.objects['Terrain']['scene_tile_tower'].append([x,y])
# tower_minion= scene.addObject(body, scene.objects['Terrain'])
# tower_minion['type_towerminion']=False
# del tower_minion['type_minion']
# tower_minion.name="tm("+str(x)+','+str(y)+")" # Tower minion (tm)
# tower_minion.worldPosition=[x,y,1]
# tower_minion.worldScale=[0.25,0.25,0.25]
# # Draw3d
# if cat=="Archer tower":
# for i in range (3):
# ct_add_tower_bullet(x,y,i, "Arrow")
# if cat=="Mage tower":
# ct_add_tower_cast(x,y)
# # Sounds
# sound_play(sndbuff_build)
# # Caracteristics
# tower_carac= scene.objects['Terrain']['tower_carac']
# tour['cat']=tower_carac[cat][0]
# tour['tower_name']=tower_name
# tour['xp']=0
# tour['lvl_current']=1
# tour['lvl']=1
# tour['damage']=tower_carac[cat][1]
# tour['speed']=tower_carac[cat][2]
# tour['range']=tower_carac[cat][3]
# tour['techno']=[]
# tour['cast']="slow"
# # tour['cast_duration']=2
# tour['cast_duration']=3
# tour['target']=[]
# tour['target_past']=[]
# # Capteur Near
# tour.sensors['Near'].distance=tour['range']*2.5 # Range : 1 point = 2,5
# # tour.sensors['Near'].skippedTicks =round(1/(tour['speed']*scene.objects['Terrain']['speed']))
# tour.sensors['Near'].skippedTicks =round(tour['speed']*50*scene.objects['Terrain']['speed']) # Speed : 1 point = 50 tics
# # Déblocage des autres threads après la construction
# scene.objects['Terrain']['thread_cmd_lock'] = False
# # print (scene.objects)
# return True
# ##
# # Suppression d'une tour
# ##
# def ct_remove(x,y):
# for obj_i in scene.objects:
# if "type_tower" in obj_i.getPropertyNames():
# if x == obj_i.worldPosition.x and y == obj_i.worldPosition.y:
# scene.objects["tm("+str(round(obj_i.worldPosition.x))+','+str(round(obj_i.worldPosition.y))+")"].endObject()
# obj_i.endObject()
# scene.objects['Points']['level']= scene.objects['Points']['level'] - 1
# ##
# # Création d'un projectile
# ##
# def ct_add_tower_bullet(x, y, num, cat="Ball"):
# if cat=="Ball":
# bullet= scene.addObject("Bullet", scene.objects['Terrain'])
# if cat=="Arrow":
# bullet= scene.addObject("Arrow", scene.objects['Terrain'])
# bullet.name="tower("+str(x)+','+str(y)+")-bullet"+str(num)
# bullet.worldPosition=[x,y,1.5]
# bullet.worldScale=[0.75,0.75,0.75]
# bullet.suspendPhysics (True)
# bullet.setVisible(False)
# bullet['activated']=False
# ##
# # Création des sorts
# ##
# def ct_add_tower_cast(x, y):
# cast= scene.addObject("Cast-slow", scene.objects['Terrain'])
# cast.name="tower("+str(x)+','+str(y)+")-cast"
# cast.worldPosition=[x,y,1.5]
# cast.worldScale=[0.75,0.75,0.75]
# cast.suspendPhysics (True)
# cast.setVisible(False)
# cast['activated']=False
# ##
# # Réaction d'une tour
# ##
# def scn_tower_near(cont):
# obj = cont.owner
# sensor = obj.sensors['Near']
# # Tir
# if sensor.positive and len(sensor.hitObjectList)>0 and scene.objects['Terrain']['run']==True :
# # Tir sur le plus avancé basé sur les distances parcourues
# target=sensor.hitObjectList[0]
# target_dist = target['dist']
# for obj_i in sensor.hitObjectList:
# if obj_i['dist']> target_dist:
# target=obj_i
# target_dist = target['dist']
# # Tir sur le plus avancé basé sur l'ordre de passage
# # target=sensor.hitObjectList[0]
# # target_id = target['navPosition']
# # for obj_i in sensor.hitObjectList:
# # if obj_i['navPosition']< target_id:
# # target=obj_i
# # target_id = target['navPosition']
# # Tir sur le plus avancé basé sur les distances par rapport à la tour -> ne marche pas
# # target=sensor.hitObjectList[0]
# # if len(sensor.hitObjectList)>1:
# # target_eloignement = False
# # target_distance_eloignement = 0
# # target_distance_approche = 100
# # print ("detection:",sensor.hitObjectList)
# # for obj_i in sensor.hitObjectList:
# # for obj_j in obj['target_past']:
# # if obj_j[0]==obj_i.name:
# # print ("name :", obj_j[0], "distance :", obj.getDistanceTo(obj_i), "distance old :", obj_j[1], "ecart :", obj.getDistanceTo(obj_i) - obj_j[1])
# # # Éloignement
# # if obj.getDistanceTo(obj_i) - obj_j[1] > 0: # Ecart de distance
# # target_eloignement = True
# # if obj.getDistanceTo(obj_i) > target_distance_eloignement:
# # target=obj_i
# # target_distance_eloignement = obj.getDistanceTo(obj_i)
# # # Approche
# # else:
# # if target_eloignement == False:
# # if obj.getDistanceTo(obj_i) < target_distance_approche:
# # target=obj_i
# # target_distance_approche = obj.getDistanceTo(obj_i)
# # if target_eloignement == True:
# # print ("Eloignement : target:", target.name, "distance :", obj.getDistanceTo(target))
# # print ("")
# # else:
# # print ("Approche : target:", target.name, "distance :", obj.getDistanceTo(target))
# # print ("")
# # obj['target_past']=[]
# # for obj_i in sensor.hitObjectList:
# # obj['target_past'].append([obj_i.name, obj.getDistanceTo(obj_i)])
# # Orientation du tower minion
# towerminion="tm("+str(round(obj.worldPosition.x))+','+str(round(obj.worldPosition.y))+")"
# angle =math.atan((target.worldPosition.y-obj.worldPosition.y)/(target.worldPosition.x-obj.worldPosition.x))
# if target.worldPosition.x>obj.worldPosition.x:
# angle2=math.pi/2+angle-scene.objects[towerminion].worldOrientation.to_euler().z
# angle3=angle
# else:
# angle2=math.pi+math.pi/2+angle-scene.objects[towerminion].worldOrientation.to_euler().z
# angle3=math.pi+angle
# scene.objects[towerminion].applyRotation((0, 0, angle2), False)
# # Sounds
# if obj['cat']=="Archer tower":
# sound_play(sndbuff_archer)
# if obj['cat']=="Mage tower":
# sound_play(sndbuff_mage)
# # Ligne (drawLine) (vitesse rapide)
# if scene.objects['Terrain']['speed']<4: # Pas d'animation à 10 -> plantage
# # Archer (tir de flêche)
# if obj['cat']=="Archer tower":
# if target.name in scene.objects:
# for i in range (3):
# bullet = scene.objects[obj.name+"-bullet"+str(i)]
# if bullet['activated']==False:
# bullet.worldPosition=[obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8]
# bullet['activated']=True
# bullet.setVisible(True)
# scene.objects['Terrain']['draw3d_process']=True
# scene.objects['Terrain']['draw3d_list'].append([20, "arrow", obj.name, bullet.name, target.name, "normal", 20])
# break
# if i ==3 :
# print ("Plus de bullet de disponible pour la tour : "+obj.name)
# # Cast zone
# if obj['cat']=="Mage tower": # Mage (cast)
# cast = scene.objects[obj.name+"-cast"]
# cast.worldPosition=[obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8]
# cast.worldScale=[0.01,0.01,0.01]
# cast.setVisible(True)
# scene.objects['Terrain']['draw3d_process']=True
# scene.objects['Terrain']['draw3d_list'].append([60, "cast", obj.name, cast.name, "slow", 60])
# # Rayon
# # FIXME : ne marche plus (zoom et pan)
# # if obj['cat']=="Test":
# # if target.name in scene.objects:
# # scene.objects['Terrain']['draw2d_process']=True
# # scene.objects['Terrain']['draw2d_list'].append([5, "ray", [obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8], target.name, angle3, ray_yellow,5]) # Suivi du minion
# # Dégats : pas d'animation à 10
# if scene.objects['Terrain']['speed'] >= 4:
# target['hp'] = target['hp'] - obj['damage']
# if target['hp']<=0:
# target['dead']=True
# # Cast (buff and debuff)
# if obj['cat']=="Mage tower":
# for target_i in sensor.hitObjectList:
# target_i['buff'].append([obj['cast'], obj['cast_duration']])
# ###############################################################################
# # Carte
# ###############################################################################
# ##
# # Texte de carte
# ##
# def ct_map_text_wave(wave):
# scene.objects['Points-Map-text']['Text']=("Wave " + str(wave))
# scene.objects['Points-Map-text'].setVisible(True,False)
# scene.objects['Points-Map-text'].color = color_text_yellow
# scene.objects['Points-Map-text']['timer']=0
# scene.objects['Points-Map-text']['anim']=True
# ##
# # Texte de carte
# ##
# def ct_map_text(text):
# scene.objects['Points-Map-text']['Text']=text
# scene.objects['Points-Map-text'].setVisible(True,False)
# ##
# # Fin
# ##
# def ct_map_end(x,y):
# scene.objects['Map_end'].worldPosition=[x,y,0.2]
# scene.objects['Map_end'].worldScale=[0.25,0.25,0.25]
# ##
# # Minion arrivé à la fin
# ##
# def scn_map_end_near(cont):
# obj = cont.owner
# sensor = obj.sensors['Near']
# if sensor.positive :
# for obj_i in sensor.hitObjectList :
# sound_play(sndbuff_life)
# if scene.objects['Points']['lifes']>0:
# scene.objects['Points']['lifes']= scene.objects['Points']['lifes']-obj_i['lifes_damage']
# scene.objects['Points']['minions_run'] -=1
# for obj_i in sensor.hitObjectList :
# obj_i.setVisible(False)
# obj_i.suspendPhysics (True)
# # obj_i.endObject()
# ##
# # Drapeau de fin
# ##
# def ct_map_endflag(x,y):
# endflag= scene.addObject("Map_endflag", scene.objects['Terrain'])
# endflag.worldPosition=[x,y,0.3]
# endflag.worldScale=[0.3,0.3,0.3]
# if round(x) == x :
# if round(y) == y :
# scene.objects['Terrain']['scene_tile_noncontruct'].append([x,y])
# else:
# scene.objects['Terrain']['scene_tile_noncontruct'].append([x,math.floor(y)])
# scene.objects['Terrain']['scene_tile_noncontruct'].append([x,math.ceil(y)])
# else:
# if round(y) == y :
# scene.objects['Terrain']['scene_tile_noncontruct'].append([math.floor(x),y])
# scene.objects['Terrain']['scene_tile_noncontruct'].append([math.ceil(x),y])
# else:
# scene.objects['Terrain']['scene_tile_noncontruct'].append([math.floor(x),math.floor(y)])
# scene.objects['Terrain']['scene_tile_noncontruct'].append([math.floor(x),math.ceil(y)])
# scene.objects['Terrain']['scene_tile_noncontruct'].append([math.ceil(x),math.floor(y)])
# scene.objects['Terrain']['scene_tile_noncontruct'].append([math.ceil(x),math.ceil(y)])
# ###############################################################################
# # Temporisation
# ###############################################################################
# def ct_sleep (duration):
# time.sleep(duration*(1/scene.objects['Terrain']['speed']))
# # def ct_tempo (duration):
# # scene.objects['Terrain']['delay_cmd']=0
# # while scene.objects['Terrain']['delay_cmd']<duration*(1/scene.objects['Terrain']['speed']):
# # # print("Temporization commands :",scene.objects['Terrain']['delay_cmd'])
# # time.sleep(0.001)
# # # pass
# # def ct_tempo_wave (duration):
# # scene.objects['Terrain']['delay_wave']=0
# # while scene.objects['Terrain']['delay_wave']<duration*(1/scene.objects['Terrain']['speed']):
# # # print("Temporization waves :",scene.objects['Terrain']['delay_wave'])
# # time.sleep(0.001)
# # # pass
# # def ct_tempo_wave_trigger (duree):
# # print ("delay wave ", scene.objects['Terrain']['delay_wave'])
# ###############################################################################
# # Affichage
# ###############################################################################
# ##
# # Texte du panel d'information
# ##
# def ct_print (text):
# # text_info (texte)
# if text=="":
# scene.objects['Info-1-text'].setVisible(False,False)
# scene.objects['Info-2-text'].setVisible(False,False)
# else:
# lines_txt=text.split("\n", 6)
# for i in range (len(lines_txt),6):
# lines_txt.append("")
# scene.objects['Info-1-text'].setVisible(True,False)
# scene.objects['Info-2-text'].setVisible(True,False)
# scene.objects['Info-1-text']['Text']=lines_txt[0]+"\n"+lines_txt[1]+"\n"+lines_txt[2]
# scene.objects['Info-2-text']['Text']=lines_txt[3]+"\n"+lines_txt[4]+"\n"+lines_txt[5]
# ###############################################################################
# # Dessin 3d
# ###############################################################################
# def scn_draw3d(cont):
# obj = cont.owner
# if obj.sensors['Draw3d'].positive==False:
# return
# if len(scene.objects['Terrain']['draw3d_list'])==0:
# scene.objects['Terrain']['draw3d_process']=False
# return
# # Dépilage des draws à executer
# for draw_cmd in scene.objects['Terrain']['draw3d_list']:
# # Archer (tir de flêche)
# # scene.objects['Terrain']['draw3d_list'].append([20, "arrow", obj.name, bullet.name, target.name, "normal", 20])
# if draw_cmd[1]=="arrow":
# if draw_cmd[4] in scene.objects:
# tower= scene.objects[draw_cmd[2]]
# bullet = scene.objects[draw_cmd[3]]
# target = scene.objects[draw_cmd[4]]
# x0 = tower.worldPosition.x
# y0 = tower.worldPosition.y
# # z0 = tower.worldPosition.z+0.8 # ajustement +0.8
# z0 = tower.worldPosition.z+1 # ajustement +1
# x1 = target.worldPosition.x
# y1 = target.worldPosition.y
# z1 = target.worldPosition.z+0.5 # ajustement +0.5
# if x1>x0:
# angle_z =math.atan((y1-y0)/(x1-x0))+math.pi/2
# else:
# angle_z =math.pi+math.atan((y1-y0)/(x1-x0))+math.pi/2
# angle_y =math.atan((z1-z0)/(math.sqrt((x1-x0)**2+(y1-y0)**2)))
# step_x=(x1-x0)/draw_cmd[6]
# step_y=(y1-y0)/draw_cmd[6]
# step_z=(z1-z0)/draw_cmd[6]
# step = draw_cmd[6]-draw_cmd[0]
# bullet.worldPosition=[x0+step_x*step, y0+step_y*step, z0+step_z*step]
# bullet.worldOrientation=[0, angle_y, angle_z]
# draw_cmd[0] = draw_cmd[0]-scene.objects['Terrain']['speed']
# # Dégats
# if draw_cmd[0]<=0:
# bullet['activated']=False
# bullet.setVisible(False)
# target['hp'] = target['hp'] - tower['damage']
# if target['hp']<=0: # Mort
# target['dead']=True
# # Mage (cast)
# # scene.objects['Terrain']['draw3d_list'].append([60, "cast", obj.name, cast.name, "slow", 60])
# if draw_cmd[1]=="cast":
# cast = scene.objects[draw_cmd[3]]
# step = draw_cmd[5]-draw_cmd[0]
# cast.worldScale=[0.05*step,0.05*step,0.05*step]
# # cast.worldScale=[0.75*step,0.75*step,0.75*step]
# draw_cmd[0] = draw_cmd[0]-scene.objects['Terrain']['speed']
# # Fin
# if draw_cmd[0]<=0:
# cast.setVisible(False)
# # Suppression des draws finis
# i=0
# for draw_cmd in scene.objects['Terrain']['draw3d_list']:
# if draw_cmd[0]<=0:
# scene.objects['Terrain']['draw3d_list'].pop(i)
# else:
# i=i+1
# if len(scene.objects['Terrain']['draw3d_list'])==0:
# scene.objects['Terrain']['draw3d_process']=False
# ###############################################################################
# # Dessin 2d (bge.render.drawLine)
# ###############################################################################
# def circle (center, radius, color):
# ang = 0.0
# # ang_step = 0.1
# ang_step = 0.2
# while ang< 2 * math.pi:
# x0 = center[0]+float(radius*math.cos(ang))
# y0 = center[1]+float(radius*math.sin(ang))
# x1 = center[0]+float(radius*math.cos(ang+ang_step))
# y1 = center[1]+float(radius*math.sin(ang+ang_step))
# bge.render.drawLine([x0,y0,center[2]],[x1,y1,center[2]],color)
# ang += ang_step
# ##
# # Affiche les draws 2d en cours
# #
# # Type de draw 2d:
# # arrow : [5, "arrow", [obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8],target.name, angle3, ray_yellow,5]
# # cast : [30, "cast", [obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8], ray_blue,30]
# # ray : [5, "ray", [obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8],[target.worldPosition.x, target.worldPosition.y, target.worldPosition.z], angle3, ray_yellow,5]
# ##
# def scn_draw2d(cont):
# obj = cont.owner
# if obj.sensors['Draw2d'].positive==False:
# return
# if len(scene.objects['Terrain']['draw2d_list'])==0:
# scene.objects['Terrain']['draw2d_process']=False
# return
# # Dépilage des draws à executer
# for draw_cmd in scene.objects['Terrain']['draw2d_list']:
# # Archer (tir de flêche)
# if draw_cmd[1]=="arrow":
# if draw_cmd[3] in scene.objects:
# # x0 = draw_cmd[2][0]+0.25*(math.cos(draw_cmd[4]))
# # y0 = draw_cmd[2][1]+0.25*(math.sin(draw_cmd[4]))
# x0 = draw_cmd[2][0]
# y0 = draw_cmd[2][1]
# z0 = draw_cmd[2][2]
# x1 = scene.objects[draw_cmd[3]].worldPosition.x
# y1 = scene.objects[draw_cmd[3]].worldPosition.y
# z1 = scene.objects[draw_cmd[3]].worldPosition.z-0.1 # ajustement -0.1
# distance = math.sqrt((x1-x0)**2+(y1-y0)**2+(z1-z0)**2)
# distance_xy = math.sqrt((x1-x0)**2+(y1-y0)**2)
# distance_z = z1-z0
# angle_z =math.atan((z1-z0)/(distance_xy))
# angle_xy =math.atan((y1-y0)/(x1-x0))
# step=distance_xy/(2+draw_cmd[6])
# step_z=distance_z/(2+draw_cmd[6])
# if x1>x0:
# angle2=angle_xy
# else:
# angle2=math.pi+angle_xy
# x2=x0+(((6-draw_cmd[0])*step)*(math.cos(angle2)))
# y2=y0+(((6-draw_cmd[0])*step)*(math.sin(angle2)))
# z2=z0-(((6-draw_cmd[0])*step_z)*(math.sin(angle_z)))
# x3=x0+(((6-draw_cmd[0])*step+step)*(math.cos(angle2)))
# y3=y0+(((6-draw_cmd[0])*step+step)*(math.sin(angle2)))
# z3=z0-(((6-draw_cmd[0])*step_z+step_z)*(math.sin(angle_z)))
# bge.render.drawLine([x2,y2, z2], [x3,y3,z3], draw_cmd[5])
# draw_cmd[0] = draw_cmd[0]-scene.objects['Terrain']['speed']
# # if scene.objects['Terrain']['speed']<1:
# # draw_cmd[0] = draw_cmd[0]-scene.objects['Terrain']['speed']
# # else:
# # draw_cmd[0] = draw_cmd[0]-1
# # bge.render.drawLine([draw_cmd[2][0]+((6-draw_cmd[0])*0.25)*(math.cos(draw_cmd[4])), draw_cmd[2][1]+((6-draw_cmd[0])*0.25)*(math.sin(draw_cmd[4])),draw_cmd[2][2]],
# # [draw_cmd[2][0]+((6-draw_cmd[0])*0.25+0.25)*(math.cos(draw_cmd[4])), draw_cmd[2][1]+((6-draw_cmd[0])*0.25+0.25)*(math.sin(draw_cmd[4])),draw_cmd[2][2]],
# # draw_cmd[5])
# # Mage (cast)
# # FIXME : Problème
# if draw_cmd[1]=="cast": # Mage (cast)
# circle(draw_cmd[2], 3.1-draw_cmd[0]*0.1, draw_cmd[3])
# circle(draw_cmd[2], 3-draw_cmd[0]*0.1, draw_cmd[3])
# circle(draw_cmd[2], 2.9-draw_cmd[0]*0.1, draw_cmd[3])
# draw_cmd[0] = draw_cmd[0]-scene.objects['Terrain']['speed']
# # if scene.objects['Terrain']['speed']<=2:
# # draw_cmd[0] = draw_cmd[0]-scene.objects['Terrain']['speed']
# # if scene.objects['Terrain']['speed']==4:
# # draw_cmd[0] = draw_cmd[0]-draw_cmd[4]/2
# # circle(draw_cmd[2], 3, draw_cmd[3]) # simple
# # radius=[3,3,2.5,2.5,2,2,1.5,1.5,1,1,1] # basé sur un tableau
# # circle(draw_cmd[2], radius[draw_cmd[0]], draw_cmd[3])
# # Rayon
# if draw_cmd[1]=="ray":
# if draw_cmd[3] in scene.objects:
# x0 = draw_cmd[2][0]+0.25*(math.cos(draw_cmd[4]))
# y0 = draw_cmd[2][1]+0.25*(math.sin(draw_cmd[4]))
# x1 = scene.objects[draw_cmd[3]].worldPosition.x
# y1 = scene.objects[draw_cmd[3]].worldPosition.y
# z1 = scene.objects[draw_cmd[3]].worldPosition.z
# bge.render.drawLine([x0,y0, draw_cmd[2][2]], [x1,y1,z1], draw_cmd[5]) # suivi minion
# # bge.render.drawLine([draw_cmd[2][0]+0.25*(math.cos(draw_cmd[4])), draw_cmd[2][1]+0.25*(math.sin(draw_cmd[4])), draw_cmd[2][2]], draw_cmd[3], draw_cmd[5]) # décalage minion
# # bge.render.drawLine(draw_cmd[2], draw_cmd[3], draw_cmd[5]) # simple
# draw_cmd[0] = draw_cmd[0]-scene.objects['Terrain']['speed']
# # Suppression des draws finis
# i=0
# for draw_cmd in scene.objects['Terrain']['draw2d_list']:
# if draw_cmd[0]<=0:
# scene.objects['Terrain']['draw2d_list'].pop(i)
# else:
# i=i+1
# if len(scene.objects['Terrain']['draw2d_list'])==0:
# scene.objects['Terrain']['draw2d_process']=False