A small code for isometric scroll... you can change #X_Tilesize (128 in this case) to change the size of the tiles.
You can also change vitesse_scroll (32 in this case) to change the velocity of the scroll.
There is inside a smart (and very fast) way to check collision pixel per pixel with the mouse.
Inside the code the seed of pathfinding structure HPA* but just the seed.
I hope it can be usefull to someone.
Code: Select all
If InitSprite() = 0 Or InitKeyboard()=0 Or InitMouse()=0 Or InitSprite3D()=0 Or InitSound()=0:MessageRequester("Error","Error DirectX",0):EndIf
ExamineDesktops()
;{-structures
Structure carte1
tile.i
altitude.i
*element
X.i
Y.i
EndStructure
Structure ordre_affichage1
X.i
Y.i
EndStructure
Structure sprite1
spritedebase.i
numeroanimation.i
maxanimation.i
vitesseanimation.i
tempoanimation.i
biasX.i
biasY.i
selection.i
EndStructure
Structure collision1
X.i
Y.i
sprite.i
EndStructure
Structure XX1
X1.i
X2.i
EndStructure
Structure impactsprite1
List XX.XX1()
EndStructure
Structure Gate1
X1.i
Y1.i
X2.i
Y2.i
EndStructure
Structure secteur1
List Gate.Gate1()
EndStructure
;}
;{-déclare les constantes
#X_Tilesize=128
#Y_Tilesize=#X_Tilesize/2
;}
;{-déclare les variables globales
Global xmax=DesktopWidth(0),ymax=DesktopHeight(0)
Global xscroll,yscroll,Xscrolliso,Yscrolliso
Global nbcaseX=Round(xmax/#X_Tilesize,1);nombre de Case en hauteur en diagonal à afficher
Global nbcaseY=Round(ymax/#Y_Tilesize,0);nombre de Case en largeur en diagonal à afficher
Global Scroll_X=80,Scroll_Y=80,IsoScroll_X=1,IsoScroll_Y=80,XX,YY
Global Scroll_X=80,Scroll_Y=80,IsoScroll_X=1,IsoScroll_Y=80,XX,YY
Global vitesse_scroll.i=32,miliscrol_X.i,miliscrol_Y.i
;}
;{-déclare les variables "temporaires"
Global T_i,T_j,T_nb,T_DecX=0,T_DecY=0,T_offset=0
;}
;déclare l'aire de jeu
Global Dim carte.carte1(1023,1023)
;déclare le tableau d'ordre d'affichage des tiles
Global Dim ordre_affichage.ordre_affichage1(20000)
;liste des caractéristiques de l'animation des arbres
Global NewList sprite.sprite1()
Global Dim secteur.secteur1(16,16)
;liste des sprites en collision avec la souris
Global NewList collision.collision1()
Global NewMap impactsprite.impactsprite1()
Global NewMap *selection()
;ouvre un écran
OpenScreen(xmax,ymax, DesktopDepth(0), "test")
;{-rempli la carte
;Tiles
For t_i=0 To 1023
t_a=1
For t_j=0 To 1023
If t_j%64=0 Or t_i%64=0:t_a+1:If t_a=4:t_a=1:EndIf:EndIf
carte(t_i,t_j)\tile=t_a
Next t_j
Next t_i
;initialise les arbres
For t_i=0 To 10000
Repeat
X=Random(1021)+1
Y=Random(1021)+1
AddElement(sprite())
sprite()\spritedebase=150
sprite()\numeroanimation=0
sprite()\maxanimation=0
sprite()\vitesseanimation=0
sprite()\tempoanimation=0
sprite()\biasX=-64
sprite()\biasY=-224
Until carte(x,y)\element=0
carte(X,Y)\element=@sprite()
Next t_i
;initialise un personnage
X=80
Y=80
AddElement(sprite())
sprite()\spritedebase=200
sprite()\numeroanimation=0
sprite()\maxanimation=0
sprite()\vitesseanimation=0
sprite()\tempoanimation=0
carte(x,y)\element=@sprite()
sprite()\biasX=0
sprite()\biasY=-30
;}
;{ définit l'ordre d'affichage des tiles
For T_j=nbcaseY To -nbcaseY Step -1
For T_i=nbcaseX To -nbcaseX Step -1
T_nb+1
ordre_affichage(T_nb)\X=-T_j-T_i
ordre_affichage(T_nb)\Y=T_i-T_j
Next T_i
For T_i=nbcaseX To -nbcaseX+1 Step -1
T_nb+1
ordre_affichage(T_nb)\X=-T_j-T_i+1
ordre_affichage(T_nb)\Y=T_i-T_j
Next T_i
Next T_j
ReDim ordre_affichage(T_nb)
;-rempli les coordonnées Isométriques des Tiles
For T_j = 0 To 1023
For T_i = 0 To 1023
T_DecX = T_DecX + (#X_Tilesize/2)
T_DecY = T_DecY + (#Y_Tilesize/2)
carte(T_i,T_j)\X=T_DecX
carte(T_i,T_j)\Y=T_DecY
Next T_i
T_offset+1
T_DecX = -(T_offset*(#X_Tilesize/2))
T_DecY = (#Y_Tilesize/2)*T_offset
Next T_j
;}
;{-création des sprites
;sprite noir vide
CreateSprite(0,#X_Tilesize,#X_Tilesize,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(0))
Box(0,0,#X_Tilesize,#X_Tilesize,RGB(255,255,255))
Box(1,1,#X_Tilesize-2,#X_Tilesize-2,RGB(1,1,1))
StopDrawing()
T_T=10000
For t_j=1 To 3
;sprite de terrain :herbe verte, herbe sèche et terre nue
CreateSprite(t_j,#X_Tilesize,#X_Tilesize,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(t_j))
Box(0,0,#X_Tilesize,#X_Tilesize,RGB(0,0,0))
Box(0,0,#X_Tilesize,#X_Tilesize,RGB(196, 178, 86))
For T_i=1 To T_T
Plot(Random(#X_Tilesize-1),Random(#X_Tilesize-1),RGB(0,200,50))
Plot(Random(#X_Tilesize-1),Random(#X_Tilesize-1),RGB(0,127,0))
Next T_i
T_T/2
StopDrawing()
Next T_j
;sprite arbre
CreateSprite(150,256,256,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(150))
Box(107,64,42,255,RGB(1,1,1))
Box(108,64,40,255,RGB(173, 103, 82))
Circle(128,65,66,RGB(1,1,1))
Circle(128,65,64,RGB(0,200,0))
Circle(128,65,30,RGB(1,1,1))
Circle(128,65,28,RGB(0,0,0))
StopDrawing()
;sprite ombre arbre
CreateSprite(170,64,64,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(170))
Circle(32,32,32,RGB(1,1,1))
StopDrawing()
;sprite personnage
CreateSprite(200,128,128,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(200))
Box(54,20,20,50,RGB(1,1,1)) ;tronc
Circle(64,20,20,RGB(120,120,120)) ;tête
StopDrawing()
;sprite de la souris
CreateSprite(100,16,16,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(100))
LineXY(0,0,15,5,RGB(255,255,255))
LineXY(0,0,5,15,RGB(255,255,255))
LineXY(15,5,5,15,RGB(255,255,255))
StopDrawing()
CreateSprite(300,#X_Tilesize,#X_Tilesize,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(300))
LineXY(0,0,127,0,RGB(255,255,255))
LineXY(127,0,127,127,RGB(255,255,255))
LineXY(127,127,0,127,RGB(255,255,255))
LineXY(0,127,0,0,RGB(255,255,255))
StopDrawing()
;transforme les sprites carrées en tiles losanges isométriques rapport 1/2
For T_i=0 To 3
CreateSprite3D(T_i,T_i)
TransformSprite3D(T_i,#X_Tilesize/2,0,#X_Tilesize,#Y_Tilesize/2,#X_Tilesize/2,#Y_Tilesize,0,#Y_Tilesize/2)
Next T_i
CreateSprite3D(150,150)
CreateSprite3D(170,170)
TransformSprite3D(170,0,0,#X_Tilesize/2,0,#X_Tilesize/2,#Y_Tilesize/2,0,#Y_Tilesize/2)
CreateSprite3D(200,200)
CreateSprite3D(100,100)
CreateSprite3D(300,300)
;}
;{- compresse les sprites pour tester les collisions
For t_k=1 To 3 ;nombre de sprites
Read.i t_sprite
Start3D()
DisplaySprite3D(t_sprite,0,0)
Stop3D()
StartDrawing(ScreenOutput())
For t_j=0 To SpriteHeight(t_sprite)
AddMapElement(impactsprite(),Str(t_sprite)+"T"+Str(t_j))
For t_i=0 To SpriteWidth(t_sprite)
If A<>Point(t_i,t_j)
If flag=1:Continue:EndIf
flag=1
AddElement(impactsprite()\XX())
impactsprite()\XX()\X1=t_i
ElseIf flag=1
flag=0:impactsprite()\XX()\X2=t_i
EndIf
Next t_i
flag=0
Next t_j
StopDrawing()
FlipBuffers()
ClearScreen(RGB(0,0,0))
Next t_k
;liste des sprites à compresser
DataSection
Data.i 1,150,200
EndDataSection
;}
;boucle principale
Repeat
FlipBuffers()
ClearScreen(RGB(0,0,0))
Delay(3)
ExamineKeyboard()
ExamineMouse()
XX=MouseX()
YY=MouseY()
;{-scroll de la carte
If XX>xmax-20
If Scroll_X<1023 And Scroll_Y>0
miliscrol_X-vitesse_scroll
If miliscrol_X<=0
Scroll_X+1:Scroll_Y-1
IsoScroll_X+1
miliscrol_X=#X_Tilesize
EndIf
EndIf
EndIf
If XX<20
If Scroll_X>0 And Scroll_Y<1023
miliscrol_X+vitesse_scroll
If miliscrol_X>=#X_Tilesize
miliscrol_X=0
Scroll_X-1:Scroll_Y+1
IsoScroll_X-1
EndIf
EndIf
EndIf
If YY>ymax-20
If Scroll_X<1023 And Scroll_Y<1023
miliscrol_Y-vitesse_scroll/2
If miliscrol_Y<=0
Scroll_X+1:Scroll_Y+1:IsoScroll_Y+1:miliscrol_Y=#Y_Tilesize
EndIf
EndIf
EndIf
If YY<20
If Scroll_X>0 And Scroll_Y>0
miliscrol_Y+vitesse_scroll/2
If miliscrol_Y>=#Y_Tilesize
Scroll_X-1:Scroll_Y-1:IsoScroll_Y-1:miliscrol_Y=0
EndIf
EndIf
EndIf
;}
;{-traitement des boutons de souris
;si on clic gauche (front montant sur clic gauche)
If boutongauche=0
If MouseButton(1)
;déselectionne les elements déja selectionnés si il y en a
ForEach *selection()
ChangeCurrentElement(sprite(),*selection())
sprite()\selection=0
Next
ClearMap(*selection())
fenetreX1=XX
fenetreY1=YY
EndIf
EndIf
;si on relache le clic gauche (front descendant sur clic gauche)
If boutongauche
fenetreX2=XX
fenetreY2=YY
If MouseButton(1)=0
fenetreValid=1
If fenetreX1>fenetreX2:Swap fenetreX1,fenetreX2:EndIf
If fenetreY1>fenetreY2:Swap fenetreY1,fenetreY2:EndIf
EndIf
EndIf
;se rappelle de l'état du clic gauche un cycle avant
boutongauche=MouseButton(1)
;}
;{-Affichage sprites 3D
collisionx=0:collisiony=0:collisionelement=0
Start3D()
For i=0 To T_nb
sx=Scroll_X+ordre_affichage(i)\X
sy=Scroll_Y+ordre_affichage(i)\Y
;Si dans le tableau de jeu...
If sx>=0 And sy>=0 And sy<=1023 And sx<=1023
T_Cases=carte(sx,sy)\tile
sxx=carte(sx,sy)\X-(IsoScroll_X*#X_Tilesize)+xmax/2-#X_Tilesize+miliscrol_X
syy=carte(sx,sy)\Y-IsoScroll_Y*#Y_Tilesize+ymax/2-#Y_Tilesize-#Y_Tilesize/2+miliscrol_Y
;affiche la case de terrain
DisplaySprite3D(T_Cases,sxx,syy)
;{-test le tile sous la souris
If XX>sxx And XX<sxx+#X_Tilesize And YY>syy And YY<syy+#Y_Tilesize
T_X=XX-sxx
T_Y=YY-syy
If FindMapElement(impactsprite(),"1T"+Str(T_Y))
ForEach impactsprite()\XX()
If T_X>=impactsprite()\XX()\X1 And T_X<=impactsprite()\XX()\X2
collisionX=sx
collisionY=sy
EndIf
Next
EndIf
EndIf
;}
EndIf
Next i
For i=0 To T_nb
sx=Scroll_X+ordre_affichage(i)\X
sy=Scroll_Y+ordre_affichage(i)\Y
;Si dans le tableau de jeu...
If sx>=0 And sy>=0 And sy<=1023 And sx<=1023
sxx=carte(sx,sy)\X-IsoScroll_X*#X_Tilesize+xmax/2-#X_Tilesize+miliscrol_X
syy=carte(sx,sy)\Y-IsoScroll_Y*#Y_Tilesize+ymax/2-#Y_Tilesize-#Y_Tilesize/2+miliscrol_Y
If carte(sx,sy)\element
;affiche l'élément sur cette case
ChangeCurrentElement(sprite(),carte(sx,sy)\element)
sxx1=sxx+sprite()\biasX
syy1=syy+sprite()\biasY
sxx2=sxx1+SpriteWidth(sprite()\spritedebase)
syy2=syy1+SpriteHeight(sprite()\spritedebase)
;{-si on a une fenetre de selection, on test le sprite courant
;si le sprite est à l'intérieur de la fenêtre ou a cheval dessus
If fenetreX1<sxx2 And fenetreX2>sxx1 And fenetreY1<syy2 And fenetreY2>syy1
T_X1=0:T_X2=SpriteWidth(sprite()\spritedebase);si on est entierement dans la fenetre
T_Y1=0:T_Y2=SpriteHeight(sprite()\spritedebase)
If sxx1<fenetreX1:T_X1=fenetreX1-sxx1:EndIf
If sxx2>fenetreX2:T_X2=fenetreX2-sxx1:EndIf
If syy1<fenetreY1:T_Y1=fenetreY1-syy1:EndIf
If syy2>fenetreY2:T_Y2=fenetreY2-syy1:EndIf
For t_a=T_Y1 To T_Y2
If FindMapElement(impactsprite(),Str(sprite()\spritedebase)+"T"+Str(t_a))
ForEach impactsprite()\XX()
If T_X2>=impactsprite()\XX()\X1 And T_X1<=impactsprite()\XX()\X2
If FindMapElement(*selection(),Str(@sprite))=0
sprite()\selection=1
AddMapElement(*selection(),Str(@sprite())):*selection()=@sprite()
EndIf
Break 2
EndIf
Next
EndIf
Next t_a
EndIf
;}
DisplaySprite3D(170,sxx1+95,syy1+237,128) ;affiche l'ombre
DisplaySprite3D(sprite()\spritedebase,sxx1,syy1,255-sprite()\selection<<7) ;si il est selectionné, le met en transparence
EndIf
EndIf
Next i
;si on avait une fenêtre de selection, on la rénitialise
If fenetreValid:fenetreValid=0:fenetreX1=0:fenetreX2=0:fenetreY1=0:fenetreY2=0:EndIf
;affichage de la souris
DisplaySprite3D(100,XX,YY)
Stop3D()
;}
;{-affiche le texte
If Val(FormatDate("%ss", Date()))=sek
FPS+1
Else
FPS$=Str(FPS)
FPS=0
EndIf
sek=Val(FormatDate("%ss", Date()))
StartDrawing(ScreenOutput())
;affichage du cadre de selection
If fenetreX1 And fenetreX2
LineXY(fenetreX1,fenetreY1,fenetreX2,fenetreY1)
LineXY(fenetreX2,fenetreY1,fenetreX2,fenetreY2)
LineXY(fenetreX2,fenetreY2,fenetreX1,fenetreY2)
LineXY(fenetreX1,fenetreY2,fenetreX1,fenetreY1)
EndIf
DrawText(1,1,"FPS: "+FPS$)
DrawText(1,15,"nombre de tiles affichées: "+Str(T_nb))
DrawText(1,30,"Tile X: "+Str(collisionX)+" Y: "+Str(collisionY))
DrawText(1,45,"element sur la tile: "+Str(carte(collisionx,collisiony)\element))
DrawText(1,60,"element sous la souris: "+Str(collisionelement))
DrawText(1,75,"fenetre X1 Y1: "+Str(miliscrol_X)+";"+Str(miliscrol_Y)+"/"+Str(rest))
StopDrawing()
;}
Until KeyboardPushed(#PB_Key_Escape)