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 # @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) # ############################################################################### # # 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']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