Saccades du sprite

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
killer7
Messages : 18
Inscription : ven. 06/févr./2004 16:24
Contact :

Message par killer7 »

Petite rectif de ton code pour que les vaisseaux s'affichent.
Il s'agit probablement d'un oubli, mais un débutant peut galèrer des heures sur une petite erreur comme celle-ci. :wink:
comtois a écrit :

Code : Tout sélectionner

;Définition des constantes
#LargeurEcran = 800
#NbColonnesVaisseaux = 3
#NbLignesVaisseaux = 4 
#NUM_INVADERS = #NbColonnesVaisseaux * #NbLignesVaisseaux

;et plus loin dans ton InitInvader()
Procedure InitInvaders() 
;pour calculer la position de chaque colonne 
;tu as juste à faire 
EspaceEntreColonne = #LArgeurEcran  / (NbColonnesVaisseaux + 1)
EspaceEntreLigne = 40
for a = 1 to #NbColonnesVaisseaux
   for b = 1 to #NbLignesVaisseaux
      aliens(x)\x = a * EspaceEntreColonne 
      aliens(x)\y = b * EspaceEntreLigne
      x + 1
   next b
next a
qui devient :

Code : Tout sélectionner

;Définition des constantes
#LargeurEcran = 800
#NbColonnesVaisseaux = 3
#NbLignesVaisseaux = 4 
#NUM_INVADERS = #NbColonnesVaisseaux * #NbLignesVaisseaux

;et plus loin dans ton InitInvader()
Procedure InitInvaders() 
;pour calculer la position de chaque colonne 
;tu as juste à faire 
EspaceEntreColonne = #LArgeurEcran  / (#NbColonnesVaisseaux + 1)
EspaceEntreLigne = 40
for a = 1 to #NbColonnesVaisseaux
   for b = 1 to #NbLignesVaisseaux
      aliens(x)\x = a * EspaceEntreColonne 
      aliens(x)\y = b * EspaceEntreLigne
      x + 1
   next b
next a
Cherchez la petite erreur !

Et pour les centrer avec la même distance des deux côtés de l'écran, j'ai du modifier de cette façon :

