diff --git a/asset/sounds/archer.wav b/asset/sounds/archer.wav new file mode 100644 index 0000000..dc16b98 Binary files /dev/null and b/asset/sounds/archer.wav differ diff --git a/asset/sounds/build.wav b/asset/sounds/build.wav new file mode 100644 index 0000000..70f9db5 Binary files /dev/null and b/asset/sounds/build.wav differ diff --git a/asset/sounds/click.ogg b/asset/sounds/click.ogg new file mode 100644 index 0000000..502a729 Binary files /dev/null and b/asset/sounds/click.ogg differ diff --git a/asset/sounds/click_construct.ogg b/asset/sounds/click_construct.ogg new file mode 100644 index 0000000..fb04bd9 Binary files /dev/null and b/asset/sounds/click_construct.ogg differ diff --git a/asset/sounds/glest/LICENCES.txt b/asset/sounds/glest/LICENCES.txt new file mode 100644 index 0000000..1d7a173 --- /dev/null +++ b/asset/sounds/glest/LICENCES.txt @@ -0,0 +1,27 @@ +============================== +Glest Game 3.2.1 License +============================== + +Except where otherwise noted, all of the documentation, multimedia and software included in the Glest Game setup package is copyrighted by The Glest Team. + +Copyright (C) 2001-2009 The Glest Team. All rights reserved. + +This software is provided without any express or implied warranty. In no event shall the author be held liable for any damages arising from the use of this software. + +This software may be redistributed freely, but all redistributions must retain all occurences of the above copyright notice and web site addresses that are currently in place. + + +email: contact_game@glest.org +web: http://glest.org/ + + +The Glest Team: + +Programmer: Martińo Figueroa +Sound artist: Jose Luis González +2D and 3D artist: Tucho Fernández +2D artist and web: José Zanni +SDL port: Matze Braun +Animation: Félix Menéndez +3D artist: Marcos Caruncho + diff --git a/asset/sounds/glest/arrow_hit5.wav b/asset/sounds/glest/arrow_hit5.wav new file mode 100644 index 0000000..dc16b98 Binary files /dev/null and b/asset/sounds/glest/arrow_hit5.wav differ diff --git a/asset/sounds/glest/battlemage_hit4.wav b/asset/sounds/glest/battlemage_hit4.wav new file mode 100644 index 0000000..d00a3df Binary files /dev/null and b/asset/sounds/glest/battlemage_hit4.wav differ diff --git a/asset/sounds/glest/machine_attack2.wav b/asset/sounds/glest/machine_attack2.wav new file mode 100644 index 0000000..70f9db5 Binary files /dev/null and b/asset/sounds/glest/machine_attack2.wav differ diff --git a/asset/sounds/life.ogg b/asset/sounds/life.ogg new file mode 100644 index 0000000..7d49262 Binary files /dev/null and b/asset/sounds/life.ogg differ diff --git a/asset/sounds/mage.wav b/asset/sounds/mage.wav new file mode 100644 index 0000000..d00a3df Binary files /dev/null and b/asset/sounds/mage.wav differ diff --git a/codetower-14.blend b/codetower-14.blend new file mode 100644 index 0000000..f2a838c Binary files /dev/null and b/codetower-14.blend differ diff --git a/ct.py b/ct.py index ad054c3..671270c 100644 --- a/ct.py +++ b/ct.py @@ -1,5 +1,7 @@ import importlib -import bge # BibliothĂšque Blender Game Engine (UPBGE) +import bge # Blender Game Engine (UPBGE) +import bpy # Blender +import aud # Sounds import math import time import sys @@ -24,26 +26,30 @@ import ct_map # ############################################################################### -# Import dynamique des fichiers Python Ă©lĂšve et vagues +# Dynamic import user file sys.setrecursionlimit(10**5) # Limite sur la rĂ©cursivitĂ© (valeur par dĂ©faut : 1000) -> segfault de Blender importlib.invalidate_caches() ct_wv = importlib.import_module('ct_waves') # waves script ct_cmd = importlib.import_module('ct_cmd') # user script (commands) -# RĂ©cupĂ©rer la scĂšne UPBGE +# UPBGE scene scene = bge.logic.getCurrentScene() +eevee = bpy.context.scene.eevee -# RĂ©cupĂ©rer le fichier de config +# Config file # print (os.getcwd()) ct_config = ET.parse('ct_config.xml') ct_config_tree = ct_config.getroot() -# Couleurs +# Colors +color_magenta = [0.800, 0.005, 0.315,1] +color_orange = [0.799, 0.130, 0.063,1] +color_white = [0.8, 0.8, 0.8, 1] +color_yellow = [0.8, 0.619, 0.021, 1] +color_black = [0, 0, 0, 1] -color_magenta = [0.800, 0.005, 0.315,1] # bouton non activable : magenta -color_orange = [0.799, 0.130, 0.063,1] # bouton activable : orange -color_white = [0.8, 0.8, 0.8, 1] # bouton focus : blanc -color_yellow = [0.8, 0.619, 0.021, 1] # bouton activĂ© : jaune +color_endbanner_bluelight = [0.361, 0.527, 0.716, 1] +color_endbanner_bluedark = [0.130, 0.254, 0.407, 1] color_text = [0, 0, 0, 1] # Noir color_text_red = [0.799, 0.031, 0.038, 1] @@ -53,8 +59,14 @@ color_cmd_hl = [0.8, 0.619, 0.021, 1] # jaune color_link = [0.024, 0.006, 0.8, 1] # bleu color_link_hl = [0.8, 0.005, 0.315, 1] # majenta -# Constantes UPBGE +# Sounds +audiodev = aud.Device() +snd_click = aud.Sound('asset/sounds/click.ogg') +sndbuff_click = aud.Sound.cache(snd_click) +snd_construct = aud.Sound('asset/sounds/click_construct.ogg') +sndbuff_construct = aud.Sound.cache(snd_construct) +# UPBGE constants JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED ACTIVATE = bge.logic.KX_INPUT_ACTIVE @@ -69,6 +81,7 @@ def cmd_tower_construct(cont): obj = cont.owner obj_Hl= scene.objects[obj.name+"-Hl"] if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['Terrain']['manip_mode']==0: + audiodev.play(sndbuff_construct) if scene.objects['Terrain']['construct_mode']==True: scene.objects['Terrain']['construct_mode']=False obj.worldScale=[1, 1, 1] @@ -112,6 +125,7 @@ def points_maj (cont): scene.objects['Coins_text']['Text']=str(scene.objects['Points']['coins']) scene.objects['Level_text']['Text']=str(scene.objects['Points']['level'])+"/"+str(scene.objects['Points']['level_max']) scene.objects['Minions_text']['Text']=str(scene.objects['Points']['minions']) + scene.objects['Points']['tics'] +=1 # Level trop Ă©levĂ© if scene.objects['Points']['level'] > scene.objects['Points']['level_max'] : @@ -119,10 +133,10 @@ def points_maj (cont): if scene.objects['Level_text'].color == color_text_red and scene.objects['Points']['level'] <= scene.objects['Points']['level_max']: scene.objects['Level_text'].color = color_text - # Fin de la vague - if scene.objects['Terrain']['thread_wave']==False: - if scene.objects['Points']['minions']==0: - terrain_fin () + # Fin de la vague + if scene.objects['Terrain']['thread_wave']==False and scene.objects['Terrain']['map_run'] == True : + if scene.objects['Points']['minions_run']==0 : + terrain_end () ############################################################################### # Terrain @@ -163,18 +177,19 @@ def scn_terrain_mo(cont): # Initialisation lors du chargement du terrain def terrain_init (cont): + # Cacher la banniĂšre de fin + scene.objects['End'].setVisible(False,True) + scene.objects['End']['timer']=0 + # Pile des draws scene.objects['Terrain']['draw_process']=False scene.objects['Terrain']['draw_list']=[] - - # Mise Ă  zĂ©ro des compteurs - scene.objects['Points']['lifes']=10 - scene.objects['Points']['lifes_max']=10 - scene.objects['Points']['coins']=0 - scene.objects['Points']['level']=0 - scene.objects['Points']['level_max']=1 - scene.objects['Points']['minions']=0 - scene.objects['Level_text'].color = color_text + + # Configuration du moteur de rendu + if scene.objects['Terrain']['speed']<4: + eevee.use_eevee_smaa = True + else: + eevee.use_eevee_smaa = False # Recherche les tuiles non constructibles (chemin) scene.objects['Terrain']['scene_tile_noncontruct'] = [] @@ -187,108 +202,91 @@ def terrain_init (cont): obj_i.collisionGroup=2 if "tile_hill" in obj_i.name: obj_i.collisionGroup=2 + scene.objects['Terrain']['scene_tile_tower']= [] # Init de la carte 1 ct_map.map1_init() + ct_map.map1_reset() + # scene.objects['Level_text'].color = color_text # Mise en route et pause du cycle -def terrain_run (cont): - if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['Terrain']['manip_mode']==0: +def terrain_run (): + audiodev.play(sndbuff_click) - # 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) - for obj_i in scene.objects: # Pause des Steerings - if "type_minion" in obj_i.getPropertyNames() and "type_towerminion" not in obj_i.getPropertyNames(): - obj_i.actuators['Steering'].velocity=0 - 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) - - # DĂ©marrage de la map - if scene.objects['Terrain']['thread_run']==False: - for obj_i in scene.objects: # Supprimer les tours - if "type_tower" in obj_i.getPropertyNames() : - obj_i.endObject() - scene.objects['Points']['level']= scene.objects['Points']['level'] - 1 - if "type_towerminion" in obj_i.getPropertyNames() : - obj_i.endObject() - scene.objects['Terrain']['scene_tile_tower']= [] - scene.objects['Stop'].setVisible(True,False) - scene.objects['Terrain']['thread_run']=True - # importlib.reload(ct_cmd) # Lecture dynamique du script python (risque de Segfault de Blender) - # importlib.reload(ct_vg) # Lecture dynamique du script python (risque de Segfault de Blender) - ct_cmd.start() # Execution des commandes - ct_wv.start() # Lancement des vagues - - # ArrĂȘt de la pause - else: - for obj_i in scene.objects: # Relance des Steerings - if "type_minion" in obj_i.getPropertyNames(): - obj_i.actuators['Steering'].velocity=obj_i.components['Minion'].args['speed']*scene.objects['Terrain']['speed'] - -# Vitesse du jeu -def terrain_runspeed (cont): - if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['Terrain']['manip_mode']==0: - obj = cont.owner - speed_mode=[0.25, 0.5, 1,2,4,10] - speed_mode_txt=["1/4", "1/2", "1", "2","4","10"] - i=speed_mode.index(scene.objects['Terrain']['speed']) - - # Affichage - if obj.name=="Speed_up" and i<5: - scene.objects['Terrain']['speed']=speed_mode[i+1] - scene.objects['Text_speed']['Text']=speed_mode_txt[i+1] - if obj.name=="Speed_down" and i>0: - scene.objects['Terrain']['speed']=speed_mode[i-1] - scene.objects['Text_speed']['Text']=speed_mode_txt[i-1] - - # Maj des Nears (Towers) et des Steerings (Minions) - for obj_i in scene.objects: - if "type_tower" in obj_i.getPropertyNames() and "Near" in obj_i.sensors : - obj_i.sensors['Near'].skippedTicks =round(1/(obj_i.components['Tower'].args['speed']*scene.objects['Terrain']['speed'])) - print (obj_i.sensors['Near'].skippedTicks) - if "type_minion" in obj_i.getPropertyNames() and "type_towerminion" not in obj_i.getPropertyNames(): - obj_i.actuators['Steering'].velocity=obj_i.components['Minion'].args['speed']*scene.objects['Terrain']['speed'] - - # Maj du fichier de config (vitesse du jeu : data/config/speed) - ct_config_tree[0][0].text=str(scene.objects['Terrain']['speed']) - buffer_xml = ET.tostring(ct_config_tree) - with open("ct_config.xml", "wb") as f: - f.write(buffer_xml) - -# ArrĂȘt et rĂ©initialisation du cycle -def terrain_stop (cont): - if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['Terrain']['manip_mode']==0: - - # ArrĂȘt des threads utilisateurs + # Pause + if scene.objects['Terrain']['run'] == True: scene.objects['Terrain']['run']=False - scene.objects['Terrain']['thread_run']=False - ct_cmd.stop() # Stop des commandes - ct_wv.stop() # Stop des vagues - - # Supprimer les enemis - for obj_i in scene.objects: - if "type_minion" in obj_i.getPropertyNames() and "type_towerminion" not in obj_i.getPropertyNames(): - obj_i.endObject() - scene.objects['Points']['minions']=0 - - # Commandes scene.objects['Pause'].setVisible(False,False) scene.objects['Pause-Hl'].setVisible(False,False) - scene.objects['Run'].setVisible(True,False) - scene.objects['Stop'].setVisible(False,False) - scene.objects['Stop-Hl'].setVisible(False,False) + scene.objects['Run-Hl'].setVisible(True,False) + for obj_i in scene.objects: # Pause des Steerings + if "type_minion" in obj_i.getPropertyNames() and "type_towerminion" not in obj_i.getPropertyNames(): + obj_i.actuators['Steering'].velocity=0 + + # Run + else : + 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) + + # DĂ©marrage de la map + if scene.objects['Terrain']['thread_run']==False: + scene.objects['Stop'].setVisible(True,False) + + # Mise Ă  zĂ©ro des compteurs + ct_map.map1_reset() + + # Supprimer les tours + for obj_i in scene.objects: + if "type_tower" in obj_i.getPropertyNames() : + obj_i.endObject() + if "type_towerminion" in obj_i.getPropertyNames() : + obj_i.endObject() + scene.objects['Terrain']['scene_tile_tower']= [] + + # Scripts utilisateur et vagues + scene.objects['Terrain']['map_run'] = True + scene.objects['Terrain']['thread_run']=True + scene.objects['Points']['time_begin']=time.localtime() + # importlib.reload(ct_cmd) # Lecture dynamique du script python (risque de Segfault de Blender) + # importlib.reload(ct_vg) # Lecture dynamique du script python (risque de Segfault de Blender) + ct_cmd.start() # Execution du script utilisateur + ct_wv.start() # Lancement du script des vagues + + # ArrĂȘt de la pause + else: + for obj_i in scene.objects: # Relance des Steerings + if "type_minion" in obj_i.getPropertyNames() and "type_towerminion" not in obj_i.getPropertyNames(): + obj_i.actuators['Steering'].velocity=obj_i.components['Minion'].args['speed']*scene.objects['Terrain']['speed'] + +# ArrĂȘt et rĂ©initialisation du cycle +def terrain_stop (): + audiodev.play(sndbuff_click) + + # ArrĂȘt des threads utilisateurs + scene.objects['Terrain']['run']=False + scene.objects['Terrain']['thread_run']=False + scene.objects['Terrain']['map_run'] = False # Ne pas afficher la banniĂšre de fin + ct_cmd.stop() # Stop du script utilisateur + ct_wv.stop() # Stop du script des vagues + + # Supprimer les enemis + for obj_i in scene.objects: + if "type_minion" in obj_i.getPropertyNames() and "type_towerminion" not in obj_i.getPropertyNames(): + obj_i.endObject() + scene.objects['Points']['minions']=0 + scene.objects['Points']['minions_run']=0 + + # Commandes + scene.objects['Pause'].setVisible(False,False) + scene.objects['Pause-Hl'].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 terrain_fin (): +def terrain_end (): scene.objects['Terrain']['run']=False scene.objects['Terrain']['thread_run']=False @@ -299,10 +297,96 @@ def terrain_fin (): scene.objects['Stop'].setVisible(False,False) scene.objects['Stop-Hl'].setVisible(False,False) + # Affichage des rĂ©sultats + if scene.objects['End']['timer']== 0: + scene.objects['Terrain']['manip_mode']=9 # FenĂȘtre modale + maptime_mn=time.localtime().tm_min-scene.objects['Points']['time_begin'].tm_min + maptime_sec=time.localtime().tm_sec-scene.objects['Points']['time_begin'].tm_sec + if maptime_sec<0: + maptime_mn-=1 + maptime_sec+=60 + scene.objects['Endbanner_wave_text']['Text']="Wave \n"+str(scene.objects['Points']['wave']) + if maptime_mn<=99: + scene.objects['Endbanner_points_text']['Text']="Level "+str(scene.objects['Points']['level_max'])+"\n Time "+ str(maptime_mn)+"'"+ str(maptime_sec)+"\"" + else: + scene.objects['Endbanner_points_text']['Text']="Level "+str(scene.objects['Points']['level_max'])+"\n Time "+ str(maptime_mn)+"'" + scene.objects['Endbanner'].color = color_endbanner_bluelight + scene.objects['Endbanner_wave_text'].color = color_black + scene.objects['Endbanner_points_text'].color = color_black + scene.objects['Endbanner_ok_text'].color = color_black + scene.objects['End'].setVisible(True,True) + scene.objects['End']['init_localPosition']= [scene.objects['End'].localPosition.x, scene.objects['End'].localPosition.y, scene.objects['End'].localPosition.z] + pas=0.5 + scene.objects['End'].localPosition.y=scene.objects['End'].localPosition.y-1*pas + scene.objects['End'].localPosition.z=scene.objects['End'].localPosition.z+0.85*pas + scene.objects['End']['timer']=scene.objects['End']['timer']+1 + if scene.objects['End']['timer']== 40: + scene.objects['Terrain']['map_run'] = False + +# Vitesse du jeu +def terrain_speed (obj): + audiodev.play(sndbuff_click) + speed_mode=[0.25, 0.5, 1,2,4,10] + speed_mode_txt=["1/4", "1/2", "1", "2","4","10"] + i=speed_mode.index(scene.objects['Terrain']['speed']) + + # Affichage + if obj.name=="Speed_up" and i<5: + scene.objects['Terrain']['speed']=speed_mode[i+1] + scene.objects['Text_speed']['Text']=speed_mode_txt[i+1] + if obj.name=="Speed_down" and i>0: + scene.objects['Terrain']['speed']=speed_mode[i-1] + scene.objects['Text_speed']['Text']=speed_mode_txt[i-1] + + # Maj des Nears (Towers) et des Steerings (Minions) + for obj_i in scene.objects: + if "type_tower" in obj_i.getPropertyNames() and "Near" in obj_i.sensors : + obj_i.sensors['Near'].skippedTicks =round(1/(obj_i.components['Tower'].args['speed']*scene.objects['Terrain']['speed'])) + if "type_minion" in obj_i.getPropertyNames() and "type_towerminion" not in obj_i.getPropertyNames(): + obj_i.actuators['Steering'].velocity=obj_i.components['Minion'].args['speed']*scene.objects['Terrain']['speed'] + + # Configuration du moteur de rendu + if scene.objects['Terrain']['speed']<4: + eevee.use_eevee_smaa = True + else: + eevee.use_eevee_smaa = False + + # Maj du fichier de config (vitesse du jeu : data/config/speed) + ct_config_tree[0][0].text=str(scene.objects['Terrain']['speed']) + buffer_xml = ET.tostring(ct_config_tree) + with open("ct_config.xml", "wb") as f: + f.write(buffer_xml) + +# Fermer la page de fin +def endbanner_hl(cont): + if cont.sensors['MO'].status == JUST_ACTIVATED: + scene.objects['Endbanner'].color = color_white + scene.objects['Endbanner_wave_text'].color = color_white + scene.objects['Endbanner_points_text'].color = color_white + scene.objects['Endbanner_ok_text'].color = color_white + if cont.sensors['MO'].status == JUST_RELEASED: + scene.objects['Endbanner'].color = color_endbanner_bluelight + scene.objects['Endbanner_wave_text'].color = color_black + scene.objects['Endbanner_points_text'].color = color_black + scene.objects['Endbanner_ok_text'].color = color_black + +def endbanner_close(cont): + if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive : + audiodev.play(sndbuff_click) + scene.objects['Terrain']['manip_mode']=0 + scene.objects['End'].localPosition.y=scene.objects['End']['init_localPosition'][0] + scene.objects['End'].localPosition.y=scene.objects['End']['init_localPosition'][1] + scene.objects['End'].localPosition.z=scene.objects['End']['init_localPosition'][2] + scene.objects['End'].setVisible(False,True) + scene.objects['Endbanner'].color = [0.592, 0.68, 0.407, 1] + scene.objects['Endbanner_wave_text'].color = color_black + scene.objects['Endbanner_points_text'].color = color_black + scene.objects['End']['timer']= 0 + ############################################################################### # Commandes ############################################################################### - + # Init def cmd_init(): # scene.objects['Terrain']['run']=False @@ -314,9 +398,10 @@ def cmd_init(): scene.objects['Construc-Hl'].setVisible(False,False) scene.objects['Map_text'].setVisible(False,False) - scene.objects['Tower_construc_mode'].setVisible(False,False) scene.objects['Text_info-1'].setVisible(False,False) scene.objects['Text_info-2'].setVisible(False,False) + scene.objects['Tower_construc_mode'].setVisible(False,False) + scene.objects['Terrain']['map_run'] = False # scene.objects['Raz-vue-Hl'].setVisible(False,False) # scene.objects['Aide-cmd-Hl'].setVisible(False,False) @@ -374,11 +459,27 @@ def cmd_hl(cont): scene.objects['Stop-Hl'].setVisible(False,False) scene.objects['Stop'].setVisible(True,False) +# Click sur les commandes +def cmd_click (cont): + obj = cont.owner + if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['Terrain']['manip_mode']==0: + if obj.name=="Pause" or obj.name=="Run": + terrain_run () + if obj.name=="Stop": + terrain_stop () + if obj.name=="Speed_up" or obj.name=="Speed_down": + terrain_speed (obj) + ############################################################################### # Gestion du clavier ############################################################################### -# Mode : Pan(1) avec Shift, Zoom (2) avec Ctrl +# Mode : +# 0 : rien (par dĂ©faut) +# 1 : Pan avec Shift +# 2 : Zoom avec Ctrl +# 9 : FenĂȘtre modale + def mode(cont): obj = cont.owner keyboard = bge.logic.keyboard @@ -414,66 +515,12 @@ def mode(cont): # Touche F5 -> Run et Pause if JUST_ACTIVATED in keyboard.inputs[bge.events.F5KEY].queue: + terrain_run () - # Pause - if scene.objects['Terrain']['run'] == True: - scene.objects['Terrain']['run']=False - scene.objects['Pause'].setVisible(False,False) - scene.objects['Run'].setVisible(True,False) - for obj_i in scene.objects: # Pause des Steerings - if "type_minion" in obj_i.getPropertyNames() and "type_towerminion" not in obj_i.getPropertyNames() : - obj_i.actuators['Steering'].velocity=0 - - # Run - else: - scene.objects['Terrain']['run']=True - scene.objects['Run'].setVisible(False,False) - scene.objects['Pause'].setVisible(True,False) - - # DĂ©marrage de la map - if scene.objects['Terrain']['thread_run']==False: - for obj_i in scene.objects: # Supprimer les tours - if "type_tower" in obj_i.getPropertyNames() : - obj_i.endObject() - scene.objects['Points']['level']= scene.objects['Points']['level'] - 1 - if "type_towerminion" in obj_i.getPropertyNames() : - obj_i.endObject() - scene.objects['Terrain']['scene_tile_tower']= [] - scene.objects['Stop'].setVisible(True,False) - scene.objects['Terrain']['thread_run']=True - # importlib.reload(ct_cmd) # Lecture dynamique du script python (risque de Segfault de Blender) - # importlib.reload(ct_vg) # Lecture dynamique du script python (risque de Segfault de Blender) - ct_cmd.start() # Execution des commandes - ct_wv.start() # Lancement des vagues - - # ArrĂȘt de la pause - else: - for obj_i in scene.objects: # Relance des Steerings - if "type_minion" in obj_i.getPropertyNames(): - obj_i.actuators['Steering'].velocity=obj_i.components['Minion'].args['speed']*scene.objects['Terrain']['speed'] - - # Touche F6 -> Stop / Init if JUST_ACTIVATED in keyboard.inputs[bge.events.F6KEY].queue: if scene.objects['Terrain']['thread_run']==True: - - # ArrĂȘt des threads utilisateurs - scene.objects['Terrain']['run']=False - scene.objects['Terrain']['thread_run']=False - ct_cmd.stop() # Stop des commandes - ct_wv.stop() # Stop des vagues - - # Supprimer les enemis - for obj_i in scene.objects: - if "type_minion" in obj_i.getPropertyNames(): - obj_i.endObject() - scene.objects['Points']['minions']=0 - - # 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) + terrain_stop () ############################################################################### # Manipulation 3D de la scĂšne diff --git a/ct_cmd.py b/ct_cmd.py index e5c5898..4b8c7e1 100644 --- a/ct_cmd.py +++ b/ct_cmd.py @@ -37,7 +37,9 @@ def start(): thread_start(threads, "commands", commands) def stop(): - thread_stop(threads, "commands") + if thread_stop(threads, "commands"): + if len(threads)==1: + threads.pop() ############################################################################### # En: Tower commands @@ -69,8 +71,8 @@ def commands(): # Code your commands here ... - ct_build(4,5, "Archer tower", "Tower #1", blue, "square-A") - # ct_build_details(4,5, "Mage tower", "Tower #1", blue, "square-A", "Mage_A_common") + # ct_build(4,5, "Archer tower", "Tower #1", blue, "square-A") + ct_build_details(4,5, "Mage tower", "Tower #1", blue, "square-A", "Mage_A_common") # ct_build(4,5, "Mage tower", "Tower #1", yellow, "square-A") # ct_build(5,5) # ct_build(5,4, "Tower #3") @@ -84,4 +86,5 @@ def commands(): ct_sleep(2) print ("Threads commands #", len(threads)-1, "are arrived -> close them.") # Thread closed << DONT CHANGE THIS LINE >> + threads.pop() scene.objects['Terrain']['thread_cmd']=False # End of cycle << DONT CHANGE THIS LINE >> diff --git a/ct_config.xml b/ct_config.xml index 1df0497..c4cbdab 100644 --- a/ct_config.xml +++ b/ct_config.xml @@ -1,7 +1,5 @@ - - 1 + 4.0 - - + \ No newline at end of file diff --git a/ct_lib.py b/ct_lib.py index f0fcd0c..13b5998 100644 --- a/ct_lib.py +++ b/ct_lib.py @@ -1,4 +1,5 @@ -import bge # BibliothĂšque Blender Game Engine (UPBGE) +import bge # Blender Game Engine (UPBGE) +import aud # Sounds import threading # Multithreading import trace import sys @@ -27,7 +28,6 @@ import random scene = bge.logic.getCurrentScene() # Colors - tower_purple = [0.202, 0.114, 0.521,1] tower_turquoise = [0.051, 0.270, 0.279,1] tower_magenta = [0.799, 0.005, 0.314,1] @@ -38,7 +38,21 @@ tower_red = [0.799, 0.031, 0.038, 1] tower_blue = [0.127, 0.456, 1.000, 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_blue = [0.127, 0.456, 1.000, 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) + +# handle_buffered = device.play(sound_buffered) +# handle_buffered.stop() ############################################################################### # MĂ©thode kill pour les tĂąches (threads) @@ -101,8 +115,10 @@ def thread_stop(threads, type_txt): 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 ############################################################################### @@ -135,11 +151,11 @@ def ct_minion(x,y,cat,level): body = random.choice(minion_3d[category][0])+"_"+random.choice(minion_3d[category][1])+"_"+random.choice(minion_3d[category][2]) ct_minion_details(x,y,cat,level,body) +# CrĂ©ation d'un minion dĂ©taillĂ©e def ct_minion_details(x,y,cat,level,body="Knight_m_A_common"): category=cat+"-lv"+str(level) # Pause - # FIXME : buggĂ© while scene.objects['Terrain']['run'] == False: time.sleep(0.01) @@ -151,7 +167,9 @@ def ct_minion_details(x,y,cat,level,body="Knight_m_A_common"): minion.name="wm("+str(scene.objects['Terrain']['idm'])+")" # Wave minion (wm), identifier minion (idm) # minion.worldPosition=mathutils.Vector((x,y,0.3)) # minion.worldPosition=mathutils.Vector((x,y,0.37)) # old 2 - scene.objects['Points']['minions']= scene.objects['Points']['minions']+1 + scene.objects['Points']['minions'] +=1 + scene.objects['Points']['minions_run'] +=1 + # print(bge.render.getVsync) # Caracteristics minion.components['Minion'].args['cat']=minion_carac[category][0] @@ -173,7 +191,9 @@ def ct_minion_details(x,y,cat,level,body="Knight_m_A_common"): # Destruction d'un minion def scn_minion_dead(cont): obj = cont.owner - scene.objects['Points']['minions']= scene.objects['Points']['minions']-1 + 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.components['Minion'].args['bounty'] obj.endObject() @@ -204,7 +224,8 @@ def ct_build(x,y, cat='Archer tower', tower_name="Tower", color=tower_purple, to 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]) ct_build_details(x,y, cat, tower_name, color, tower_3d, body) - + +# CrĂ©ation d'une tour dĂ©taillĂ©e def ct_build_details(x,y, cat='Archer tower', tower_name="Tower", color=tower_purple, tower_3d="square-A", body="Archer_m_A_common"): # VĂ©rification de la place @@ -231,6 +252,10 @@ def ct_build_details(x,y, cat='Archer tower', tower_name="Tower", color=tower_pu 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] + + # Sounds + audiodev.play(sndbuff_build) + # sndhdl_build.stop() # CaractĂ©ristiques (composant python et propriĂ©tĂ©s de l'objet 3D) tour.components['Tower'].args['cat']=tower_carac[cat][0] @@ -311,11 +336,13 @@ def scn_tower_near(cont): if target.name in scene.objects: scene.objects['Terrain']['draw_process']=True scene.objects['Terrain']['draw_list'].append([5, "arrow", [obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8],target.name, angle3, ray_yellow, 5]) + audiodev.play(sndbuff_archer) # Cast zone if obj['cat']=="Mage tower": # Mage (cast) scene.objects['Terrain']['draw_process']=True scene.objects['Terrain']['draw_list'].append([30, "cast", [obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8],ray_blue,30]) + audiodev.play(sndbuff_mage) # Rayon if obj['cat']=="Test": @@ -345,8 +372,10 @@ def scn_map_end_near(cont): sensor = obj.sensors['Near'] for i in range (len(sensor.hitObjectList)) : sensor.hitObjectList[i].endObject() - scene.objects['Points']['lifes']= scene.objects['Points']['lifes']-sensor.hitObjectList[0].components['Minion'].args['lifes_damage'] - scene.objects['Points']['minions']= scene.objects['Points']['minions']-1 + audiodev.play(sndbuff_life) + if scene.objects['Points']['lifes']>0: + scene.objects['Points']['lifes']= scene.objects['Points']['lifes']-sensor.hitObjectList[0].components['Minion'].args['lifes_damage'] + scene.objects['Points']['minions_run'] -=1 # Drapeau de fin def ct_map_endflag(x,y): @@ -423,7 +452,8 @@ def ct_map_text(text): def circle (center, radius, color): ang = 0.0 - ang_step = 0.1 + # 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)) @@ -444,15 +474,12 @@ def circle (center, radius, color): # Affiche les draws en cours # FIXME: tir sur le plus avancĂ© -# FIXME : remplacer le rayon par un projectile -# FIXME : remplacer le cercle par un cercle progressif # # Type de draw : # 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_draw(cont): obj = cont.owner if obj.sensors['Property'].positive==False: diff --git a/ct_map.py b/ct_map.py index 4fd3528..cb2e91d 100644 --- a/ct_map.py +++ b/ct_map.py @@ -16,10 +16,13 @@ from ct_lib import * # BibliothĂšque CodeTower # ############################################################################### +scene = bge.logic.getCurrentScene() + ############################################################################### # Carte 1 ############################################################################### - + +# Loading the map def map1_init(): # Taille de la carte @@ -33,3 +36,14 @@ def map1_init(): ct_map_end(1,-10) ct_map_endflag(0.5,-10) ct_map_endflag(1.5,-10) + +# Reset counters +def map1_reset(): + scene.objects['Points']['lifes']=10 + scene.objects['Points']['lifes_max']=10 + scene.objects['Points']['coins']=0 + scene.objects['Points']['level']=0 + scene.objects['Points']['level_max']=1 + scene.objects['Points']['minions']=0 + scene.objects['Points']['minions_run']=0 + diff --git a/ct_waves.py b/ct_waves.py index d168c56..d8a3afe 100644 --- a/ct_waves.py +++ b/ct_waves.py @@ -29,8 +29,10 @@ def start(): thread_start(threads, "waves", waves) def stop(): - thread_stop(threads, "waves") - + if thread_stop(threads, "waves"): + if len(threads)==1: + threads.pop() + ############################################################################### # En: Waves commands # Fr: Commandes des vagues @@ -78,20 +80,24 @@ def stop(): def waves(): # Wave 1 + scene.objects['Points']['wave']= 1 ct_map_text("Wave 1") for i in range (15): ct_minion(14,3,"Orc",1) ct_sleep (1) - ct_sleep (20) + # ct_sleep (20) # Wave 2 - ct_map_text("Wave 2") - for i in range (20): - # ct_minion(14,3,"Knight",1) - ct_minion_details(14,3,"Knight",1, "OldKnight_m_A_common") - ct_sleep (1) + # scene.objects['Points']['wave']= 2 + # ct_map_text("Wave 2") + # for i in range (20): + # # ct_minion(14,3,"Knight",1) + # # ct_minion(14,3,"Orc",1) + # ct_minion_details(14,3,"Knight",1, "OldKnight_m_A_common") + # ct_sleep (1) ct_sleep (2) print ("Threads waves #", len(threads)-1, "are arrived -> close them.") # Thread closed << DONT CHANGE THIS LINE >> + threads.pop() scene.objects['Terrain']['thread_wave']=False # End of cycle << DONT CHANGE THIS LINE >>