Prendre un lutin par la main..MAJ!!!.
Publié : mar. 10/avr./2007 15:53
Objectif : suivre le chemin donné par un programme de pathfinding.
Contrainte: le sprite(lutin!) doit se déplacer sur le chemin pixel par pixel et non case par case
Principe : Une "tête chercheuse" regarde les cases voisines pour avancer, dès que la case est trouvée, la tête fait une pause et le sprite fait sa translation. Quand la case de destination est atteinte, la tête reprend les recherches.
Pas de gestion des diagonales (le lutin devra ralentir lors de ses déplacements en diagonale), le premier chemin trouvé est pris.
J'ai d'autres idées pour suivre un chemin(créer une structure "fils", ou stocker le chemin sous forme de chaîne de caractères dans l'étape n°3 du pathfinding) mais avec celle-là je peux gérer des chemins différents qui se croisent sans rien modifier(exemple si il y a un chemin vert et un rouge, juste rajouter dans l'énumération #chemin_vert, #chemin_rouge,#chemin_croisement).
La condition d'arrêt est très fragile
En effet, si l'égalité n'est pas vérifiée, la translation continue!
Ca pose problème si dx et dy ne sont pas des diviseurs de 16!!!
Je mettrai une condition sur l'écart par rapport au point d'arrivée si |x_lutin*16-x|<=1 pixel (idem pour y)par exemple.
Et vous, vous faites comment pour suivre les cases d'un tableau ?
Je sais que je devrai gérer tout ça avec des listes chaînées...et ça me fait très peur
Carte à charger:

Hasta la vista!
Contrainte: le sprite(lutin!) doit se déplacer sur le chemin pixel par pixel et non case par case
Principe : Une "tête chercheuse" regarde les cases voisines pour avancer, dès que la case est trouvée, la tête fait une pause et le sprite fait sa translation. Quand la case de destination est atteinte, la tête reprend les recherches.
Pas de gestion des diagonales (le lutin devra ralentir lors de ses déplacements en diagonale), le premier chemin trouvé est pris.
J'ai d'autres idées pour suivre un chemin(créer une structure "fils", ou stocker le chemin sous forme de chaîne de caractères dans l'étape n°3 du pathfinding) mais avec celle-là je peux gérer des chemins différents qui se croisent sans rien modifier(exemple si il y a un chemin vert et un rouge, juste rajouter dans l'énumération #chemin_vert, #chemin_rouge,#chemin_croisement).
La condition d'arrêt est très fragile

Code : Tout sélectionner
If x_lutin*16=x And y_lutin*16=y
chercher_chemin=1
EndIf
Ca pose problème si dx et dy ne sont pas des diviseurs de 16!!!
Je mettrai une condition sur l'écart par rapport au point d'arrivée si |x_lutin*16-x|<=1 pixel (idem pour y)par exemple.
Et vous, vous faites comment pour suivre les cases d'un tableau ?
Je sais que je devrai gérer tout ça avec des listes chaînées...et ça me fait très peur

Carte à charger:
Code : Tout sélectionner
;suivre un chemin...
;ECHAP ou click droit pour quitter
;auteur Huitbit
Enumeration
#spr_ecran
#spr_decor
#spr_mur
#spr_chemin
#spr_depart
#spr_arrivee
#spr_lutin
#case_mur
#case_chemin
#case_traitee
EndEnumeration
;coordonnées dans le tableau map(63,63))
#x_max=64
#y_max=64
#x_depart=8
#y_depart=8
#x_arrivee=56
#y_arrivee=56
x_lutin.b=#x_depart
y_lutin.b=#y_depart
;coordonnées d'affichage écran
dx.b=0 ;variation selon les x
dy.b=0 ;variation selon les y
x.w=0
y.w=0
chercher_chemin.b=1 ; commande de recherche du chemin si 1 chercher ; si 0 stopper la recherche
Global Dim map.b(#x_max-1,#y_max-1)
;dessin de la carte********************************
Procedure.b initialisation()
CreateSprite(#spr_ecran,1280,1024)
;traitement de l'image decor
StartDrawing(SpriteOutput(#spr_decor))
For j=0 To 63
For i=0 To 63
If Red(Point(i,j))=0
map(i,j)=#case_mur ; pixel noir = case mur
ElseIf Red(Point(i,j))=255
map(i,j)=#case_chemin ;pixel rouge = case chemin
EndIf
Next i
Next j
StopDrawing()
;affichage des murs, départ et arrivée
UseBuffer(#spr_ecran)
For j=0 To 63
For i=0 To 63
If map(i,j)=#case_mur
DisplaySprite(#spr_mur,i*16,j*16)
ElseIf map(i,j)=#case_chemin
DisplaySprite(#spr_chemin,i*16,j*16)
EndIf
Next i
Next j
DisplaySprite(#spr_depart,#x_depart*16,#y_depart*16)
DisplaySprite(#spr_arrivee,#x_arrivee*16,#y_arrivee*16)
UseBuffer(-1)
EndProcedure
;programme principal***********************
InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(1280,1024,32,"suivre_chemin")
UsePNGImageDecoder()
;****************carte à explorer*****************************
LoadSprite(#spr_decor,"suivre_chemin.png")
;**********************************************************************
;création des sprites****************
CreateSprite(#spr_mur,16,16)
StartDrawing(SpriteOutput(#spr_mur))
Box(0,0,16,16,RGB(0,100,100))
StopDrawing()
CreateSprite(#spr_chemin,16,16)
StartDrawing(SpriteOutput(#spr_chemin))
Box(0,0,16,16,RGB(187, 120, 8))
StopDrawing()
CreateSprite(#spr_depart,16,16)
StartDrawing(SpriteOutput(#spr_depart))
DrawText(4,0,"D")
StopDrawing()
CreateSprite(#spr_arrivee,16,16)
StartDrawing(SpriteOutput(#spr_arrivee))
DrawText(4,0,"A")
StopDrawing()
CreateSprite(#spr_lutin,16,16)
StartDrawing(SpriteOutput(#spr_lutin))
Circle(8,8,8,RGB(0,255,0))
StopDrawing()
initialisation()
;boucle principale****************************************************
Repeat
Delay(10)
DisplaySprite(#spr_ecran,0,0)
;gestion du déplacement du lutin sur le chemin****************
If x_lutin<>#x_arrivee And y_lutin<>#y_arrivee
If chercher_chemin=1
For i=-1 To 1
For j=-1 To 1
If map(x_lutin+i,y_lutin+j)=#case_chemin
chercher_chemin=0
map(x_lutin+i,y_lutin+j)=#case_traitee
dx=i*2
dy=j*2
x=16*x_lutin
y=16*y_lutin
x_lutin=x_lutin+i
y_lutin=y_lutin+j
Break 2
EndIf
Next j
Next i
EndIf
;translation d'une case chemin à une autre(boucle de recherche stoppée pendant ce temps)
x=x+dx
y=y+dy
DisplayTransparentSprite(#spr_lutin,x,y)
If x_lutin*16=x And y_lutin*16=y
chercher_chemin=1
EndIf
;fin de la translation
EndIf
ExamineKeyboard()
ExamineMouse()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or MouseButton(#PB_MouseButton_Right )
End