gestion des casts (buff et debuff)

This commit is contained in:
Philippe Roy 2022-04-01 01:34:54 +02:00
parent 974b3abc21
commit 52e91a553b
7 changed files with 48 additions and 88 deletions

View File

@ -5,11 +5,11 @@
* if * if
* Manipulation de liste * Manipulation de liste
* Manipulation de dictionnaire * 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 ### Principes
* Une tour ou une techno coûte un niveau général (100 crédits, voire de plus en plus chère) * 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 ### Stratégies en place
* Créer une tour : wave 1 * Créer une tour : wave 1

BIN
codetower-18.blend Normal file

Binary file not shown.

48
ct.py
View File

@ -13,14 +13,14 @@ import xml.etree.ElementTree as ET # Creating/parsing XML file
############################################################################### ###############################################################################
# ct.py # ct.py
# @title: the CodeTower game # @title: the CodeTower game
# @project: Blender-EduTech # @project: CodeTower
# @lang: fr,en # @lang: fr,en
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr> # @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy # @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL # @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. # 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 button : cmd_*
# Commands trigged by 3D scene objects : scn_* # 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 # Dynamic import user file
sys.setrecursionlimit(10**5) # Limite sur la récursivité (valeur par défaut : 1000) -> segfault de Blender sys.setrecursionlimit(10**5) # Limite sur la récursivité (valeur par défaut : 1000) -> segfault de Blender
importlib.invalidate_caches() 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) ct_cmd = importlib.import_module('ct_cmd') # user script (commands)
# UPBGE scene # UPBGE scene
@ -133,14 +133,14 @@ def points_maj (cont):
scene.objects['Points']['tics'] +=1 scene.objects['Points']['tics'] +=1
# Augmentation d'un niveau # 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']['level_max'] +=1
scene.objects['Points']['coins'] -=100 scene.objects['Points']['coins'] -=100
# Level trop élevé # Level trop élevé
if 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_red 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 scene.objects['Level_text'].color = color_text
# Ramasse minions perdues # 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)) 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 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 # Fin de la vague
if scene.objects['Terrain']['thread_wave']==False and scene.objects['Terrain']['map_run'] == True : if scene.objects['Terrain']['thread_wave']==False and scene.objects['Terrain']['map_run'] == True :
if scene.objects['Points']['minions_run']==0 : if scene.objects['Points']['minions_run']==0 :
@ -292,7 +282,7 @@ def terrain_run ():
scene.objects['Points']['time_begin']=time.localtime() scene.objects['Points']['time_begin']=time.localtime()
if scene.objects['Terrain']['debug_flag']==False: # Lecture dynamique du script python (risque de Segfault de Blender) if scene.objects['Terrain']['debug_flag']==False: # Lecture dynamique du script python (risque de Segfault de Blender)
importlib.reload(ct_cmd) importlib.reload(ct_cmd)
importlib.reload(ct_map) # importlib.reload(ct_map)
ct_cmd.start() # Execution du script utilisateur ct_cmd.start() # Execution du script utilisateur
ct_map.start(1) # Lancement du script de la permière vague ct_map.start(1) # Lancement du script de la permière vague
@ -508,7 +498,7 @@ def cmd_hl(cont):
def cmd_click (cont): def cmd_click (cont):
obj = cont.owner obj = cont.owner
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and scene.objects['Terrain']['manip_mode']==0: 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 () terrain_run ()
if obj.name=="Stop": if obj.name=="Stop":
terrain_stop () terrain_stop ()
@ -645,28 +635,6 @@ def manip(cont):
delta_x=cont.sensors['DownM'].position[0]-obj['click_x'] delta_x=cont.sensors['DownM'].position[0]-obj['click_x']
delta_y=cont.sensors['DownM'].position[1]-obj['click_y'] 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 # Pan
if obj['manip_mode']==1: # Shift if obj['manip_mode']==1: # Shift
scene.objects['Camera'].applyMovement((delta_x*-sensibilite_pan, delta_y*sensibilite_pan, 0), True) scene.objects['Camera'].applyMovement((delta_x*-sensibilite_pan, delta_y*sensibilite_pan, 0), True)

