ajou du kaykit medievale, du kenney castle kit, remplacement de bullets par une ligne si speed > 2

This commit is contained in:
Philippe Roy 2022-03-24 17:00:09 +01:00
parent 0195710cf8
commit b398daf533
25 changed files with 432 additions and 109 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -0,0 +1,31 @@
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.
For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -0,0 +1,22 @@
KayKit : Medieval Builder Pack (1.0)
Created/distributed by Kay Lousberg (www.kaylousberg.com)
Creation date: 30/07/2021 15:00
------------------------------
License: (Creative Commons Zero, CC0)
http://creativecommons.org/publicdomain/zero/1.0/
This content is free to use in personal, educational and commercial projects.
Support me by using a brand resource provided in this pack or by crediting Kay Lousberg, www.kaylousberg.com (this is not mandatory)
------------------------------
Patreon: http://patreon.com/kaylousberg
Follow on Twitter for updates:
http://twitter.com/KayLousberg

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

View File

@ -0,0 +1,51 @@
# This is an Asset Catalog Definition file for Blender.
#
# Empty lines and lines starting with `#` will be ignored.
# The first non-ignored line should be the version indicator.
# Other lines are of the format "UUID:catalog/path/for/assets:simple catalog name"
VERSION 1
da604c58-5cc1-494e-814f-1ebb2768027b:Chateau:Chateau
80aea8db-d92b-41d3-b718-08f6d7ba8aa7:Habitation:Habitation
fef231d1-d07a-4490-96a3-aa4340a38ce2:Nature:Nature
5827dcb7-1878-4f86-b2cd-154a55cc5a64:Route:Route
491c2dd1-e566-4c35-8e04-7f0823f6dd84:Tuiles Carrées:Tuiles Carrées
b75f637c-0888-47ed-b2a1-b010d058c34c:Tuiles Carrées/Eau:Tuiles Carrées-Eau
c7033d6a-b529-4f85-8258-7e719fba64f9:Tuiles Carrées/Eau/Forêt:Tuiles Carrées-Eau-Forêt
777ccf01-e36d-428a-b98b-8a52f18aa008:Tuiles Carrées/Eau/Rocher:Tuiles Carrées-Eau-Rocher
563e92cb-9e5f-4d54-a799-7959cf7e9b5e:Tuiles Carrées/Eau/Sable:Tuiles Carrées-Eau-Sable
e2259054-b20d-4155-8c74-64085d470268:Tuiles Carrées/Mer:Tuiles Carrées-Mer
bd4f3cfd-b0cb-4fb3-adc8-2b44d1f0c4cb:Tuiles Carrées/Mer/Uniquement mer:Tuiles Carrées-Mer-Uniquement mer
4f88fb33-6d8b-4705-b571-8daf112967ce:Tuiles Carrées/Nu:Tuiles Carrées-Nu
9fa82237-814b-4410-bb70-7c227f929454:Tuiles Carrées/Routes:Tuiles Carrées-Routes
55b5d853-ba1f-4c3b-86e5-7de755292999:Tuiles Carrées/Routes/Forêt:Tuiles Carrées-Routes-Forêt
ecfcc553-bed4-4701-844f-928c4b8047db:Tuiles Carrées/Routes/Rocher:Tuiles Carrées-Routes-Rocher
cfccc1e6-e257-48f0-8550-94ed347b6b00:Tuiles Carrées/Routes/Sable:Tuiles Carrées-Routes-Sable
a87a1c82-11bf-4c95-87cc-5194074e7756:Tuiles Hexagonales:Tuiles Hexagonales
9232d0c3-3ee7-4b7d-83e5-0d03c165b22e:Tuiles Hexagonales/Forêt:Tuiles Hexagonales-Forêt
2096840f-7019-488b-8ff9-72cdffb61bc9:Tuiles Hexagonales/Forêt/Forêt + fond:Tuiles Hexagonales-Forêt-Forêt + fond
260e3709-a673-40ff-9474-940ca33cb3b8:Tuiles Hexagonales/Forêt/Forêt + fond/Mer:Tuiles Hexagonales-Forêt-Forêt + fond-Mer
03a7b3cd-5501-48ea-b8ba-3a5bcf289e45:Tuiles Hexagonales/Forêt/Forêt + fond/Nu:Tuiles Hexagonales-Forêt-Forêt + fond-Nu
3a82529a-ace7-437d-af42-01d211b822fb:Tuiles Hexagonales/Forêt/Forêt + fond/Routes:Tuiles Hexagonales-Forêt-Forêt + fond-Routes
9652643a-e4d1-4dce-9c95-3d89d8fad49a:Tuiles Hexagonales/Forêt/Mer:Tuiles Hexagonales-Forêt-Mer
37fd89a2-4745-4b5a-b6a8-6b666351bfeb:Tuiles Hexagonales/Forêt/Nu:Tuiles Hexagonales-Forêt-Nu
6f4264c0-0f07-4ffc-ac0a-05567a6d41c5:Tuiles Hexagonales/Forêt/Routes:Tuiles Hexagonales-Forêt-Routes
1ea4d072-2d7f-4148-9741-fcd19d2b7592:Tuiles Hexagonales/Mer:Tuiles Hexagonales-Mer
7531a4ab-3d33-43f8-9339-98c7c724b216:Tuiles Hexagonales/Rocher:Tuiles Hexagonales-Rocher
03c1ca74-8128-44ad-96e4-3534c2e837a5:Tuiles Hexagonales/Rocher/Mer:Tuiles Hexagonales-Rocher-Mer
d9df6d97-1801-4a86-a577-d6532ff49c0b:Tuiles Hexagonales/Rocher/Nu:Tuiles Hexagonales-Rocher-Nu
63fa17f0-bdae-4f41-a8f5-1d1666938e94:Tuiles Hexagonales/Rocher/Rocher + fond:Tuiles Hexagonales-Rocher-Rocher + fond
8acca401-b617-449d-a838-35a07c0eedf9:Tuiles Hexagonales/Rocher/Rocher + fond/Mer:Tuiles Hexagonales-Rocher-Rocher + fond-Mer
dd85e064-9bee-48c3-a3df-abd175d151d9:Tuiles Hexagonales/Rocher/Rocher + fond/Nu:Tuiles Hexagonales-Rocher-Rocher + fond-Nu
445ba6b7-8ea5-4d82-a4c1-77728342706b:Tuiles Hexagonales/Rocher/Rocher + fond/Routes:Tuiles Hexagonales-Rocher-Rocher + fond-Routes
e5b53048-5c9f-4cec-abcf-8332c1ffe997:Tuiles Hexagonales/Rocher/Routes:Tuiles Hexagonales-Rocher-Routes
18db8fd4-ea0b-4524-972d-e43f0b4285fd:Tuiles Hexagonales/Sable:Tuiles Hexagonales-Sable
f16ad74b-565f-49bd-8a41-03d00a12290a:Tuiles Hexagonales/Sable/Mer:Tuiles Hexagonales-Sable-Mer
3629b0af-7055-40c2-993f-d31b6257497a:Tuiles Hexagonales/Sable/Nu:Tuiles Hexagonales-Sable-Nu
bffa85c4-d2d6-44e5-9739-0ae8fc762be9:Tuiles Hexagonales/Sable/Routes:Tuiles Hexagonales-Sable-Routes
6b766e72-f77b-43e0-8f11-92ab523bfc70:Tuiles Hexagonales/Sable/Sable + fond:Tuiles Hexagonales-Sable-Sable + fond
85fc5e90-453d-4dd7-980b-3aaef2537268:Tuiles Hexagonales/Sable/Sable + fond/Mer:Tuiles Hexagonales-Sable-Sable + fond-Mer
510338ff-80ad-45e4-83ee-3f426ff07414:Tuiles Hexagonales/Sable/Sable + fond/Nu:Tuiles Hexagonales-Sable-Sable + fond-Nu
761dddcf-9445-42a5-be72-5bb26b2510c0:Tuiles Hexagonales/Sable/Sable + fond/Routes:Tuiles Hexagonales-Sable-Sable + fond-Routes
e0414173-500b-4525-8214-2db73836a847:Tuiles Hexagonales/Transitions:Tuiles Hexagonales-Transitions

