mirror of
https://forge.apps.education.fr/phroy/codetower.git
synced 2024-01-27 11:35:17 +01:00
refonte de la gestion des vagues
This commit is contained in:
parent
51b423a0cb
commit
345a32a70d
45
IDEAS.md
Normal file
45
IDEAS.md
Normal file
@ -0,0 +1,45 @@
|
||||
# CodeTower Ideas
|
||||
|
||||
### Stratégies pédagogique
|
||||
* while True
|
||||
* if
|
||||
* Manipulation de liste
|
||||
* Manipulation de dictionnaire
|
||||
* Création d'objet (méthode et propriété) - 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
|
||||
|
||||
### Stratégies en place
|
||||
* Créer une tour : wave 1
|
||||
* Créer une tour pendant un tour car la cadence des minions plus grande : wave 2
|
||||
|
||||
### Idées générales
|
||||
* Perte de level, ou redéfinir stratégie -> détruire des tours
|
||||
* Minion qui attaque les tours ou désactive les tours (bruillard de guerre)
|
||||
* Boss -> lent mais costaud
|
||||
* Healer -> ciblage
|
||||
* Régénération des squelettes -> ciblage sur squelette nécromencien
|
||||
* Barracks
|
||||
|
||||
### Idées pour les tours d'archer
|
||||
* Minion avec armure -> augmenter le niveau d'une tour
|
||||
* Changer la stratégie de la tour -> le plus fort, le plus en avance
|
||||
* Minion insensible au feu au froid -> changer de type de projectile (feu, froid,acide,electricité)
|
||||
* Détection sur la tour -> niveau, type de minion et ciblage
|
||||
* Minion qui se régénère -> feu ou acide
|
||||
* Evaluer le niveau d'une tour (cadence, distance et dégats) -> rédéfinir les paramètres en gardant le même niveau
|
||||
* Passer mode tir multiple -> moins de dégats mais plus massif
|
||||
* Tir handicapant (vitesse ou attaque)
|
||||
|
||||
### Idées pour les tours de mage
|
||||
* Minion trop rapide -> réduire la vitesse des minions tour de magie
|
||||
* Minion invisible -> change le cast en détection et marquage
|
||||
* Bruillard de guerre -> cas de dissipation
|
||||
* Tour de magie en support -> augmente la cadence et la distance sur une tour précise et proche
|
||||
* Cast d'aveuglement -> modification du steering
|
||||
* Cast d'allongement des effets sur une tour de magie précise et proche
|
||||
|
||||
* Perte de level, ou redéfinir stratégie -> détruire des tours
|
||||
|
BIN
codetower-15.blend
Normal file
BIN
codetower-15.blend
Normal file
Binary file not shown.
78
ct.py
78
ct.py
@ -10,8 +10,6 @@ import webbrowser
|
||||
import threading # Multithreading
|
||||
import xml.etree.ElementTree as ET # Creating/parsing XML file
|
||||
|
||||
import ct_map
|
||||
|
||||
###############################################################################
|
||||
# ct.py
|
||||
# @title: the CodeTower game
|
||||
@ -23,13 +21,18 @@ import ct_map
|
||||
#
|
||||
# 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_*
|
||||
# Commands trigged by user (student or map designer) : ct_*
|
||||
# 3D scene manipulation : manip_*
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# 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_map = importlib.import_module('ct_map1') # waves script
|
||||
ct_cmd = importlib.import_module('ct_cmd') # user script (commands)
|
||||
|
||||
# UPBGE scene
|
||||
@ -48,6 +51,8 @@ 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_kaykit_black = [0.019, 0.032, 0.037, 1]
|
||||
|
||||
color_endbanner_bluelight = [0.361, 0.527, 0.716, 1]
|
||||
color_endbanner_bluedark = [0.130, 0.254, 0.407, 1]
|
||||
|
||||
@ -127,30 +132,41 @@ def points_maj (cont):
|
||||
scene.objects['Minions_text']['Text']=str(scene.objects['Points']['minions'])
|
||||
scene.objects['Points']['tics'] +=1
|
||||
|
||||
# Augmentation d'un niveau
|
||||
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']:
|
||||
scene.objects['Level_text'].color = color_text
|
||||
|
||||
# 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['Points']['minions_run']==0 :
|
||||
terrain_end ()
|
||||
|
||||
# Vague suivante
|
||||
if scene.objects['Points']['wave'] < scene.objects['Terrain']['nb_waves']:
|
||||
scene.objects['Points']['wave'] +=1
|
||||
ct_map.start(scene.objects['Points']['wave']) # Lancement du script de la vague
|
||||
else: # Fin de la map
|
||||
terrain_end ()
|
||||
|
||||
###############################################################################
|
||||
# Terrain
|
||||
###############################################################################
|
||||
|
||||
# Mouse over du terrain
|
||||
def scn_terrain_mo(cont):
|
||||
def scn_terrain_mo (cont):
|
||||
|
||||
# Affiche la position de la tour de construction
|
||||
if scene.objects['Terrain']['construct_mode']==True:
|
||||
hitObject = cont.sensors['MO'].hitObject
|
||||
hitPosition = cont.sensors['MO'].hitPosition
|
||||
if hitObject is not None :
|
||||
if round(hitPosition.x) >= scene.objects['Terrain']['taille'][0] and round(hitPosition.x) <= scene.objects['Terrain']['taille'][1] and round(hitPosition.y) >= scene.objects['Terrain']['taille'][2] and round(hitPosition.y) <= scene.objects['Terrain']['taille'][3] :
|
||||
if round(hitPosition.x) >= scene.objects['Terrain']['size'][0] and round(hitPosition.x) <= scene.objects['Terrain']['size'][1] and round(hitPosition.y) >= scene.objects['Terrain']['size'][2] and round(hitPosition.y) <= scene.objects['Terrain']['size'][3] :
|
||||
if [round(hitPosition.x),round(hitPosition.y)] in scene.objects['Terrain']['scene_tile_noncontruct'] or [round(hitPosition.x),round(hitPosition.y)] in scene.objects['Terrain']['scene_tile_tower']:
|
||||
pass
|
||||
else:
|
||||
@ -186,7 +202,7 @@ def terrain_init (cont):
|
||||
scene.objects['Terrain']['draw_list']=[]
|
||||
|
||||
# Configuration du moteur de rendu
|
||||
if scene.objects['Terrain']['speed']<4:
|
||||
if scene.objects['Terrain']['speed']<10:
|
||||
eevee.use_eevee_smaa = True
|
||||
else:
|
||||
eevee.use_eevee_smaa = False
|
||||
@ -204,10 +220,10 @@ def terrain_init (cont):
|
||||
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
|
||||
# Init de la carte
|
||||
ct_map.map_init()
|
||||
ct_map.map_reset()
|
||||
scene.objects['Level_text'].color = color_text
|
||||
|
||||
# Mise en route et pause du cycle
|
||||
def terrain_run ():
|
||||
@ -235,7 +251,7 @@ def terrain_run ():
|
||||
scene.objects['Stop'].setVisible(True,False)
|
||||
|
||||
# Mise à zéro des compteurs
|
||||
ct_map.map1_reset()
|
||||
ct_map.map_reset()
|
||||
|
||||
# Supprimer les tours
|
||||
for obj_i in scene.objects:
|
||||
@ -249,10 +265,11 @@ def terrain_run ():
|
||||
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)
|
||||
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)
|
||||
ct_cmd.start() # Execution du script utilisateur
|
||||
ct_wv.start() # Lancement du script des vagues
|
||||
ct_map.start(1) # Lancement du script de la permière vague
|
||||
|
||||
# Arrêt de la pause
|
||||
else:
|
||||
@ -269,7 +286,7 @@ def terrain_stop ():
|
||||
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
|
||||
ct_map.stop() # Stop du script des vagues
|
||||
|
||||
# Supprimer les enemis
|
||||
for obj_i in scene.objects:
|
||||
@ -285,7 +302,7 @@ def terrain_stop ():
|
||||
scene.objects['Stop'].setVisible(False,False)
|
||||
scene.objects['Stop-Hl'].setVisible(False,False)
|
||||
|
||||
# Fin naturelle du cycle
|
||||
# Fin de la map
|
||||
def terrain_end ():
|
||||
scene.objects['Terrain']['run']=False
|
||||
scene.objects['Terrain']['thread_run']=False
|
||||
@ -300,6 +317,9 @@ def terrain_end ():
|
||||
# Affichage des résultats
|
||||
if scene.objects['End']['timer']== 0:
|
||||
scene.objects['Terrain']['manip_mode']=9 # Fenêtre modale
|
||||
scene.objects['Camera'].worldPosition.x = scene.objects['Camera']['init_lx']
|
||||
scene.objects['Camera'].worldPosition.y = scene.objects['Camera']['init_ly']
|
||||
scene.objects['Camera'].worldPosition.z = scene.objects['Camera']['init_lz']
|
||||
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:
|
||||
@ -481,6 +501,8 @@ def cmd_click (cont):
|
||||
# 9 : Fenêtre modale
|
||||
|
||||
def mode(cont):
|
||||
if scene.objects['Terrain']['manip_mode']==9: # Fenêtre modale
|
||||
return
|
||||
obj = cont.owner
|
||||
keyboard = bge.logic.keyboard
|
||||
|
||||
@ -579,9 +601,10 @@ def manip_reset(cont):
|
||||
|
||||
# Position de départ pour la manipulation de la vue
|
||||
def manip_start(cont):
|
||||
obj = cont.owner
|
||||
obj['click_x']=cont.sensors['ClickM'].position[0]
|
||||
obj['click_y']=cont.sensors['ClickM'].position[1]
|
||||
if scene.objects['Terrain']['manip_mode']!=9:
|
||||
obj = cont.owner
|
||||
obj['click_x']=cont.sensors['ClickM'].position[0]
|
||||
obj['click_y']=cont.sensors['ClickM'].position[1]
|
||||
|
||||
# Cacher le cercle de la manipulation Orbit
|
||||
def manip_stop(cont):
|
||||
@ -629,12 +652,13 @@ def manip(cont):
|
||||
|
||||
# Manipulation du modèle ou de la caméra
|
||||
def manip_wheel(cont):
|
||||
obj = cont.owner
|
||||
sensibilite_wheel = 5 # Base : 20
|
||||
if cont.sensors['WheelUp'].positive:
|
||||
scene.objects['Camera'].applyMovement((0, 0, -sensibilite_wheel), True)
|
||||
if cont.sensors['WheelDown'].positive:
|
||||
scene.objects['Camera'].applyMovement((0, 0, sensibilite_wheel), True)
|
||||
if scene.objects['Terrain']['manip_mode']!=9: # Fenêtre modale
|
||||
obj = cont.owner
|
||||
sensibilite_wheel = 5 # Base : 20
|
||||
if cont.sensors['WheelUp'].positive:
|
||||
scene.objects['Camera'].applyMovement((0, 0, -sensibilite_wheel), True)
|
||||
if cont.sensors['WheelDown'].positive:
|
||||
scene.objects['Camera'].applyMovement((0, 0, sensibilite_wheel), True)
|
||||
|
||||
###############################################################################
|
||||
# Aide
|
||||
|
33
ct_cmd.py
33
ct_cmd.py
@ -37,9 +37,12 @@ def start():
|
||||
thread_start(threads, "commands", commands)
|
||||
|
||||
def stop():
|
||||
if thread_stop(threads, "commands"):
|
||||
if len(threads)==1:
|
||||
threads.pop()
|
||||
thread_stop(threads, "commands")
|
||||
|
||||
def end():
|
||||
ct_sleep (2)
|
||||
print ("Threads commands #", len(threads)-1, "are arrived -> close them.")
|
||||
scene.objects['Terrain']['thread_cmd']=False
|
||||
|
||||
###############################################################################
|
||||
# En: Tower commands
|
||||
@ -71,20 +74,16 @@ 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, "Mage tower", "Tower #1", yellow, "square-A")
|
||||
# ct_build(5,5)
|
||||
# ct_build(5,4, "Tower #3")
|
||||
# ct_build(4,4, "Tower #4", [0.3, 0.5, 0.5, 1])
|
||||
# ct_build(4,5, "Tower #5")
|
||||
while True:
|
||||
|
||||
# ct_tempo(20)
|
||||
if ct_level()==1:
|
||||
ct_build(4,5, "Archer tower", "Tower #1", blue, "square-A")
|
||||
|
||||
# ct_remove(4,4)
|
||||
# ct_print("ok")
|
||||
if ct_level()==2:
|
||||
ct_build(4,-2, "Archer tower", "Tower #2", blue, "square-A")
|
||||
|
||||
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 >>
|
||||
if ct_level()==3:
|
||||
ct_build(5,6, "Mage tower", "Tower #3", yellow, "square-A")
|
||||
|
||||
|
||||
end() # End of cycle << DONT CHANGE THIS LINE >>
|
||||
|
83
ct_lib.py
83
ct_lib.py
@ -20,8 +20,10 @@ import random
|
||||
# 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.
|
||||
#
|
||||
# Commandes déclenchées par les joueurs : ct_*
|
||||
# Commandes déclenchées par la scene 3D : scn_*
|
||||
# Commands trigged by button : cmd_*
|
||||
# Commands trigged by 3D scene objects : scn_*
|
||||
# Commands trigged by user (student or map designer) : ct_*
|
||||
# 3D scene manipulation : manip_*
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
@ -35,10 +37,14 @@ tower_orange = [0.799, 0.130, 0.063,1]
|
||||
tower_yellow = [0.799, 0.617, 0.021, 1]
|
||||
tower_green = [0.246, 0.687, 0.078, 1]
|
||||
tower_red = [0.799, 0.031, 0.038, 1]
|
||||
tower_blue = [0.127, 0.456, 1.000, 1]
|
||||
tower_blue = [0.127, 0.456, 1.000, 1]
|
||||
tower_black = [0, 0, 0, 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()
|
||||
@ -51,8 +57,15 @@ 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()
|
||||
###############################################################################
|
||||
# Données générales
|
||||
###############################################################################
|
||||
|
||||
def ct_level_current():
|
||||
return scene.objects['Points']['level']
|
||||
|
||||
def ct_level():
|
||||
return scene.objects['Points']['level_max']
|
||||
|
||||
###############################################################################
|
||||
# Méthode kill pour les tâches (threads)
|
||||
@ -126,28 +139,12 @@ def thread_stop(threads, type_txt):
|
||||
###############################################################################
|
||||
|
||||
# Minion caracteristics : category (class), level, hp, speed, armor, bounty, lifes_damage
|
||||
|
||||
minion_carac={
|
||||
'Knight-lv1' : ["Knight", 1 , 2.0, 1.0, 0.0, 5,1],
|
||||
'Knight-lv2' : ["Knight", 2, 4.0, 1.0, 1.0, 20,1],
|
||||
'Knight-lv3' : ["Knight", 3, 8.0, 1.0, 2.0, 80,1],
|
||||
'Orc-lv1' : ["Orc", 1 , 2.0, 1.0, 0.0, 5,1],
|
||||
'Orc-lv2' : ["Orc", 2, 4.0, 1.0, 1.0, 20,1],
|
||||
'Orc-lv3' : ["Orc", 3, 8.0, 1.0, 2.0, 80,1]}
|
||||
|
||||
# Minion 3d object : body (male,female,old, ...), variante (A,B,C,D, ...), level
|
||||
|
||||
minion_3d={
|
||||
'Knight-lv1' : [['Knight_m', 'Knight_f', 'OldKnight_m'],['A','B','C','D'],['common']],
|
||||
'Knight-lv2' : [['Knight_m', 'Knight_f', 'OldKnight_m'],['A','B','C','D'],['uncommon']],
|
||||
'Knight-lv3' : [['Knight_m', 'Knight_f', 'OldKnight_m'],['A','B','C','D'],['rare']],
|
||||
'Orc-lv1' : [['Orc'],['A','B','C','D','E','F'],['common']],
|
||||
'Orc-lv2' : [['Orc'],['A','B','C','D','E','F'],['uncommon']],
|
||||
'Orc-lv3' : [['Orc'],['A','B','C','D','E','F'],['rare']]}
|
||||
|
||||
# Création d'un minion
|
||||
def ct_minion(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])
|
||||
ct_minion_details(x,y,cat,level,body)
|
||||
|
||||
@ -165,13 +162,11 @@ def ct_minion_details(x,y,cat,level,body="Knight_m_A_common"):
|
||||
minion.worldPosition=[x,y,0.1]
|
||||
scene.objects['Terrain']['idm']=scene.objects['Terrain']['idm']+1
|
||||
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'] +=1
|
||||
scene.objects['Points']['minions_run'] +=1
|
||||
# print(bge.render.getVsync)
|
||||
|
||||
# Caracteristics
|
||||
minion_carac= scene.objects['Terrain']['minion_carac']
|
||||
minion.components['Minion'].args['cat']=minion_carac[category][0]
|
||||
minion.components['Minion'].args['level']=minion_carac[category][1]
|
||||
minion.components['Minion'].args['hp']=minion_carac[category][2]
|
||||
@ -186,7 +181,6 @@ def ct_minion_details(x,y,cat,level,body="Knight_m_A_common"):
|
||||
minion.actuators['Steering'].target=scene.objects[scene.objects['Terrain']['endtile']]
|
||||
minion.actuators['Steering'].distance=0.5
|
||||
minion.actuators['Steering'].velocity=minion.components['Minion'].args['speed']*scene.objects['Terrain']['speed']
|
||||
# print (minion.getPropertyNames())
|
||||
|
||||
# Destruction d'un minion
|
||||
def scn_minion_dead(cont):
|
||||
@ -203,21 +197,9 @@ def scn_minion_dead(cont):
|
||||
|
||||
# Tower caracteristics : category (class), damage, speed, range
|
||||
|
||||
tower_carac={
|
||||
'Archer tower' : ["Archer tower", 1.0 , 0.02, 2.5],
|
||||
'Mage tower' : ["Mage tower", 1.0 , 0.005, 2.5],
|
||||
'Barrack' : ["Barrack", 1.0 , 0.0001, 2.5]}
|
||||
|
||||
tower_minion_3d={
|
||||
'Archer-lv1' : [['Archer_m', 'Archer_f', "OldArcher_m"],['A','B','C','D'],['common']],
|
||||
'Archer-lv2' : [['Archer_m', 'Archer_f', "OldArcher_m"],['A','B','C','D'],['uncommon']],
|
||||
'Archer-lv3' : [['Archer_m', 'Archer_f', "OldArcher_m"],['A','B','C','D'],['rare']],
|
||||
'Mage-lv1' : [['Mage'],['A','B','C','D'],['common']],
|
||||
'Mage-lv2' : [['Mage'],['A','B','C','D'],['uncommon']],
|
||||
'Mage-lv3' : [['Mage'],['A','B','C','D'],['rare']]}
|
||||
|
||||
# Création d'une tour
|
||||
def ct_build(x,y, cat='Archer tower', tower_name="Tower", color=tower_purple, tower_3d="square-A"):
|
||||
tower_minion_3d= scene.objects['Terrain']['tower_minion_3d']
|
||||
if cat=='Archer tower': # Archer
|
||||
category="Archer-lv1"
|
||||
if cat=='Mage tower': # Mage
|
||||
@ -255,9 +237,9 @@ def ct_build_details(x,y, cat='Archer tower', tower_name="Tower", color=tower_pu
|
||||
|
||||
# Sounds
|
||||
audiodev.play(sndbuff_build)
|
||||
# sndhdl_build.stop()
|
||||
|
||||
# Caractéristiques (composant python et propriétés de l'objet 3D)
|
||||
# Caracteristics
|
||||
tower_carac= scene.objects['Terrain']['tower_carac']
|
||||
tour.components['Tower'].args['cat']=tower_carac[cat][0]
|
||||
tour.components['Tower'].args['lvl']=1
|
||||
tour.components['Tower'].args['tower_name']=tower_name
|
||||
@ -303,7 +285,6 @@ def scn_tower_near(cont):
|
||||
# FIXME: tir sur le plus avancé
|
||||
if sensor.positive and len(sensor.hitObjectList)>0 and scene.objects['Terrain']['run']==True :
|
||||
target=sensor.hitObjectList[0]
|
||||
# target.actuators['Steering'].velocity=(target.components['Minion'].args['speed']*scene.objects['Terrain']['speed'])/2 # Reduction de la vitesse du minion
|
||||
|
||||
# Orientation du tower minion
|
||||
towerminion="tm("+str(round(obj.worldPosition.x))+','+str(round(obj.worldPosition.y))+")"
|
||||
@ -329,13 +310,13 @@ def scn_tower_near(cont):
|
||||
|
||||
# Ligne (drawLine) (vitesse rapide)
|
||||
# if scene.objects['Terrain']['speed']>=1:
|
||||
if scene.objects['Terrain']['speed']<10: # Pas d'animation à 10 -> plantage
|
||||
if scene.objects['Terrain']['speed']<11: # Pas d'animation à 10 -> plantage
|
||||
|
||||
# Archer (tir de flêche)
|
||||
if obj['cat']=="Archer tower":
|
||||
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])
|
||||
scene.objects['Terrain']['draw_list'].append([5, "arrow", [obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.8],target.name, angle3, ray_black, 5])
|
||||
audiodev.play(sndbuff_archer)
|
||||
|
||||
# Cast zone
|
||||
@ -351,11 +332,20 @@ def scn_tower_near(cont):
|
||||
scene.objects['Terrain']['draw_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
|
||||
# FIXME : cast -> buff
|
||||
target['hp'] = target['hp'] - obj.components['Tower'].args['damage']
|
||||
if target['hp']<=0:
|
||||
target['dead']=True
|
||||
|
||||
# Buf
|
||||
if obj['cat']=="Mage tower":
|
||||
print (sensor.hitObjectList)
|
||||
i =0
|
||||
for target_i in sensor.hitObjectList:
|
||||
if target.actuators['Steering'].velocity== target.components['Minion'].args['speed']*scene.objects['Terrain']['speed']:
|
||||
target.actuators['Steering'].velocity /= 2
|
||||
i+=1
|
||||
print (i)
|
||||
|
||||
###############################################################################
|
||||
# Carte
|
||||
###############################################################################
|
||||
@ -482,7 +472,7 @@ def circle (center, radius, color):
|
||||
#
|
||||
def scn_draw(cont):
|
||||
obj = cont.owner
|
||||
if obj.sensors['Property'].positive==False:
|
||||
if obj.sensors['Draw'].positive==False:
|
||||
return
|
||||
if len(scene.objects['Terrain']['draw_list'])==0:
|
||||
scene.objects['Terrain']['draw_process']=False
|
||||
@ -530,6 +520,7 @@ def scn_draw(cont):
|
||||
# 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])
|
||||
|
49
ct_map.py
49
ct_map.py
@ -1,49 +0,0 @@
|
||||
import bge # Bibliothèque Blender Game Engine (UPBGE)
|
||||
from ct_lib import * # Bibliothèque CodeTower
|
||||
|
||||
###############################################################################
|
||||
# ct_map.py
|
||||
# @title: Map definition
|
||||
# @project: CodeTower
|
||||
# @lang: fr,en
|
||||
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
|
||||
# @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 waves definition
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
scene = bge.logic.getCurrentScene()
|
||||
|
||||
###############################################################################
|
||||
# Carte 1
|
||||
###############################################################################
|
||||
|
||||
# Loading the map
|
||||
def map1_init():
|
||||
|
||||
# Taille de la carte
|
||||
scene.objects['Terrain']['taille'] = [-15,15,-10,10]
|
||||
|
||||
# Navmesh
|
||||
scene.objects['Terrain']['navmesh'] = "Navmesh.004"
|
||||
|
||||
# Ajout des sorties
|
||||
scene.objects['Terrain']['endtile'] = "tile_straight.036"
|
||||
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
|
||||
|
198
ct_map1.py
Normal file
198
ct_map1.py
Normal file
@ -0,0 +1,198 @@
|
||||
import bge # Bibliothèque Blender Game Engine (UPBGE)
|
||||
from ct_lib import * # Bibliothèque CodeTower
|
||||
|
||||
###############################################################################
|
||||
# ct_map1.py
|
||||
# @title: Map #1 definition
|
||||
# @project: CodeTower
|
||||
# @lang: fr,en
|
||||
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
|
||||
# @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
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
scene = bge.logic.getCurrentScene()
|
||||
|
||||
###############################################################################
|
||||
# En: Threads management << DONT CHANGE THIS SECTION >>
|
||||
# Fr: Gestion des tâches (threads) << NE PAS MODIFIER CETTE SECTION >>
|
||||
###############################################################################
|
||||
|
||||
threads=[]
|
||||
|
||||
def start(wave):
|
||||
scene.objects['Terrain']['thread_wave']=True
|
||||
if wave==1:
|
||||
thread_start(threads, "waves", wave1)
|
||||
if wave==2:
|
||||
thread_start(threads, "waves", wave2)
|
||||
if wave==3:
|
||||
thread_start(threads, "waves", wave3)
|
||||
|
||||
|
||||
def stop():
|
||||
thread_stop(threads, "waves")
|
||||
|
||||
def end():
|
||||
ct_sleep (2)
|
||||
print ("Threads waves #", len(threads)-1, "are arrived -> close them.")
|
||||
scene.objects['Terrain']['thread_wave']=False
|
||||
|
||||
###############################################################################
|
||||
# En: Minions definition
|
||||
# Fr: Définition des minions
|
||||
#
|
||||
# Minion caracteristics :
|
||||
# - category, minion class (string) :
|
||||
# - Knight
|
||||
# - Barbarian
|
||||
# - Warrior
|
||||
# - Mage
|
||||
# - Rogue
|
||||
# - Orc
|
||||
# - Squelette
|
||||
# - level : 1, 2 or 3 (integer)
|
||||
# - hp (float)
|
||||
# - speed (float)
|
||||
# - armor (float)
|
||||
# - bounty (integer)
|
||||
# - lifes_damage (integer)
|
||||
#
|
||||
# Minion 3D object :
|
||||
# - body : male,female,old, ... (string)
|
||||
# - variante : A,B,C,D, ... (string)
|
||||
# - level : common, uncommon, rare, ... (string)
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
def minion_definition():
|
||||
|
||||
# Minion caracteristics : category (class), level, hp, speed, armor, bounty, lifes_damage
|
||||
minion_carac={
|
||||
'Knight-lv1' : ["Knight", 1 , 2.0, 1.0, 0.0, 5,1],
|
||||
'Knight-lv2' : ["Knight", 2, 4.0, 1.0, 1.0, 20,1],
|
||||
'Knight-lv3' : ["Knight", 3, 8.0, 1.0, 2.0, 80,1],
|
||||
'Orc-lv1' : ["Orc", 1 , 2.0, 1.0, 0.0, 5,1],
|
||||
'Orc-lv2' : ["Orc", 2, 4.0, 1.0, 1.0, 20,1],
|
||||
'Orc-lv3' : ["Orc", 3, 8.0, 1.0, 2.0, 80,1]}
|
||||
scene.objects['Terrain']['minion_carac'] = minion_carac
|
||||
|
||||
# Minion 3D object : body (male,female,old, ...), variante (A,B,C,D, ...), level
|
||||
minion_3d={
|
||||
'Knight-lv1' : [['Knight_m', 'Knight_f', 'OldKnight_m'],['A','B','C','D'],['common']],
|
||||
'Knight-lv2' : [['Knight_m', 'Knight_f', 'OldKnight_m'],['A','B','C','D'],['uncommon']],
|
||||
'Knight-lv3' : [['Knight_m', 'Knight_f', 'OldKnight_m'],['A','B','C','D'],['rare']],
|
||||
'Orc-lv1' : [['Orc'],['A','B','C','D','E','F'],['common']],
|
||||
'Orc-lv2' : [['Orc'],['A','B','C','D','E','F'],['uncommon']],
|
||||
'Orc-lv3' : [['Orc'],['A','B','C','D','E','F'],['rare']]}
|
||||
scene.objects['Terrain']['minion_3d'] = minion_3d
|
||||
|
||||
###############################################################################
|
||||
# En: Waves commands
|
||||
# Fr: Commandes des vagues
|
||||
#
|
||||
# Spawn a minion : ct_minion (x, y, cat, level)
|
||||
# - x spwan position (integer)
|
||||
# - y spwan position (integer)
|
||||
# - category, minion class (string) :
|
||||
# - Knight
|
||||
# - Barbarian
|
||||
# - Warrior
|
||||
# - Mage
|
||||
# - Rogue
|
||||
# - Orc
|
||||
# - Squelette
|
||||
# - level (1, 2 or 3)
|
||||
|
||||
#
|
||||
# Time management (temporization) : ct_sleep(delay)
|
||||
# - delay : delay in seconds (integer)
|
||||
#
|
||||
# UI management : ct_map_text(text)
|
||||
# - text for the wave label
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# Wave 1
|
||||
def wave1():
|
||||
ct_map_text("Wave 1")
|
||||
for i in range (15):
|
||||
ct_minion(14,3,"Orc",1)
|
||||
ct_sleep (2)
|
||||
end()
|
||||
|
||||
# Wave 2
|
||||
def wave2():
|
||||
ct_map_text("Wave 2")
|
||||
for i in range (20):
|
||||
ct_minion(14,3,"Orc",1)
|
||||
ct_sleep (1)
|
||||
end()
|
||||
|
||||
# Wave 3
|
||||
def wave3():
|
||||
ct_map_text("Wave 3")
|
||||
for i in range (25):
|
||||
ct_minion(14,3,"Knight",1)
|
||||
# ct_minion_details(14,3,"Knight",1, "OldKnight_m_A_common")
|
||||
ct_sleep (1)
|
||||
end()
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Tower definition
|
||||
###############################################################################
|
||||
|
||||
def tower_definition():
|
||||
|
||||
# Tower caracteristics : category (class), damage, speed, range
|
||||
tower_carac={
|
||||
'Archer tower' : ["Archer tower", 1.0 , 0.02, 2.5],
|
||||
'Mage tower' : ["Mage tower", 0.0 , 0.005, 2.5],
|
||||
'Barrack' : ["Barrack", 1.0 , 0.0001, 2.5]}
|
||||
scene.objects['Terrain']['tower_carac'] = tower_carac
|
||||
|
||||
# Minion 3D object : body (male,female,old, ...), variante (A,B,C,D, ...), level
|
||||
tower_minion_3d={
|
||||
'Archer-lv1' : [['Archer_m', 'Archer_f', "OldArcher_m"],['A','B','C','D'],['common']],
|
||||
'Archer-lv2' : [['Archer_m', 'Archer_f', "OldArcher_m"],['A','B','C','D'],['uncommon']],
|
||||
'Archer-lv3' : [['Archer_m', 'Archer_f', "OldArcher_m"],['A','B','C','D'],['rare']],
|
||||
'Mage-lv1' : [['Mage'],['A','B','C','D'],['common']],
|
||||
'Mage-lv2' : [['Mage'],['A','B','C','D'],['uncommon']],
|
||||
'Mage-lv3' : [['Mage'],['A','B','C','D'],['rare']]}
|
||||
scene.objects['Terrain']['tower_minion_3d'] = tower_minion_3d
|
||||
|
||||
###############################################################################
|
||||
# Map
|
||||
###############################################################################
|
||||
|
||||
# Initialization
|
||||
def map_init():
|
||||
scene.objects['Terrain']['size'] = [-15,15,-10,10] # Map size
|
||||
scene.objects['Terrain']['navmesh'] = "Navmesh.004" # Navmesh
|
||||
minion_definition()
|
||||
tower_definition()
|
||||
scene.objects['Terrain']['nb_waves'] = 3 # Number of waves
|
||||
|
||||
# Ajout des sorties
|
||||
scene.objects['Terrain']['endtile'] = "tile_straight.036"
|
||||
ct_map_end(1,-10)
|
||||
ct_map_endflag(0.5,-10)
|
||||
ct_map_endflag(1.5,-10)
|
||||
|
||||
# Reset counters
|
||||
def map_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
|
||||
scene.objects['Points']['wave']=1
|
||||
|
103
ct_waves.py
103
ct_waves.py
@ -1,103 +0,0 @@
|
||||
import bge # Bibliothèque Blender Game Engine (UPBGE)
|
||||
from ct_lib import * # Bibliothèque CodeTower
|
||||
|
||||
###############################################################################
|
||||
# ct_waves.py
|
||||
# @title: Waves for the CodeTower game
|
||||
# @project: CodeTower
|
||||
# @lang: fr,en
|
||||
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
|
||||
# @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 waves definition
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# En: Threads management << DONT CHANGE THIS SECTION >>
|
||||
# Fr: Gestion des tâches (threads) << NE PAS MODIFIER CETTE SECTION >>
|
||||
###############################################################################
|
||||
|
||||
threads=[]
|
||||
scene = bge.logic.getCurrentScene()
|
||||
|
||||
def start():
|
||||
scene.objects['Terrain']['thread_wave']=True
|
||||
thread_start(threads, "waves", waves)
|
||||
|
||||
def stop():
|
||||
if thread_stop(threads, "waves"):
|
||||
if len(threads)==1:
|
||||
threads.pop()
|
||||
|
||||
###############################################################################
|
||||
# En: Waves commands
|
||||
# Fr: Commandes des vagues
|
||||
#
|
||||
# Spawn a minion : ct_minion (x, y, cat, level)
|
||||
# - x spwan position (integer)
|
||||
# - y spwan position (integer)
|
||||
# - cat : minion class (string) :
|
||||
# - Knight
|
||||
# - Barbarian
|
||||
# - Warrior
|
||||
# - Mage
|
||||
# - Rogue
|
||||
# - Orc
|
||||
# - Squelette
|
||||
# - level (1, 2 or 3)
|
||||
#
|
||||
# Time management (temporization) : ct_tempo(delay)
|
||||
# - delay : delay in seconds (integer)
|
||||
#
|
||||
# UI management : ct_map_text(text)
|
||||
# - text for the wave label
|
||||
#
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# Minion caracteristics : category (class), level, hp, speed, armor, bounty, lifes_damage
|
||||
|
||||
# minion_carac={
|
||||
# 'Knight-lv1' : ["Knight", 1 , 2.0, 1.0, 0.0, 5,1],
|
||||
# 'Knight-lv2' : ["Knight", 2, 4.0, 1.0, 1.0, 20,1],
|
||||
# 'Knight-lv3' : ["Knight", 3, 8.0, 1.0, 2.0, 80,1],
|
||||
# 'Orc-lv1' : ["Orc", 1 , 2.0, 1.0, 0.0, 5,1],
|
||||
# 'Orc-lv2' : ["Orc", 2, 4.0, 1.0, 1.0, 20,1],
|
||||
# 'Orc-lv3' : ["Orc", 3, 8.0, 1.0, 2.0, 80,1]}
|
||||
|
||||
# minion_3d={
|
||||
# 'Knight-lv1' : [['Knight_m', 'Knight_f', 'OldKnight_m'],['A','B','C','D'],['common']],
|
||||
# 'Knight-lv2' : [['Knight_m', 'Knight_f', 'OldKnight_m'],['A','B','C','D'],['uncommon']],
|
||||
# 'Knight-lv3' : [['Knight_m', 'Knight_f', 'OldKnight_m'],['A','B','C','D'],['rare']],
|
||||
# 'Orc-lv1' : [['Orc'],['A','B','C','D','E','F'],['common']],
|
||||
# 'Orc-lv2' : [['Orc'],['A','B','C','D','E','F'],['uncommon']],
|
||||
# 'Orc-lv3' : [['Orc'],['A','B','C','D','E','F'],['rare']]}
|
||||
|
||||
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)
|
||||
|
||||
# Wave 2
|
||||
# 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 >>
|
Loading…
Reference in New Issue
Block a user