diff --git a/README.md b/README.md index e3676a8..0efa3d8 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,22 @@ # 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. - -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). +![Screenshot](img/screenshot-01.jpg) ### 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 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) +Binaries (GNU/Linux and Windows) : [www.phroy.org](http://www.phroy.org/cloud/index.php/s/nyoWT6xMkxAJ9Pm) ### 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). +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)** - x 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)** - x 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) diff --git a/UML.xmi b/UML.xmi index 8158606..9f10598 100644 --- a/UML.xmi +++ b/UML.xmi @@ -1,749 +1,760 @@ - + umbrello uml modeller http://umbrello.kde.org 1.6.12 UnicodeUTF8 - + - + - - + + - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - + + + + + + + + + - - - - - + + + + + - + - - - - - - + + + + + + - + - + - + - + - + - + - - - + + + - - - + + - + - - - - - - + + + + + + - - - - - - - + + + + + + + - + - - - - - - - - + + + + + + + + - + - - + + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + + + + + + + + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + - + - - + + - + - - - + + - + - + - - + + - + - - + + + - - - - - - - + - + + + + + + + - - + + - - + + + + + + + - - - - - - - - - - - - - + - - + + + + + + + - + - - + + - + - - + + - - - - - - - + - - + + - + - - + + - + + + + + + + + + + + + + - - - + + - + + + + + + + - + + + - - - - - - - - - - - - - + - - - + - + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - - - + - - - + + + - + - - + + - + + + + + + + - - - + + + - + + + + + + + - - - + + + - - - - - - - - - - - - - + - - + + + - + - - + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -752,223 +763,228 @@ - + - + - + - + - + - - - - - - - - - - + + + + + + + + + + - - + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - + + - - - + + + - - - - - - - + + + + + + + - - - - + + + + - - - - - - - - + + + + + + + + + - - - + + + - - - - + + + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - + + + + + + + + + + - - + + + + + - - - - + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/codetower-35.blend b/codetower-35.blend index f1ef727..1a8269f 100644 Binary files a/codetower-35.blend and b/codetower-35.blend differ diff --git a/ct.py b/ct.py index 7edc5c6..b09b5b5 100644 --- a/ct.py +++ b/ct.py @@ -32,7 +32,7 @@ import ct_map1 as ct_map # waves script # Commands trigged by 3D scene objects : scn_* # Commands trigged by user (student or map designer) : ct_* # 3D scene manipulation : manip_* -# +# ############################################################################### # Debug flag @@ -122,7 +122,7 @@ def cmd_tower_construct(cont): scene.objects['Tower_construc_mode'].color = color_cmd text_info ("Tower position : ") scene.objects['Cmd-text']['Text']= "" - + ############################################################################### # User interface : texte info et compteurs ############################################################################### @@ -138,7 +138,7 @@ def text_info (text): else: lines_txt=text.split("\n", 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-2-text'].setVisible(True,False) 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['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 if scene.objects['Points']['lifes'] == 0 or scene.objects['Points']['wave'] == scene.objects['Terrain']['nb_waves'] : terrain_end () @@ -278,8 +283,8 @@ def scn_terrain_mo (cont): ## def terrain_init (): - - # Cacher les fenêtres + + # Cacher les fenêtres scene.objects['End'].setVisible(False,True) scene.objects['End']['timer']=0 scene.objects['Doc'].setVisible(False,True) @@ -288,13 +293,13 @@ def terrain_init (): scene.active_camera = scene.objects["Camera"] scene.objects['Sun'].setVisible(True,True) scene.addOverlayCollection(scene.cameras['Camera-Hud'], bpy.data.collections['Hud']) - + # Pile des draws scene.objects['Terrain']['draw2d_process']=False scene.objects['Terrain']['draw2d_list']=[] scene.objects['Terrain']['draw3d_process']=False scene.objects['Terrain']['draw3d_list']=[] - + # Ramasse-miettes scene.objects['Points']['minions_lost']=[] @@ -382,7 +387,7 @@ def terrain_run (): # Execution du script utilisateur par importlib -> Segfault de Blender # importlib.reload(ct_cmd) # ct_cmd.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 @@ -406,7 +411,7 @@ def terrain_stop (): runpy.run_module('ct_cmd', run_name='stop') # Stop du script utilisateur ct_map.stop() # Stop du script des vagues - # Supprimer les enemis + # Suppression des minions for obj_i in scene.objects: if "type_minion" in obj_i.getPropertyNames(): obj_i.endObject() @@ -431,7 +436,7 @@ def terrain_stop (): def terrain_end (): scene.objects['Terrain']['run']=False scene.objects['Terrain']['thread_run']=False - + # Commandes scene.objects['Pause'].setVisible(False,False) scene.objects['Pause-Hl'].setVisible(False,False) @@ -568,7 +573,7 @@ def endbanner_close_click(cont): def sound_play (sound): if scene.objects['Commands']['sound']: audiodev.play(sound) - + def sound_set (): scene.objects['NoSound-cmd'].suspendPhysics() scene.objects['NoSound-cmd'].setVisible(False,False) @@ -602,7 +607,7 @@ def sound_unset (): f.write(buffer_xml) ############################################################################### -# Commandes +# Commandes ############################################################################### color_cmd = (0.8, 0.8, 0.8, 1) # Blanc @@ -798,7 +803,7 @@ def cmd_click (cont): def mode(cont): obj = cont.owner keyboard = bge.logic.keyboard - + # Touche ESC if JUST_ACTIVATED in keyboard.inputs[bge.events.ESCKEY].queue: # Fenêtres modales @@ -815,9 +820,9 @@ def mode(cont): bge.logic.endGame() # Fenêtre modale (inhibition des touches hors ESC) - if scene.objects['Terrain']['manip_mode']==9: + if scene.objects['Terrain']['manip_mode']==9: return - + # Shift -> mode 1 : Pan (clic milieu) if JUST_ACTIVATED in keyboard.inputs[bge.events.LEFTSHIFTKEY].queue: obj['manip_mode']=1 @@ -830,7 +835,7 @@ def mode(cont): if JUST_ACTIVATED in keyboard.inputs[bge.events.RIGHTCTRLKEY].queue: 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: obj['manip_mode']=0 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_y']=0 - # Touche F5 -> Run et Pause + # Touche F5 -> Run et Pause if JUST_ACTIVATED in keyboard.inputs[bge.events.F5KEY].queue: terrain_run () - # Touche F6 -> Stop / Init + # Touche F6 -> Stop / Init if JUST_ACTIVATED in keyboard.inputs[bge.events.F6KEY].queue: if scene.objects['Terrain']['thread_run']==True: 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: obj.applyRotation((rres, 0, 0), Local) # print ("delta x ",rx-obj.worldOrientation.to_euler().x) - + # y if ry is not None: 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=[30, 30, 30] -############################################################################### +############################################################################### # Documentation ############################################################################### @@ -1219,7 +1224,7 @@ def doc_hl (cont): scene.objects[name].color = color_doc_chap else: scene.objects[name].color = color_doc_fct - + ############################################################################### # About ############################################################################### @@ -1337,7 +1342,7 @@ def about_link(cont): 'About_link-kenney' : 'https://www.kenney.nl'} webbrowser.open(link [name]) -# FIXME: souris graphique trop compliqué +# FIXME: souris graphique trop compliqué def about_link_hl(cont): decal = 15 if cont.sensors['MO'].status == JUST_ACTIVATED : diff --git a/ct_config.xml b/ct_config.xml index cd730e0..4784d9c 100644 --- a/ct_config.xml +++ b/ct_config.xml @@ -1,6 +1,6 @@ 4.0 - True + False \ No newline at end of file diff --git a/ct_lib.py b/ct_lib.py index b6de771..3f3abf1 100644 --- a/ct_lib.py +++ b/ct_lib.py @@ -263,7 +263,9 @@ def scn_minion_dead(cont): scene.objects['Points']['minions_run'] -=1 scene.objects['Points']['kills'] +=1 scene.objects['Points']['coins']= scene.objects['Points']['coins']+obj['bounty'] - obj.endObject() + obj.setVisible(False) + obj.suspendPhysics (True) + # obj.endObject() ############################################################################### # 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']['minions_run'] -=1 for obj_i in sensor.hitObjectList : - obj_i.endObject() + obj_i.setVisible(False) + obj_i.suspendPhysics (True) + # obj_i.endObject() ## # Drapeau de fin