Page 1 sur 2
Saccades du sprite
Publié : ven. 06/févr./2004 16:27
par killer7
bonjour,
J'aimerais comprendre pourquoi lors d'un déplacement mon sprite saccade.
Exemple : le joueur sur un Space Invaders Like (ou même les aliens).
Existe-t-il une solution pour que tout celà devienne fluide ?
Merci d'avance !

Publié : ven. 06/févr./2004 16:30
par Patrick88
tu nous montres le bout de code qui chiotte, afin que l'on puisse t'aider...
t'as mis le flipbuffer() ?
patrick
Publié : ven. 06/févr./2004 16:32
par comtois
Essaye ça
Code : Tout sélectionner
;Danilo - Forum Anglais
;- procedures
Procedure InitGameTimer()
Shared _GT_DevCaps.TIMECAPS
timeGetDevCaps_(_GT_DevCaps,SizeOf(TIMECAPS))
timeBeginPeriod_(_GT_DevCaps\wPeriodMin)
EndProcedure
Procedure StopGameTimer()
Shared _GT_DevCaps.TIMECAPS
timeEndPeriod_(_GT_DevCaps\wPeriodMin)
EndProcedure
;- variables
Global player1_move.f, player1_x.f, player1_y.f
;- _program start
;- _Init
If InitSprite()=0 Or InitKeyboard()=0
MessageRequester("ERROR","Cant init DirectX !",#MB_ICONERROR):End
EndIf
If OpenScreen(800,600,32,"Timing")=0
If OpenScreen(800,600,24,"Timing")=0
If OpenScreen(800,600,16,"Timing")=0
MessageRequester("ERROR","Cant open screen !",#MB_ICONERROR):End
EndIf:EndIf:EndIf
If CreateSprite(1,32,32)=0
CloseScreen()
MessageRequester("ERROR","Cant create sprite !",#MB_ICONERROR):End
Else
StartDrawing(SpriteOutput(1))
Box (0,0,32,32,$00FFFF)
Line(0,0,32,32,$000000)
Line(32,0,0,32,$000000)
StopDrawing()
EndIf
player1_speed.f = 0.50
; timer initialisieren
InitGameTimer()
StartTime = TimeGetTime_()
;StartTime = GetTickCount_()
time = StartTime
SetFrameRate(75)
;- _game loop
Repeat
; calculate multiplicator
multiplicator.f = StartTime
StartTime = TimeGetTime_()
;StartTime = GetTickCount_()
multiplicator = StartTime - multiplicator
; calc framerate
If TimeGetTime_()-time >= 1000
;If GetTickCount_()-time >= 1000
time = TimeGetTime_()
;time = GetTickCount_()
FPS = Frames-1
Frames = 1
Else
Frames+1
EndIf
ClearScreen(0,0,0)
; show framerate
StartDrawing(ScreenOutput())
DrawingMode(1):FrontColor($80,$FF,$00)
Locate(50,50):DrawText("FrameRate: "+Str(FPS))
StopDrawing()
ExamineKeyboard()
; calc move-step for player1
player1_move = player1_speed * multiplicator
If KeyboardPushed(#PB_Key_Left)
player1_x - player1_move : EndIf
If KeyboardPushed(#PB_Key_Right)
player1_x + player1_move : EndIf
If KeyboardPushed(#PB_Key_Up)
player1_y - player1_move : EndIf
If KeyboardPushed(#PB_Key_Down)
player1_y + player1_move : EndIf
If player1_x < -32 : player1_x = 800 : EndIf
If player1_x > 800 : player1_x = -32 : EndIf
If player1_y < -32 : player1_y = 600 : EndIf
If player1_y > 600 : player1_y = -32 : EndIf
DisplaySprite(1,player1_x,player1_y)
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
;- _program end
StopGameTimer()
Publié : ven. 06/févr./2004 16:37
par killer7
Patrick88>>
Oui, j'ai bien mis Flipbuffer() à la fin de la boucle principale.
Je précise que c'est un mode fenêtré 640x480.
Comtois >>
Merci vais essayer de mettre un Timer de ce genre, c'est vrai que j'aurais du y penser.
M'en vais tester tout ça !!!
Publié : ven. 06/févr./2004 18:13
par killer7
J'ai essayé, rien à faire ça saccade (encore plus lol).
Compiles et testes ton exemple, celà saccade aussi.
Publié : ven. 06/févr./2004 18:20
par comtois
chez moi , ça ne saccade pas .
Publié : ven. 06/févr./2004 18:20
par Chris
Je viens d'essayer le code : Aucune saccade chez moi !!
Chris

Publié : ven. 06/févr./2004 18:25
par Invité
Bah j'ai bien des tâches qui tournent en arrière plan, mais de là à monopoliser l'AMD 2200+, je sais pas.
P'tet ça alors.
Vais tout couper et retester tout ça.
Merci de vos réponses rapides en tout cas.

Publié : sam. 07/févr./2004 15:18
par killer7
Rien à faire j'ai toujours des petits acoups !
... vais tout reprendre depuis le début.
Petite question :
Comment les spécialistes de ce Forum feraient pour structurer le joueur, les aliens, etc ... par rapport à ce code source ?
Une structure pour le joueur, aliens, etc ...
http://darkprograms.hmt-forum.com/viewtopic.php?t=126
Question vachement important pour les débutants comme moi et d'autres !
Merci d'avance !
Publié : dim. 08/févr./2004 2:46
par killer7
Bon, j'ai réussi à structurer tout ça.
Par contre je bloque un peu sur comment afficher les lignes de vaisseaux aliens, par la boucle For en se servant de la structure (vaisseaux aliens)
Comment préparer les lignes puis les afficher à l'écran ???
Publié : dim. 08/févr./2004 4:05
par killer7
Finalement j'ai procédé ainsi :
Voici les 1ères parties importantes de la conversion du lien en code source utilisant des structures et des procédures, je trouve que c'est plus propre. Ce tutorial
http://purebasic.hypervox.co.uk/ m'a bien aidé puisque j'ai utilisé des parties du code proposé, j'ai ensuite ajouté la partie des aliens.
Code : Tout sélectionner
; etc ...
#NUM_INVADERS = 50
Global player_1.Player
Global invaders_1.Invaders
Global spacex, spacey
; etc ...
Structure Player
x.w ;position du joueur - x
y.w ;position du joueur - y
width.w ;largeur du sprite
height.w ;hauteur du sprite
speed.f ;vitesse du joueur
fps.w ;frames par secondes du joueur
frameno.w ;numéro courant du frame
frames.Frame[3] ;array of frames to animate
EndStructure
Structure Invaders
x.w ;position des aliens - x
y.w ;position des aliens - y
width.w ;largeur du sprite
height.w ;hauteur du sprite
speed.f ;vitesse des aliens
fps.w ;frames par secondes des aliens
frameno.w ;numéro courant du frame
frames.Frame[3] ;array of frames to animate
EndStructure
; etc ...
Dim aliens.Invaders(#NUM_INVADERS)
;etc ...
; ////////////////////////////////////////////////////////////////////////////////////////
Procedure InitPlayer()
;
; Load player variable
;
; load sprite and set player's initial x,y and speed
result = LoadSprite(#player1,"fighter2.bmp",0)
If result = 0
MessageRequester("b","Problème de chargement des sprites !!!",0)
EndIf
player_1\speed = 2 ; 1 / 0.50 / 0.30
player_1\width = 60
player_1\height = 60
player_1\x = (#SCREEN_WIDTH - player_1\width) /2
player_1\y = 520
; now load the frame data (note: not the bitmap, just the cordinates
startpointx = 0
startpointy = 0
For x = 0 To 2
player_1\frames[x]\x1 = startpointx
player_1\frames[x]\y1 = startpointy
player_1\frames[x]\x2 = startpointx + 60
player_1\frames[x]\y2 = startpointy
startpointx = startpointx + 60
Next
player_1\frameno = 0
EndProcedure
; ////////////////////////////////////////////////////////////////////////////////////////
; ////////////////////////////////////////////////////////////////////////////////////////
Procedure AnimatePlayer()
;
; Animate the player
; Clip the sprite
;
CurrFrame = player_1\frameno
ClipSprite(#player1, player_1\frames[CurrFrame]\x1, player_1\frames[CurrFrame]\y1, player_1\width ,player_1\height)
DisplayTransparentSprite(#player1,player_1\x,player_1\y)
CurrFrame = CurrFrame + 1
If CurrFrame > 2
CurrFrame = 0
EndIf
player_1\frameno = CurrFrame
EndProcedure
; ////////////////////////////////////////////////////////////////////////////////////////
; ////////////////////////////////////////////////////////////////////////////////////////
Procedure InitInvaders()
;
; Load invaders variable
;
; load sprite and set invader's initial x,y and speed
result = LoadSprite(#invaders1,"invaders1.bmp",0)
If result = 0
MessageRequester("b","Problème de chargement des sprites !!!",0)
EndIf
invaders_1\speed = 1
invaders_1\width = 37
invaders_1\height = 25
For x = 0 To #NUM_INVADERS - 1
spacex = spacex + 60
aliens(x)\x = aliens(x)\x + spacex
aliens(x)\y = aliens(x)\y + spacey
If spacex > 550
spacex = 0
spacey = spacey + 40
EndIf
Next x
EndProcedure
; ////////////////////////////////////////////////////////////////////////////////////////
; ////////////////////////////////////////////////////////////////////////////////////////
Procedure AnimateInvaders()
;
; Animate invaders
; Clip the sprite
;
For i = 0 To #NUM_INVADERS - 1
DisplayTransparentSprite(#invaders1,aliens(i)\x,aliens(i)\y)
Next i
; mouvement des vaisseaux à définir ...
EndProcedure
; ////////////////////////////////////////////////////////////////////////////////////////
voilou, si vous avez des sugestions d'amélioration pour tout ça, merci d'avance.
sinon, encore une petite question : comment centrer mes colonnes de vaisseaux à l'écran par rapport à x ???
Ps: p'tain je me suis fait un monologue.
Enfin voilà si celà peux aider quelqu'un tant mieux.
Le code source :
http://darkprograms.hmt-forum.com/viewtopic.php?t=126 me semblait très intéressant à structurer de façon procédurale.
Publié : dim. 08/févr./2004 10:09
par comtois
killer7 a écrit :
sinon, encore une petite question : comment centrer mes colonnes de vaisseaux à l'écran par rapport à x ???
Ben pour ça tu as besoin de connaitre le nombre de colonnes , et la largeur de ton écran
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
bon ,c'est une autre façon de faire, à chacun son goût
par contre avec ce système colonne , ligne , ça peut te permettre de faire des figures avec tes aliens avec des datas par exemples , ou un fichier texte
ça donnerait un truc du genre
data.l 1,1,1,1,1,1,1
data.l 0,1,1,1,1,1,0
data.l 0,0,1,1,1,0,0
data.l 0,0,0,1,0,0,0
tu as juste à lire les datas , si c'est un 1 tu places un alien , sinon rien
Publié : dim. 08/févr./2004 19:08
par killer7
Merci bien Comtois !
C'est vrai que la méthode est très intéressante, et ouvre pas mal de possibilités au niveaux de l'affichage des vaisseaux.
Je me pencherais en détails sur la Data.
Autre question :
Par rapport à mon dernier source affiché, comment faire pour que mes vaisseaux lorsqu'ils touchent le bord de l'écran (exemple à droite), descendent d'une ligne et repartent en sens inverse ?
Détecter la collision et enchainer sur la suite en gros : 1 ligne plus bas + sens inverse.
Merci d'avance !
Je tenais quand même à spécifier que je suis ici depuis peu et je suis très étonné de la rapidité de réponse et de la convivialité.
Bravo à tous !
On progresse à grands pas sur ce type de Forum.
Publié : dim. 08/févr./2004 20:43
par comtois
dans ta Structure Invaders , tu ajoutes un paramètre
Code : Tout sélectionner
Sens.b ; déplacement vers la droite = 1 , déplacement vers la gauche = -1
ensuite dans ta Procedure InitInvaders()
tu initialises ainsi
puis dans ta procédure AnimateInvaders()
tu ajoutes le test de collision avec les bords de l'écran
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 > #LargeurEcran 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
Bon ça c'est juste pour te donner une idée , mais en fait , je crois que dans ce type de jeu , c'est toute la Ligne qui change de Sens ?
ça signifie qu'il faudrait le traiter non pas pour chaque alien , mais par ligne
en gros , tu as besoin de connaitre par Ligne le premier alien à gauche et le premier à droite ?
faudrait que je rejoue à ce jeu pour me souvenir du principe

ou alors va falloir que tu précises un peu mieux le comportement que tu souhaites
Publié : mar. 10/févr./2004 14:55
par cederavic
j'ai commencer a lire, mais j'ai pas fini lol
si tu fait une version windows, je te conseil vivement de prendre la libray spriteex et de metre un waitvbl (voir forum suggestions...) ça evite entre autre les "demi saccade" (une moitier de la fenetre decaler par rapport a l'autre)