Voici le code de mon punch.
Pour les puristes, soyez indulgents car il a été conçu dans l'esprit du punch (utiliser les data en direct, j'avais jamais osé

Je suis parti du moteur et j'ai garni sans faire déborder

Il y a même des Goto (j'adore ça

Ce n'est donc pas un exemple de codage propre mais ça pourra peut-être donner des idées !
RAPPEL :
Moteur
http://purebasic.fr/french/viewtopic.php?f=1&t=14757
Fichiers
https://www.dropbox.com/s/1mdepbk03kgvz ... h.rar?dl=0
Code : Tout sélectionner
;Auteur Huitbit
;jeu "Retour à Winterfell"
;été 2014
;Pb 5.22
; Hors punch
MessageRequester("PurePunch2014", "But du jeu : trouver puis attraper la clé pour rentrer chez vous !" + Chr(13) + " [ESPACE] : démarrer et épée" + Chr(13) + " [HAUT] : changer de direction" + Chr(13) + "[GAUCHE/DROITE] : déplacer la bascule")
; fin hors punch
;- Déclarations constantes et variables
L = 320
H = 240
Enumeration
#porte
#roc
#cle
#popD
#popG
#epee
#batBas
#batHaut
#basculeA
#basculeB
#spriteSheet
#popDCoup
#popGCoup
#volA
#volB
#volNull
EndEnumeration
Define.f xA, yA, vxA, vyA, vA, yAprecedent, xB, yB, vxB, vyB, vB, yBprecedent, xRoc, yRoc, vxRoc, vyRoc, yScroll, rA, rB
vol = #volNull
sprBascule = #basculeA
a = 128 ; largeur du sprite bascule
b = 32 ; hauteur bascule 32
lBascule = 132 ; longueur de la bascule (diagonale du sprite)
c = 16 ; côté de la plupart des sprites
pente.f = 0.25 ; 32/128
alpha.f = ATan2(a, b)
omega.f = 0 ; vitesse angulaire
m = 100 ; masse d'un chevalier
jbascule = 14520 ; moment d'inertie de la planche
xBascule = 96
yBascule = 208
yCb = yBascule + c ; ordonnée du centre de la bascule
xCb = xBascule + b ; abscisse du centre de la bascule
;- Macros
Macro chuteLibre(x, y, vx, vy)
vy = vy + 0.6
x = x + vx * 0.1
y = y + vy * 0.1
EndMacro
Macro rayon(r, x1, y1, x2, y2)
r = Sqr((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
EndMacro
;-
;- PROGRAMME PRINCIPAL
;-
InitSprite()
InitKeyboard()
InitSound()
OpenWindow(0, 0, 0, 2 * L, 2 * H, "Punch", #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, L, H, 1, 0, 0, #PB_Screen_SmartSynchronization)
LoadSprite(#spriteSheet, "s.bmp")
DisplaySprite(#spriteSheet, 0, 0)
For i = 0 To 7
GrabSprite(i, 0, 16 * i, 16, 16)
Next i
GrabSprite(#basculeA, 0, 128, 128, 32)
GrabSprite(#basculeB, 0, 160, 128, 32)
;- Initialisation
jeu:
LoadMusic(0, "v.it")
PlayMusic(0)
vol = #volNull
sprBascule = #basculeA
xBascule = 96
yBascule = 208
yCb = yBascule + c
xCb = xBascule + b
xA = xBascule
yA = 194 ; prise en compte de l'inclinaison de la planche
xB = xBascule + a - c
yB = yBascule + 14
sprA = #popD
sprB = #popG
xRoc = 32
yRoc = 16
bat = #batHaut
xBat.f = 10 * 16
yBat.f = 3 * Random(1) * 16
rndX = 3
cleTrouvee = 0
Dim sprPorte.l(8) ; 8 portes valeur #porte=0 et l'index de la porte qui contient la clé
sprPorte(8) = Random(7) ; la clé sera dans une des 8 portes
;-
;- BOUCLE PRINCIPALE
;-
Repeat
;- gestion des collisions
If SpriteCollision(#epee, xEpee, yEpee, #batHaut, xBat, yBat + yScroll)
yBat = H
EndIf ; SpriteCollision(#epee,#batHaut)
Restore coordoonneesPortes
For i = 0 To 7
Read.l cln
Read.l lgn
If sprPorte(i) <> -1 ; porte fermée(=0) ou clé (=2)
If SpriteCollision(#epee, xEpee, yEpee, sprPorte(i), 16 * cln, 16 * lgn)
If i <> sprPorte(8) ; s'il n'y a rien derrière la porte
sprPorte(i) = -1
Else
If cleTrouvee = 0
sprPorte(i) = #cle
cleTrouvee = 1
pauseEpee = ElapsedMilliseconds()
EndIf
If cleTrouvee = 2
xEpee = 0
MessageRequester("", "Gagné!")
Goto jeu
EndIf
EndIf ; If i <> sprPorte(8)
EndIf ; SpriteCollision(#epee,sprPorte(i))
EndIf ; sprPorte(i)<>-1
Next i
If yRoc < H - 60 ; personnage sur bascule intouchable
If SpriteCollision(sprA, xA, yA + yScroll, #roc, xRoc, yRoc + yScroll)
yA = YA + 16
EndIf
If SpriteCollision(sprB, xB, yB + yScroll, #roc, xRoc, yRoc + yScroll)
yB = yB + 16
EndIf
EndIf ; yRoc<H-60
If yBat < H - 60 ; personnage sur bascule intouchable
If SpriteCollision(sprA, xA, yA + yScroll, #batHaut, xBat, yBat + yScroll)
yA = YA + 16
EndIf
If SpriteCollision(sprB, xB, yB + yScroll, #batHaut, xBat, yBat + yScroll)
yB = yB + 16
EndIf
EndIf ; yBat<H-60
;- gestion du clavier
If ElapsedMilliseconds() - chronoKeyboard > 200
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
If xBascule + a * 0.75 > 0 ; limite bord gauche écran
xBascule = xBascule - 4
If vol <> #volA ; si B est en vol, A se déplace avec la bascule
xA = xA - 4
EndIf
If vol <> #volB ; si A est en vol, B se déplace avec la bascule
xB = xB - 4
EndIf
EndIf ; xBascule > 0
EndIf ; KeyboardPushed(#PB_Key_Left)
If KeyboardPushed(#PB_Key_Right)
If xBascule + a * 0.25 < L ; a largeur du sprite bascule
xBascule = xBascule + 4
If vol <> #volA ; si B est en vol, A se déplace avec la bascule
xA = xA + 4
EndIf
If vol <> #volB ; si A est en vol, B se déplace avec la bascule
xB = xB + 4
EndIf
EndIf ; xBascule + a < L
EndIf ; KeyboardPushed(#PB_Key_Right)
If KeyboardPushed(#PB_Key_Up) ; changement d'orientation du sauteur
If vol <> #volNull
If vol <> #volA ; si B est en vol
If sprB = #popG
sprB = #popD
Else
sprB = #popG
EndIf
EndIf ; #volA
If vol <> #volB ; si A est en vol
If sprA = #popD
sprA = #popG
Else
sprA = #popD
EndIf
EndIf
chronoKeyboard = ElapsedMilliseconds()
EndIf ; #volNull
EndIf ; KeyboardPushed(#PB_Key_Up)
If KeyboardPushed(#PB_Key_Space)
If vol = #volA
If sprA = #popD
sprA = #popDCoup
EndIf
If sprA = #popG
sprA = #popGCoup
EndIf
EndIf
If vol = #volB
If sprB = #popG
sprB = #popGCoup
EndIf
If sprB = #popD
sprB = #popDCoup
EndIf
EndIf
If vol = #volNull
vol = #volB
xB = xA + a - c
yB = yA
vxB = 0 * Sin(alpha)
vyB = -30 * Cos(alpha)
sprBascule = #basculeB
yA = yBascule + 14
sprA = #popD
sprB = #popG
chronoKeyboard = ElapsedMilliseconds()
EndIf ; vol=#volNull
EndIf ; KeyboardPushed(#PB_Key_Space)
EndIf ; ElapsedMilliseconds()-chronoKeyboard>200
xCb = xBascule + 64 ; mise à jour de la position du centre de la bascule
;- animation
If vol = #volA
yAprecedent = yA
chuteLibre(xA, yA, vxA, vyA)
If vyA > 0 ; le sprite A redescend
If (xA >= xBascule) And (xA <= xBascule + 48)
If (yA + c) >= yBascule And (yAprecedent + c) <= yBascule
yA = yCb - pente * (xCb - (xA + c)) - c - 2
vol = #volB
rayon(rA,(xA + 8),(yA + c), xCb, yCb)
rayon(rB,(xB + 8),(yB + c), xCb, yCb)
jtotal = m * (rA * rA + rB * rB) + jbascule
omega = m * ((xA + 8 - xCb) * vyA - (yA + c - yCb) * vxA) / jtotal
yB = yCb - pente * (xB - xCb) - c
vB = Abs(rB * omega * #E)
If vB > 70 ; vMax=racine(2*g*hMax) avec hMax=H=480
vB = 70
EndIf
If vB < 30
vB = 30
EndIf
vxB = -vB * Sin(alpha) + dxBascule * 0.1
vyB = -vB * Cos(alpha)
yA = yBascule + b - pente * (xA - xBascule) - c - 2
sprBascule = #basculeB
Select sprA
Case #popD, #popDCoup
sprA = #popD
Case #popG, #popGCoup
sprA = #popG
EndSelect
sprB = #popG
EndIf ; test sur yA+c=yApiedDroit et la position précedente du pied droit
EndIf ; test xA
EndIf ; vyA>0
If yA > H ; le chevalier rate la bascule, fin du jeu
Delay(1000)
Goto jeu
EndIf
If yA < 64 ; le chevalier dépasse une certaine hauteur, déclenchement du scrolling
yScroll = -yA + 64
Else
yScroll = 0
EndIf
If xA > (L - C) ; rebond sur le bord droit de l'écran
vxA = -vxA
EndIf
EndIf ; vol=#volA
If vol = #volB
yBprecedent = yB
chuteLibre(xB, yB, vxB, vyB)
If vyB > 0 ; le sprite B redescend
If (xB >= xBascule + 72) And (xB <= xBascule + a)
If (yB + c) >= yBascule And (yBprecedent + c) <= yBascule
yB = yCb - pente * (xB - xCb) - c - 2
vol = #volA
rayon(rA,(xA + 8),(yA + c), xCb, yCb)
rayon(rB,(xB + 8),(yB + c), xCb, yCb)
jtotal = m * (rA * rA + rB * rB) + jbascule
omega = m * ((xB + 8 - xCb) * vyB - (yB + c - yCb) * vxB) / jtotal
yA = yBascule + pente * (xA + c - xBascule) - c
vA = Abs(rA * omega * #E)
If vA > 70
vA = 70
EndIf
If vA < 30 ; on fixe une vitesse minimale
vA = 30
EndIf
vxA = vA * Sin(alpha) + dxBascule * 0.1
vyA = -vA * Cos(alpha)
yB = yCb + pente * (xB + c - xCb) - c - 2
sprBascule = #basculeA
sprA = #popD
Select sprB
Case #popG, #popGCoup
sprB = #popG
Case #popD, #popDCoup
sprB = #popD
EndSelect
EndIf ; test sur yB+c=yBpiedGauche et la position précedente du pied gauche
EndIf ; test xB
EndIf ; vyB>0
If yB > H
Delay(1000)
Goto jeu
EndIf
If yB < 64
yScroll = -yB + 64
Else
yScroll = 0
EndIf
If xB < 0
vxB = -vxB
EndIf
EndIf ; vol=#volB
If ElapsedMilliseconds() - pauseEpee > 1000 ; neutralisation épée après découverte de la clé
If cleTrouvee = 1
cleTrouvee = 2 ; clé disponible
EndIf
EndIf ; ElapsedMilliseconds() - pauseEpee > 1000
; animation de la chauve-souris
If ElapsedMilliseconds() - chronoBat > 100
chronoBat = ElapsedMilliseconds()
bat = bat + 1
If bat > #batBas + 1
bat = #batBas
EndIf
xBat = xBat + rndX
yBat = yBat + 4
If yBat > H ; quand elle sort de l'écran, on la fait sortir d'une des deux fenêtres avec une direction au hasard
bat = #batHaut
xBat = 10 * 16
yBat = 3 * Random(1) * 16
rndX = 4 * (-1 + Random(2))
If rndX = 0
rndX = 4
EndIf
EndIf
EndIf
; animation des rochers
chuteLibre(xRoc, yRoc, vxRoc, vyRoc)
If yRoc > H
Restore coordonneesKnights
For i = 0 To Random(2)
Read.l xRoc
Read.l yRoc
Next i
xRoc = xRoc * 16
yRoc = yRoc * 16
vyRoc = 6
vxRoc = -6 + Random(12)
EndIf
;- affichage
DisplaySprite(#spriteSheet, -a, -240 + yScroll)
Restore coordoonneesPortes
For i = 0 To 7
Read.l cln
Read.l lgn
If sprPorte(i) <> -1
DisplayTransparentSprite(sprPorte(i), 16 * cln, 16 * lgn + yScroll)
EndIf
Next i
DisplayTransparentSprite(sprBascule, xBascule, yBascule + yScroll)
xEpee = 0
If sprA = #popDCoup
xEpee = xA + 12
yEpee = yA + yScroll
sprA = #popD
EndIf
If sprA = #popGCoup
xEpee = xA - 12
yEpee = yA + yScroll
sprA = #popG
EndIf
If sprB = #popDCoup
xEpee = xB + 12
yEpee = yB + yScroll
sprB = #popD
EndIf
If sprB = #popGCoup
xEpee = xB - 12
yEpee = yB + yScroll
sprB = #popG
EndIf
If xEpee <> 0 ; rappel : initialisation de l'abscisse de l'épée à chaque boucle, si xEpee est changé alors on affiche l'épée
DisplayTransparentSprite(#epee, xEpee, yEpee)
EndIf ; xEpee <> 0
DisplayTransparentSprite(#roc, xRoc, yRoc + yScroll)
DisplayTransparentSprite(bat, xBat, yBat + yScroll)
DisplayTransparentSprite(sprA, xA, yA + yScroll)
DisplayTransparentSprite(sprB, xB, yB + yScroll)
FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow
DataSection
coordoonneesPortes:
Data.l 6, 7, 13, 7, 1, 4, 1, 7, 1, 10, 18, 5, 18, 8, 18, 11
coordonneesKnights:
Data.l 2, 1, 17, 2, 9, -3
EndDataSection