Code : Tout sélectionner

 EspaceEntreColonne = (#SCREEN_WIDTH - 40) / (#NbColonnesVaisseaux + 1)
40 étant la largeur de mon sprite.

Sinon c'est bien ce que je voulais, les vaisseaux s'affichent, centrés à l'écran par rapport à x.
killer7
Messages : 18
Inscription : ven. 06/févr./2004 16:24
Contact :

Message par killer7 »

Donc voilou la procedure InitInvaders :

Code : Tout sélectionner

; ////////////////////////////////////////////////////////////////////////////////////////
Procedure InitInvaders()

  result = LoadSprite(#invaders1,"gfx\invaders1.jpg",0)
    
  If result = 0
    MessageRequester("Erreur","Problème de chargement des sprites !!!",0)
  EndIf 

  invaders_1\speed  = 0 
  invaders_1\width  = 40
  invaders_1\height = 30
  aliens(x)\sens    = 1 

  EspaceEntreColonne = (#SCREEN_WIDTH - 40) / (#NbColonnesInvaders + 1)
  EspaceEntreLigne = 40 
  For a = 1 To #NbColonnesInvaders 
     For b = 1 To #NbLignesInvaders 
        aliens(x)\x = a * EspaceEntreColonne 
        aliens(x)\y = b * EspaceEntreLigne 
        x + 1 
     Next b 
  Next a 
EndProcedure
; ////////////////////////////////////////////////////////////////////////////////////////
Mais ou je bloque par rapport au code à Comtois pour la procedure AnimateInvaders.
Proposition de Comtois :

Code : Tout sélectionner

;ajout dans la structure Invaders
Sens.b ; déplacement vers la droite = 1 , déplacement vers la gauche = -1

Code : Tout sélectionner

;ajout dans la procedure InitInvaders
aliens(x)\sens    = 1 

Code : Tout sélectionner

  For i = 0 To #NUM_INVADERS - 1 
    ; Test de la collision ( le test sera différent selon que tu centres ton sprite ou non par rapport à aliens(i)\x ) 
    ; à toi d'adapter , dans ce cas , je considère que le sprite n'est pas centré 
    If aliens(i)\X + aliens(i)\width > #SCREEN_WIDTH Or aliens(i)\X < 0 
      aliens(i)\Sens * -1 ; on inverse le sens de déplacement de l'alien 
      aliens(i)\Y + 1 ; et on ajoute une ligne 
    EndIf 
    DisplayTransparentSprite(#invaders1,aliens(i)\X+aliens(i)\Sens,aliens(i)\Y) 
  Next i

C'est comment faire démarrer le mouvement des mes vaisseaux aliens ?

Toutes les colonnes et lignes doivent se déplacer vers la droite, ensuite collision bord écran, on descend d'une ligne (définie) et on repart mouvement vers la gauche.
Etc ...

Si kikun a le temps de m'aider un peu, merci d'avance. :wink:
Car j'ai beau avoir retourné le code ci-dessus dans tous les sens : niet déplacement. :?:

Il va de soit que InitInvaders() et AnimateInvaders() ont été déclarées.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Ben je t'ai proposé quelques pistes de réflexions , en aucun cas un code prêt à l'emploi . Il faut donc que tu cherches à comprendre la solution proposée pour l'adapter à ton besoin ,voire la rejeter et partir sur une autre piste .

Si tu ne comprends pas certains points n'hésite pas à demander .

Car comme je te le disais , le déplacement que je te propose ne me semble pas correct par rapport au jeu classique , c'est juste une méthode à adapter que je te propose .

Et malheureusement il y a une petite erreur dans cette piste :)

Code : Tout sélectionner

  For i = 0 To #NUM_INVADERS - 1 
    ; Ici il faut bien sûr changer la position des sprites 
     aliens(i)\X + aliens(i)\Sens ; pour aller plus vite mets sens = 4 par exemple
    ; Test de la collision ( le test sera différent selon que tu centres ton sprite ou non par rapport à aliens(i)\x ) 
    ; à toi d'adapter , dans ce cas , je considère que le sprite n'est pas centré 
    If aliens(i)\X + aliens(i)\width > #SCREEN_WIDTH Or aliens(i)\X < 0 
      aliens(i)\Sens * -1 ; on inverse le sens de déplacement de l'alien 
      aliens(i)\Y + 1 ; et on ajoute une ligne 
    EndIf 
    DisplayTransparentSprite(#invaders1,aliens(i)\X,aliens(i)\Y) 

  Next i 
Sinon il faut initialiser aliens()\Sens pour chaque sprite dans ta procédure init

Code : Tout sélectionner

 For a = 1 To #NbColonnesInvaders 
     For b = 1 To #NbLignesInvaders 
        aliens(x)\x = a * EspaceEntreColonne 
        aliens(x)\y = b * EspaceEntreLigne 
        aliens(x)sens = 1
        x + 1 
     Next b 
  Next a 
EndProcedure 
et bien sûr ceci n'est qu'une piste .
En fait , il me semble que les aliens se déplacent selon un autre mode , à savoir qu'ils oscillent de gauche à droite ?? ça signifie que dans ce cas
une seule variable sens suffirait pour l'ensemble des aliens
ou alors , ça pourrait être fait par ligne, bref , il y a plein de possibilités , je ne vais pas toutes les énumérer ici :)
killer7
Messages : 18
Inscription : ven. 06/févr./2004 16:24
Contact :

Message par killer7 »

En tout cas merci, j'ai compris pas mal de chose grâce à tes portions de code. Et j'ai bien saisi que c'était des pistes à explorer.

Le code fonctionne ...

Code : Tout sélectionner

; ////////////////////////////////////////////////////////////////////////////////////////
Procedure AnimateInvaders() 
  For x = 0 To #NUM_INVADERS - 1 
     aliens(x)\x + aliens(x)\sens 
    If aliens(x)\x + aliens(x)\width > (#SCREEN_WIDTH - 60) Or aliens(x)\x < 20 
      aliens(x)\sens * -1
      aliens(x)\y + 10
    EndIf 
    DisplayTransparentSprite(#invaders1,aliens(x)\x,aliens(x)\y)  
   Next x
 EndProcedure
; ////////////////////////////////////////////////////////////////////////////////////////
Et tu as raison, une fois que la première colonne (ou le premier sprite) touche un bord de l'écran (ou le point spécifié), c'est tous les vaisseaux qui doivent repartir vers la gauche.

Dans ce cas de code, toutes les colonnes de vaisseaux viennent buter les unes après les autres et bien évidemment se chevauchent en repartant en sens inverse.
Il faudrait que dès que le premier sprite bute, les aliens repartent en sens inverse. (je sais pas si c'est clair : comme un space invaders)
Oscillation droite/gauche comme tu le disais.

Comment procèder ???

Je tente de trouver la soluce, m'enfin pas facile.

En tous les cas milles merci déjà.
Invité

Message par Invité »

En fait , les aliens oscillent , pour ça tu as besoin de trois variables globales :
Vitesse de déplacement horizontal
Sens de déplacement
Amplitude de l'oscillation

Code : Tout sélectionner

Global Vitesse.l,sens.l,Amplitude.l
Vitesse = 2 
sens = 0
Amplitude = 40 


ensuite dans ta procedure tous les aliens se déplacement dans le même sens , à la même vitesse 
on incrémente un compteur , et quand l'amplitude maxi est atteinte , on inverse le sens de déplacement .

Procedure AnimateInvaders() 
   For x = 0 To #NUM_INVADERS - 1 
      aliens(x)\x + Vitesse 
      sens + 1
      If sens > Amplitude ; Donc 40 * Vitesse = un déplacement de 80 pixels > à adapter 
         Vitesse * -1
         sens = 0
         aliens(x)\y + 10 
      EndIf 
      DisplayTransparentSprite(#invaders1,aliens(x)\x,aliens(x)\y)  
   Next x 
EndProcedure
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

zut , j'étais pas connecté !

juste pour te dire que tu devrais faire un tour sur le musée purebasic, Chrystal noir avait posté le code d'un invaders , je ne sais pas s'il fonctionne sur ce principe , mais tu pourras y trouver une source d'inspiration pour la suite de ton jeu , à savoir la gestion du tir .
killer7
Messages : 18
Inscription : ven. 06/févr./2004 16:24
Contact :

Message par killer7 »

Voilà le code qui me parait le plus approprié pour le mouvement que je désire obtenir : (bien que ta soluce d'oscillation fonctionne parfaitement et sans défaut).

C'est juste que je veux des va-et-vient.

Code : Tout sélectionner

; ////////////////////////////////////////////////////////////////////////////////////////
Procedure AnimateInvaders()           
  For x = 0 To #NUM_INVADERS - 1
    aliens(x)\x = aliens(x)\x + aliens(x)\sens
    If aliens(x)\x > (#SCREEN_WIDTH - 60) Or aliens(x)\x < 20 
      For x = 0 To #NUM_INVADERS - 1
        aliens(x)\sens = - aliens(x)\sens 
        aliens(x)\y + 5
      Next x 
    EndIf             
    DisplayTransparentSprite(#invaders1,aliens(x)\x,aliens(x)\y)   
   Next x   
 EndProcedure
; ////////////////////////////////////////////////////////////////////////////////////////
Et bien sur me voilà de nouveau heurté à un problème, ou plutôt deux.
A chaque allez-retour, un sprite apparait (et qui disparait aussitôt) aux coordonnées x =0, y=0 (en fait à la première descente d'une ligne)
... et plus mes lignes descendent, j'ai un décalage qui s'opére sur l'affichage de mes vaisseaux aliens.

??? mystère, mystère ???

Je planche dessus, il me semblerait que je doive modifier la structure InitInvaders pour corriger ces défauts (l'initialisation de l'affichage).

Pourquoi un sprite apparait en haut de l'écran à gauche à chaque descente d'une ligne ???
Ce doit être lui qui décale tout par la suite, non ?

Merci pour l'info pour le Forum le musée du PureBasic.
Je vais mater tout ça.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

faudrait que tu colles ton code ici , ça serait plus simple de voir ce qui ne va pas . par contre fais une version forum , c'est à dire sans truc à charger , si tu as un loadsprite() quelque part , dans ce cas , passe la ligne en commentaire et ajoute un truc du genre createsprite() en faisant en sorte de donner exactement les mêmes dimensions que le sprite que tu charges ,de façon à ce que ton code fonctionne en faisant juste un copier/coller .
Répondre