Put kills into the pool

This commit is contained in:
Philippe Roy 2022-07-21 00:13:52 +02:00
parent 78213d448a
commit 3f54e0a1ab
6 changed files with 740 additions and 728 deletions

View File

@ -1,43 +1,22 @@
# CodeTower # CodeTower
**Code your tower ! (coding tower defense)** **Code your tower (coding tower defense)**
CodeTower is a Tower Defense coding game where the towers are driven by Python code. CodeTower is a Tower Defense coding game where the towers are driven by Python code.
**Stop the minions waves with your favorite editing software !** * [Screencast](http://www.phroy.org/cloud/index.php/s/djBtGFSXBfCFJM7)
[![CodeTower - Gameplay](img/screen-04-ytb.png)](https://www.youtube.com/watch?v=snZaTSre8FA "CodeTower - Gameplay") It's a early prototype. CodeTower is a open source software distributed under the terms of the [GPLv3 license]('https://www.gnu.org/licenses/gpl-3.0.html').
The game engine is [Blender](https://blender.org) / [UPGE](https://upbge.org).
It's a early prototype. ![Screenshot](img/screenshot-01.jpg)
CodeTower is a open source software distributed under the terms of the [GPLv3 license](https://www.gnu.org/licenses/gpl-3.0.html).
The game engine is open source : [Blender](https://blender.org) / [UPBGE](https://upbge.org).
Assets (3D models, sounds, icons) : [Kenney]( https://www.kenney.nl/ ) and [Kaylousberg](https://www.kaylousberg.com).
### Download ### Download
* itch.io : [itch.io / codetower](https://phroy.itch.io/codetower) Source repository (Gitlab) : https://gitlab.com/phroy/codetower
* Source repository (Gitlab) : https://gitlab.com/phroy/codetower Binaries (GNU/Linux and Windows) : [www.phroy.org](http://www.phroy.org/cloud/index.php/s/nyoWT6xMkxAJ9Pm)
* Binaries repository (GNU/Linux and Windows) : [www.phroy.org](http://www.phroy.org/cloud/index.php/s/nyoWT6xMkxAJ9Pm)
### Python script
The Python script is the file **"ct_cmd.py"** (in the game folder), you have to edit it with your favorite editing software (Spyder, Emacs, Atom, ...).
### Map commands
The level points will be spent for build or upgrade. So you have to know your level before action.
* **Get your level : ct_level ()**
- Return your level (integer)
* **Time management (temporization) : ct_sleep (delay)**
- delay : duration in seconds (float)
### Tower commands ### Tower commands
@ -45,6 +24,8 @@ With your Python script, you can build, remove and upgrade your towers.
For each tower, you will be able to choose dynamically most appropriate techno (archer tower) or spell (mage tower). For each tower, you will be able to choose dynamically most appropriate techno (archer tower) or spell (mage tower).
The Python script is the file **ct_cmd.py** (in the game folder), you have to edit it with editing software (Spyder, Emacs, Atom, ...).
* **Build a tower : ct_build (x, y, category, name, color, style)** * **Build a tower : ct_build (x, y, category, name, color, style)**
- x position (integer) - x position (integer)
- y position (integer) - y position (integer)
@ -60,3 +41,9 @@ For each tower, you will be able to choose dynamically most appropriate techno (
* **Remove a tower : ct_remove (x, y)** * **Remove a tower : ct_remove (x, y)**
- x position (integer) - x position (integer)
- y position (integer) - y position (integer)
* **Get your level : ct_level ()**
- Return your level (integer)
* **Time management (temporization) : ct_sleep (delay)**
- delay : duration in seconds (float)

1364
UML.xmi

File diff suppressed because it is too large Load Diff

Binary file not shown.

49
ct.py
View File

@ -32,7 +32,7 @@ import ct_map1 as ct_map # waves script
# Commands trigged by 3D scene objects : scn_* # Commands trigged by 3D scene objects : scn_*
# Commands trigged by user (student or map designer) : ct_* # Commands trigged by user (student or map designer) : ct_*
# 3D scene manipulation : manip_* # 3D scene manipulation : manip_*
# #
############################################################################### ###############################################################################
# Debug flag # Debug flag
@ -122,7 +122,7 @@ def cmd_tower_construct(cont):
scene.objects['Tower_construc_mode'].color = color_cmd scene.objects['Tower_construc_mode'].color = color_cmd
text_info ("Tower position : ") text_info ("Tower position : ")
scene.objects['Cmd-text']['Text']= "" scene.objects['Cmd-text']['Text']= ""
############################################################################### ###############################################################################
# User interface : texte info et compteurs # User interface : texte info et compteurs
############################################################################### ###############################################################################
@ -138,7 +138,7 @@ def text_info (text):
else: else:
lines_txt=text.split("\n", 6) lines_txt=text.split("\n", 6)
for i in range (len(lines_txt),6): for i in range (len(lines_txt),6):
lines_txt.append("") lines_txt.append("")
scene.objects['Info-1-text'].setVisible(True,False) scene.objects['Info-1-text'].setVisible(True,False)
scene.objects['Info-2-text'].setVisible(True,False) scene.objects['Info-2-text'].setVisible(True,False)
scene.objects['Info-1-text']['Text']=lines_txt[0]+"\n"+lines_txt[1]+"\n"+lines_txt[2] scene.objects['Info-1-text']['Text']=lines_txt[0]+"\n"+lines_txt[1]+"\n"+lines_txt[2]
@ -225,6 +225,11 @@ def points_maj (cont):
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 :
# Suppression des minions
for obj_i in scene.objects:
if "type_minion" in obj_i.getPropertyNames():
obj_i.endObject()
# Fin ou vague suivante # Fin ou vague suivante
if scene.objects['Points']['lifes'] == 0 or scene.objects['Points']['wave'] == scene.objects['Terrain']['nb_waves'] : if scene.objects['Points']['lifes'] == 0 or scene.objects['Points']['wave'] == scene.objects['Terrain']['nb_waves'] :
terrain_end () terrain_end ()
@ -278,8 +283,8 @@ def scn_terrain_mo (cont):
## ##
def terrain_init (): def terrain_init ():
# Cacher les fenêtres # Cacher les fenêtres
scene.objects['End'].setVisible(False,True) scene.objects['End'].setVisible(False,True)
scene.objects['End']['timer']=0 scene.objects['End']['timer']=0
scene.objects['Doc'].setVisible(False,True) scene.objects['Doc'].setVisible(False,True)
@ -288,13 +293,13 @@ def terrain_init ():
scene.active_camera = scene.objects["Camera"] scene.active_camera = scene.objects["Camera"]
scene.objects['Sun'].setVisible(True,True) scene.objects['Sun'].setVisible(True,True)
scene.addOverlayCollection(scene.cameras['Camera-Hud'], bpy.data.collections['Hud']) scene.addOverlayCollection(scene.cameras['Camera-Hud'], bpy.data.collections['Hud'])
# Pile des draws # Pile des draws
scene.objects['Terrain']['draw2d_process']=False scene.objects['Terrain']['draw2d_process']=False
scene.objects['Terrain']['draw2d_list']=[] scene.objects['Terrain']['draw2d_list']=[]
scene.objects['Terrain']['draw3d_process']=False scene.objects['Terrain']['draw3d_process']=False
scene.objects['Terrain']['draw3d_list']=[] scene.objects['Terrain']['draw3d_list']=[]
# Ramasse-miettes # Ramasse-miettes
scene.objects['Points']['minions_lost']=[] scene.objects['Points']['minions_lost']=[]
@ -382,7 +387,7 @@ def terrain_run ():
# Execution du script utilisateur par importlib -> Segfault de Blender # Execution du script utilisateur par importlib -> Segfault de Blender
# importlib.reload(ct_cmd) # importlib.reload(ct_cmd)
# ct_cmd.start() # Execution du script utilisateur # ct_cmd.start() # Execution du script utilisateur
runpy.run_module('ct_cmd', run_name='start') # Execution du script utilisateur runpy.run_module('ct_cmd', run_name='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
@ -406,7 +411,7 @@ def terrain_stop ():
runpy.run_module('ct_cmd', run_name='stop') # Stop du script utilisateur runpy.run_module('ct_cmd', run_name='stop') # Stop du script utilisateur
ct_map.stop() # Stop du script des vagues ct_map.stop() # Stop du script des vagues
# Supprimer les enemis # Suppression des minions
for obj_i in scene.objects: for obj_i in scene.objects:
if "type_minion" in obj_i.getPropertyNames(): if "type_minion" in obj_i.getPropertyNames():
obj_i.endObject() obj_i.endObject()
@ -431,7 +436,7 @@ def terrain_stop ():
def terrain_end (): def terrain_end ():
scene.objects['Terrain']['run']=False scene.objects['Terrain']['run']=False
scene.objects['Terrain']['thread_run']=False scene.objects['Terrain']['thread_run']=False
# Commandes # Commandes
scene.objects['Pause'].setVisible(False,False) scene.objects['Pause'].setVisible(False,False)
scene.objects['Pause-Hl'].setVisible(False,False) scene.objects['Pause-Hl'].setVisible(False,False)
@ -568,7 +573,7 @@ def endbanner_close_click(cont):
def sound_play (sound): def sound_play (sound):
if scene.objects['Commands']['sound']: if scene.objects['Commands']['sound']:
audiodev.play(sound) audiodev.play(sound)
def sound_set (): def sound_set ():
scene.objects['NoSound-cmd'].suspendPhysics() scene.objects['NoSound-cmd'].suspendPhysics()
scene.objects['NoSound-cmd'].setVisible(False,False) scene.objects['NoSound-cmd'].setVisible(False,False)
@ -602,7 +607,7 @@ def sound_unset ():
f.write(buffer_xml) f.write(buffer_xml)
############################################################################### ###############################################################################
# Commandes # Commandes
############################################################################### ###############################################################################
color_cmd = (0.8, 0.8, 0.8, 1) # Blanc color_cmd = (0.8, 0.8, 0.8, 1) # Blanc
@ -798,7 +803,7 @@ def cmd_click (cont):
def mode(cont): def mode(cont):
obj = cont.owner obj = cont.owner
keyboard = bge.logic.keyboard keyboard = bge.logic.keyboard
# Touche ESC # Touche ESC
if JUST_ACTIVATED in keyboard.inputs[bge.events.ESCKEY].queue: if JUST_ACTIVATED in keyboard.inputs[bge.events.ESCKEY].queue:
# Fenêtres modales # Fenêtres modales
@ -815,9 +820,9 @@ def mode(cont):
bge.logic.endGame() bge.logic.endGame()
# Fenêtre modale (inhibition des touches hors ESC) # Fenêtre modale (inhibition des touches hors ESC)
if scene.objects['Terrain']['manip_mode']==9: if scene.objects['Terrain']['manip_mode']==9:
return return
# Shift -> mode 1 : Pan (clic milieu) # Shift -> mode 1 : Pan (clic milieu)
if JUST_ACTIVATED in keyboard.inputs[bge.events.LEFTSHIFTKEY].queue: if JUST_ACTIVATED in keyboard.inputs[bge.events.LEFTSHIFTKEY].queue:
obj['manip_mode']=1 obj['manip_mode']=1
@ -830,7 +835,7 @@ def mode(cont):
if JUST_ACTIVATED in keyboard.inputs[bge.events.RIGHTCTRLKEY].queue: if JUST_ACTIVATED in keyboard.inputs[bge.events.RIGHTCTRLKEY].queue:
obj['manip_mode']=2 obj['manip_mode']=2
# Pas de modificateur -> mode 0 : Pas de Orbit (mode 0) ici # Pas de modificateur -> mode 0 : Pas de Orbit (mode 0) ici
if JUST_RELEASED in keyboard.inputs[bge.events.LEFTSHIFTKEY].queue: if JUST_RELEASED in keyboard.inputs[bge.events.LEFTSHIFTKEY].queue:
obj['manip_mode']=0 obj['manip_mode']=0
if JUST_RELEASED in keyboard.inputs[bge.events.RIGHTSHIFTKEY].queue: if JUST_RELEASED in keyboard.inputs[bge.events.RIGHTSHIFTKEY].queue:
@ -851,11 +856,11 @@ def mode(cont):
scene.objects['Mouse_main']['past_x']=0 scene.objects['Mouse_main']['past_x']=0
scene.objects['Mouse_main']['past_y']=0 scene.objects['Mouse_main']['past_y']=0
# Touche F5 -> Run et Pause # Touche F5 -> Run et Pause
if JUST_ACTIVATED in keyboard.inputs[bge.events.F5KEY].queue: if JUST_ACTIVATED in keyboard.inputs[bge.events.F5KEY].queue:
terrain_run () terrain_run ()
# Touche F6 -> Stop / Init # Touche F6 -> Stop / Init
if JUST_ACTIVATED in keyboard.inputs[bge.events.F6KEY].queue: if JUST_ACTIVATED in keyboard.inputs[bge.events.F6KEY].queue:
if scene.objects['Terrain']['thread_run']==True: if scene.objects['Terrain']['thread_run']==True:
terrain_stop () terrain_stop ()
@ -906,7 +911,7 @@ def applyRotationTo(obj, rx=None, ry=None, rz=None, Local=True):
if rx-obj.worldOrientation.to_euler().x > rres: if rx-obj.worldOrientation.to_euler().x > rres:
obj.applyRotation((rres, 0, 0), Local) obj.applyRotation((rres, 0, 0), Local)
# print ("delta x ",rx-obj.worldOrientation.to_euler().x) # print ("delta x ",rx-obj.worldOrientation.to_euler().x)
# y # y
if ry is not None: if ry is not None:
while (abs(ry-obj.worldOrientation.to_euler().y) > rres) : while (abs(ry-obj.worldOrientation.to_euler().y) > rres) :
@ -1104,7 +1109,7 @@ def mouse_down():
scene.objects['Mouse_main'].worldScale /= (dist_past/dist) *size_scale scene.objects['Mouse_main'].worldScale /= (dist_past/dist) *size_scale
scene.objects['Mouse_main'].worldScale=[30, 30, 30] scene.objects['Mouse_main'].worldScale=[30, 30, 30]
############################################################################### ###############################################################################
# Documentation # Documentation
############################################################################### ###############################################################################
@ -1219,7 +1224,7 @@ def doc_hl (cont):
scene.objects[name].color = color_doc_chap scene.objects[name].color = color_doc_chap
else: else:
scene.objects[name].color = color_doc_fct scene.objects[name].color = color_doc_fct
############################################################################### ###############################################################################
# About # About
############################################################################### ###############################################################################
@ -1337,7 +1342,7 @@ def about_link(cont):
'About_link-kenney' : 'https://www.kenney.nl'} 'About_link-kenney' : 'https://www.kenney.nl'}
webbrowser.open(link [name]) webbrowser.open(link [name])
# FIXME: souris graphique trop compliqué # FIXME: souris graphique trop compliqué
def about_link_hl(cont): def about_link_hl(cont):
decal = 15 decal = 15
if cont.sensors['MO'].status == JUST_ACTIVATED : if cont.sensors['MO'].status == JUST_ACTIVATED :

View File

@ -1,6 +1,6 @@
<data> <data>
<config> <config>
<speed>4.0</speed> <speed>4.0</speed>
<sound>True</sound> <sound>False</sound>
</config> </config>
</data> </data>

View File

@ -263,7 +263,9 @@ def scn_minion_dead(cont):
scene.objects['Points']['minions_run'] -=1 scene.objects['Points']['minions_run'] -=1
scene.objects['Points']['kills'] +=1 scene.objects['Points']['kills'] +=1
scene.objects['Points']['coins']= scene.objects['Points']['coins']+obj['bounty'] scene.objects['Points']['coins']= scene.objects['Points']['coins']+obj['bounty']
obj.endObject() obj.setVisible(False)
obj.suspendPhysics (True)
# obj.endObject()
############################################################################### ###############################################################################
# Spells / Casts # Spells / Casts
@ -581,7 +583,9 @@ def scn_map_end_near(cont):
scene.objects['Points']['lifes']= scene.objects['Points']['lifes']-obj_i['lifes_damage'] scene.objects['Points']['lifes']= scene.objects['Points']['lifes']-obj_i['lifes_damage']
scene.objects['Points']['minions_run'] -=1 scene.objects['Points']['minions_run'] -=1
for obj_i in sensor.hitObjectList : for obj_i in sensor.hitObjectList :
obj_i.endObject() obj_i.setVisible(False)
obj_i.suspendPhysics (True)
# obj_i.endObject()
## ##
# Drapeau de fin # Drapeau de fin