Binary file not shown.

View File

@ -0,0 +1,31 @@
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.
For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

View File

@ -0,0 +1,22 @@
Castle Kit (1.0)
Created/distributed by Kenney (www.kenney.nl)
------------------------------
License: (Creative Commons Zero, CC0)
http://creativecommons.org/publicdomain/zero/1.0/
This content is free to use in personal, educational and commercial projects.
Support us by crediting (Kenney or www.kenney.nl), this is not mandatory.
------------------------------
Donate: http://support.kenney.nl
Request: http://request.kenney.nl
Patreon: http://patreon.com/kenney/
Follow on Twitter for updates:
@KenneyNL

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

View File

@ -0,0 +1,19 @@
# This is an Asset Catalog Definition file for Blender.
#
# Empty lines and lines starting with `#` will be ignored.
# The first non-ignored line should be the version indicator.
# Other lines are of the format "UUID:catalog/path/for/assets:simple catalog name"
VERSION 1
e5c10ba1-5859-49f2-8837-45856abfa2a1:Demi-mur:Demi-mur
f31b303f-5203-499c-a723-dec0b3533233:Escalier:Escalier
8bfb5b97-3afa-4e53-b650-ebd2a7fee265:Flag:Flag
4a118eb9-687d-4b3f-9579-a454082d5da9:Mur:Mur
26a8dc80-2c96-4904-981a-045aba2dec8b:Porte:Porte
6a9ccf6a-56c0-4f43-8833-fcecd5e29d27:Tour carré:Tour carré
48374c65-e1cd-49d1-a00e-0504d3f802f8:Tour carré/Base:Tour carré-Base
cc288fe0-22cc-45e1-94be-471ed1943ef2:Tour carré/Haut:Tour carré-Haut
86e0974a-8dbd-4cba-b385-f995bb503788:Tour carré/Milieu:Tour carré-Milieu
517a32c2-db11-4a0a-88f3-31d60b3eac8c:Tour carré/Toit:Tour carré-Toit
083c48a1-e03b-48a6-bc47-362e799e291e:Tour ronde:Tour ronde

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

