Back to Winterfell "dépunché"

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Back to Winterfell "dépunché"

Message par Huitbit »

Hello,

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é :P )!
Je suis parti du moteur et j'ai garni sans faire déborder :mrgreen:
Il y a même des Goto (j'adore ça :mrgreen: ).

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
Hasta la vista !
Elevé au MSX !
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Back to Winterfell "dépunché"

Message par djes »

Merci ! Je mettrai les codes dépunchés dans l'archive finale. J'espère ne pas en oublier !
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Back to Winterfell "dépunché"

Message par graph100 »

la taille de ton code me conforte dans l'idée que le maximum de réduction pour un punch de x lignes et 80 colonnes, c'est environ 10x lignes.

C'est bon à savoir pour les punchs à venir 8)
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Re: Back to Winterfell "dépunché"

Message par Huitbit »

Hello,

Tu as raison, le rapport de 10 à l'air faisable pour la plupart des codes.
Après, il y a les artistes du punch...

Pour mon code, en supprimant les espaces et les commentaires, ça tombe en-dessous des 400 lignes (environ 380 lignes)
Ca veut dire que j'aurais pu faire mieux !

J'ai "punché" comme un sagouin parce que l'échéance arrivait à grands pas et je voulais
que le code soit testé avant le jour J.
Avec 100 lignes(c'est à dire 7 ou 8 lignes punchées voire plus) de plus, j'aurais pu ajouter un joli "Game over" ou "Congratulations" en sprite, améliorer la jouabilité, mettre plus d'animations..etc !

Ca sera pour la prochaine fois !

Hasta la vista !
Elevé au MSX !
Répondre