Page 3 sur 4

Publié : mer. 15/nov./2006 18:45
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 ^^

@++

Publié : ven. 24/nov./2006 18:51
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

Publié : sam. 25/nov./2006 13:08
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é.

Publié : sam. 25/nov./2006 14:21
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

Publié : sam. 25/nov./2006 14:33
par Fig
Arf oubliez ça il parait que ca ne marche que de MON réseau local. c'était trop beau :cry:

Publié : mer. 29/nov./2006 9:31
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.

Publié : mar. 13/févr./2007 8:23
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

Publié : mar. 13/févr./2007 10:01
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

Publié : mar. 13/févr./2007 10:06
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.

Publié : mar. 13/févr./2007 10:44
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. :)

@++

Publié : mar. 13/févr./2007 13:35
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 ?

Publié : mar. 13/févr./2007 13:44
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.

Publié : mar. 13/févr./2007 14:07
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

Publié : mar. 25/août/2009 21:36
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 !

Publié : mar. 25/août/2009 22:20
par Atomo
Essai de placer un Global devant la ligne

Code : Tout sélectionner

Dim Map.World( #TailleMapX , #TailleMapY )