Code Map2D Isométrique

Programmation avancée de jeux en PureBasic
Anonyme

Message par Anonyme »

j'avais réussi avec une map normale (pas isométrique) , il était facile de déterminer se qu'il y avait sur l'écran Grace a Scroll/TailleTile et Scroll/TailleTile + Screen/TailleTile , mais comme avec l'isométrique avec ma technique il y a des tiles de valeur négative, faudrais tout passer en positifs et ainsi faire le tri ^^ mais le temps me manque pour ce genre de manip, je verrais ton code ^^

@++
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Message par Fig »

Voila le code, ça marche avec toutes les dimensions ici une carte de 1024x1024.
Pas de ralentissement je reste au fps maximum.
Par contre comme promis c'est programmé comme un sagoin et le code ne prévoit pas un changement de taille de Tiles (les miennes font 64x64 -64x32- affichées).
Mon ftp free n'est pas encore validé donc je n'ai pas pu mettre en ligne les sprites. (l'interface fait 1024x168). je les mettrais des que possible.

Code : Tout sélectionner

InitSprite()
InitKeyboard()
InitMouse()
InitSound()
OpenScreen(1024,768,32,"")
Structure monde
x.l
y.l
z.b
type.b
perso.w
EndStructure
Structure element
spritedebase.b
spritecourant.b
nbsprite.b
x.l
y.l
xdes.l
ydes.l
repere.w
EndStructure

;-constantes
#taillex=1023
#tailley=#taillex
#TailleTileX = 64
#TailleTileY = #TailletileX/2
#Relief=5
#nbelement=2000


Macro FPSec
; *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 
   ; CALCUL ET AFFICHAGE DU FPS 
   If FPST.l<ElapsedMilliseconds() 
    FPST.l=ElapsedMilliseconds()+1000 
      fps.l=FPSC.l 
    FPSC=0 
    EndIf 
  
     FPSC+1 
      
    StartDrawing(SpriteOutput(1)) 
    DrawText(0,0,Str(fps)+" fps") 
    StopDrawing() 
   
  ; *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 
EndMacro
Macro Test
  If ScrollY<(#tailley+1)/2+2
    x1=ScrollX+ScrollY-2
    y1=ScrollY-ScrollX-16
    If x1<0:x1=0:EndIf
    If y1<0:y1=0:EndIf
    
    Else
  x1=ScrollY<<1-#tailley-4
    If ScrollX>(ScrollY-#tailley-1):x1=x1+ScrollX-ScrollY+#tailley+2:EndIf
  y1=#TailleY-15
    If ScrollX>(ScrollY-#tailley-1):y1=y1-ScrollX+ScrollY-#tailleY-1:EndIf
    
  EndIf
x2=x1+35
If x2>#taillex:x2=#taillex:EndIf
y2=y1+35
If y2>#tailley:y2=#tailley:EndIf
affiche_terrain=1
EndMacro
;-variables
Global scrollx.l=-127
Global scrolly.l=127
Global x1.l=0
Global y1.l=0
Global x2.l=x1+35
Global y2.l=y2+35

;-booleens d'états
Global Debugg.b=0
Global affiche_terrain.b=1

;Global
Global Dim monde.monde(#taillex,#tailley)
Global Dim element.element(#nbelement)

Global Dim fct.w(#taillex)


Declare createminimap(x,y)
Declare CreateMapIsometric(Taille_Map_X.l,Taille_Map_Y.l,TileType.b)
Declare updatemap()
Declare minicarte()


;SortStructuredArray (perso(), 0, OffsetOf (perso\y), #PB_Sort_Long ) 
;LoadSound(0,"Oui.wav")

;-Charge les sprites
TransparentSpriteColor(#PB_Default,RGB(255,255,255))
Restore interfac
For i=1 To 2
Read a$
LoadSprite(i,a$)
Next i
Restore herbe
;herbes
For i=3 To 4
Read a$
LoadSprite(i,a$)
Next i
Restore arbre
;arbres
For i=20 To 120

Next i
Restore objet
;objets
For i=120 To 121
Read a$
LoadSprite(i,a$)
Next i
TransparentSpriteColor(121,RGB(0,0,0))
StartDrawing(SpriteOutput(1))
  DrawText(350,22,"TAPER 1 pour le mode debugg qui affiche les coordonnées de chaque Tile")
StopDrawing()
DataSection
Interfac:
Data.s "taskbar.bmp","fleche.bmp"
herbe:
Data.s "herbe1.bmp","repereherbe.bmp"
arbre:
Data.s ""
objet:
Data.s "repere.bmp","bas1.bmp"
montagne:
Data.l 1111221111,1112332111,1123443211,1234554321,2345665432,2345665432,1234554321,1123443211,1112332111,1111221111

EndDataSection

CreateMapIsometric(#tailleX,#tailleY,3)
;monde(1,1)\perso=1
;element(1)\x=1:element(1)\y=1:element(1)\xdes=1:element(1)\ydes=1:element(1)\spritedebase=121
;element(1)\spritecourant=121:element(1)\nbsprite=1:element(1)\repere=120
createminimap(155,155)
monde(3,3)\z=2
monde(4,3)\z=3
monde(4,4)\z=7

;-boucle principale
Repeat

FlipBuffers()

If affiche_terrain=1
updatemap()
affiche_terrain=0
GrabSprite(0,0,0,1024,768)
Else
DisplaySprite(0,0,0)
EndIf

DisplaySprite(1,0,600);affiche interface
ExamineMouse()
x=MouseX():y=MouseY()
ExamineKeyboard ()

;deplacement ecran
If x<2 And ScrollX>-#taillex/2
;If KeyboardReleased(#PB_Key_Left)
  ScrollX-1
  test
EndIf
If x>1022 And ScrollX<#taillex/2
;If KeyboardReleased(#PB_Key_Right)
  ScrollX+1
  test
EndIf
If y<2 And ScrollY>0
;If KeyboardReleased(#PB_Key_Up) And ScrollY>0
  ScrollY-1
  test
EndIf
If y>766 And ScrollY<#tailley-13
;If KeyboardReleased(#PB_Key_Down) And ScrollY<242
  ScrollY+1
  test
EndIf

;affiche la souris
DisplayTransparentSprite(2,x,y)
FPSec

;ExamineKeyboard ()
If KeyboardReleased(#PB_Key_1):Debugg=~(Debugg):affiche_terrain=1:LoadSprite(3,"herbe1.bmp"):EndIf
Until KeyboardPushed ( #PB_Key_Escape )
End

Procedure createminimap(X,Y)
UseBuffer(1)
ratx.f=X/#taillex
raty.f=Y/#tailley
For i=0 To #tailleX
For j=0 To #tailleY
k=monde(i,j)\perso
L=element(monde(i,j)\perso)\repere
DisplaySprite (monde(i,j)\type+1,i*ratx+862,j*raty+5)
If monde(i,j)\perso<>0:DisplaySprite(element(monde(i,j)\perso)\repere,i*ratx+862,j*raty+5):EndIf
Next j
Next I
UseBuffer(-1)
EndProcedure
Procedure CreateMapIsometric(Taille_Map_X.l,Taille_Map_Y.l,TileType.b)
Shared DecalageX.l,DecalageY.l,Offset.l

For y = 0 To Taille_Map_Y
For x = 0 To Taille_Map_X

 DecalageX = DecalageX + (#TailleTileX/2)
 DecalageY = DecalageY + (#TailleTileY/2)
 
 monde(x,y)\x=DecalageX
 monde(x,y)\y=DecalageY
 monde(x,y)\z=Random(#relief)
 monde(x,y)\Type=TileType
 monde(x,y)\perso=0
Next x
   Offset+1
   DecalageX = -(Offset*(#TailleTileX/2))   
   DecalageY = (#TailleTileY/2)*Offset
Next y
EndProcedure
Procedure UpdateMap()
Shared TilePosX.l,TilePosY.l
ClearScreen(RGB(0,0,0))

For y=y1 To y2
For x=x1 To x2
TilePosX = monde(x,y)\x- ScrollX*#TailleTileX
TilePosY = monde(x,y)\y-ScrollY*#TailleTileY-monde(x,y)\z

 If Debugg<>0
 StartDrawing(SpriteOutput(monde(x,y)\type))
 DrawText(12,6,Str(x)+"/"+Str(y)+"   ",RGB(255,0,0));coordonnées x,y
 ;DrawText(12,6,Str(monde(x,y)\z)+"   ",RGB(255,0,0));coordonnées en z
 StopDrawing()
 EndIf
 
 DisplayTransparentSprite(monde(x,y)\type ,TilePosX,TilePosY)

Next x
Next y

  If Debugg<>0
  StartDrawing(SpriteOutput(1))
  DrawText(402,42,"ScrollX="+Str(ScrollX)+"  ScrollY="+Str(ScrollY)+"      ")
  DrawText(402,72,"x1="+Str(x1)+"    x2="+Str(x2)+"  Surface Tiles affichée="+Str((x2-x1)*(y2-y1))+"       ")
  DrawText(402,102,"y1="+Str(y1)+"    y2="+Str(y2)+"       ")
  StopDrawing()
  EndIf

EndProcedure
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Anonyme

Message par Anonyme »

je n'ai pas pu tester :?

sinon, ton écran à une capacité a afficher ScreenSizeX / TailleTileSizeX et ScreenSizeY / TailleTileSizeY
Fait un +2 pour évité de voir apparaitre ou disparaitre à l'écran tes tiles
le fait de faire se ces divisions, ca va te rendre un nombre exploitable dans un tableau, ou une zone mémoire. Ensuite , le problème est de savoir ou on se trouve dans le tableau par rapport a ce qui est affiché à l'écran, pareil, que précédement , ScrollX / TailleTileSizeX, et idem pour y, cepandant attention à ne pas sortir de la taille du tableau. avec mon exemple de map isométrique, tu peut difficilement faire se genre de manip.
Dès que j'ai du temps libre à consacrer à ca , je ferais un exemple optimisé.
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Message par Fig »

Voila comme free n'active pas mon ftp avant qque jours, je me sers de la freebox comme ftp ... :wink:

ftp://hd1.freebox.fr/Disque%20dur/Video/OptimiseIso.zip
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Message par Fig »

Arf oubliez ça il parait que ca ne marche que de MON réseau local. c'était trop beau :cry:
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Message par Fig »

Voila ... http://fig77.free.fr/OptimiseIso.zip

Je suis pas plus graphiste que programmmeur :roll:

Maintenant je met au point le système d'animation des éléments du jeu et leur affichage.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Tres interessant ce topic. J'arrive a faire une map en 3DIso platte, j'avais déjà réussi avant de lire ce sujet, mais j'avoue que ça m'a beaucoup apprit et que votre technique est bien plus optimisé que la mienne, mais je but sur un truc, je ne sais pas trop comment faire pour avoir des murs, des portes etc...
Voici le genre de decore que j'aimerais pouvoir faire.Image

Et tant qu'on y est a votre avis faire de la 3Diso avec des blocs Hexagonaux c'est du délire d'essayer ou pas ?

Merci d'avance pour vos conseilles
Anonyme

Message par Anonyme »

Mon exemple montre en effet comment faire de l'iso "plate"
les murs sont ni plus ni moins une seconde couche de sprite qui sont affiché par dessus.
Pour des tiles hexagonaux , c'est faisable, mais pour ma part, ca n'apporte pas grand chose, juste des cheveux blanc ^^

si tu fait tes propres graphismes , je te conseille aussi de faire une recherche sur google --> "pixel art"

j'avais fait des trucs de se genre :
ImageImageImage
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

A d'accord les mur sont une deuxième couche...c'est interessant ça... Faut que j'étudie comment faire... Merci pour le tuyau.
Anonyme

Message par Anonyme »

Voila , je t'ai bricolé un truc tout bête pas vraiment propre au niveau du code, mais bon, le principe est là.
Tu peut aussi utilisé un tableau avec 3 dimensions , (la 3° etant pour définir la couche)

File:1->Bricolo.rar
Image

Le top, c'est que le tri des sprites se fait automatiquement. :)

@++
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Merci beaucoup ...c'est marrant je voyait pas la chose comme ça pour la gestion des murs (1 bloc = 1 mur) Moi je pensais que dans un bloc il pouvait y avoir du sol et du mur (genre mur a droite, mur a gauche, porte, etc...) mais du coup ta solution me resout pas mal de problème :oP
En tout cas un grand merci ... comme on dit il ne reste plus qu'a ...Tient une autre question puisque tu maitrises si bien l'iso...le traitement d'un personnage tu le ferais comment ? tu le tracerais a quel moment ? est ce que tu le ferais précis au bloc ou au pixel pour le deplacement ?
Anonyme

Message par Anonyme »

je tracerais les entités entre l'affichage du sol & des murs
pour les déplacement, je le ferais par blocs, de plus, grace à cette methode tu peut facilement implenté l'algo A* (pathfinding). Mais oublie pas d'interpolé les déplacement entre les blocs sinon on verra que c'est un déplacement bloc/bloc, donne aussi la posibilité de ton ou tes personnages, de s'arreter entre 2 blocs si ce dernier le permet.
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Cpl.Bator a écrit :je tracerais les entités entre l'affichage du sol & des murs
pour les déplacement, je le ferais par blocs, de plus, grace à cette methode tu peut facilement implenté l'algo A* (pathfinding). Mais oublie pas d'interpolé les déplacement entre les blocs sinon on verra que c'est un déplacement bloc/bloc, donne aussi la posibilité de ton ou tes personnages, de s'arreter entre 2 blocs si ce dernier le permet.
Merci pour ces tres bon conseille. J'ai déjà implémenté l'Algo A* qu'avait fait comtoie pour un jeu style bonberman ça ne devrait pas trop me poser de problème. vivement ce week-end que je puiss réellement faire mes tests ... :P
powerpsy
Messages : 2
Inscription : mar. 25/août/2009 21:26

Message par powerpsy »

Bonjour !

Désolé de reprendre des vieux trucs, mais pour moi cela me semble essentiel. Je suis en train d'approcher la 3D iso.

En reprenant tes codes plus haut, il y a quelques erreurs à la compilation.
là ou il est simple de mettre à jour les:
ClearScreen(0,0,0)
en
ClearScreen(RGB(0,0,0))
et autres instructions du genre, je bloque un peu plus sur les déclarations de la variable "Map".

"Map() is not a function (or not available in demo version)..."

Ma question est donc la suivante: est ce que PB4.31 a changé depuis ou est ce qu'il faut la version complète pour utiliser ce code ?

Merci !
Atomo
Messages : 207
Inscription : lun. 17/sept./2007 12:27

Message par Atomo »

Essai de placer un Global devant la ligne

Code : Tout sélectionner

Dim Map.World( #TailleMapX , #TailleMapY )
Répondre