View File

@ -0,0 +1,20 @@
import os
import bpy
# put the location to the folder where the objs are located here in this fashion
# this line will only work on windows ie C:\objects
path_to_obj_dir = os.path.join('/home/phroy/Documents/blender-edutech/codetower/asset/kaykit_medieval/dae')
# get list of all files in directory
file_list = sorted(os.listdir(path_to_obj_dir))
print (file_list)
# get a list of files ending in 'dae'
obj_list = [item for item in file_list if item.endswith('.dae')]
# loop through the strings in obj_list and add the files to the scene
for item in obj_list:
path_to_file = os.path.join(path_to_obj_dir, item)
bpy.ops.wm.collada_import(filepath = path_to_file)
# if heavy importing is expected
# you may want use saving to main file after every import
bpy.ops.wm.save_mainfile(filepath = "/home/phroy/Documents/blender-edutech/codetower/asset/kaykit_medieval/file.blend")

BIN
codetower-12.blend Normal file

Binary file not shown.

93
ct.py
View File

@ -14,7 +14,7 @@ import ct_map
# ct.py
# @title: the CodeTower game
# @project: Blender-EduTech
# @lang: fr
# @lang: fr,en
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL
@ -25,10 +25,10 @@ import ct_map
###############################################################################
# Import dynamique des fichiers Python élève et vagues
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()
ct_vg = importlib.import_module('ct_vg')
ct_cmd = importlib.import_module('ct_cmd')
ct_wv = importlib.import_module('ct_waves') # waves script
ct_cmd = importlib.import_module('ct_cmd') # user script (commands)
# Récupérer la scène UPBGE
scene = bge.logic.getCurrentScene()
@ -40,18 +40,18 @@ ct_config_tree = ct_config.getroot()
# Couleurs
couleur_magenta = [0.800, 0.005, 0.315,1] # bouton non activable : magenta
couleur_orange = [0.799, 0.130, 0.063,1] # bouton activable : orange
couleur_blanc = [0.8, 0.8, 0.8, 1] # bouton focus : blanc
couleur_jaune = [0.8, 0.619, 0.021, 1] # bouton activé : jaune
color_magenta = [0.800, 0.005, 0.315,1] # bouton non activable : magenta
color_orange = [0.799, 0.130, 0.063,1] # bouton activable : orange
color_white = [0.8, 0.8, 0.8, 1] # bouton focus : blanc
color_yellow = [0.8, 0.619, 0.021, 1] # bouton activé : jaune
couleur_texte = [0, 0, 0, 1] # Noir
couleur_texte_rouge = [0.799, 0.031, 0.038, 1]
color_text = [0, 0, 0, 1] # Noir
color_text_red = [0.799, 0.031, 0.038, 1]
couleur_cmd = [0.8, 0.8, 0.8, 1] # blanc
couleur_cmd_hl = [0.8, 0.619, 0.021, 1] # jaune
couleur_lien = [0.024, 0.006, 0.8, 1] # bleu
couleur_lien_hl = [0.8, 0.005, 0.315, 1] # majenta
color_cmd = [0.8, 0.8, 0.8, 1] # blanc
color_cmd_hl = [0.8, 0.619, 0.021, 1] # jaune
color_link = [0.024, 0.006, 0.8, 1] # bleu
color_link_hl = [0.8, 0.005, 0.315, 1] # majenta
# Constantes UPBGE
@ -72,20 +72,20 @@ def cmd_tower_construct(cont):
if scene.objects['Terrain']['construct_mode']==True:
scene.objects['Terrain']['construct_mode']=False
obj.worldScale=[1, 1, 1]
obj.color = couleur_cmd
obj.color = color_cmd
obj_Hl.worldScale=[1, 1, 1]
obj_Hl.color = couleur_cmd
obj_Hl.color = color_cmd
scene.objects['Tower_construc_mode'].setVisible(False,False)
scene.objects['Tower_construc_mode'].color = couleur_cmd
scene.objects['Tower_construc_mode'].color = color_cmd
text_info ("")
else:
scene.objects['Terrain']['construct_mode']=True
obj.worldScale=[1.25, 1.25, 1.25]
obj.color = couleur_cmd_hl
obj.color = color_cmd_hl
obj_Hl.worldScale=[1.25, 1.25, 1.25]
obj_Hl.color = couleur_cmd_hl
obj_Hl.color = color_cmd_hl
scene.objects['Tower_construc_mode'].setVisible(True,False)
scene.objects['Tower_construc_mode'].color = couleur_cmd
scene.objects['Tower_construc_mode'].color = color_cmd
text_info ("Tower position : ")
###############################################################################
@ -93,18 +93,18 @@ def cmd_tower_construct(cont):
###############################################################################
# Affichage sur la boite de texte sur 6 lignes
def text_info (texte):
if texte=="":
def text_info (text):
if text=="":
scene.objects['Text_info-1'].setVisible(False,False)
scene.objects['Text_info-2'].setVisible(False,False)
else:
lignes_txt=texte.split("\n", 6)
for i in range (len(lignes_txt),6):
lignes_txt.append("")
lines_txt=text.split("\n", 6)
for i in range (len(lines_txt),6):
lines_txt.append("")
scene.objects['Text_info-1'].setVisible(True,False)
scene.objects['Text_info-2'].setVisible(True,False)
scene.objects['Text_info-1']['Text']=lignes_txt[0]+"\n"+lignes_txt[1]+"\n"+lignes_txt[2]
scene.objects['Text_info-2']['Text']=lignes_txt[3]+"\n"+lignes_txt[4]+"\n"+lignes_txt[5]
scene.objects['Text_info-1']['Text']=lines_txt[0]+"\n"+lines_txt[1]+"\n"+lines_txt[2]
scene.objects['Text_info-2']['Text']=lines_txt[3]+"\n"+lines_txt[4]+"\n"+lines_txt[5]
# Mise à jour de l'affichage des compteurs
def points_maj (cont):
@ -115,9 +115,9 @@ def points_maj (cont):
# Level trop élevé
if scene.objects['Points']['level'] > scene.objects['Points']['level_max'] :
scene.objects['Level_text'].color = couleur_texte_rouge
if scene.objects['Level_text'].color == couleur_texte_rouge and scene.objects['Points']['level'] <= scene.objects['Points']['level_max']:
scene.objects['Level_text'].color = couleur_texte
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
if scene.objects['Terrain']['thread_wave']==False:
@ -169,7 +169,7 @@ def terrain_init (cont):
scene.objects['Points']['level']=0
scene.objects['Points']['level_max']=1
scene.objects['Points']['minions']=0
scene.objects['Level_text'].color = couleur_texte
scene.objects['Level_text'].color = color_text
# Recherche les tuiles non constructibles (chemin)
scene.objects['Terrain']['scene_tile_noncontruct'] = []
@ -219,7 +219,7 @@ def terrain_run (cont):
# 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)
ct_cmd.start() # Execution des commandes
ct_vg.start() # Lancement des vagues
ct_wv.start() # Lancement des vagues
# Arrêt de la pause
else:
@ -247,6 +247,7 @@ def terrain_runspeed (cont):
for obj_i in scene.objects:
if "type_tower" in obj_i.getPropertyNames() and "Near" in obj_i.sensors :
obj_i.sensors['Near'].skippedTicks =round(1/(obj_i.components['Tower'].args['speed']*scene.objects['Terrain']['speed']))
print (obj_i.sensors['Near'].skippedTicks)
if "type_minion" in obj_i.getPropertyNames():
obj_i.actuators['Steering'].velocity=obj_i.components['Minion'].args['speed']*scene.objects['Terrain']['speed']
@ -264,7 +265,7 @@ def terrain_stop (cont):
scene.objects['Terrain']['run']=False
scene.objects['Terrain']['thread_run']=False
ct_cmd.stop() # Stop des commandes
ct_vg.stop() # Stop des vagues
ct_wv.stop() # Stop des vagues
# Supprimer les enemis
for obj_i in scene.objects:
@ -434,7 +435,7 @@ def mode(cont):
# 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)
ct_cmd.start() # Execution des commandes
ct_vg.start() # Lancement des vagues
ct_wv.start() # Lancement des vagues
# Arrêt de la pause
else:
@ -451,7 +452,7 @@ def mode(cont):
scene.objects['Terrain']['run']=False
scene.objects['Terrain']['thread_run']=False
ct_cmd.stop() # Stop des commandes
ct_vg.stop() # Stop des vagues
ct_wv.stop() # Stop des vagues
# Supprimer les enemis
for obj_i in scene.objects:
@ -542,7 +543,7 @@ def manip(cont):
# Orbit (1280 * 720 px) Pas de Orbit ici
# if obj['manip_mode']==0:
# scene.objects['Orbit'].color=couleur_cmd
# 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
@ -556,7 +557,7 @@ def manip(cont):
# [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=couleur_cmd_hl
# 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:
@ -588,13 +589,13 @@ def manip_wheel(cont):
# if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
# # scene.replace('Scene-Aide') # Bug Eevee -> même scene mais camera différente
# scene.active_camera=scene.objects['Aide-Camera']
# scene.objects['Apropos-Lien_projet'].color= couleur_lien
# scene.objects['Apropos-Lien_maquette'].color= couleur_lien
# scene.objects['Apropos-Lien_a4'].color= couleur_lien
# scene.objects['Apropos-Lien_blender'].color= couleur_lien
# scene.objects['Apropos-Lien_upbge'].color= couleur_lien
# scene.objects['Apropos-Lien_cc'].color= couleur_lien
# scene.objects['Apropos-Lien_gpl'].color= couleur_lien
# scene.objects['Apropos-Lien_projet'].color= color_link
# scene.objects['Apropos-Lien_maquette'].color= color_link
# scene.objects['Apropos-Lien_a4'].color= color_link
# scene.objects['Apropos-Lien_blender'].color= color_link
# scene.objects['Apropos-Lien_upbge'].color= color_link
# scene.objects['Apropos-Lien_cc'].color= color_link
# scene.objects['Apropos-Lien_gpl'].color= color_link
# # Fermer la page d'aide
# def aide_fermer(cont):
@ -625,7 +626,7 @@ def manip_wheel(cont):
# def aide_apropos_hl(cont):
# if cont.sensors['MO'].status == JUST_ACTIVATED :
# obj = cont.owner
# obj.color = couleur_lien_hl
# obj.color = color_link_hl
# if cont.sensors['MO'].status == JUST_RELEASED :
# obj = cont.owner
# obj.color = couleur_lien
# obj.color = color_link