View File

@ -9,8 +9,8 @@ from ct_lib import * # Bibliothèque CodeTower
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr> # @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy # @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL # @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. # 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: if ct_level()==1:
ct_build(4,5, "Archer tower", "Tower #1", blue, "square-A") 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") ct_build(4,-2, "Archer tower", "Tower #2", blue, "square-A")
if ct_level()==3: 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 >> end() # End of cycle << DONT CHANGE THIS LINE >>

View File

@ -10,8 +10,8 @@ from collections import OrderedDict
# @copyright: Copyright (C) 2022 Philippe Roy # @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL # @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. # 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.
# #
############################################################################### ###############################################################################

View File

@ -17,8 +17,8 @@ import random
# @copyright: Copyright (C) 2022 Philippe Roy # @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL # @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. # 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 button : cmd_*
# Commands trigged by 3D scene objects : scn_* # Commands trigged by 3D scene objects : scn_*
@ -133,7 +133,6 @@ def thread_stop(threads, type_txt):
print ("There are zombies threads",type_txt, ".") print ("There are zombies threads",type_txt, ".")
return False return False
############################################################################### ###############################################################################
# Vagues (minions) # 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['bounty']=minion_carac[category][5]
minion['lifes_damage']=minion_carac[category][6] minion['lifes_damage']=minion_carac[category][6]
minion['buff']=[] minion['buff']=[]
minion['debuff']=[] minion['resist']=[]
# Actuator Steering # Actuator Steering
minion.actuators['Steering'].navmesh=scene.objects[scene.objects['Terrain']['navmesh']] 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'].distance=0.5
minion.actuators['Steering'].velocity=minion['speed_base']*scene.objects['Terrain']['speed'] 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 # Destruction d'un minion
def scn_minion_dead(cont): def scn_minion_dead(cont):
obj = cont.owner obj = cont.owner
@ -203,6 +192,31 @@ def scn_minion_dead(cont):
scene.objects['Points']['coins']= scene.objects['Points']['coins']+obj['bounty'] scene.objects['Points']['coins']= scene.objects['Points']['coins']+obj['bounty']
obj.endObject() 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 # 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['speed']=tower_carac[cat][2]
tour['range']=tower_carac[cat][3] tour['range']=tower_carac[cat][3]
tour['techno']=[] tour['techno']=[]
tour['cast']="" tour['cast']="slow"
tour['cast_duration']=2
# Gestion du draw
tour['fire_frame']=0
tour['fire_target']=[]
# Capteur Near # Capteur Near
tour.sensors['Near'].distance=tour['range'] tour.sensors['Near'].distance=tour['range']
tour.sensors['Near'].skippedTicks =round(1/(tour['speed']*scene.objects['Terrain']['speed'])) 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 return True
# Suppression d'une tour # Suppression d'une tour
@ -350,13 +356,10 @@ def scn_tower_near(cont):
if target['hp']<=0: if target['hp']<=0:
target['dead']=True target['dead']=True
# Buf # Cast (buff and debuff)
if obj['cat']=="Mage tower": if obj['cat']=="Mage tower":
i =0
for target_i in sensor.hitObjectList: for target_i in sensor.hitObjectList:
if target_i.actuators['Steering'].velocity== target['speed_base']*scene.objects['Terrain']['speed']: target_i['buff'].append([obj['cast'], obj['cast_duration']])
target_i.actuators['Steering'].velocity /= 2
i+=1
############################################################################### ###############################################################################
# Carte # Carte
@ -464,16 +467,6 @@ def circle (center, radius, color):
bge.render.drawLine([x0,y0,center[2]],[x1,y1,center[2]],color) bge.render.drawLine([x0,y0,center[2]],[x1,y1,center[2]],color)
ang += ang_step 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 # Affiche les draws en cours
# FIXME: tir sur le plus avancé # FIXME: tir sur le plus avancé
# #

View File

@ -9,10 +9,9 @@ from ct_lib import * # Bibliothèque CodeTower
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr> # @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy # @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL # @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.
# #
############################################################################### ###############################################################################