Console
Clique sur « Exécuter » pour lancer le programme.
Code CoddyRun
@ CONFIGURATION
ecran est une toile
dimension(ecran, 400, 500)
LC est un nombre
LC vaut 100
HT est un nombre
HT vaut 125
HAUT est un nombre
HAUT vaut 500
// les rangees sont rangees dans un "anneau" de 12 cases (sa taille ne change jamais)
ANNEAU est un nombre
ANNEAU vaut 12
@ LES RANGEES
// la rangee numero n : sa tuile noire est dans la colonne rangCol[n mod 12]
rangCol est un tableau
rangTapee est un tableau
pour kr de 0 à ANNEAU - 1
rangCol ajoute 0
rangTapee ajoute faux
fin pour
@ ETAT DU JEU
// etat : 0 attente du premier appui, 1 en jeu, 2 perdu, 9 preparation
etat est un nombre
etat vaut 0
appActif est un booléen
appActif vaut vrai
defile, vitesse, aJouer, genere, score, meilleur, tic, erreurCol, erreurRang, finT est un nombre
erreurBlanche est un booléen
action, ptX, ptY est un nombre
// les petites notes qui s'envolent quand on tape une tuile (6 cases fixes)
noteX, noteY, noteT est un tableau
pour kr de 0 à 5
noteX ajoute 0
noteY ajoute 0
noteT ajoute 0
fin pour
tic vaut 0
essayer
meilleur vaut parametre('touches_magiques', 'meilleur')
attraper
meilleur vaut 0
fin essayer
seuils est un tableau
seuils vaut [30, 70, 120]
@ OUTILS
// le bas (en pixels) de la rangee n
fonction basRangee(n)
retourne HAUT + defile - n * HT
fin fonction
fonction colonneDe(n)
retourne rangCol[n mod ANNEAU]
fin fonction
procédure centrer(txt, xMil, ty, coul, taillePolice)
label(ecran, xMil - label_largeur(txt, taillePolice) / 2, ty, txt, coul, taillePolice)
fin procédure
// cree les rangees jusqu'a "jusque" (jamais deux fois de suite la meme colonne)
procédure genererJusque(jusque)
tant que genere < jusque
genere ajoute 1
c est un nombre
c vaut hasard(0, 3)
si genere > 0 alors
si c = colonneDe(genere - 1) alors
c vaut (c + hasard(1, 3)) mod 4
fin si
fin si
rangCol[genere mod ANNEAU] vaut c
rangTapee[genere mod ANNEAU] vaut faux
fin tant que
fin procédure
procédure nouvellePartie()
defile vaut 0
vitesse vaut 13
aJouer vaut 0
genere vaut -1
score vaut 0
finT vaut 0
erreurCol vaut -1
erreurRang vaut -1
erreurBlanche vaut faux
kn est un nombre
pour kn de 0 à 5
noteT[kn] vaut 0
fin pour
appelle genererJusque(5)
etat vaut 0
fin procédure
@ TAPER (appele par la boucle principale)
procédure reussite(c)
rangTapee[aJouer mod ANNEAU] vaut vrai
noteX[score mod 6] vaut c * LC + LC / 2
noteY[score mod 6] vaut basRangee(aJouer) - HT / 2
noteT[score mod 6] vaut 12
aJouer ajoute 1
score ajoute 1
// ca accelere un peu a chaque tuile
vitesse vaut minimum(13 + score * 0.21, 38)
si etat = 0 alors
etat vaut 1
fin si
fin procédure
procédure perdre(c, n, blanche)
erreurCol vaut c
erreurRang vaut n
erreurBlanche vaut blanche
finT vaut 0
si score > meilleur alors
meilleur vaut score
parametre('touches_magiques', 'meilleur', meilleur)
fin si
etat vaut 2
fin procédure
// une touche du clavier : la colonne c
procédure taperColonne(c)
si colonneDe(aJouer) = c et basRangee(aJouer) > 0 alors
appelle reussite(c)
sinon
// la case blanche juste dans la rangee a jouer
appelle perdre(c, aJouer, vrai)
fin si
fin procédure
// un clic : quelle case a ete touchee ?
procédure taperPoint(x, y)
c est un nombre
c vaut arrondi_inferieur(x / LC)
n est un nombre
n vaut arrondi_inferieur((HAUT + defile - y) / HT)
si c >= 0 et c <= 3 et n >= aJouer alors
si n = aJouer et colonneDe(n) = c alors
appelle reussite(c)
sinon si n > aJouer et n <= genere et colonneDe(n) = c alors
// une tuile noire plus haut : trop tot, on ne compte rien
score vaut score
sinon
appelle perdre(c, n, vrai)
fin si
fin si
fin procédure
@ ANIMATION (le processus)
procédure animer()
si etat = 1 alors
defile vaut defile + vitesse
appelle genererJusque(aJouer + 6)
// une tuile noire est sortie de l'ecran sans etre tapee ?
si basRangee(aJouer) - HT / 3 > HAUT alors
appelle perdre(colonneDe(aJouer), aJouer, faux)
fin si
sinon si etat = 2 alors
finT ajoute 1
// on remonte doucement pour montrer la tuile ratee
si non erreurBlanche et basRangee(erreurRang) > HAUT - 40 alors
defile vaut defile - 12
fin si
fin si
kn est un nombre
pour kn de 0 à 5
si noteT[kn] > 0 alors
noteY[kn] vaut noteY[kn] - 6
noteT[kn] vaut noteT[kn] - 1
fin si
fin pour
fin procédure
@ DESSIN
// le cadre autour de la toile
procédure dessinerCadre()
// le bord sombre
rectangle(ecran, 0, 0, 400, 7, #1A1A2E)
rectangle(ecran, 0, HAUT - 7, 400, 7, #1A1A2E)
rectangle(ecran, 0, 0, 7, HAUT, #1A1A2E)
rectangle(ecran, 393, 0, 7, HAUT, #1A1A2E)
fin procédure
procédure dessiner()
effacer(ecran)
contour(ecran, #0)
// un fond qui change doucement de couleur
teinte est un nombre
teinte vaut (tic * 2) mod 360
r est un nombre
r vaut arrondi(225 + 25 * sinus(radians(teinte)))
v est un nombre
v vaut arrondi(225 + 25 * sinus(radians(teinte + 120)))
b est un nombre
b vaut arrondi(235 + 20 * sinus(radians(teinte + 240)))
dégradé(ecran, [rgb(r, v, b), #FFFFFF])
// les colonnes
kc est un nombre
pour kc de 1 à 3
ligne(ecran, kc * LC, 0, kc * LC, HAUT, rgba(0, 0, 0, 0.12), 1)
fin pour
// les rangees visibles
n est un nombre
pour n de maximum(0, aJouer - 2) à genere
bas est un nombre
bas vaut basRangee(n)
hautT est un nombre
hautT vaut bas - HT
si bas > 0 et hautT < HAUT alors
ligne(ecran, 0, bas, 400, bas, rgba(0, 0, 0, 0.1), 1)
c est un nombre
c vaut colonneDe(n)
x est un nombre
x vaut c * LC
si rangTapee[n mod ANNEAU] alors
// tuile deja jouee : grise et transparente
rectangle(ecran, x + 1, hautT + 1, LC - 2, HT - 2, rgba(30, 30, 50, 0.18))
sinon si etat = 2 et non erreurBlanche et n = erreurRang alors
rectangle(ecran, x + 1, hautT + 1, LC - 2, HT - 2, sialors(finT mod 6 < 3, #E53935, #212121))
sinon
rectangle(ecran, x + 1, hautT + 1, LC - 2, HT - 2, #15151F)
rectangle(ecran, x + 1, hautT + 1, LC - 2, 6, rgba(255, 255, 255, 0.12))
rectangle(ecran, x + 6, bas - 12, LC - 12, 4, rgba(120, 180, 255, 0.35))
si n = 0 et etat = 0 alors
appelle centrer("TOUCHE", x + LC / 2, hautT + HT / 2, #FFFFFF, 15)
appelle centrer("ICI", x + LC / 2, hautT + HT / 2 + 20, #FFFFFF, 15)
fin si
fin si
// la case blanche touchee par erreur
si etat = 2 et erreurBlanche et n = erreurRang alors
rectangle(ecran, erreurCol * LC + 1, hautT + 1, LC - 2, HT - 2, sialors(finT mod 6 < 3, #E53935, #FFCDD2))
fin si
fin si
fin pour
// les notes qui s'envolent
kn est un nombre
pour kn de 0 à 5
si noteT[kn] > 0 alors
appelle centrer("♪", noteX[kn], noteY[kn], rgba(90, 120, 255, noteT[kn] / 12), 26)
fin si
fin pour
// le score et les etoiles
appelle centrer(convertir_texte(score), 202, 72, rgba(0, 0, 0, 0.25), 52)
appelle centrer(convertir_texte(score), 200, 70, #E53935, 52)
rectangle_arrondi(ecran, 60, 16, 280, 10, 5, rgba(0, 0, 0, 0.15))
rectangle_arrondi(ecran, 60, 16, 280 * minimum(score, seuils[2]) / seuils[2], 10, 5, #FFB300)
ke est un nombre
pour ke de 0 à 2
ex est un nombre
ex vaut 60 + 280 * seuils[ke] / seuils[2]
appelle centrer("★", ex, 28, sialors(score >= seuils[ke], #FFC107, #B0BEC5), 22)
fin pour
si etat = 0 et aJouer = 0 alors
appelle centrer("TOUCHES MAGIQUES", 200, 120, #263238, 26)
appelle centrer("Tape les tuiles noires, jamais les blanches !", 200, 146, #546E7A, 12)
appelle centrer("Clic, ou les touches D F J K", 200, 166, #546E7A, 12)
si meilleur > 0 alors
appelle centrer("Meilleur : " + convertir_texte(meilleur), 200, 190, #E53935, 13)
fin si
fin si
si etat = 2 et finT > 10 alors
rectangle(ecran, 0, 0, 400, 500, rgba(0, 0, 0, 0.35))
rectangle_arrondi(ecran, 50, 150, 300, 200, 18, #FFFFFF)
si erreurBlanche alors
appelle centrer("Case blanche !", 200, 190, #E53935, 22)
sinon
appelle centrer("Trop tard !", 200, 190, #E53935, 22)
fin si
appelle centrer(convertir_texte(score) + " tuiles", 200, 235, #263238, 30)
etoiles est un nombre
etoiles vaut 0
pour ke de 0 à 2
si score >= seuils[ke] alors
etoiles ajoute 1
fin si
fin pour
pour ke de 0 à 2
appelle centrer("★", 160 + ke * 40, 275, sialors(ke < etoiles, #FFC107, #E0E0E0), 30)
fin pour
si score >= meilleur et score > 0 alors
appelle centrer("NOUVEAU RECORD !", 200, 305, #43A047, 15)
sinon
appelle centrer("Meilleur : " + convertir_texte(meilleur), 200, 305, #78909C, 14)
fin si
appelle centrer("ESPACE ou clic : rejouer", 200, 335, #1E88E5, 14)
fin si
appelle dessinerCadre()
fin procédure
@ LE PROCESSUS
processus Piano()
tant que appActif
tic ajoute 1
si etat <> 9 alors
appelle animer()
appelle dessiner()
affiche ecran
fin si
pause 60
fin tant que
fin processus
@ DEMARRAGE
appelle nouvellePartie()
Piano()
tant que appActif
interagir ecran, ["d", "f", "j", "k", " ", "x"] dans action, ptX, ptY
si action = 6 alors
appActif vaut faux
sinon si etat = 0 ou etat = 1 alors
si action >= 1 et action <= 4 alors
appelle taperColonne(action - 1)
sinon si action = 0 alors
appelle taperPoint(ptX, ptY)
fin si
sinon si etat = 2 et finT > 10 alors
si action = 5 ou action = 0 alors
etat vaut 9
appelle nouvellePartie()
fin si
fin si
fin tant que
effacer(ecran)
remplir(ecran, #FFFFFF)
appelle dessinerCadre()
label(ecran, 200 - label_largeur("À bientôt ! ♪", 30) / 2, 250, "À bientôt ! ♪", #263238, 30)
affiche ecran