View File

@ -5,7 +5,7 @@ from ct_lib import * # Bibliothèque CodeTower
# ct_cmd.py
# @title: Commands for the CodeTower game
# @project: CodeTower
# @lang: fr
# @lang: fr,en
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL
@ -56,7 +56,7 @@ def stop():
# - y position (integer)
#
# Time management (temporization) : ct_tempo(delay)
# - delay : delay in seconds (integer)
# - delay : delay in seconds (float)
#
###############################################################################
@ -66,14 +66,14 @@ def commands():
ct_build(4,5, "Tower #1")
ct_build(5,5, "Tower #2", green)
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")
# 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")
ct_tempo(20)
# ct_tempo(20)
ct_remove(4,4)
ct_print("ok")
# ct_remove(4,4)
# ct_print("ok")
ct_tempo(2)
print ("Threads commands #", len(threads)-1, "are arrived -> close them.") # Thread closed << DONT CHANGE THIS LINE >>

View File

@ -5,7 +5,7 @@ from collections import OrderedDict
# ct_comp.py
# @title: Composants python
# @project: CodeTower
# @lang: fr
# @lang: fr,en
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL
@ -16,7 +16,7 @@ from collections import OrderedDict
###############################################################################
# Récupérer les objets 3D
scene = bge.logic.getCurrentScene()
# scene = bge.logic.getCurrentScene()
###############################################################################
# Minion
@ -47,6 +47,7 @@ class Tower(bge.types.KX_PythonComponent):
args = OrderedDict([
("cat", ""),
("level", 0),
("tower_name", ""),
("damage", 0.0),
("speed", 0.0),
("range", 0.0)

142
ct_lib.py
View File

@ -13,7 +13,7 @@ import random
# ct_lib.py
# @title: User library
# @project: CodeTower
# @lang: fr
# @lang: fr,en
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL
@ -109,50 +109,51 @@ def thread_stop(threads, type_txt):
# Minion caracteristics : category (class), level, hp, speed, armor, bounty, lifes_damage
carac_minion={
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]}
# Minion 3d object : body (male,female,old, ...), head (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']]}
# Création d'un minion
def ct_minion(x,y,cat,level):
while scene.objects['Terrain']['run'] == False: # Pause
category=cat+"-lv"+str(level)
# Pause
while scene.objects['Terrain']['run'] == False:
time.sleep(0)
# Objet 3D
minion= scene.addObject(cat, scene.objects['Terrain'])
# Object 3D
body = random.choice(minion_3d[category][0])+"_"+random.choice(minion_3d[category][1])+"_"+random.choice(minion_3d[category][2])
minion= scene.addObject(body, scene.objects['Terrain'])
minion.worldScale=mathutils.Vector((0.25,0.25,0.25))
minion.worldPosition=mathutils.Vector((x,y,0.1))
# minion.worldPosition=mathutils.Vector((x,y,0.3))
# minion.worldPosition=mathutils.Vector((x,y,0.37)) # old 2
scene.objects['Points']['minions']= scene.objects['Points']['minions']+1
# Caractéristiques
minion.components['Minion'].args['cat']=carac_minion[cat+"-lv"+str(level)][0]
minion.components['Minion'].args['level']=carac_minion[cat+"-lv"+str(level)][1]
minion.components['Minion'].args['hp']=carac_minion[cat+"-lv"+str(level)][2]
minion.components['Minion'].args['speed']=carac_minion[cat+"-lv"+str(level)][3]
minion.components['Minion'].args['armor']=carac_minion[cat+"-lv"+str(level)][4]
minion.components['Minion'].args['bounty']=carac_minion[cat+"-lv"+str(level)][5]
minion.components['Minion'].args['lifes_damage']=carac_minion[cat+"-lv"+str(level)][6]
# Caracteristics
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]
minion.components['Minion'].args['speed']=minion_carac[category][3]
minion.components['Minion'].args['armor']=minion_carac[category][4]
minion.components['Minion'].args['bounty']=minion_carac[category][5]
minion.components['Minion'].args['lifes_damage']=minion_carac[category][6]
minion['hp'] =minion.components['Minion'].args['hp']
# Actionneur Steering
# Actuator Steering
minion.actuators['Steering'].navmesh=scene.objects[scene.objects['Terrain']['navmesh']]
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']
# Tete
# if class_minion=="Knight":
# head = random.choice(['Knight_head-A', 'Knight_head-B'])
# minion_head= scene.addObject(head, minion)
# minion_head.worldScale=mathutils.Vector((0.25,0.25,0.25))
# minion_head.setParent(minion, True, True)
# minion_head.localPosition.z=0.703713 # Position de la tête
# Accessoires
# Destruction d'un minion
def scn_minion_dead(cont):
obj = cont.owner
@ -166,9 +167,12 @@ def scn_minion_dead(cont):
# Tower caracteristics : category (class), damage, speed, range
carac_tower={
tower_carac={
'Base' : ["Base", 1.0 , 0.02, 3.0]}
# carac_tower={
# 'Base' : ["Base", 1.0 , 0.02, 3.0]}
# Création d'une tour
def ct_build(x,y,tower_name="Tower",color=tower_purple, cat='Base'):
@ -193,22 +197,27 @@ def ct_build(x,y,tower_name="Tower",color=tower_purple, cat='Base'):
scene.objects['Terrain']['scene_tile_tower'].append([x,y])
# Caractéristiques (composant python et propriétés de l'objet 3D)
tour.components['Tower'].args['cat']=carac_tower[cat][0]
tour.components['Tower'].args['cat']=tower_carac[cat][0]
tour.components['Tower'].args['lvl']=1
tour.components['Tower'].args['tower_name']=tower_name
tour.components['Tower'].args['damage']=carac_tower[cat][1]
tour.components['Tower'].args['speed']=carac_tower[cat][2]
tour.components['Tower'].args['range']=carac_tower[cat][3]
tour['cat']=carac_tower[cat][0]
tour.components['Tower'].args['damage']=tower_carac[cat][1]
tour.components['Tower'].args['speed']=tower_carac[cat][2]
tour.components['Tower'].args['range']=tower_carac[cat][3]
tour['cat']=tower_carac[cat][0]
tour['lvl']=1
tour['tower_name']=tower_name
tour['damage']=carac_tower[cat][1]
tour['speed']=carac_tower[cat][2]
tour['range']=carac_tower[cat][3]
tour['damage']=tower_carac[cat][1]
tour['speed']=tower_carac[cat][2]
tour['range']=tower_carac[cat][3]
# Capteur Near
tour.sensors['Near'].distance=tour.components['Tower'].args['range']
tour.sensors['Near'].skippedTicks =round(1/(tour.components['Tower'].args['speed']*scene.objects['Terrain']['speed']))
print (tour.sensors['Near'].skippedTicks)
# for obj_i in scene.objects:
# if "type_tower" in obj_i.getPropertyNames():
# print (obj_i['tower_name'])
return True
# Supression d'une tour
@ -223,19 +232,31 @@ def ct_remove(x,y):
def scn_tower_near(cont):
obj = cont.owner
sensor = obj.sensors['Near']
# Tir
# FIXME: deux tirs à la fois ?
# FIXME: tir sur le plus avancé
if len(sensor.hitObjectList)>0 and scene.objects['Terrain']['run']==True :
# Tir
target=sensor.hitObjectList[0]
target.actuators['Steering'].velocity=(target.components['Minion'].args['speed']*scene.objects['Terrain']['speed'])/2
bullet= scene.addObject("Bullet", scene.objects['Terrain'])
bullet.mass=0.001 # bullet.applyForce=((0,0,9.81),True)
bullet.worldPosition=mathutils.Vector((obj.worldPosition.x,obj.worldPosition.y,1.5))
bullet.worldScale=[0.75,0.75,0.75]
# bullet.worldScale=[0.5,0.5,0.5]
bullet.worldLinearVelocity.x = (target.worldPosition.x-bullet.worldPosition.x)*bullet['velocity']
bullet.worldLinearVelocity.y= (target.worldPosition.y-bullet.worldPosition.y)*bullet['velocity']
bullet.worldLinearVelocity.z = (target.worldPosition.z+0.1-bullet.worldPosition.z)*bullet['velocity']
# target.actuators['Steering'].velocity=(target.components['Minion'].args['speed']*scene.objects['Terrain']['speed'])/2 # Reduction de la vitesse du minion
# Bullet (3d object) (vitesse <=1)
if scene.objects['Terrain']['speed']<=1:
bullet= scene.addObject("Bullet", scene.objects['Terrain'])
bullet.mass=0.001 # bullet.applyForce=((0,0,9.81),True)
bullet.worldPosition=mathutils.Vector((obj.worldPosition.x,obj.worldPosition.y,1.5))
bullet.worldScale=[0.75,0.75,0.75]
# bullet.worldScale=[0.5,0.5,0.5]
bullet.worldLinearVelocity.x = (target.worldPosition.x-bullet.worldPosition.x)*bullet['velocity']
bullet.worldLinearVelocity.y= (target.worldPosition.y-bullet.worldPosition.y)*bullet['velocity']
bullet.worldLinearVelocity.z = (target.worldPosition.z+0.1-bullet.worldPosition.z)*bullet['velocity']
# Line (vitesse >=2)
if scene.objects['Terrain']['speed']>=2:
bge.render.drawLine([obj.worldPosition.x, obj.worldPosition.y, obj.worldPosition.z+0.1],
[target.worldPosition.x, target.worldPosition.y, target.worldPosition.z],
[0.8, 0.619, 0.021])
# Dégats
target['hp'] = target['hp'] - obj.components['Tower'].args['damage']
@ -288,27 +309,44 @@ def ct_map_endflag(x,y):
# Temporisation
###############################################################################
def ct_tempo (duree):
time.sleep(duree*(1/scene.objects['Terrain']['speed']))
def ct_sleep (duration):
time.sleep(duration*(1/scene.objects['Terrain']['speed']))
def ct_tempo (duration):
scene.objects['Terrain']['delay_cmd']=0
while scene.objects['Terrain']['delay_cmd']<duration*(1/scene.objects['Terrain']['speed']):
# print("Temporization commands :",scene.objects['Terrain']['delay_cmd'])
time.sleep(0.001)
# pass
def ct_tempo_wave (duration):
scene.objects['Terrain']['delay_wave']=0
while scene.objects['Terrain']['delay_wave']<duration*(1/scene.objects['Terrain']['speed']):
# print("Temporization waves :",scene.objects['Terrain']['delay_wave'])
time.sleep(0.001)
# pass
# def ct_tempo_wave_trigger (duree):
# print ("delay wave ", scene.objects['Terrain']['delay_wave'])
###############################################################################
# Affichage
###############################################################################
# Texte du panel d'information
def ct_print (texte):
def ct_print (text):
# text_info (texte)
if texte=="":
if text=="":
scene.objects['Text_info-1'].setVisible(False,False)
scene.objects['Text_info-2'].setVisible(False,False)
else:
lignes_txt=texte.split("\n", 6)
for i in range (len(lignes_txt),6):
lignes_txt.append("")
lines_txt=texte.split("\n", 6)
for i in range (len(lines_txt),6):
lines_txt.append("")
scene.objects['Text_info-1'].setVisible(True,False)
scene.objects['Text_info-2'].setVisible(True,False)
scene.objects['Text_info-1']['Text']=lignes_txt[0]+"\n"+lignes_txt[1]+"\n"+lignes_txt[2]
scene.objects['Text_info-2']['Text']=lignes_txt[3]+"\n"+lignes_txt[4]+"\n"+lignes_txt[5]
scene.objects['Text_info-1']['Text']=lines_txt[0]+"\n"+lines_txt[1]+"\n"+lines_txt[2]
scene.objects['Text_info-2']['Text']=lines_txt[3]+"\n"+lines_txt[4]+"\n"+lines_txt[5]
# Texte de carte
def ct_map_text(text):

View File

@ -5,7 +5,7 @@ from ct_lib import * # Bibliothèque CodeTower
# ct_map.py
# @title: Map definition
# @project: CodeTower
# @lang: fr
# @lang: fr,en
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL

87
ct_waves.py Normal file
View File

@ -0,0 +1,87 @@
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():
thread_stop(threads, "waves")
###############################################################################
# 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
# carac_minion={
# '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]}
def waves():
# Wave 1
ct_map_text("Wave 1")
for i in range (15):
ct_minion(14,3,"Knight",1)
# ct_tempo_wave (1)
ct_sleep (1)
ct_tempo_wave (20)
# # Wave 2
ct_map_text("Wave 2")
for i in range (20):
ct_minion(14,3,"Knight",1)
ct_sleep (1)
ct_sleep (2)
# ct_tempo_wave (2)
print ("Threads waves #", len(threads)-1, "are arrived -> close them.") # Thread closed << DONT CHANGE THIS LINE >>
scene.objects['Terrain']['thread_wave']=False # End of cycle << DONT CHANGE THIS LINE >>