Console
Clique sur « Exécuter » pour lancer le programme.
Code CoddyRun
@ CONFIGURATION
LARG est un nombre
LARG vaut 600
HAUT est un nombre
HAUT vaut 360
// 60 images, 6 foulees par boucle
NB est un nombre
NB vaut 60
FOULEES est un nombre
FOULEES vaut 6
// la ligne du sol sous les pieds
SOL_Y est un nombre
SOL_Y vaut 322
HANCHE_Y est un nombre
HANCHE_Y vaut 236
// vitesses de defilement (pixels par image) : plus c'est proche, plus ca va vite.
// Elles sont choisies pour que chaque decor retombe pile sur sa position
// de depart apres les 60 images : la boucle ne saute pas.
V_LOIN est un nombre
V_LOIN vaut 4
V_COLLINE est un nombre
V_COLLINE vaut 8
V_TRIBUNE est un nombre
V_TRIBUNE vaut 12
V_PISTE est un nombre
V_PISTE vaut 16
@ LES COULEURS
PEAU est un texte
PEAU vaut #E2A47C
PEAU_LOIN est un texte
PEAU_LOIN vaut #B87A55
MAILLOT est un texte
MAILLOT vaut #2563EB
MAILLOT_LOIN est un texte
MAILLOT_LOIN vaut #1E40AF
SHORT est un texte
SHORT vaut #1E293B
CHAUSSURE est un texte
CHAUSSURE vaut #F97316
CHAUSSURE_LOIN est un texte
CHAUSSURE_LOIN vaut #C2410C
CHEVEUX est un texte
CHEVEUX vaut #3B2314
FOULE est un tableau
FOULE vaut [#EF4444, #F59E0B, #10B981, #3B82F6, #EC4899]
@ VARIABLES DE CALCUL
// les points calcules pour une jambe ou un bras
genouX, genouY, chevX, chevY, angPied est un nombre
coudeX, coudeY, mainX, mainY est un nombre
// les points d'un polygone de colline (35 points)
ptsColline est un tableau
pour ki de 0 à 69
ptsColline ajoute 0
fin pour
ptsTronc est un tableau
pour ki de 0 à 7
ptsTronc ajoute 0
fin pour
@ OUTILS
fonction rad(degres)
retourne degres * pi() / 180
fin fonction
// un reste toujours positif, meme pour les nombres negatifs
fonction resteMod(v, m)
r est un nombre
r vaut v mod m
si r < 0 alors
r vaut r + m
fin si
retourne r
fin fonction
@ LE DECOR
procédure ciel(ec)
// un degrade vertical en bandes
k est un nombre
pour k de 0 à 17
f est un nombre
f vaut k / 17
rectangle(ec, 0, k * 10, LARG, 11, rgba(arrondi(96 + 128 * f), arrondi(165 + 75 * f), arrondi(250 - 4 * f), 1))
fin pour
// le soleil
cercle(ec, 520, 54, 46, rgba(255, 255, 255, 0.18))
cercle(ec, 520, 54, 34, rgba(255, 247, 200, 0.4))
cercle(ec, 520, 54, 24, #FDE68A)
fin procédure
procédure nuage(ec, x, y, s)
cercle(ec, x, y, 14 * s, #FFFFFF)
cercle(ec, x + 16 * s, y - 8 * s, 17 * s, #FFFFFF)
cercle(ec, x + 34 * s, y, 13 * s, #FFFFFF)
rectangle_arrondi(ec, x - 10 * s, y, 56 * s, 13 * s, 6 * s, #FFFFFF)
ellipse(ec, x + 18 * s, y + 12 * s, 28 * s, 3 * s, rgba(148, 163, 184, 0.25))
fin procédure
// une rangee de collines qui defile (la forme se repete tous les 240 px)
procédure collines(ec, decal, base, haut1, haut2, coul)
k est un nombre
pour k de 0 à 32
x est un nombre
x vaut k * 20 - 20
ptsColline[k * 2] vaut x
ptsColline[k * 2 + 1] vaut base - haut1 * sinus(2 * pi() * (x + decal) / 240) - haut2 * sinus(2 * pi() * (x + decal) / 80)
fin pour
ptsColline[66] vaut LARG + 20
ptsColline[67] vaut 260
ptsColline[68] vaut -20
ptsColline[69] vaut 260
polygone(ec, ptsColline, coul)
fin procédure
procédure tribunes(ec, etape)
decal est un nombre
decal vaut etape * V_TRIBUNE
k est un nombre
x est un nombre
y est un nombre
idx est un nombre
px est un nombre
// le mur et le toit
rectangle(ec, 0, 176, LARG, 76, #64748B)
rectangle(ec, 0, 168, LARG, 10, #334155)
rectangle(ec, 0, 244, LARG, 8, #475569)
// les rangees de spectateurs (le motif se repete tous les 120 px)
rang est un nombre
pour rang de 0 à 2
y vaut 196 + rang * 18
rectangle(ec, 0, y + 6, LARG, 4, #475569)
pour k de 0 à 61
x vaut k * 12 + rang * 6 - resteMod(decal, 120)
si x > -10 et x < LARG + 10 alors
idx vaut (k * 3 + rang) mod 5
rectangle_arrondi(ec, x - 5, y - 2, 10, 9, 3, FOULE[idx])
cercle(ec, x, y - 6, 4, sialors(k mod 2 = 0, #F1C7A5, #A86F4C))
// quelques supporters levent les bras
si (k + rang * 3) mod 5 = 0 et etape mod 4 < 2 alors
ligne(ec, x - 4, y - 1, x - 7, y - 11, FOULE[idx], 2)
ligne(ec, x + 4, y - 1, x + 7, y - 11, FOULE[idx], 2)
fin si
fin si
fin pour
fin pour
// les piliers du toit
pour k de 0 à 6
px vaut k * 120 - resteMod(decal, 120)
rectangle(ec, px, 168, 6, 80, #1E293B)
fin pour
// un panneau publicitaire en bas des tribunes
rectangle(ec, 0, 244, LARG, 8, #0F172A)
pour k de 0 à 6
px vaut k * 120 + 30 - resteMod(decal, 120)
label(ec, px, 251, "CODDYRUN", #FDE047, 8)
fin pour
fin procédure
procédure piste(ec, etape)
decal est un nombre
decal vaut etape * V_PISTE
k est un nombre
x est un nombre
// la pelouse rayee
rectangle(ec, 0, 252, LARG, 12, #4ADE80)
pour k de 0 à 11
rectangle(ec, k * 60 - resteMod(decal, 60), 252, 30, 12, #22C55E)
fin pour
// la piste rouge et ses couloirs
rectangle(ec, 0, 264, LARG, HAUT - 264, #C2553A)
rectangle(ec, 0, 264, LARG, 3, #FFFFFF)
rectangle(ec, 0, 298, LARG, 2, #FFFFFF)
rectangle(ec, 0, 340, LARG, 2, #FFFFFF)
// les reperes au sol qui defilent
pour k de 0 à 11
x vaut k * 60 - resteMod(decal, 60)
rectangle(ec, x, 281, 18, 2, rgba(255, 255, 255, 0.55))
rectangle(ec, x + 30, 352, 22, 2, rgba(255, 255, 255, 0.55))
fin pour
// le grain de la piste
pour k de 0 à 23
x vaut resteMod(k * 41 - decal, 960) - 20
cercle(ec, x, 306 + (k * 13) mod 32, 1.3, rgba(120, 40, 25, 0.5))
fin pour
fin procédure
@ LE COUREUR
// calcule le genou et la cheville d'une jambe (ph va de 0 a 1)
procédure calculerJambe(hx, hy, ph)
cuisse est un nombre
cuisse vaut 90 + 36 * sinus(ph * 2 * pi())
// le genou se plie fort quand la jambe revient vers l'avant
pli est un nombre
pli vaut 10
si ph >= 0.2 et ph <= 0.85 alors
pli vaut 10 + 82 * sinus(pi() * (ph - 0.2) / 0.65)
fin si
tibia est un nombre
tibia vaut cuisse + pli
genouX vaut hx + cosinus(rad(cuisse)) * 40
genouY vaut hy + sinus(rad(cuisse)) * 40
chevX vaut genouX + cosinus(rad(tibia)) * 40
chevY vaut genouY + sinus(rad(tibia)) * 40
angPied vaut tibia - 95
fin procédure
procédure dessinerJambe(ec, hx, hy, ph, peauC, chaussureC)
appelle calculerJambe(hx, hy, ph)
// la cuisse : le haut est cache par le short
ligne(ec, hx, hy, genouX, genouY, peauC, 13)
ligne(ec, hx, hy, hx + (genouX - hx) * 0.38, hy + (genouY - hy) * 0.38, SHORT, 15)
cercle(ec, genouX, genouY, 6.5, peauC)
// le mollet
ligne(ec, genouX, genouY, chevX, chevY, peauC, 10)
cercle(ec, chevX, chevY, 5, peauC)
// la chaussure
bx est un nombre
bx vaut chevX + cosinus(rad(angPied)) * 16
by est un nombre
by vaut chevY + sinus(rad(angPied)) * 16
ligne(ec, chevX - cosinus(rad(angPied)) * 3, chevY - sinus(rad(angPied)) * 3, bx, by, chaussureC, 9)
// la semelle blanche, juste sous la chaussure
sx est un nombre
sx vaut -sinus(rad(angPied)) * 4
sy est un nombre
sy vaut cosinus(rad(angPied)) * 4
ligne(ec, chevX - cosinus(rad(angPied)) * 3 + sx, chevY - sinus(rad(angPied)) * 3 + sy, bx + sx, by + sy, #FFFFFF, 3)
fin procédure
procédure calculerBras(ex, ey, ph)
angHaut est un nombre
angHaut vaut 90 + 55 * sinus(ph * 2 * pi())
angAvant est un nombre
angAvant vaut angHaut - 85
coudeX vaut ex + cosinus(rad(angHaut)) * 29
coudeY vaut ey + sinus(rad(angHaut)) * 29
mainX vaut coudeX + cosinus(rad(angAvant)) * 26
mainY vaut coudeY + sinus(rad(angAvant)) * 26
fin procédure
procédure dessinerBras(ec, ex, ey, ph, peauC, maillotC)
appelle calculerBras(ex, ey, ph)
ligne(ec, ex, ey, coudeX, coudeY, peauC, 10)
// la manche du maillot
ligne(ec, ex, ey, ex + (coudeX - ex) * 0.4, ey + (coudeY - ey) * 0.4, maillotC, 14)
cercle(ec, coudeX, coudeY, 5, peauC)
ligne(ec, coudeX, coudeY, mainX, mainY, peauC, 9)
cercle(ec, mainX, mainY, 6, peauC)
fin procédure
// la poussiere soulevee par un pied, calculee sur les images precedentes
procédure poussiere(ec, hx, ph)
j est un nombre
pour j de 0 à 4
phPasse est un nombre
phPasse vaut resteMod(ph - j * FOULEES / NB, 1)
auSol est un booléen
auSol vaut faux
si phPasse < 0.14 alors
auSol vaut vrai
fin si
si auSol alors
appelle calculerJambe(hx, HANCHE_Y, phPasse)
px est un nombre
px vaut chevX - j * V_PISTE
cercle(ec, px - 4, SOL_Y - 3 - j * 2, 2 + j * 1.6, rgba(230, 170, 140, 0.4 - j * 0.07))
cercle(ec, px + 3, SOL_Y - 2 - j * 2.5, 1.5 + j * 1.2, rgba(230, 170, 140, 0.3 - j * 0.05))
fin si
fin pour
fin procédure
procédure coureur(ec, cx, ph)
// le corps descend un peu a chaque appui
hy est un nombre
hy vaut HANCHE_Y + 3 * cosinus(ph * 4 * pi())
// l'ombre
ellipse(ec, cx + 4, SOL_Y + 2, 30 - 3 * cosinus(ph * 4 * pi()), 5, rgba(60, 20, 10, 0.25))
appelle poussiere(ec, cx, ph)
appelle poussiere(ec, cx, resteMod(ph + 0.5, 1))
// les epaules, penchees vers l'avant
ex est un nombre
ex vaut cx + 17
ey est un nombre
ey vaut hy - 56
// le bras et la jambe du cote loin, dessines en premier et plus fonces
appelle dessinerBras(ec, ex - 3, ey + 3, ph, PEAU_LOIN, MAILLOT_LOIN)
appelle dessinerJambe(ec, cx - 2, hy, resteMod(ph + 0.5, 1), PEAU_LOIN, CHAUSSURE_LOIN)
// le tronc
nx est un nombre
nx vaut 0.96
ny est un nombre
ny vaut 0.29
ptsTronc[0] vaut cx - 12 * nx
ptsTronc[1] vaut hy - 12 * ny - 2
ptsTronc[2] vaut cx + 12 * nx
ptsTronc[3] vaut hy + 12 * ny - 2
ptsTronc[4] vaut ex + 13 * nx
ptsTronc[5] vaut ey + 13 * ny
ptsTronc[6] vaut ex - 13 * nx
ptsTronc[7] vaut ey - 13 * ny
polygone(ec, ptsTronc, MAILLOT)
cercle(ec, ex, ey, 12, MAILLOT)
// une bande blanche sur le cote du maillot
ligne(ec, cx + 5, hy - 6, ex + 4, ey + 6, rgba(255, 255, 255, 0.35), 3)
// le short
rectangle_arrondi(ec, cx - 12, hy - 8, 25, 17, 6, SHORT)
// le dossard
rectangle_arrondi(ec, cx + 2, hy - 40, 17, 15, 2, #FFFFFF)
label(ec, cx + 4, hy - 28, "42", #111827, 10)
// le cou et la tete
tx est un nombre
tx vaut ex + 9
ty est un nombre
ty vaut ey - 23
ligne(ec, ex + 2, ey - 4, tx - 2, ty + 7, PEAU, 10)
cercle(ec, tx - 2, ty - 3, 15, CHEVEUX)
cercle(ec, tx + 2, ty + 1, 13.5, PEAU)
cercle(ec, tx - 4, ty + 2, 3.5, PEAU_LOIN)
cercle(ec, tx + 8, ty - 1, 2, #111827)
ligne(ec, tx + 7, ty + 7, tx + 12, ty + 6, #9A4B32, 1.6)
// le bandeau et ses rubans qui flottent
ligne(ec, tx - 14, ty - 6, tx + 13, ty - 9, #DC2626, 5)
ondule est un nombre
ondule vaut sinus(ph * 4 * pi())
ligne(ec, tx - 13, ty - 6, tx - 29, ty - 3 + ondule * 5, #DC2626, 3.5)
ligne(ec, tx - 13, ty - 5, tx - 27, ty + 5 - ondule * 4, #B91C1C, 3.5)
// la jambe et le bras du cote proche
appelle dessinerJambe(ec, cx + 2, hy, ph, PEAU, CHAUSSURE)
appelle dessinerBras(ec, ex + 2, ey + 1, resteMod(ph + 0.5, 1), PEAU, MAILLOT)
fin procédure
@ UNE IMAGE DE L'ANIMATION
procédure dessinerImage(ec, etape)
ph est un nombre
ph vaut resteMod(etape * FOULEES / NB, 1)
appelle ciel(ec)
appelle nuage(ec, 70, 52, 1)
appelle nuage(ec, 300, 34, 0.75)
appelle nuage(ec, 420, 92, 0.6)
appelle collines(ec, etape * V_LOIN, 150, 14, 6, #A7C7E7)
appelle collines(ec, etape * V_COLLINE, 166, 16, 7, #6BAF6E)
appelle tribunes(ec, etape)
appelle piste(ec, etape)
// la camera suit le coureur, qui avance et recule un peu
cx est un nombre
cx vaut 250 + 10 * sinus(etape * 2 * pi() / NB)
// les traits de vitesse
k est un nombre
pour k de 0 à 4
lx est un nombre
lx vaut cx - 70 - resteMod(etape * 12 + k * 23, 60)
ly est un nombre
ly vaut 196 + k * 24
ligne(ec, lx, ly, lx - 34, ly, rgba(255, 255, 255, 0.55), 2)
fin pour
appelle coureur(ec, cx, ph)
fin procédure
@ DEMARRAGE
film est un tableau
cadre est une toile
dimension(cadre, LARG, HAUT)
numImage est un nombre
pour numImage de 0 à NB - 1
appelle dessinerImage(cadre, numImage)
film ajoute cadre
effacer(cadre)
fin pour
animation(film, 70, 20)