diff --git a/IDEAS.md b/IDEAS.md index 209bad3..aa216f2 100644 --- a/IDEAS.md +++ b/IDEAS.md @@ -5,11 +5,11 @@ * if * Manipulation de liste * Manipulation de dictionnaire -* Création d'objet (méthode et propriété) - POO +* Création d'objet (méthodes et propriétés) - POO ### Principes * Une tour ou une techno coûte un niveau général (100 crédits, voire de plus en plus chère) -* Les tours évolues (xp) individuellement niveau local et peuvent accèder à des nouvelles technos +* Les tours évolues (xp) individuellement niveau local et peuvent accèder à des nouvelles technos ou sorts ### Stratégies en place * Créer une tour : wave 1 diff --git a/codetower-18.blend b/codetower-18.blend new file mode 100644 index 0000000..028eef6 Binary files /dev/null and b/codetower-18.blend differ diff --git a/ct.py b/ct.py index 40183f2..1bf8a0d 100644 --- a/ct.py +++ b/ct.py @@ -13,14 +13,14 @@ import xml.etree.ElementTree as ET # Creating/parsing XML file ############################################################################### # ct.py # @title: the CodeTower game -# @project: Blender-EduTech +# @project: CodeTower # @lang: fr,en # @authors: Philippe Roy # @copyright: Copyright (C) 2022 Philippe Roy # @license: GNU GPL -# +# +# This game is a tower defense coding game. The towers are driven by Python code. # Ce simulateur est un jeu du type tower defense où les tours sont à piloter par la programmation Python. -# This game is a tower defense coding game. The towers are driven with Python code. # # Commands trigged by button : cmd_* # Commands trigged by 3D scene objects : scn_* @@ -32,7 +32,7 @@ import xml.etree.ElementTree as ET # Creating/parsing XML file # 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_map = importlib.import_module('ct_map1') # waves script +ct_map = importlib.import_module('ct_map1') # waves script ct_cmd = importlib.import_module('ct_cmd') # user script (commands) # UPBGE scene @@ -133,14 +133,14 @@ def points_maj (cont): scene.objects['Points']['tics'] +=1 # Augmentation d'un niveau - if scene.objects['Points']['coins']>100: + if scene.objects['Points']['coins']>=100: scene.objects['Points']['level_max'] +=1 scene.objects['Points']['coins'] -=100 # Level trop élevé if scene.objects['Points']['level'] > scene.objects['Points']['level_max'] : scene.objects['Level_text'].color = color_text_red - if scene.objects['Level_text'].color == color_text_red and scene.objects['Points']['level'] <= scene.objects['Points']['level_max']: + if scene.objects['Points']['level'] <= scene.objects['Points']['level_max']: scene.objects['Level_text'].color = color_text # Ramasse minions perdues @@ -155,16 +155,6 @@ def points_maj (cont): print ("Minion lost : x or y outside the map (x, y, z, x', y') : ", obj_i.name, obj_i.worldPosition.x, obj_i.worldPosition.y, obj_i.worldPosition.z, abs(obj_i.worldLinearVelocity.x), abs(obj_i.worldLinearVelocity.y)) obj_i['dead']=True - - # scene.objects['Points']['minions_state'].append([obj_i.name, worldPosition.x, obj_i.worldPosition.y, obj_i.worldPosition.z]) - # if scene.objects['Points']['tics']%240 ==0: - # for obj_i in scene.objects: - # if "type_minion" in obj_i.getPropertyNames() and "type_towerminion" not in obj_i.getPropertyNames(): - # if obj_i.name - # print (obj_i.name, obj_i.worldPosition.x, obj_i.worldPosition.y, obj_i.worldPosition.z) - # scene.objects['Points']['minions_state'].append([obj_i.name, worldPosition.x, obj_i.worldPosition.y, obj_i.worldPosition.z]) - - # 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 : @@ -292,7 +282,7 @@ def terrain_run (): scene.objects['Points']['time_begin']=time.localtime() if scene.objects['Terrain']['debug_flag']==False: # Lecture dynamique du script python (risque de Segfault de Blender) importlib.reload(ct_cmd) - importlib.reload(ct_map) + # importlib.reload(ct_map) ct_cmd.start() # Execution du script utilisateur ct_map.start(1) # Lancement du script de la permière vague @@ -508,7 +498,7 @@ def cmd_hl(cont): 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": + if obj.name=="Pause" or obj.name=="Run": # FIXME problème sur l'icone pause terrain_run () if obj.name=="Stop": terrain_stop () @@ -645,28 +635,6 @@ def manip(cont): delta_x=cont.sensors['DownM'].position[0]-obj['click_x'] delta_y=cont.sensors['DownM'].position[1]-obj['click_y'] - # Orbit (1280 * 720 px) Pas de Orbit ici - # if obj['manip_mode']==0: - # scene.objects['Orbit'].color=color_cmd - # scene.objects['Orbit'].setVisible(True,False) - # dist_orbit = math.sqrt(((1280/2)-obj['click_x'])**2+((720/2)-obj['click_y'])**2) - # if dist_orbit<235 : # Orbit sur x et z - # n=10 - # pas_x=(delta_x*40*sensibilite_orbit)/n - # pas_y=(((1280/2)-cont.sensors['DownM'].position[0])+((720/2)-cont.sensors['DownM'].position[1]))*0.005 - # pas_z=(delta_y*40*sensibilite_orbit)/n - # for i in range (n): - # bge.render.drawLine([scene.objects['Orbit'].worldPosition.x+pas_x*i, scene.objects['Orbit'].worldPosition.y+abs(pas_y*math.sin((3.14*i)/n)), scene.objects['Orbit'].worldPosition.z-pas_z*i], - # [scene.objects['Orbit'].worldPosition.x+pas_x*(i+1), scene.objects['Orbit'].worldPosition.y+abs(pas_y*math.sin((3.14*(i+1))/n)), scene.objects['Orbit'].worldPosition.z-pas_z*(i+1)], - # [0.8, 0.619, 0.021]) - # scene.objects['Terrain'].applyRotation((delta_y*sensibilite_orbit, 0, delta_x*sensibilite_orbit), True) - # else: # Orbit sur y - # scene.objects['Orbit'].color=color_cmd_hl - # if abs(delta_x) >= abs(delta_y): - # scene.objects['Terrain'].applyRotation((0, delta_x*sensibilite_orbit, 0), True) - # else: - # scene.objects['Terrain'].applyRotation((0, delta_y*sensibilite_orbit, 0), True) - # Pan if obj['manip_mode']==1: # Shift scene.objects['Camera'].applyMovement((delta_x*-sensibilite_pan, delta_y*sensibilite_pan, 0), True) diff --git a/ct_cmd.py b/ct_cmd.py index dc06d8c..8f31c04 100644 --- a/ct_cmd.py +++ b/ct_cmd.py @@ -9,8 +9,8 @@ from ct_lib import * # Bibliothèque CodeTower # @authors: Philippe Roy # @copyright: Copyright (C) 2022 Philippe Roy # @license: GNU GPL -# -# En: This game is a tower defense coding game. The towers are driven with Python code. +# +# En: This game is a tower defense coding game. The towers are driven by Python code. # Fr: Ce simulateur est un jeu du type tower defense où les tours sont à piloter par la programmation Python. # ############################################################################### @@ -79,11 +79,11 @@ def commands(): if ct_level()==1: ct_build(4,5, "Archer tower", "Tower #1", blue, "square-A") - if ct_level()==2: + if ct_level()==1: ct_build(4,-2, "Archer tower", "Tower #2", blue, "square-A") if ct_level()==3: - ct_build(5,6, "Mage tower", "Tower #3", yellow, "round-A") + ct_build(5,5, "Mage tower", "Tower #3", magenta, "square-B") end() # End of cycle << DONT CHANGE THIS LINE >> diff --git a/ct_comp.py b/ct_comp.py index e49f396..38c8203 100644 --- a/ct_comp.py +++ b/ct_comp.py @@ -10,8 +10,8 @@ from collections import OrderedDict # @copyright: Copyright (C) 2022 Philippe Roy # @license: GNU GPL # +# This game is a tower defense coding game. The towers are driven by Python code. # Ce simulateur est un jeu du type tower defense où les tours sont à piloter par la programmation Python. -# This game is a tower defense coding game. The towers are driven with Python code. # ############################################################################### diff --git a/ct_lib.py b/ct_lib.py index 24794d2..e624e4d 100644 --- a/ct_lib.py +++ b/ct_lib.py @@ -17,8 +17,8 @@ import random # @copyright: Copyright (C) 2022 Philippe Roy # @license: GNU GPL # +# This game is a tower defense coding game. The towers are driven by Python code. # Ce simulateur est un jeu du type tower defense où les tours sont à piloter par la programmation Python. -# This game is a tower defense coding game. The towers are driven with Python code. # # Commands trigged by button : cmd_* # Commands trigged by 3D scene objects : scn_* @@ -133,7 +133,6 @@ def thread_stop(threads, type_txt): print ("There are zombies threads",type_txt, ".") return False - ############################################################################### # Vagues (minions) ############################################################################### @@ -176,7 +175,7 @@ def ct_minion_details(x,y,cat,level,body="Knight_m_A_common"): minion['bounty']=minion_carac[category][5] minion['lifes_damage']=minion_carac[category][6] minion['buff']=[] - minion['debuff']=[] + minion['resist']=[] # Actuator Steering minion.actuators['Steering'].navmesh=scene.objects[scene.objects['Terrain']['navmesh']] @@ -184,16 +183,6 @@ def ct_minion_details(x,y,cat,level,body="Knight_m_A_common"): minion.actuators['Steering'].distance=0.5 minion.actuators['Steering'].velocity=minion['speed_base']*scene.objects['Terrain']['speed'] -def scn_minion_lost(cont): - obj = cont.owner - print (obj.name, obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z) - # for obj_i in scene.objects: - # if "type_minion" in obj_i.getPropertyNames() and "type_towerminion" not in obj_i.getPropertyNames(): - # if obj_i.worldPosition.y>11: - # obj_i.endObject() - # # print (obj_i.name, obj_i.worldPosition.x, obj_i.worldPosition.y, obj_i.worldPosition.z) - - # Destruction d'un minion def scn_minion_dead(cont): obj = cont.owner @@ -203,6 +192,31 @@ def scn_minion_dead(cont): scene.objects['Points']['coins']= scene.objects['Points']['coins']+obj['bounty'] obj.endObject() +############################################################################### +# Spells +############################################################################### + +# Buff/debuff Minion +def scn_minion_affect(cont): + obj = cont.owner + # print (obj.name, obj['buff']) + slow_state=False + + # 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'])/2 + else: + obj.actuators['Steering'].velocity = obj['speed_base']*scene.objects['Terrain']['speed'] + ############################################################################### # Tours ############################################################################### @@ -261,20 +275,12 @@ def ct_build_details(x,y, cat='Archer tower', tower_name="Tower", color=tower_pu tour['speed']=tower_carac[cat][2] tour['range']=tower_carac[cat][3] tour['techno']=[] - tour['cast']="" - - # Gestion du draw - tour['fire_frame']=0 - tour['fire_target']=[] + tour['cast']="slow" + tour['cast_duration']=2 # Capteur Near tour.sensors['Near'].distance=tour['range'] tour.sensors['Near'].skippedTicks =round(1/(tour['speed']*scene.objects['Terrain']['speed'])) - - # for obj_i in scene.objects: - # if "type_tower" in obj_i.getPropertyNames(): - # print (obj_i['tower_name']) - # print (tour.getPropertyNames()) return True # Suppression d'une tour @@ -350,13 +356,10 @@ def scn_tower_near(cont): if target['hp']<=0: target['dead']=True - # Buf + # Cast (buff and debuff) if obj['cat']=="Mage tower": - i =0 for target_i in sensor.hitObjectList: - if target_i.actuators['Steering'].velocity== target['speed_base']*scene.objects['Terrain']['speed']: - target_i.actuators['Steering'].velocity /= 2 - i+=1 + target_i['buff'].append([obj['cast'], obj['cast_duration']]) ############################################################################### # Carte @@ -464,16 +467,6 @@ def circle (center, radius, color): bge.render.drawLine([x0,y0,center[2]],[x1,y1,center[2]],color) ang += ang_step -# Fire : projectile ou cast -# def scn_tower_fire(cont): -# obj = cont.owner -# if obj["fire_frame"]!=0: -# if obj['cat']=="Archer tower": # Archer (tir de flêche) -# bge.render.drawLine([obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8],obj['fire_target'][0], ray_yellow) -# if obj['cat']=="Mage tower": # Mage (cast) -# circle([obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8], 3, ray_blue) -# obj["fire_frame"] -=1 - # Affiche les draws en cours # FIXME: tir sur le plus avancé # diff --git a/ct_map1.py b/ct_map1.py index e83d046..103b695 100644 --- a/ct_map1.py +++ b/ct_map1.py @@ -9,10 +9,9 @@ from ct_lib import * # Bibliothèque CodeTower # @authors: Philippe Roy # @copyright: Copyright (C) 2022 Philippe Roy # @license: GNU GPL -# -# This game is a tower defense coding game. The towers are driven with Python code. # -# The file is the the map and waves definition +# This game is a tower defense coding game. The towers are driven by Python code. +# The file is the the map and waves definition. # ###############################################################################