import bge # Bibliothèque Blender Game Engine (UPBGE) import ct # Bibliothèque CodeTower import threading # Multithreading import trace import sys import time import mathutils ############################################################################### # ct_lib.py # @title: Bibliothèque utilisateur # @project: CodeTower # @lang: fr # @authors: Philippe Roy # @copyright: Copyright (C) 2022 Philippe Roy # @license: GNU GPL # # Commandes déclenchées par les joueurs : ct_* # Commandes déclenchées par la scene 3D : scn_* # ############################################################################### # # 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 # Récupérer les objets 3D scene = bge.logic.getCurrentScene() # print("Objets de la scene : ", scene.objects) ############################################################################### # 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, "ouvert.") 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,"fermé.") else: print ("Thread",type_txt, "#",i,"encore ouvert ...") t.kill() t.join() if not t.is_alive(): print ("Thread",type_txt, "#",i,"tué.") else: print ("Thread",type_txt, "#",i,"zombie ...") zombie_flag=True i +=1 if zombie_flag==False: print ("Tous les threads",type_txt, "sont fermés.") else: print ("Il reste des threads",type_txt, "zombies.") ############################################################################### # Vagues (minions) # # Caractéristiques : # - Ufo basique : vitesse =1 ; pv_max= 2 (point de vie) # ############################################################################### # Création d'un minion def ct_minion(x,y): ufo= scene.addObject("Ufo", scene.objects['Terrain']) scene.objects['Points']['minions']= scene.objects['Points']['minions']+1 ufo.worldPosition=mathutils.Vector((x,y,0.37)) ufo.worldScale=mathutils.Vector((0.25,0.25,0.25)) ufo.actuators['Steering'].velocity=ufo['vitesse'] # Dégats sur minion # def scn_minion_degat(cont): # obj = cont.owner # sensor = obj.sensors['Collision'] # obj['pv'] = obj['pv']- sensor.hitObject['degat'] # sensor.hitObject.endObject() # if obj['pv']<=0: # scene.objects['Points']['pieces']= scene.objects['Points']['pieces']+obj['pieces'] # obj.endObject() # scene.objects['Points']['minions']= scene.objects['Points']['minions']-1 ############################################################################### # Tours # # Caractéristiques : # - Tour basique : dégats = 1.0 ; portée = 3.0 ; vitesse =0,2 # ############################################################################### # Création d'une tour def ct_tour(x,y): tour= scene.addObject("Tour", scene.objects['Terrain']) tour.worldPosition=mathutils.Vector((x,y,0.2)) tour.worldScale=mathutils.Vector((1,1,1)) scene.objects['Terrain']['scene_non_contruct'].append([x,y]) # Réaction d'une tour def scn_tour_near(cont): obj = cont.owner sensor = obj.sensors['Near'] if len(sensor.hitObjectList)>0: # Tir sur minion target=sensor.hitObjectList[0] bullet= scene.addObject("Bullet", scene.objects['Terrain'], 60*2, False) # bullet['degat'] = obj['degat'] bullet.mass=0.001 # bullet.applyForce=((0,0,9.81),True) bullet.worldPosition=mathutils.Vector((obj.worldPosition.x,obj.worldPosition.y,1.5)) # bullet.worldScale=mathutils.Vector((0.5,0.5,0.5)) bullet.worldScale=[0.5,0.5,0.5] bullet.worldLinearVelocity.x = (target.worldPosition.x-bullet.worldPosition.x)*bullet['vitesse'] bullet.worldLinearVelocity.y= (target.worldPosition.y-bullet.worldPosition.y)*bullet['vitesse'] bullet.worldLinearVelocity.z = (target.worldPosition.z+0.1-bullet.worldPosition.z)*bullet['vitesse'] # Dégats sur minion target['pv'] = target['pv']- obj['degat'] # bullet.endObject() if target['pv']<=0: scene.objects['Points']['pieces']= scene.objects['Points']['pieces']+target['pieces'] target.endObject() scene.objects['Points']['minions']= scene.objects['Points']['minions']-1 ############################################################################### # Temporisation ############################################################################### def tempo (duree): time.sleep(duree)