Console
Clique sur « Exécuter » pour lancer le programme.
Code CoddyRun
@ CONFIGURATION
ecran est une toile
dimension(ecran, 640, 540)
COLS est un nombre
COLS vaut 16
RANGS est un nombre
RANGS vaut 11
TC est un nombre
TC vaut 40
MY est un nombre
MY vaut 40
VAGUES_MAX est un nombre
VAGUES_MAX vaut 20
@ LES TOURS (index 1 a 4)
tNom est un tableau
tNom vaut ["", "Archer", "Canon", "Glace", "Mage"]
tCout est un tableau
tCout vaut [0, 50, 90, 70, 140]
tPortee est un tableau
tPortee vaut [0, 110, 90, 90, 135]
tDegats est un tableau
tDegats vaut [0, 6, 22, 3, 2]
tCadence est un tableau
tCadence vaut [0, 10, 28, 14, 2]
tVolant est un tableau
tVolant vaut [0, 1, 0, 1, 1]
tDescr est un tableau
tDescr vaut ["", "Rapide, touche les volants", "Explose : dégâts de zone", "Ralentit les ennemis", "Rayon continu, longue portée"]
tCoul est un tableau
tCoul ajoute #000000
tCoul ajoute #8D6E63
tCoul ajoute #607D8B
tCoul ajoute #4FC3F7
tCoul ajoute #AB47BC
@ LES ENNEMIS (index 1 a 5)
eNom est un tableau
eNom vaut ["", "Gobelin", "Loup", "Orc", "Chauve-souris", "Troll"]
eBaseVie est un tableau
eBaseVie vaut [0, 20, 14, 70, 18, 600]
eBaseVit est un tableau
eBaseVit vaut [0, 1.1, 2, 0.7, 1.5, 0.5]
eBaseOr est un tableau
eBaseOr vaut [0, 5, 6, 12, 8, 100]
eBaseVol est un tableau
eBaseVol vaut [0, 0, 0, 0, 1, 0]
eBaseDegat est un tableau
eBaseDegat vaut [0, 1, 1, 2, 1, 5]
@ LES DEUX CARTES : les points de passage du chemin (colonne, rang)
carte1X est un tableau
carte1X vaut [-1, 4, 4, 9, 9, 13, 13, 16]
carte1Y est un tableau
carte1Y vaut [2, 2, 8, 8, 3, 3, 8, 8]
carte2X est un tableau
carte2X vaut [-1, 3, 3, 7, 7, 11, 11, 16]
carte2Y est un tableau
carte2Y vaut [5, 5, 1, 1, 9, 9, 4, 4]
nomsCartes est un tableau
nomsCartes vaut ["La Prairie", "Le Canyon"]
wpX est un tableau
wpY est un tableau
// la grille : 0 herbe (constructible), 1 chemin, 2 decor
terrain est un tableau
occupe est un tableau
@ LES OBJETS EN JEU
// tours
tourCol, tourRang, tourType, tourNiv, tourRecharge, tourDirX, tourDirY, tourTir, tourInvesti, tourCibleX, tourCibleY, tourMode est un tableau
// tourMode : 0 vise le premier monstre, 1 vise le plus resistant
// ennemis
enX, enY, enWp, enVie, enVieMax, enVit, enType, enRalenti, enActif, enDist est un tableau
// projectiles
prX, prY, prCible, prType, prDeg, prActif, prTX, prTY est un tableau
// effets
popTxt, popX, popY, popT est un tableau
paX, paY, paVX, paVY, paT, paC est un tableau
// la vague a venir
spawnTypes est un tableau
@ ETAT DU JEU
// etat : 0 titre, 1 jeu, 2 fin, 3 aide, 9 preparation
etat est un nombre
etat vaut 0
appActif, enPause, vagueEnCours, gagne est un booléen
appActif vaut vrai
carteChoisie, tresor, vies, vague, vitesseJeu, selType, selTour, tic est un nombre
spawnIdx, spawnChrono, flashChateau, tues est un nombre
message est un texte
action, ptX, ptY est un nombre
carteChoisie vaut 1
// --- la difficulte ---
difficulte est un nombre
difficulte vaut 1
diffNom est un tableau
diffNom vaut ["Facile", "Normal", "Difficile"]
diffVie est un tableau
diffVie vaut [0.75, 1, 1.3]
diffOr est un tableau
diffOr vaut [200, 150, 120]
diffVies est un tableau
diffVies vaut [30, 20, 10]
// --- les records : une case par carte et par difficulte ---
records est un tableau
kr est un nombre
pour kr de 0 à 5
valR est un nombre
essayer
valR vaut parametre('tower_defense', 'rec' + convertir_texte(kr))
attraper
valR vaut 0
fin essayer
records ajoute valR
fin pour
// --- l'aide ---
pageAide est un nombre
pageAide vaut 0
ecranRetour est un nombre
ecranRetour vaut 0
// --- entre deux vagues : un compte a rebours ---
compteVague est un nombre
compteVague vaut 0
DELAI_VAGUE est un nombre
DELAI_VAGUE vaut 330
prochaine est un tableau
// --- la pluie de feu (un sort a recharger) ---
sortRecharge est un nombre
sortRecharge vaut 0
SORT_DELAI est un nombre
SORT_DELAI vaut 800
flashSort est un nombre
flashSort vaut 0
// couleurs des monstres pour l'apercu de la vague
coulMonstre est un tableau
coulMonstre ajoute #000000
coulMonstre ajoute #8BC34A
coulMonstre ajoute #90A4AE
coulMonstre ajoute #33691E
coulMonstre ajoute #6A1B9A
coulMonstre ajoute #795548
@ OUTILS
fonction centreX(col)
retourne col * TC + TC / 2
fin fonction
fonction centreY(rang)
retourne MY + rang * TC + TC / 2
fin fonction
fonction distance(x1, y1, x2, y2)
retourne racine((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
fin fonction
fonction degatsTour(t)
retourne tDegats[tourType[t]] * (1 + 0.5 * (tourNiv[t] - 1))
fin fonction
fonction porteeTour(t)
retourne tPortee[tourType[t]] * (1 + 0.12 * (tourNiv[t] - 1))
fin fonction
fonction prixAmelioration(t)
retourne arrondi(tCout[tourType[t]] * 0.75 * tourNiv[t])
fin fonction
fonction ennemisVivants()
n est un nombre
n vaut 0
ke est un nombre
si longueur(enActif) > 0 alors
pour ke de 0 à longueur(enActif) - 1
si enActif[ke] alors
n ajoute 1
fin si
fin pour
fin si
retourne n
fin fonction
procédure ajouterPop(txt, x, y)
popTxt ajoute txt
popX ajoute x
popY ajoute y
popT ajoute 16
fin procédure
procédure exploser(x, y, coul, nb)
kx est un nombre
pour kx de 1 à nb
si longueur(paT) < 150 alors
paX ajoute x
paY ajoute y
paVX ajoute hasard(-5, 5)
paVY ajoute hasard(-6, 2)
paT ajoute hasard(8, 15)
paC ajoute coul
fin si
fin pour
fin procédure
@ PREPARER UNE PARTIE
procédure preparerCarte()
vide wpX
vide wpY
kw est un nombre
si carteChoisie = 1 alors
pour kw de 0 à longueur(carte1X) - 1
wpX ajoute carte1X[kw]
wpY ajoute carte1Y[kw]
fin pour
sinon
pour kw de 0 à longueur(carte2X) - 1
wpX ajoute carte2X[kw]
wpY ajoute carte2Y[kw]
fin pour
fin si
vide terrain
vide occupe
kc est un nombre
pour kc de 0 à COLS * RANGS - 1
terrain ajoute 0
occupe ajoute 0
fin pour
// on trace le chemin entre les points de passage
pour kw de 0 à longueur(wpX) - 2
cx est un nombre
cx vaut wpX[kw]
cy est un nombre
cy vaut wpY[kw]
fx est un nombre
fx vaut wpX[kw + 1]
fy est un nombre
fy vaut wpY[kw + 1]
tant que cx <> fx ou cy <> fy
si cx >= 0 et cx < COLS et cy >= 0 et cy < RANGS alors
terrain[cy * COLS + cx] vaut 1
fin si
cx vaut cx + signe(fx - cx)
cy vaut cy + signe(fy - cy)
fin tant que
si fx >= 0 et fx < COLS et fy >= 0 et fy < RANGS alors
terrain[fy * COLS + fx] vaut 1
fin si
fin pour
// quelques arbres et rochers
pour kc de 0 à COLS * RANGS - 1
si terrain[kc] = 0 et (kc * 7 + arrondi_inferieur(kc / COLS) * 13) mod 11 = 0 alors
terrain[kc] vaut 2
fin si
fin pour
fin procédure
procédure nouvellePartie()
appelle preparerCarte()
vide tourCol
vide tourRang
vide tourType
vide tourNiv
vide tourRecharge
vide tourDirX
vide tourDirY
vide tourTir
vide tourInvesti
vide tourCibleX
vide tourCibleY
vide tourMode
appelle viderVague()
tresor vaut diffOr[difficulte]
vies vaut diffVies[difficulte]
compteVague vaut 0
sortRecharge vaut 0
flashSort vaut 0
appelle genererProchaine(1)
vague vaut 0
vitesseJeu vaut 1
selType vaut 1
selTour vaut -1
tues vaut 0
flashChateau vaut 0
enPause vaut faux
vagueEnCours vaut faux
gagne vaut faux
message vaut "Place des tours le long du chemin, puis ESPACE pour lancer la vague 1."
fin procédure
procédure viderVague()
vide enX
vide enY
vide enWp
vide enVie
vide enVieMax
vide enVit
vide enType
vide enRalenti
vide enActif
vide enDist
vide prX
vide prY
vide prCible
vide prType
vide prDeg
vide prActif
vide prTX
vide prTY
vide popTxt
vide popX
vide popY
vide popT
vide paX
vide paY
vide paVX
vide paVY
vide paT
vide paC
fin procédure
@ LES VAGUES
// la composition d'une vague, preparee a l'avance pour pouvoir l'annoncer
procédure genererProchaine(w)
vide prochaine
nb est un nombre
nb vaut 6 + w * 2
ki est un nombre
pour ki de 1 à nb
r est un nombre
r vaut hasard(0, 99)
sorte est un nombre
sorte vaut 1
si w >= 3 et r < 25 alors
sorte vaut 2
sinon si w >= 4 et r >= 25 et r < 40 alors
sorte vaut 4
sinon si w >= 5 et r >= 40 et r < 58 alors
sorte vaut 3
fin si
prochaine ajoute sorte
fin pour
// un troll toutes les 5 vagues (deux a la derniere !)
si w mod 5 = 0 alors
prochaine ajoute 5
si w = VAGUES_MAX alors
prochaine ajoute 5
fin si
fin si
fin procédure
fonction compterDans(liste, sorte)
n est un nombre
n vaut 0
kc est un nombre
si longueur(liste) > 0 alors
pour kc de 0 à longueur(liste) - 1
si liste[kc] = sorte alors
n ajoute 1
fin si
fin pour
fin si
retourne n
fin fonction
procédure lancerVague()
si vagueEnCours alors
message vaut "La vague " + convertir_texte(vague) + " est déjà en cours !"
sinon
// appeler la vague en avance rapporte un bonus
bonusAvance est un nombre
bonusAvance vaut 0
si vague > 0 et compteVague > 0 alors
bonusAvance vaut arrondi(compteVague / 15)
tresor vaut tresor + bonusAvance
fin si
compteVague vaut 0
vague ajoute 1
appelle viderVague()
vide spawnTypes
kp est un nombre
pour kp de 0 à longueur(prochaine) - 1
spawnTypes ajoute prochaine[kp]
fin pour
appelle genererProchaine(vague + 1)
spawnIdx vaut 0
spawnChrono vaut 0
vagueEnCours vaut vrai
si vague mod 5 = 0 alors
message vaut "Vague " + convertir_texte(vague) + " : attention, un TROLL arrive !"
sinon
message vaut "Vague " + convertir_texte(vague) + " : " + convertir_texte(longueur(spawnTypes)) + " monstres en approche !"
fin si
si bonusAvance > 0 alors
message vaut message + " (bonus d'avance : +" + convertir_texte(bonusAvance) + " or)"
fin si
fin si
fin procédure
// le sort : une pluie de feu sur tous les monstres
procédure pluieDeFeu()
si sortRecharge > 0 alors
message vaut "La pluie de feu se recharge encore (" + convertir_texte(arrondi(sortRecharge / 16)) + " s)."
sinon si ennemisVivants() = 0 alors
message vaut "Aucun monstre à brûler pour l'instant !"
sinon
ke est un nombre
pour ke de 0 à longueur(enActif) - 1
si enActif[ke] alors
part est un nombre
part vaut sialors(enType[ke] = 5, 15, 40)
appelle exploser(enX[ke], enY[ke], #FF7043, 6)
appelle toucher(ke, arrondi(enVieMax[ke] * part / 100))
fin si
fin pour
sortRecharge vaut SORT_DELAI
flashSort vaut 8
message vaut "PLUIE DE FEU ! Tous les monstres sont brûlés."
fin si
fin procédure
procédure faireApparaitre(sorte)
enX ajoute wpX[0] * TC + TC / 2
enY ajoute centreY(wpY[0])
enWp ajoute 1
vieM est un nombre
vieM vaut arrondi(eBaseVie[sorte] * (1 + (vague - 1) * 0.18) * diffVie[difficulte])
enVie ajoute vieM
enVieMax ajoute vieM
enVit ajoute eBaseVit[sorte]
enType ajoute sorte
enRalenti ajoute 0
enActif ajoute vrai
enDist ajoute 0
fin procédure
procédure toucher(ke, deg)
si enActif[ke] alors
enVie[ke] vaut enVie[ke] - deg
si enVie[ke] <= 0 alors
enActif[ke] vaut faux
gain est un nombre
gain vaut eBaseOr[enType[ke]]
tresor vaut tresor + gain
tues ajoute 1
appelle ajouterPop("+" + convertir_texte(gain), enX[ke] - 8, enY[ke] - 14)
appelle exploser(enX[ke], enY[ke], #FFD54F, 6)
fin si
fin si
fin procédure
@ UNE IMAGE DE JEU
procédure mettreAJour()
ke est un nombre
kt est un nombre
kp est un nombre
// ---------- 0. Entre deux vagues : le compte a rebours ----------
si non vagueEnCours et vague > 0 et compteVague > 0 alors
compteVague soustrait 1
si compteVague = 0 alors
appelle lancerVague()
fin si
fin si
si sortRecharge > 0 alors
sortRecharge soustrait 1
fin si
si flashSort > 0 alors
flashSort soustrait 1
fin si
// ---------- 1. Les monstres sortent de la grotte ----------
si vagueEnCours et spawnIdx < longueur(spawnTypes) alors
spawnChrono ajoute 1
si spawnChrono >= maximum(10, 28 - vague) alors
spawnChrono vaut 0
appelle faireApparaitre(spawnTypes[spawnIdx])
spawnIdx ajoute 1
fin si
fin si
// ---------- 2. Ils avancent sur le chemin ----------
si longueur(enActif) > 0 alors
pour ke de 0 à longueur(enActif) - 1
si enActif[ke] alors
vit est un nombre
vit vaut enVit[ke]
si enRalenti[ke] > 0 alors
vit vaut vit * 0.45
enRalenti[ke] vaut enRalenti[ke] - 1
fin si
cibleX est un nombre
cibleX vaut wpX[enWp[ke]] * TC + TC / 2
cibleY est un nombre
cibleY vaut centreY(wpY[enWp[ke]])
dxe est un nombre
dxe vaut cibleX - enX[ke]
dye est un nombre
dye vaut cibleY - enY[ke]
distE est un nombre
distE vaut racine(dxe * dxe + dye * dye)
si distE <= vit alors
enX[ke] vaut cibleX
enY[ke] vaut cibleY
enWp[ke] vaut enWp[ke] + 1
si enWp[ke] >= longueur(wpX) alors
// il atteint le chateau !
enActif[ke] vaut faux
vies vaut vies - eBaseDegat[enType[ke]]
flashChateau vaut 8
appelle ajouterPop("-" + convertir_texte(eBaseDegat[enType[ke]]) + " vie", 560, 300)
fin si
sinon
enX[ke] vaut enX[ke] + dxe / distE * vit
enY[ke] vaut enY[ke] + dye / distE * vit
fin si
enDist[ke] vaut enDist[ke] + vit
fin si
fin pour
fin si
// ---------- 3. Les tours visent et tirent ----------
si longueur(tourType) > 0 alors
pour kt de 0 à longueur(tourType) - 1
si tourRecharge[kt] > 0 alors
tourRecharge[kt] vaut tourRecharge[kt] - 1
fin si
si tourTir[kt] > 0 alors
tourTir[kt] vaut tourTir[kt] - 1
fin si
tx est un nombre
tx vaut centreX(tourCol[kt])
ty est un nombre
ty vaut centreY(tourRang[kt])
// la cible : le monstre le plus avance a portee
meilleur est un nombre
meilleur vaut -1
meilleureDist est un nombre
meilleureDist vaut -1
portee est un nombre
portee vaut porteeTour(kt)
si longueur(enActif) > 0 alors
pour ke de 0 à longueur(enActif) - 1
si enActif[ke] alors
si eBaseVol[enType[ke]] = 0 ou tVolant[tourType[kt]] = 1 alors
si distance(tx, ty, enX[ke], enY[ke]) <= portee alors
// mode 0 : le plus avance ; mode 1 : celui qui a le plus de vie
critere est un nombre
critere vaut sialors(tourMode[kt] = 1, enVie[ke], enDist[ke])
si critere > meilleureDist alors
meilleur vaut ke
meilleureDist vaut critere
fin si
fin si
fin si
fin si
fin pour
fin si
si meilleur >= 0 alors
dc est un nombre
dc vaut maximum(1, distance(tx, ty, enX[meilleur], enY[meilleur]))
tourDirX[kt] vaut (enX[meilleur] - tx) / dc
tourDirY[kt] vaut (enY[meilleur] - ty) / dc
si tourRecharge[kt] = 0 alors
tourRecharge[kt] vaut tCadence[tourType[kt]]
si tourType[kt] = 4 alors
// le mage frappe directement avec son rayon
tourCibleX[kt] vaut enX[meilleur]
tourCibleY[kt] vaut enY[meilleur]
appelle toucher(meilleur, degatsTour(kt))
tourTir[kt] vaut 3
sinon
prX ajoute tx
prY ajoute ty - 12
prCible ajoute meilleur
prType ajoute tourType[kt]
prDeg ajoute degatsTour(kt)
prActif ajoute 1
prTX ajoute enX[meilleur]
prTY ajoute enY[meilleur]
tourTir[kt] vaut 4
fin si
fin si
fin si
fin pour
fin si
// ---------- 4. Les projectiles volent vers leur cible ----------
si longueur(prActif) > 0 alors
pour kp de 0 à longueur(prActif) - 1
si prActif[kp] = 1 alors
cible est un nombre
cible vaut prCible[kp]
si enActif[cible] alors
prTX[kp] vaut enX[cible]
prTY[kp] vaut enY[cible]
sinon si prType[kp] <> 2 alors
// la cible est morte : la fleche se perd
prActif[kp] vaut 0
fin si
si prActif[kp] = 1 alors
vitP est un nombre
vitP vaut sialors(prType[kp] = 2, 6, 9)
dxp est un nombre
dxp vaut prTX[kp] - prX[kp]
dyp est un nombre
dyp vaut prTY[kp] - prY[kp]
dp est un nombre
dp vaut racine(dxp * dxp + dyp * dyp)
si dp <= vitP alors
prActif[kp] vaut 0
si prType[kp] = 2 alors
// boulet de canon : explosion de zone
appelle exploser(prTX[kp], prTY[kp], #FF7043, 10)
pour ke de 0 à longueur(enActif) - 1
si enActif[ke] et eBaseVol[enType[ke]] = 0 alors
si distance(prTX[kp], prTY[kp], enX[ke], enY[ke]) <= 42 alors
appelle toucher(ke, prDeg[kp])
fin si
fin si
fin pour
sinon
si prType[kp] = 3 alors
enRalenti[cible] vaut 45
fin si
appelle toucher(cible, prDeg[kp])
fin si
sinon
prX[kp] vaut prX[kp] + dxp / dp * vitP
prY[kp] vaut prY[kp] + dyp / dp * vitP
fin si
fin si
fin si
fin pour
fin si
// ---------- 5. Effets ----------
nbE est un nombre
nbE vaut longueur(popT)
si nbE > 0 alors
pour kp de nbE - 1 à 0 pas -1
popT[kp] vaut popT[kp] - 1
popY[kp] vaut popY[kp] - 1
si popT[kp] <= 0 alors
popTxt supprime kp
popX supprime kp
popY supprime kp
popT supprime kp
fin si
fin pour
fin si
nbE vaut longueur(paT)
si nbE > 0 alors
pour kp de nbE - 1 à 0 pas -1
paX[kp] vaut paX[kp] + paVX[kp]
paY[kp] vaut paY[kp] + paVY[kp]
paVY[kp] vaut paVY[kp] + 0.6
paT[kp] vaut paT[kp] - 1
si paT[kp] <= 0 alors
paX supprime kp
paY supprime kp
paVX supprime kp
paVY supprime kp
paT supprime kp
paC supprime kp
fin si
fin pour
fin si
si flashChateau > 0 alors
flashChateau soustrait 1
fin si
// ---------- 6. Fin de vague, defaite, victoire ----------
si vies <= 0 alors
vies vaut 0
gagne vaut faux
appelle finirPartie()
sinon si vagueEnCours et spawnIdx >= longueur(spawnTypes) et ennemisVivants() = 0 alors
vagueEnCours vaut faux
bonus est un nombre
bonus vaut 20 + vague * 3
tresor vaut tresor + bonus
si vague >= VAGUES_MAX alors
gagne vaut vrai
appelle finirPartie()
sinon
compteVague vaut DELAI_VAGUE
message vaut "Vague " + convertir_texte(vague) + " repoussée ! +" + convertir_texte(bonus) + " or. ESPACE : vague suivante en avance (bonus)."
fin si
fin si
fin procédure
fonction numRecord()
retourne (carteChoisie - 1) * 3 + difficulte
fin fonction
procédure finirPartie()
si vague > records[numRecord()] alors
records[numRecord()] vaut vague
parametre('tower_defense', 'rec' + convertir_texte(numRecord()), vague)
fin si
etat vaut 2
fin procédure
@ LES ACTIONS DU JOUEUR
procédure cliquerCarte(x, y)
col est un nombre
col vaut arrondi_inferieur(x / TC)
rang est un nombre
rang vaut arrondi_inferieur((y - MY) / TC)
si col >= 0 et col < COLS et rang >= 0 et rang < RANGS alors
kc est un nombre
kc vaut rang * COLS + col
si occupe[kc] > 0 alors
selTour vaut occupe[kc] - 1
message vaut tNom[tourType[selTour]] + " niveau " + convertir_texte(tourNiv[selTour]) + " : U améliorer, V vendre"
sinon si terrain[kc] = 1 alors
selTour vaut -1
message vaut "On ne construit pas sur le chemin !"
sinon si terrain[kc] = 2 alors
selTour vaut -1
message vaut "Il y a un arbre ou un rocher ici."
sinon si tresor < tCout[selType] alors
selTour vaut -1
message vaut "Pas assez d'or pour un " + tNom[selType] + " (" + convertir_texte(tCout[selType]) + ")."
sinon
tresor vaut tresor - tCout[selType]
tourCol ajoute col
tourRang ajoute rang
tourType ajoute selType
tourNiv ajoute 1
tourRecharge ajoute 0
tourDirX ajoute 1
tourDirY ajoute 0
tourTir ajoute 0
tourInvesti ajoute tCout[selType]
tourCibleX ajoute 0
tourCibleY ajoute 0
tourMode ajoute 0
occupe[kc] vaut longueur(tourType)
selTour vaut longueur(tourType) - 1
appelle exploser(centreX(col), centreY(rang), #FFFFFF, 8)
message vaut tNom[selType] + " construit ! (U pour l'améliorer)"
fin si
sinon si y > 480 alors
// la barre du bas : choisir une tour
kb est un nombre
pour kb de 0 à 3
si x >= 8 + kb * 118 et x < 8 + kb * 118 + 112 alors
selType vaut kb + 1
selTour vaut -1
message vaut tNom[selType] + " : " + tDescr[selType]
fin si
fin pour
fin si
fin procédure
procédure ameliorer()
si selTour < 0 alors
message vaut "Clique d'abord sur une tour."
sinon si tourNiv[selTour] >= 3 alors
message vaut "Cette tour est déjà au niveau maximum."
sinon si tresor < prixAmelioration(selTour) alors
message vaut "Il faut " + convertir_texte(prixAmelioration(selTour)) + " or pour l'améliorer."
sinon
prix est un nombre
prix vaut prixAmelioration(selTour)
tresor vaut tresor - prix
tourInvesti[selTour] vaut tourInvesti[selTour] + prix
tourNiv[selTour] vaut tourNiv[selTour] + 1
appelle exploser(centreX(tourCol[selTour]), centreY(tourRang[selTour]), #FFEB3B, 12)
message vaut tNom[tourType[selTour]] + " passe au niveau " + convertir_texte(tourNiv[selTour]) + " !"
fin si
fin procédure
procédure changerMode()
si selTour < 0 alors
message vaut "Clique d'abord sur une tour."
sinon
tourMode[selTour] vaut 1 - tourMode[selTour]
si tourMode[selTour] = 0 alors
message vaut tNom[tourType[selTour]] + " vise maintenant le PREMIER monstre."
sinon
message vaut tNom[tourType[selTour]] + " vise maintenant le plus RÉSISTANT."
fin si
fin si
fin procédure
procédure vendreTour()
si selTour < 0 alors
message vaut "Clique d'abord sur une tour."
sinon
rendu est un nombre
rendu vaut arrondi(tourInvesti[selTour] * 0.6)
tresor vaut tresor + rendu
occupe[tourRang[selTour] * COLS + tourCol[selTour]] vaut 0
// on retire la tour de toutes les listes
tourCol supprime selTour
tourRang supprime selTour
tourType supprime selTour
tourNiv supprime selTour
tourRecharge supprime selTour
tourDirX supprime selTour
tourDirY supprime selTour
tourTir supprime selTour
tourInvesti supprime selTour
tourCibleX supprime selTour
tourCibleY supprime selTour
tourMode supprime selTour
// les numeros des tours suivantes ont change : on refait la grille
kc est un nombre
pour kc de 0 à COLS * RANGS - 1
occupe[kc] vaut 0
fin pour
si longueur(tourType) > 0 alors
kt est un nombre
pour kt de 0 à longueur(tourType) - 1
occupe[tourRang[kt] * COLS + tourCol[kt]] vaut kt + 1
fin pour
fin si
selTour vaut -1
message vaut "Tour vendue : +" + convertir_texte(rendu) + " or."
fin si
fin procédure
@ DESSIN : LA CARTE
procédure dessinerCarte()
kc est un nombre
pour kc de 0 à COLS * RANGS - 1
x est un nombre
x vaut (kc mod COLS) * TC
y est un nombre
y vaut MY + arrondi_inferieur(kc / COLS) * TC
si terrain[kc] = 1 alors
rectangle(ecran, x, y, TC, TC, #D7B98E)
si (kc + arrondi_inferieur(kc / COLS)) mod 3 = 0 alors
cercle(ecran, x + 12, y + 28, 2, #BFA27A)
cercle(ecran, x + 30, y + 10, 2, #BFA27A)
fin si
sinon
si (kc + arrondi_inferieur(kc / COLS)) mod 2 = 0 alors
rectangle(ecran, x, y, TC, TC, #6FB45A)
sinon
rectangle(ecran, x, y, TC, TC, #66AA52)
fin si
si terrain[kc] = 2 alors
si kc mod 3 = 0 alors
// un rocher
ellipse(ecran, x + 20, y + 28, 13, 5, rgba(0, 0, 0, 0.2))
polygone(ecran, [x + 8, y + 30, x + 13, y + 15, x + 24, y + 11, x + 33, y + 20, x + 32, y + 30], #90A4AE)
polygone(ecran, [x + 14, y + 22, x + 22, y + 15, x + 28, y + 21], #CFD8DC)
sinon
// un arbre
ellipse(ecran, x + 20, y + 32, 12, 4, rgba(0, 0, 0, 0.2))
rectangle(ecran, x + 18, y + 22, 5, 10, #6D4C41)
cercle(ecran, x + 20, y + 16, 12, #2E7D32)
cercle(ecran, x + 15, y + 20, 7, #388E3C)
cercle(ecran, x + 25, y + 13, 5, #43A047)
fin si
sinon si (kc * 7) mod 9 = 0 alors
// des petites fleurs
cercle(ecran, x + 10, y + 12, 2, #FFF176)
cercle(ecran, x + 28, y + 30, 2, #F48FB1)
fin si
fin si
fin pour
// la grotte d'ou sortent les monstres
gy est un nombre
gy vaut centreY(wpY[0])
ellipse(ecran, 6, gy, 18, 22, #5D4037)
ellipse(ecran, 6, gy + 2, 11, 15, #1B1B1B)
// le chateau a defendre
cyc est un nombre
cyc vaut centreY(wpY[longueur(wpY) - 1])
si flashChateau > 0 et flashChateau mod 2 = 0 alors
rectangle(ecran, 600, cyc - 46, 40, 72, #EF5350)
sinon
rectangle(ecran, 600, cyc - 46, 40, 72, #B0BEC5)
fin si
rectangle(ecran, 600, cyc - 56, 10, 12, #90A4AE)
rectangle(ecran, 618, cyc - 56, 10, 12, #90A4AE)
rectangle(ecran, 606, cyc - 2, 18, 28, #5D4037)
ligne(ecran, 623, cyc - 56, 623, cyc - 82, #6D4C41, 2)
polygone(ecran, [623, cyc - 82, 639, cyc - 76 + (tic mod 6) / 2, 623, cyc - 70], #E53935)
fin procédure
procédure dessinerUneTour(x, y, ty, niv, dirX, dirY, tir)
// le socle en pierre
rectangle_arrondi(ecran, x - 17, y - 13, 34, 30, 6, #78909C)
rectangle_arrondi(ecran, x - 15, y - 15, 30, 28, 6, #B0BEC5)
si ty = 1 alors
// ARCHER : tour en bois et toit rouge
rectangle(ecran, x - 9, y - 22, 18, 22, #8D6E63)
triangle(ecran, x - 13, y - 21, x + 13, y - 21, x, y - 36, #C62828)
ligne(ecran, x, y - 10, x + dirX * 16, y - 10 + dirY * 16, #4E342E, 2)
sinon si ty = 2 alors
// CANON : il pivote vers sa cible
cercle(ecran, x, y - 4, 11, #455A64)
ligne(ecran, x, y - 4, x + dirX * 18, y - 4 + dirY * 18, #263238, 7)
si tir > 0 alors
cercle(ecran, x + dirX * 20, y - 4 + dirY * 20, 5, #FFB74D)
fin si
sinon si ty = 3 alors
// GLACE : un cristal qui pulse
pulse est un nombre
pulse vaut sialors(tic mod 10 < 5, 2, 0)
cercle(ecran, x, y - 12, 13 + pulse, rgba(79, 195, 247, 0.25))
polygone(ecran, [x, y - 30, x + 9, y - 12, x, y + 2, x - 9, y - 12], #4FC3F7)
polygone(ecran, [x, y - 30, x + 3, y - 12, x, y + 2, x - 3, y - 12], #E1F5FE)
sinon
// MAGE : tour violette et orbe brillant
rectangle(ecran, x - 8, y - 22, 16, 22, #7B1FA2)
triangle(ecran, x - 11, y - 21, x + 11, y - 21, x, y - 38, #4A148C)
cercle(ecran, x, y - 40, 5 + sialors(tic mod 6 < 3, 1, 0), #E1BEE7)
fin si
// le niveau : des petits points
kn est un nombre
pour kn de 1 à niv
cercle(ecran, x - 12 + kn * 6, y + 11, 2.5, #FFD54F)
fin pour
fin procédure
procédure dessinerTours()
kt est un nombre
si longueur(tourType) > 0 alors
pour kt de 0 à longueur(tourType) - 1
x est un nombre
x vaut centreX(tourCol[kt])
y est un nombre
y vaut centreY(tourRang[kt])
appelle dessinerUneTour(x, y, tourType[kt], tourNiv[kt], tourDirX[kt], tourDirY[kt], tourTir[kt])
// la tour selectionnee montre sa portee
si kt = selTour alors
contour(ecran, #FFFFFF, 2)
cercle(ecran, x, y, porteeTour(kt), rgba(255, 255, 255, 0.1))
contour(ecran, #0)
fin si
fin pour
fin si
fin procédure
procédure dessinerUnEnnemi(x, y, sorte, anim)
pas2 est un nombre
pas2 vaut sialors((tic + anim * 3) mod 8 < 4, 0, 2)
si sorte = 1 alors
// GOBELIN
ellipse(ecran, x, y + 9, 8, 3, rgba(0, 0, 0, 0.25))
rectangle_arrondi(ecran, x - 5, y - 4 - pas2, 10, 12, 3, #5D4037)
cercle(ecran, x, y - 8 - pas2, 6, #8BC34A)
triangle(ecran, x - 5, y - 9 - pas2, x - 12, y - 13 - pas2, x - 4, y - 5 - pas2, #8BC34A)
triangle(ecran, x + 5, y - 9 - pas2, x + 12, y - 13 - pas2, x + 4, y - 5 - pas2, #8BC34A)
cercle(ecran, x + 2, y - 9 - pas2, 1.5, #D32F2F)
sinon si sorte = 2 alors
// LOUP
ellipse(ecran, x, y + 8, 12, 3, rgba(0, 0, 0, 0.25))
ellipse(ecran, x, y - pas2, 12, 6, #78909C)
cercle(ecran, x + 10, y - 5 - pas2, 5, #90A4AE)
triangle(ecran, x + 8, y - 9 - pas2, x + 11, y - 15 - pas2, x + 13, y - 9 - pas2, #78909C)
ligne(ecran, x - 7, y + 3, x - 8 + pas2, y + 8, #546E7A, 2)
ligne(ecran, x + 6, y + 3, x + 7 - pas2, y + 8, #546E7A, 2)
cercle(ecran, x + 12, y - 6 - pas2, 1, #FFEB3B)
sinon si sorte = 3 alors
// ORC
ellipse(ecran, x, y + 11, 12, 4, rgba(0, 0, 0, 0.25))
rectangle_arrondi(ecran, x - 10, y - 8 - pas2, 20, 18, 5, #4E342E)
cercle(ecran, x, y - 13 - pas2, 8, #33691E)
triangle(ecran, x - 4, y - 9 - pas2, x - 2, y - 9 - pas2, x - 3, y - 13 - pas2, #FFFFFF)
triangle(ecran, x + 2, y - 9 - pas2, x + 4, y - 9 - pas2, x + 3, y - 13 - pas2, #FFFFFF)
ligne(ecran, x + 10, y - 2, x + 16, y - 16, #6D4C41, 4)
sinon si sorte = 4 alors
// CHAUVE-SOURIS : elle vole, on voit son ombre au sol
ellipse(ecran, x, y + 12, 7, 2, rgba(0, 0, 0, 0.2))
aile est un nombre
aile vaut sialors(tic mod 6 < 3, 10, 4)
triangle(ecran, x - 3, y - 10, x - 15, y - 10 - aile, x - 12, y - 4, #6A1B9A)
triangle(ecran, x + 3, y - 10, x + 15, y - 10 - aile, x + 12, y - 4, #6A1B9A)
cercle(ecran, x, y - 9, 5, #4A148C)
cercle(ecran, x - 2, y - 10, 1, #FF5252)
cercle(ecran, x + 2, y - 10, 1, #FF5252)
sinon
// TROLL : le boss
ellipse(ecran, x, y + 15, 20, 6, rgba(0, 0, 0, 0.3))
rectangle_arrondi(ecran, x - 16, y - 14 - pas2, 32, 28, 8, #795548)
cercle(ecran, x, y - 22 - pas2, 12, #8D6E63)
cercle(ecran, x - 4, y - 24 - pas2, 2, #FFEB3B)
cercle(ecran, x + 4, y - 24 - pas2, 2, #FFEB3B)
ligne(ecran, x - 16, y - 6, x - 24, y + 6, #6D4C41, 6)
ligne(ecran, x + 16, y - 6, x + 26, y - 20, #5D4037, 7)
fin si
fin procédure
procédure dessinerEnnemis()
ke est un nombre
si longueur(enActif) > 0 alors
pour ke de 0 à longueur(enActif) - 1
si enActif[ke] alors
x est un nombre
x vaut enX[ke]
y est un nombre
y vaut enY[ke]
sorte est un nombre
sorte vaut enType[ke]
appelle dessinerUnEnnemi(x, y, sorte, ke)
// ralenti par la glace
si enRalenti[ke] > 0 alors
cercle(ecran, x, y - 4, 12, rgba(129, 212, 250, 0.35))
fin si
// barre de vie
largV est un nombre
largV vaut sialors(sorte = 5, 36, 22)
rectangle(ecran, x - largV / 2, y - 26 - sialors(sorte = 5, 14, 0), largV, 4, rgba(0, 0, 0, 0.55))
rectangle(ecran, x - largV / 2, y - 26 - sialors(sorte = 5, 14, 0), largV * maximum(0, enVie[ke]) / enVieMax[ke], 4, #66BB6A)
fin si
fin pour
fin si
fin procédure
procédure dessinerTirs()
kp est un nombre
si longueur(prActif) > 0 alors
pour kp de 0 à longueur(prActif) - 1
si prActif[kp] = 1 alors
si prType[kp] = 1 alors
// une fleche
dxf est un nombre
dxf vaut prTX[kp] - prX[kp]
dyf est un nombre
dyf vaut prTY[kp] - prY[kp]
df est un nombre
df vaut maximum(1, racine(dxf * dxf + dyf * dyf))
ligne(ecran, prX[kp], prY[kp], prX[kp] - dxf / df * 10, prY[kp] - dyf / df * 10, #4E342E, 2)
cercle(ecran, prX[kp], prY[kp], 1.5, #ECEFF1)
sinon si prType[kp] = 2 alors
cercle(ecran, prX[kp], prY[kp], 5, #212121)
cercle(ecran, prX[kp] - 1, prY[kp] - 1, 2, #757575)
sinon
cercle(ecran, prX[kp], prY[kp], 5, rgba(129, 212, 250, 0.4))
cercle(ecran, prX[kp], prY[kp], 3, #E1F5FE)
fin si
fin si
fin pour
fin si
// les rayons des mages
kt est un nombre
si longueur(tourType) > 0 alors
pour kt de 0 à longueur(tourType) - 1
si tourType[kt] = 4 et tourTir[kt] > 0 alors
x est un nombre
x vaut centreX(tourCol[kt])
y est un nombre
y vaut centreY(tourRang[kt]) - 40
ligne(ecran, x, y, tourCibleX[kt], tourCibleY[kt] - 6, rgba(206, 147, 216, 0.45), 7)
ligne(ecran, x, y, tourCibleX[kt], tourCibleY[kt] - 6, #F3E5F5, 2)
cercle(ecran, tourCibleX[kt], tourCibleY[kt] - 6, 6, rgba(225, 190, 231, 0.6))
fin si
fin pour
fin si
fin procédure
procédure dessinerEffets()
kp est un nombre
si longueur(paT) > 0 alors
pour kp de 0 à longueur(paT) - 1
cercle(ecran, paX[kp], paY[kp], 2.5, paC[kp])
fin pour
fin si
si longueur(popT) > 0 alors
pour kp de 0 à longueur(popT) - 1
label(ecran, popX[kp], popY[kp], popTxt[kp], #FFD54F, 13)
fin pour
fin si
fin procédure
procédure dessinerInterface()
// en haut
rectangle(ecran, 0, 0, 640, 40, #263238)
cercle(ecran, 20, 20, 9, #FFD54F)
cercle(ecran, 20, 20, 6, #FFA000)
label(ecran, 36, 26, convertir_texte(tresor), #FFE082, 17)
cercle(ecran, 128, 18, 5, #EF5350)
cercle(ecran, 136, 18, 5, #EF5350)
triangle(ecran, 123, 20, 141, 20, 132, 29, #EF5350)
label(ecran, 148, 26, convertir_texte(vies), #FFFFFF, 17)
label(ecran, 200, 26, "Vague " + convertir_texte(vague) + " / " + convertir_texte(VAGUES_MAX), #FFFFFF, 15)
// la pluie de feu et sa recharge
si sortRecharge = 0 alors
rectangle_arrondi(ecran, 300, 8, 96, 24, 10, #E64A19)
label(ecran, 308, 25, "F : feu prêt", #FFFFFF, 12)
sinon
rectangle_arrondi(ecran, 300, 8, 96, 24, 10, rgba(255, 255, 255, 0.1))
rectangle_arrondi(ecran, 300, 8, 96 * (SORT_DELAI - sortRecharge) / SORT_DELAI, 24, 10, rgba(230, 74, 25, 0.5))
label(ecran, 308, 25, "F : feu " + convertir_texte(arrondi(sortRecharge / 16)) + " s", #FFCCBC, 12)
fin si
si vitesseJeu = 2 alors
rectangle_arrondi(ecran, 404, 9, 34, 22, 10, #FF7043)
label(ecran, 410, 25, "x2", #FFFFFF, 14)
fin si
si non vagueEnCours alors
rectangle_arrondi(ecran, 444, 7, 190, 26, 12, #43A047)
si vague > 0 et compteVague > 0 alors
// la barre se vide : la vague partira toute seule
rectangle_arrondi(ecran, 444, 7, 190 * compteVague / DELAI_VAGUE, 26, 12, #2E7D32)
label(ecran, 452, 25, "ESPACE : vague " + convertir_texte(vague + 1) + " (+" + convertir_texte(arrondi(compteVague / 15)) + " or)", #FFFFFF, 12)
sinon
si tic mod 20 < 14 alors
label(ecran, 452, 25, "ESPACE : lancer la vague " + convertir_texte(vague + 1), #FFFFFF, 12)
fin si
fin si
sinon
label(ecran, 452, 25, "Monstres : " + convertir_texte(ennemisVivants() + longueur(spawnTypes) - spawnIdx), #FFAB91, 13)
fin si
// la barre de vie du troll, s'il est la
kt est un nombre
si longueur(enActif) > 0 alors
pour kt de 0 à longueur(enActif) - 1
si enActif[kt] et enType[kt] = 5 alors
rectangle_arrondi(ecran, 170, 46, 300, 18, 8, rgba(0, 0, 0, 0.6))
rectangle_arrondi(ecran, 170, 46, 300 * enVie[kt] / enVieMax[kt], 18, 8, #8D6E63)
label(ecran, 180, 60, "TROLL", #FFFFFF, 12)
fin si
fin pour
fin si
si flashSort > 0 alors
rectangle(ecran, 0, 40, 640, 440, rgba(255, 112, 67, 0.04 * flashSort))
fin si
// en bas : les tours a construire
rectangle(ecran, 0, 480, 640, 60, #263238)
kb est un nombre
pour kb de 0 à 3
bx est un nombre
bx vaut 8 + kb * 118
si kb + 1 = selType et selTour < 0 alors
contour(ecran, #FFD54F, 2)
rectangle_arrondi(ecran, bx, 486, 112, 48, 8, rgba(255, 213, 79, 0.15))
sinon
contour(ecran, rgba(255, 255, 255, 0.15), 1)
rectangle_arrondi(ecran, bx, 486, 112, 48, 8, rgba(255, 255, 255, 0.05))
fin si
contour(ecran, #0)
cercle(ecran, bx + 18, 510, 11, tCoul[kb + 1])
label(ecran, bx + 14, 515, convertir_texte(kb + 1), #FFFFFF, 12)
label(ecran, bx + 36, 505, tNom[kb + 1], #FFFFFF, 13)
si tresor >= tCout[kb + 1] alors
label(ecran, bx + 36, 524, convertir_texte(tCout[kb + 1]) + " or", #FFE082, 12)
sinon
label(ecran, bx + 36, 524, convertir_texte(tCout[kb + 1]) + " or", #E57373, 12)
fin si
fin pour
// la tour selectionnee
si selTour >= 0 alors
contour(ecran, tCoul[tourType[selTour]], 2)
rectangle_arrondi(ecran, 482, 486, 152, 48, 8, rgba(255, 255, 255, 0.06))
contour(ecran, #0)
label(ecran, 490, 502, tNom[tourType[selTour]] + " niv. " + convertir_texte(tourNiv[selTour]), #FFFFFF, 12)
si tourNiv[selTour] < 3 alors
label(ecran, 490, 516, "U : améliorer (" + convertir_texte(prixAmelioration(selTour)) + ")", #A5D6A7, 10)
sinon
label(ecran, 490, 516, "Niveau maximum", #A5D6A7, 10)
fin si
label(ecran, 490, 529, "V : vendre (" + convertir_texte(arrondi(tourInvesti[selTour] * 0.6)) + ")", #FFCC80, 10)
si tourMode[selTour] = 0 alors
label(ecran, 568, 502, "T : 1er", #90CAF9, 10)
sinon
label(ecran, 568, 502, "T : fort", #F48FB1, 10)
fin si
sinon
// l'apercu de la prochaine vague
label(ecran, 488, 500, "Vague " + convertir_texte(sialors(vagueEnCours, vague + 1, vague + 1)) + " :", #B0BEC5, 10)
km est un nombre
xm est un nombre
xm vaut 492
pour km de 1 à 5
nbM est un nombre
nbM vaut compterDans(prochaine, km)
si nbM > 0 alors
cercle(ecran, xm, 520, 6, coulMonstre[km])
label(ecran, xm + 8, 525, convertir_texte(nbM), #FFFFFF, 11)
xm vaut xm + 28
fin si
fin pour
label(ecran, 560, 500, "H : aide", #78909C, 10)
fin si
// le message
rectangle(ecran, 0, 460, 640, 20, rgba(0, 0, 0, 0.55))
label(ecran, 8, 475, message, #FFFFFF, 12)
si enPause alors
rectangle(ecran, 0, 40, 640, 440, rgba(0, 0, 0, 0.45))
label(ecran, 320 - label_largeur("PAUSE", 40) / 2, 250, "PAUSE", #FFFFFF, 40)
label(ecran, 320 - label_largeur("P : reprendre X : menu", 15) / 2, 282, "P : reprendre X : menu", #B0BEC5, 15)
fin si
fin procédure
procédure dessinerJeu()
effacer(ecran)
contour(ecran, #0)
appelle dessinerCarte()
appelle dessinerTours()
appelle dessinerEnnemis()
appelle dessinerTirs()
appelle dessinerEffets()
appelle dessinerInterface()
fin procédure
procédure dessinerTitre()
effacer(ecran)
contour(ecran, #0)
appelle dessinerCarte()
rectangle(ecran, 0, 0, 640, 540, rgba(0, 0, 0, 0.35))
rectangle_arrondi(ecran, 90, 80, 460, 350, 18, rgba(38, 50, 56, 0.95))
label(ecran, 320 - label_largeur("LA DÉFENSE", 34) / 2, 135, "LA DÉFENSE", #FFD54F, 34)
label(ecran, 320 - label_largeur("DU ROYAUME", 34) / 2, 172, "DU ROYAUME", #FFD54F, 34)
label(ecran, 320 - label_largeur("Arrête 20 vagues de monstres avant ton château !", 14) / 2, 202, "Arrête 20 vagues de monstres avant ton château !", #CFD8DC, 14)
label(ecran, 320 - label_largeur("Choisis ta carte (1 ou 2) :", 14) / 2, 240, "Choisis ta carte (1 ou 2) :", #FFFFFF, 14)
kc est un nombre
pour kc de 0 à 1
bx est un nombre
bx vaut 130 + kc * 200
si kc + 1 = carteChoisie alors
contour(ecran, #FFD54F, 3)
rectangle_arrondi(ecran, bx, 256, 180, 66, 12, rgba(255, 213, 79, 0.18))
sinon
contour(ecran, rgba(255, 255, 255, 0.2), 1)
rectangle_arrondi(ecran, bx, 256, 180, 66, 12, rgba(255, 255, 255, 0.05))
fin si
contour(ecran, #0)
label(ecran, bx + 90 - label_largeur(convertir_texte(kc + 1) + ". " + nomsCartes[kc], 16) / 2, 284, convertir_texte(kc + 1) + ". " + nomsCartes[kc], #FFFFFF, 16)
si records[kc * 3 + difficulte] > 0 alors
label(ecran, bx + 90 - label_largeur("Record : vague " + convertir_texte(records[kc * 3 + difficulte]), 12) / 2, 308, "Record : vague " + convertir_texte(records[kc * 3 + difficulte]), #A5D6A7, 12)
sinon
label(ecran, bx + 90 - label_largeur("Pas encore jouée", 12) / 2, 308, "Pas encore jouée", #90A4AE, 12)
fin si
fin pour
label(ecran, 320 - label_largeur("Difficulté : < " + diffNom[difficulte] + " > (Q / D)", 15) / 2, 352, "Difficulté : < " + diffNom[difficulte] + " > (Q / D)", #FFE082, 15)
label(ecran, 320 - label_largeur("ESPACE : jouer H : aide X : quitter", 16) / 2, 386, "ESPACE : jouer H : aide X : quitter", #69F0AE, 16)
label(ecran, 320 - label_largeur("Archer 50 · Canon 90 · Glace 70 · Mage 140", 12) / 2, 410, "Archer 50 · Canon 90 · Glace 70 · Mage 140", #90A4AE, 12)
fin procédure
procédure dessinerAide()
effacer(ecran)
contour(ecran, #0)
appelle dessinerCarte()
rectangle(ecran, 0, 0, 640, 540, rgba(15, 25, 30, 0.88))
label(ecran, 30, 46, "AIDE", #FFD54F, 30)
label(ecran, 520, 44, "Page " + convertir_texte(pageAide + 1) + " / 4", #90A4AE, 13)
ligne(ecran, 30, 58, 610, 58, #455A64, 2)
kh est un nombre
yh est un nombre
si pageAide = 0 alors
label(ecran, 30, 90, "LE BUT DU JEU", #69F0AE, 16)
label(ecran, 30, 114, "Les monstres sortent de la grotte (à gauche) et suivent le chemin.", #ECEFF1, 13)
label(ecran, 30, 134, "S'ils atteignent ton château (à droite), tu perds des vies.", #ECEFF1, 13)
label(ecran, 30, 154, "Tiens bon pendant 20 vagues pour sauver le royaume !", #ECEFF1, 13)
label(ecran, 30, 194, "LES COMMANDES", #69F0AE, 16)
label(ecran, 30, 220, "1 2 3 4 choisir une tour", #ECEFF1, 13)
label(ecran, 30, 242, "Clic herbe construire la tour choisie", #ECEFF1, 13)
label(ecran, 30, 264, "Clic tour la sélectionner (sa portée s'affiche)", #ECEFF1, 13)
label(ecran, 30, 286, "U / V améliorer (jusqu'au niveau 3) / vendre", #ECEFF1, 13)
label(ecran, 30, 308, "T changer la cible : le 1er monstre ou le plus fort", #ECEFF1, 13)
label(ecran, 30, 330, "ESPACE lancer la vague (en avance = bonus d'or)", #ECEFF1, 13)
label(ecran, 30, 352, "F pluie de feu : brûle tous les monstres", #ECEFF1, 13)
label(ecran, 30, 374, "A vitesse x2 P pause H aide", #ECEFF1, 13)
label(ecran, 30, 414, "Entre deux vagues, une barre verte se vide : quand elle est vide,", #FFE082, 12)
label(ecran, 30, 432, "la vague suivante part toute seule !", #FFE082, 12)
sinon si pageAide = 1 alors
label(ecran, 30, 90, "LES TOURS", #69F0AE, 16)
pour kh de 1 à 4
yh vaut 100 + kh * 84
rectangle_arrondi(ecran, 30, yh - 66, 580, 76, 10, rgba(255, 255, 255, 0.05))
appelle dessinerUneTour(72, yh - 18, kh, 1, 1, 0, 0)
label(ecran, 110, yh - 42, tNom[kh] + " - " + convertir_texte(tCout[kh]) + " or", tCoul[kh], 15)
label(ecran, 110, yh - 22, tDescr[kh], #ECEFF1, 12)
label(ecran, 110, yh - 4, "Portée : " + convertir_texte(arrondi(tPortee[kh] / 40 * 10) / 10) + " cases Dégâts : " + convertir_texte(tDegats[kh]) + " Tirs/s : " + convertir_texte(arrondi(166 / tCadence[kh]) / 10), #B0BEC5, 11)
si tVolant[kh] = 1 alors
label(ecran, 470, yh - 42, "Touche les volants", #A5D6A7, 11)
sinon
label(ecran, 470, yh - 42, "Pas les volants !", #EF9A9A, 11)
fin si
fin pour
label(ecran, 30, 470, "Chaque amélioration : +50 % de dégâts et +12 % de portée.", #FFE082, 12)
sinon si pageAide = 2 alors
label(ecran, 30, 90, "LES MONSTRES", #69F0AE, 16)
pour kh de 1 à 5
yh vaut 96 + kh * 70
rectangle_arrondi(ecran, 30, yh - 56, 580, 62, 10, rgba(255, 255, 255, 0.05))
appelle dessinerUnEnnemi(72, yh - 18, kh, kh)
label(ecran, 110, yh - 32, eNom[kh], coulMonstre[kh], 15)
label(ecran, 110, yh - 12, "Vie : " + convertir_texte(eBaseVie[kh]) + " Vitesse : " + convertir_texte(eBaseVit[kh]) + " Rapporte : " + convertir_texte(eBaseOr[kh]) + " or Château : -" + convertir_texte(eBaseDegat[kh]), #B0BEC5, 11)
si eBaseVol[kh] = 1 alors
label(ecran, 470, yh - 32, "VOLANT", #CE93D8, 12)
fin si
si kh = 5 alors
label(ecran, 470, yh - 32, "BOSS (vagues 5, 10...)", #FFAB91, 11)
fin si
fin pour
label(ecran, 30, 470, "Les monstres deviennent plus résistants à chaque vague.", #FFE082, 12)
sinon
label(ecran, 30, 90, "ASTUCES DE STRATÈGE", #69F0AE, 16)
label(ecran, 30, 122, "- Construis dans les VIRAGES : une tour y couvre deux bouts du chemin.", #ECEFF1, 13)
label(ecran, 30, 148, "- La GLACE ralentit, le CANON explose : ensemble, ils sont redoutables.", #ECEFF1, 13)
label(ecran, 30, 174, "- Le canon ne touche pas les CHAUVES-SOURIS : garde des archers !", #ECEFF1, 13)
label(ecran, 30, 200, "- Contre le TROLL, règle des tours sur « le plus fort » (touche T).", #ECEFF1, 13)
label(ecran, 30, 226, "- Garde la PLUIE DE FEU pour les moments chauds ou pour le troll.", #ECEFF1, 13)
label(ecran, 30, 252, "- Appeler la vague en avance rapporte de l'or... si tu es prêt !", #ECEFF1, 13)
label(ecran, 30, 278, "- Améliorer une tour coûte souvent moins cher qu'en construire une.", #ECEFF1, 13)
label(ecran, 30, 320, "LES DIFFICULTÉS", #69F0AE, 16)
label(ecran, 30, 346, "Facile : 200 or, 30 vies, monstres plus faibles", #A5D6A7, 13)
label(ecran, 30, 368, "Normal : 150 or, 20 vies", #FFE082, 13)
label(ecran, 30, 390, "Difficile : 120 or, 10 vies, monstres plus résistants", #EF9A9A, 13)
fin si
label(ecran, 320 - label_largeur("Q / D : changer de page ESPACE ou H : retour", 13) / 2, 520, "Q / D : changer de page ESPACE ou H : retour", #90A4AE, 13)
fin procédure
procédure dessinerFin()
appelle dessinerJeu()
rectangle(ecran, 0, 0, 640, 540, rgba(0, 0, 0, 0.5))
rectangle_arrondi(ecran, 120, 140, 400, 230, 18, rgba(38, 50, 56, 0.97))
si gagne alors
rectangle_arrondi(ecran, 120, 140, 400, 6, 3, #69F0AE)
label(ecran, 320 - label_largeur("LE ROYAUME EST SAUVÉ !", 26) / 2, 190, "LE ROYAUME EST SAUVÉ !", #FFD54F, 26)
etoiles est un nombre
etoiles vaut 1
si vies >= 15 alors
etoiles vaut 3
sinon si vies >= 8 alors
etoiles vaut 2
fin si
ke est un nombre
pour ke de 0 à 2
ex est un nombre
ex vaut 270 + ke * 50
si ke < etoiles alors
polygone(ecran, [ex, 205, ex + 6, 220, ex + 20, 221, ex + 9, 230, ex + 13, 245, ex, 236, ex - 13, 245, ex - 9, 230, ex - 20, 221, ex - 6, 220], #FFD54F)
sinon
polygone(ecran, [ex, 205, ex + 6, 220, ex + 20, 221, ex + 9, 230, ex + 13, 245, ex, 236, ex - 13, 245, ex - 9, 230, ex - 20, 221, ex - 6, 220], rgba(255, 255, 255, 0.15))
fin si
fin pour
label(ecran, 320 - label_largeur("20 vagues repoussées, " + convertir_texte(vies) + " vies restantes", 15) / 2, 275, "20 vagues repoussées, " + convertir_texte(vies) + " vies restantes", #FFFFFF, 15)
sinon
rectangle_arrondi(ecran, 120, 140, 400, 6, 3, #EF5350)
label(ecran, 320 - label_largeur("LE CHÂTEAU EST TOMBÉ...", 26) / 2, 195, "LE CHÂTEAU EST TOMBÉ...", #EF9A9A, 26)
label(ecran, 320 - label_largeur("Tu as tenu jusqu'à la vague " + convertir_texte(vague) + " (" + diffNom[difficulte] + ")", 16) / 2, 240, "Tu as tenu jusqu'à la vague " + convertir_texte(vague) + " (" + diffNom[difficulte] + ")", #FFFFFF, 16)
label(ecran, 320 - label_largeur("Astuce : la Glace + le Canon font un duo redoutable !", 12) / 2, 275, "Astuce : la Glace + le Canon font un duo redoutable !", #90CAF9, 12)
fin si
label(ecran, 320 - label_largeur("Monstres vaincus : " + convertir_texte(tues), 14) / 2, 305, "Monstres vaincus : " + convertir_texte(tues), #CFD8DC, 14)
label(ecran, 320 - label_largeur("ESPACE : rejouer X : menu", 15) / 2, 345, "ESPACE : rejouer X : menu", #69F0AE, 15)
fin procédure
@ LE PROCESSUS : la bataille en temps reel
processus Bataille()
tant que appActif
tic ajoute 1
si etat = 1 alors
si non enPause alors
kv est un nombre
pour kv de 1 à vitesseJeu
si etat = 1 alors
appelle mettreAJour()
fin si
fin pour
fin si
si etat = 1 alors
appelle dessinerJeu()
fin si
sinon si etat = 2 alors
appelle dessinerFin()
sinon si etat = 0 alors
appelle dessinerTitre()
sinon si etat = 3 alors
appelle dessinerAide()
fin si
affiche ecran
pause 60
fin tant que
fin processus
@ DEMARRAGE
appelle preparerCarte()
Bataille()
tant que appActif
si etat = 0 alors
interagir ecran, ["1", "2", " ", "x", "q", "d", "h"] dans action, ptX, ptY
si action = 1 ou action = 2 alors
carteChoisie vaut action
appelle preparerCarte()
sinon si action = 0 alors
si ptY >= 256 et ptY <= 322 alors
si ptX >= 130 et ptX <= 310 alors
carteChoisie vaut 1
appelle preparerCarte()
sinon si ptX >= 330 et ptX <= 510 alors
carteChoisie vaut 2
appelle preparerCarte()
fin si
fin si
sinon si action = 3 alors
etat vaut 9
appelle nouvellePartie()
etat vaut 1
sinon si action = 4 alors
appActif vaut faux
sinon si action = 5 alors
difficulte vaut (difficulte + 2) mod 3
sinon si action = 6 alors
difficulte vaut (difficulte + 1) mod 3
sinon si action = 7 alors
pageAide vaut 0
ecranRetour vaut 0
etat vaut 3
fin si
sinon si etat = 3 alors
// ----- AIDE -----
interagir ecran, ["q", "d", " ", "h"] dans action, ptX, ptY
si action = 1 alors
pageAide vaut (pageAide + 3) mod 4
sinon si action = 2 alors
pageAide vaut (pageAide + 1) mod 4
sinon si action = 3 ou action = 4 alors
etat vaut ecranRetour
fin si
sinon si etat = 1 alors
interagir ecran, ["1", "2", "3", "4", " ", "u", "v", "a", "p", "x", "f", "t", "h"] dans action, ptX, ptY
si etat = 1 alors
si action = 0 alors
si non enPause alors
appelle cliquerCarte(ptX, ptY)
fin si
sinon si action >= 1 et action <= 4 alors
selType vaut action
selTour vaut -1
message vaut tNom[selType] + " (" + convertir_texte(tCout[selType]) + " or) : " + tDescr[selType]
sinon si action = 5 alors
appelle lancerVague()
sinon si action = 6 alors
appelle ameliorer()
sinon si action = 7 alors
appelle vendreTour()
sinon si action = 8 alors
vitesseJeu vaut 3 - vitesseJeu
sinon si action = 9 alors
enPause vaut non enPause
sinon si action = 10 alors
si enPause alors
enPause vaut faux
etat vaut 0
sinon
enPause vaut vrai
fin si
sinon si action = 11 alors
appelle pluieDeFeu()
sinon si action = 12 alors
appelle changerMode()
sinon si action = 13 alors
// l'aide met le jeu en pause
enPause vaut vrai
pageAide vaut 0
ecranRetour vaut 1
etat vaut 3
fin si
fin si
sinon si etat = 2 alors
interagir ecran, [" ", "x"] dans action, ptX, ptY
si action = 1 ou action = 0 alors
etat vaut 9
appelle nouvellePartie()
etat vaut 1
sinon
etat vaut 0
fin si
fin si
fin tant que
effacer(ecran)
remplir(ecran, #263238)
label(ecran, 320 - label_largeur("Le royaume te remercie !", 28) / 2, 270, "Le royaume te remercie !", #FFD54F, 28)
affiche ecran