Coordonnée orthonormal et Coordonée Isometric

Programmation avancée de jeux en PureBasic
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Coordonnée orthonormal et Coordonée Isometric

Message par Thyphoon »

Bonjour,

j'ai un petit problème.. je n'arrive pas a transformer des coordonnées orthonormal vers des coordonnées Isométriques

Si mon personnage avance dans le réel sur l'axe des X_Réel de 500 et sur Y_Réel de 0 alors sur la map isométrique ça devient : ?????
au depart je faisais
XIso=X_Réel-Y_Réel
YIso=(X_Réel+Y_Réel)/2

mais ça fonctionne pas... ça doit être tout bête mais là je décroche

lorsque je trace ma map j'utilise cette formules


for y=1 to 10
for x=1 to 10
xTile=x*32-y*32
yTile=y*16 + x*16
displaysprite(Mapx(x,y),xTile,YTile)
next x
next y

merci d'avance a ceux qui aurons le courage de me lire
:P
Anonyme

Message par Anonyme »

for y=1 to 10
for x=1 to 10
xTile=(x*32)-(y*32)
yTile=(y*16) + (x*16)
displaysprite(Mapx(x,y),xTile,YTile)
next x
next y
Oublie pas les parenthèses , le - a la priorité sur le *
Anonyme

Message par Anonyme »

Code : Tout sélectionner

InitSprite() : InitMouse() : InitKeyboard()
OpenScreen(1024,768,32,"")



#TILE_W = 32
#TILE_H = #TILE_W/2



Declare DisplayIsoLevel()





Repeat
  ClearScreen($FFFFFF)
    ExamineKeyboard()
    ExamineMouse()

      DisplayIsoLevel()
      
      
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
End 



Procedure DrawSingleIsoTile(X,Y,Color)

Static Zoom.f

Zoom = 1 + 1 * Cos(ElapsedMilliseconds()/1000)


  _X = (X*(#TILE_W*Zoom)/2)
  _Y = (Y*(#TILE_H*Zoom))   
  
  IsoX = (_X-_Y)+512
  IsoY = ((_X+_Y)/2)+384



  X1 = IsoX 
  Y1 = IsoY - (#TILE_H*Zoom)/2
  
  X2 = IsoX + (#TILE_W*Zoom)/2
  Y2 = IsoY 
  
  X3 = IsoX 
  Y3 = IsoY + (#TILE_H*Zoom)/2
  
  X4 = IsoX - (#TILE_W*Zoom)/2
  Y4 = IsoY 
  
  
 
  
  LineXY(X1,Y1,X2,Y2,$000000)
  LineXY(X2,Y2,X3,Y3,$000000)
  LineXY(X3,Y3,X4,Y4,$000000)
  LineXY(X4,Y4,X1,Y1,$000000)

 ; FillArea(IsoX,IsoY,0,Color)


EndProcedure


Procedure DisplayIsoLevel()
Restore Niveau10x10
StartDrawing(ScreenOutput())
For Y = 0 To 9
  For X = 0 To 9
    Read Tile 
    
  
    
    Select Tile
      Case 0 : DrawSingleIsoTile(X,Y,$1F1F7F)
      Case 1 : DrawSingleIsoTile(X,Y,$00FF00)
    EndSelect

  Next
Next 
Circle(MouseX(),MouseY(),2,$000000)
StopDrawing()
EndProcedure








DataSection
Niveau10x10:
Data.l 1,1,1,1,1,1,1,1,1,1
Data.l 1,0,1,0,0,0,0,0,0,1
Data.l 1,1,1,0,1,0,0,0,0,1
Data.l 1,0,0,0,1,1,0,0,0,1
Data.l 1,0,0,0,0,0,0,0,0,1
Data.l 1,1,1,0,0,0,0,0,0,1
Data.l 1,0,1,0,0,0,0,0,0,1
Data.l 1,0,0,0,1,0,0,0,0,1
Data.l 1,0,0,0,1,0,0,0,0,1
Data.l 1,1,1,1,1,1,1,1,1,1
EndDataSection


Ps , ta 1° formule est bonne , recherche tile based game sur google.

++ :wink:
Anonyme

Message par Anonyme »

Alors , ca a répondu a tes attentes ? si tu veut je peut te filer un p'tit snippet te permetant de choisir le tile isométrique a la souris.
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 :Alors , ca a répondu a tes attentes ? si tu veut je peut te filer un p'tit snippet te permetant de choisir le tile isométrique a la souris.
Oui ça m'a beaucoup aidé, j'avais pas eu le temps de te repondre (je viens de réinstallé ma machine car j'ai eu un crash de disque dur), mais j'ai encore quelques souci... mais j'essaie de trouver tout seul ou est mon petit bug !
par contre ton snippet pour choisir le tile isométrique a la souris ça m'interesse !!! :D
un grand merci d'avance
Anonyme

Message par Anonyme »

je n'ai pas pris en compte le scrooling :

Code : Tout sélectionner


InitSprite() : InitMouse() : InitKeyboard()
OpenScreen(1024,768,32,"")



#TILE_W = 32
#TILE_H = #TILE_W/2



Declare DisplayIsoLevel()
Declare LoadMap()


Global Dim MapIsometric(10,10)


LoadMap()


Repeat
  ClearScreen($FFFFFF)
    ExamineKeyboard()
    ExamineMouse()

      DisplayIsoLevel()
     
     
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
End



Procedure DrawSingleIsoTile(X,Y,Color)

Static Zoom.f

Zoom = 1; + 1 * Cos(ElapsedMilliseconds()/1000)


  _X = (X*(#TILE_W*Zoom)/2)
  _Y = (Y*(#TILE_H*Zoom))   
 
 

  IsoX = (_X-_Y);+512
  IsoY = ((_X+_Y)/2);+384



  X1 = IsoX
  Y1 = IsoY - (#TILE_H*Zoom)/2
 
  X2 = IsoX + (#TILE_W*Zoom)/2
  Y2 = IsoY
 
  X3 = IsoX
  Y3 = IsoY + (#TILE_H*Zoom)/2
 
  X4 = IsoX - (#TILE_W*Zoom)/2
  Y4 = IsoY
 
 
 
 
  LineXY(X1,Y1,X2,Y2,Color)
  LineXY(X2,Y2,X3,Y3,Color)
  LineXY(X3,Y3,X4,Y4,Color)
  LineXY(X4,Y4,X1,Y1,Color)

 ; FillArea(IsoX,IsoY,0,Color)


EndProcedure


Procedure DisplayIsoLevel()

StartDrawing(ScreenOutput())



; AFFICHAGE DE LA CARTE ISOMETRIQUE (CODE NON OPTIMISER POUR LE SCROOLING ISOMETRIQUE
For Y = 0 To 9
  For X = 0 To 9
  
    Select MapIsometric(X,Y)
      Case 0 : DrawSingleIsoTile(X,Y,$1F1F7F)
      Case 1 : DrawSingleIsoTile(X,Y,$00FF00)
    EndSelect
    
  Next
Next


; Convertion des coordonées de la souris ( elle est déjà en "mode iso" )
; en coordonées "orthonormale" exploitable pour parcourir le tableau de 
; la carte.

Mx.f=MouseX()/#TILE_W*2
My.f=MouseY()/#TILE_H

ey.f=(2*My-Mx)/2
ex.f=Mx+ey

DrawSingleIsoTile(ex,ey,255)

DrawText(10,10,Str(ex)+":"+Str(ey))

Circle(MouseX(),MouseY(),2,$000000)
StopDrawing()
EndProcedure


Procedure LoadMap()
Restore Niveau10x10
For Y = 0 To 9
  For X = 0 To 9
    Read Tile
    MapIsometric(X,Y) = Tile
  Next
Next
EndProcedure





DataSection
Niveau10x10:
Data.l 1,1,1,1,1,1,1,1,1,1
Data.l 1,0,1,0,0,0,0,0,0,1
Data.l 1,1,1,0,1,0,0,0,0,1
Data.l 1,0,0,0,1,1,0,0,0,1
Data.l 1,0,0,0,0,0,0,0,0,1
Data.l 1,1,1,0,0,0,0,0,0,1
Data.l 1,0,1,0,0,0,0,0,0,1
Data.l 1,0,0,0,1,0,0,0,0,1
Data.l 1,0,0,0,1,0,0,0,0,1
Data.l 1,1,1,1,1,1,1,1,1,1
EndDataSection

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

Message par Thyphoon »

Merci beaucoup !
Justement mon petit bug qui me prend la tête est du au Scrolling...
Le problème réside dans ma procédure render()

les variables PointerX et PointerY donne les coordonées du Tile sur le quel on est centré
les variables DeltaXReal et DeltaYReal varie pour amener au tile suivant.
mais ça me pose problème a la ligne 49/50 des que je passe sur le tile suivant, j'ai un décalage et je ne sais pas comment l'annuler pour qu'on revienne bien là ou il faut.

il faut utilisé les flèches pour se balader !

Mon code pas propre du tout :

Code : Tout sélectionner

#TILE_W=64

#TILE_H=32
InitSprite()
InitMouse() 
InitKeyboard()
OpenWindow(0, 0, 0, 640, 480, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0)

;Simple render de tile

Procedure.f Real2IsoX(X.l, Y.l)
	ProcedureReturn X-Y
EndProcedure

Procedure.f Real2IsoY(X.l, Y.l)
	ProcedureReturn (Y + X)/2
EndProcedure


Procedure InitRenderingWindows(Width,Height)
EndProcedure

Procedure Render(PointerXReal.l, PointerYReal.l)
  WindowWidth.l =520
	WindowHeight.l = 300
	WindowCenterX=Int(WindowWidth/2)
	WindowCenterY=Int(WindowHeight/2)
	WindowTileCenterX=Round(WindowCenterX/32,#PB_Round_Up )
	WindowTileCenterY=Round(WindowCenterY/16,#PB_Round_Up )
	
	 UnitIso.l=Round(Sqr(Pow(16,2)+Pow(32,2)),#PB_Round_Down );
  PointerX.l=Int(Real2IsoX(PointerXReal, PointerYReal)/UnitIso)
  PointerY.l=Int(Real2IsoY(PointerXReal, PointerYReal)/UnitIso)
  DeltaXReal.l = Real2IsoX(PointerXReal, PointerYReal)-(PointerX*UnitIso)
	DeltaYReal.l = Real2IsoY(PointerXReal, PointerYReal)-(PointerY*UnitIso)
	
	
	
CreateSprite(200, WindowWidth, WindowHeight)
StartDrawing(SpriteOutput(200))
  TileMapWidth=(WindowTileCenterX+WindowTileCenterY)/4  ;Retirer le /4 c'est juste pour voir si la map est bien centré
  MapWidth=WindowTileCenterX*32
	For Y = 0 To TileMapWidth
		For X = 0 To TileMapWidth
	      
	  	 _X = (X*#TILE_W/2)
       _Y = (Y*#TILE_H)   
       IsoX = (_X-_Y)+WindowCenterX-DeltaXReal
       IsoY = ((_X+_Y)/2)+WindowCenterY-Int(TileMapWidth/2)*32-DeltaYReal
	  
      	X1 = IsoX
        Y1 = IsoY - #TILE_H/2
       
        X2 = IsoX + #TILE_W/2
        Y2 = IsoY
       
        X3 = IsoX
        Y3 = IsoY + #TILE_H/2
       
        X4 = IsoX - #TILE_W/2
        Y4 = IsoY
        Color=RGB(255,255,255)
       
        LineXY(X1,Y1,X2,Y2,Color)
        LineXY(X2,Y2,X3,Y3,Color)
        LineXY(X3,Y3,X4,Y4,Color)
        LineXY(X4,Y4,X1,Y1,Color)
        Circle(IsoX,IsoY,5,#Green)
	  	  
	  Next x
	Next y
  DrawText(10, 40, "X:" + Str(DeltaXReal) + "  Y:" + Str(DeltaYReal)+" PX:"+Str(PointerX)+" PY:"+Str(PointerY))

  
  	Circle(MouseX(),MouseY(),2,#Yellow)
  	Circle(WindowCenterX,WindowCenterY,2,#Red)
  	StopDrawing()

	DisplaySprite(200, 0, 0)
EndProcedure



Repeat
	; Il est très important de traiter tous les événements restants dans la file d'attente à chaque tour
	;
	Repeat
	     
		Event = WindowEvent()
		If Event = #PB_Event_CloseWindow
			End
		EndIf
	Until Event = 0
	ExamineMouse()
	ExamineKeyboard()
	ExamineMouse()
	If KeyboardPushed(#PB_Key_Up) : PointerYReal + 1 : EndIf
	If KeyboardPushed(#PB_Key_Down) : PointerYReal-1 : EndIf
	If KeyboardPushed(#PB_Key_Left) : PointerXReal-1 : EndIf
	If KeyboardPushed(#PB_Key_Right) : PointerXReal + 1 : EndIf
	If KeyboardPushed(#PB_Key_Escape):End:EndIf
	FlipBuffers()
	ClearScreen(#Red)
	
	render(PointerXReal, PointerYReal)
	StartDrawing(ScreenOutput())
	

StopDrawing()
	Delay(1)
ForEver
Anonyme

Message par Anonyme »

tu cherches a faire un scrolling infini ?

tiens , ca marche mieux :

Code : Tout sélectionner

  PointerX.l=Int(Real2IsoX(PointerXReal, PointerYReal)/UnitIso)
  PointerY.l=Int(Real2IsoY(PointerXReal, PointerYReal)/UnitIso)
  DeltaXReal.l = Real2IsoX(PointerXReal, PointerYReal)-(PointerX)
  DeltaYReal.l = Real2IsoY(PointerXReal, PointerYReal)-(PointerY)
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 :tu cherches a faire un scrolling infini ?

tiens , ca marche mieux :

Code : Tout sélectionner

  PointerX.l=Int(Real2IsoX(PointerXReal, PointerYReal)/UnitIso)
  PointerY.l=Int(Real2IsoY(PointerXReal, PointerYReal)/UnitIso)
  DeltaXReal.l = Real2IsoX(PointerXReal, PointerYReal)-(PointerX)
  DeltaYReal.l = Real2IsoY(PointerXReal, PointerYReal)-(PointerY)
hé hé merci mais c'est pas encore ça... :P

Je souhaite que lorsque je me déplace lorsque j'arrive au centre du prochain tile je revienne au centre... donc c'est bien un Scrolling infini :P
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

C'est bon j'ai enfin trouvé ! je poste un exemple des que c'est un peu prêt présentable !! :D
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Le code est pas encore propre, j'ai du nettoyage a faire et de l'optimisation ... le pointeur a la souris n'est pas bon non plus, mais le scroll fonctionne bien !!
essayer avec les fleches

Code : Tout sélectionner

;- #### Animation ####
;	*Animation  DataSheet
;	Offset	|	Size	|	Type	|	Description
;	0		 |	2		  |	.w		|	Frames
;	2		    |	1		  |	.b		|	0 No Loop Animation / 1 Loop Animation
;	3		    |	4		  |	*		  |	IdSprite	Frame[ 1]
;	7		    |	2		  |	.w		|	Temps d'affichage en milliseconde
;	9		    |	4		  |	*	  	|	IdSprite	Frame[ 2]
;	13		  |	2		  |	.w		|	Temps d'affichage en milliseconde
;	3+x*6	  |	4		  |	*		  |	IdSprite	Frame[ x]
;	7+x*6	  |	2	  	|	.w		|	Temps d'affichage en milliseconde
;etc....

;Ajout d'un sprite a une animation
Procedure SetSpriteToAnimation(*Anim, IdSprite.l, Time.w)
	If *Anim>0
		Size.l = MemorySize(*Anim)
	Else
		Size.l = 3
		*Anim = AllocateMemory(Size)
	EndIf
	*Anim = ReAllocateMemory(*Anim, Size + 6)
	PokeW(*Anim, PeekW(*Anim) + 1)
	PokeL(*Anim + Size, IdSprite)
	PokeW(*Anim + Size + 4, Time)
	ProcedureReturn *Anim
EndProcedure

;Retourne le sprite correspondant a l'image d'une Animation
Procedure.l GetSpriteFromAnimation(*Anim, Frame.w)
	Location.l = 3 + Frame*6
	If Location<MemorySize(*Anim)
		ProcedureReturn PeekL(*Anim + Location) : 
	Else
		ProcedureReturn #False
	EndIf
EndProcedure

;Retourne le temps d'affichage d'une imge dans une animation
Procedure.l GetTimeSpriteFromAnimation(*Anim, Frame.w)
	Location.l = 7 + Frame*6
	If Location<MemorySize(*Anim)
		ProcedureReturn PeekW(*Anim + Location) : 
	Else
		ProcedureReturn #False
	EndIf
EndProcedure

;Active ou desactive le bouclage de l'annimation
Procedure.b SetAnimationLoop(*Anim, Loop.b)
	If *Anim>0
		PokeB(*Anim + 2, Loop)
		ProcedureReturn #True
	Else
		ProcedureReturn #False
	EndIf
EndProcedure

;Retourne le nombre d'image dans une animation
Procedure GetFramesAnimation(*Anim)
	ProcedureReturn PeekW(*Anim)
EndProcedure

;Retourne 1 si l'animation est Bouclé et 0 dans le cas contraire
Procedure.b GetAnimationLoop(*Anim)
	If *Anim>0
		ProcedureReturn PeekB(*Anim + 2)
	EndIf
EndProcedure

;-#### Element ####
;	*Element  DataSheet
;	Offset	|	Size	|	Type	|	Description
;	0		    |	2		  |	.w		|	States
;	2		    |	1		  |	.b		|	0 l'animation est Global / 1 l'animation est unique
;	3		    |	2		  |	.w		|	CurrentFrame / Si l'animation est Global alors on utilise cet enplassement pour connaitre l'image actuel de l'animation
;	5		    |	4	  	|	.l		|	Si l'animation est Global alors on utilise cet enplassement pour connaitre le prochain temps de changement d'image
;	9		    |	1		  |	.b		|	0 IdSprite / 1 *Animation	State[1]
;	10		  |	4		  |	*		  |	IdSprite or *Animation 	State[1]
;	14		  |	1		  |	.b		|	0 IdSprite / 1 *Animation	State[2]
;	15		  |	4	  	|	*		  |	IdSprite or *Animation 	State[2]
;	9+x*5	  |	1	  	|	.b		|	0 IdSprite / 1 *Animation	State[x]
;	10+x*5	|	4	  	|	*		  |	IdSprite or *Animation 	State[x]

Procedure DebugElement(*Element)
	Debug"__________"
	Debug "Element:" + Str(*Element)
	Debug "States :" + Str(PeekW(*Element));	0		    |	2		  |	.w		|	States
	Debug "Animation Type :" + Str(PeekB(*Element + 2));	2		    |	1		  |	.b		|	0 l'animation est Global / 1 l'animation est unique
	Debug "CurrentFrame:" + Str(PeekW(*Element + 3));	3		    |	2		  |	.w		|	CurrentFrame / Si l'animation est Global alors on utilise cet enplassement pour connaitre l'image actuel de l'animation
	Debug "NextTime:" + Str(PeekL(*Element + 3));;	5		    |	4	  	|	.l		|	Si l'animation est Global alors on utilise cet enplassement pour connaitre le prochain temps de changement d'image
	For z = 0 To PeekW(*Element)-1
		Debug "Type" + Str(z + 1) + " :" + Str(PeekB(*Element + 9*z*5));	9		    |	1		  |	.b		|	0 IdSprite / 1 *Animation	State[1]
		Debug "Sprite/Anim" + Str(z + 1) + " :" + Str(PeekL(*Element + 10*z*5));	10		  |	4		  |	*		  |	IdSprite or *Animation 	State[1]
	Next
EndProcedure

;Rajoute une animation ou une image a un Element
Procedure SetStatetoElement(*Element, *Anim, IdSprite = 0)
	If *Element>0 ;si l'element existe on regarde sa taille
		Size.l = MemorySize(*Element)
	Else ;si l'element n'existe pas on le créer
		Size.l = 9
		*Element = AllocateMemory(Size)
		PokeB(*Element + 2, 0)
	EndIf
	*Element = ReAllocateMemory(*Element, Size + 5)
	PokeW(*Element, PeekW(*Element) + 1) ;Ajout d'un etat
	State = PeekW(*Element)-1
	If *Anim>0 ; Si c'est une Animation
		PokeB(*Element + 9 + State*5, 1)
		PokeL(*Element + 10 + State*5, *Anim)
	Else  ; Si c'est un Sprite
		PokeB(*Element + 9 + State*5, 0)
		PokeL(*Element + 10 + State*5, IdSprite)
	EndIf
	ProcedureReturn *Element
EndProcedure

;position l'animation d'un element
Procedure SetFrameToElement(*Element, Frame.w)
 	PokeW(*Element + 3, Frame)
EndProcedure

;-#### Map ####
;*Map(Coord X, Coord Y, Level)
#MapMaxWidth = 512
#MapMaxHeight = 512
#MapMaxLevel = 4
#TILE_W=64
#TILE_H=32
Structure Map
	*Element			;Pointeur vers l'element
	ElementState.w		;Etat de l'element
	Time.l				;Si l'animation est uniquel alors on utilise cet enplassement pour connaitre le prochain  temps de changement d'image
	IdScript.l			;Script lors d'un action sur cet Element
EndStructure

Global Dim Map.Map(#MapMaxWidth, #MapMaxHeight, #MapMaxLevel)

Procedure GetSpriteFromMap(X.l, Y.l, L.l)
	If X<0 Or X>#MapMaxWidth Or Y<0 Or Y>#MapMaxHeight
		ProcedureReturn 0
	EndIf
	*Element = Map(X, Y, L)\Element;
	If *Element>0
		State = (Map(X, Y, L)\ElementState + 1)-1
		If PeekB(*Element + 9 + State*5) = 0 ;Si c'est un Sprite
			ProcedureReturn PeekL(*Element + 10 + State*5);On retourne l'idsprite
		Else ;Si c'est une animation
			*Anim = PeekL(*Element + 10 + State*5)
			If PeekB(*Element + 2) = 0 ;Si l'animation est Global
				Frame.w = PeekW(*Element + 3)
				If PeekL(*Element + 5) = 0 : 
					PokeL(*Element + 5, ElapsedMilliseconds() + GetTimeSpriteFromAnimation(*Anim, Frame))
				EndIf
				
				If ElapsedMilliseconds()>PeekL(*Element + 5);Si le temps s'est écoulé pour cette image
					Frame.w + 1;on passe a l'image suivante
					If Frame>GetFramesAnimation(*Anim)-1 ; si on depasse le nombre d'image du film
						SetAnimationLoop(*Anim, #True)
						If GetAnimationLoop(*Anim) = #True ;Si  on boucle
							Frame = 0
						Else
							Frame-1
						EndIf
					EndIf
					SetFrameToElement(*Element, Frame);On rafraichit l'image courante
					PokeL(*Element + 5, ElapsedMilliseconds() + GetTimeSpriteFromAnimation(*Anim, Frame));(On note quand est ce qu'on passera a l'image suivante
				EndIf
			EndIf
			ProcedureReturn GetSpriteFromAnimation(*Anim, Frame.w)
		EndIf
	EndIf
EndProcedure

;###############################################################################
;On test
;###############################################################################

InitSprite()
InitMouse() 
InitKeyboard()
OpenWindow(0, 0, 0, 640, 480, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0)

;Creation d'un Element et attribution d'une animation

;Sol
CreateSprite(0, 64, 64)
StartDrawing(SpriteOutput(0))
	col = RGB(115, 53, 8)
	LineXY(0, 48, 32, 32, col)
	LineXY(32, 32, 64, 48, col)
	LineXY(64, 48, 32, 64, col)
	LineXY(32, 64, 0, 48, col)
	FillArea(32, 48, -1, RGB(115, 53, 8))
StopDrawing()
*ElementSol = 0
*ElementSol = SetStatetoElement(*ElementSol, 0, 0)

;Poteau
CreateSprite(11, 64, 64)
StartDrawing(SpriteOutput(11))
	col = RGB(115, 53, 8)
	LineXY(0, 48, 32, 32, col)
	LineXY(32, 32, 64, 48, col)
	LineXY(64, 48, 32, 64, col)
	LineXY(32, 64, 0, 48, col)
	FillArea(32, 48, -1, RGB(115, 53, 8))
	LineXY(30, 48, 30, 0, #Green)
	LineXY(31, 49, 31, 1, #Green)
	LineXY(32, 50, 32, 2, #Green)
	LineXY(33, 49, 33, 1, RGB(0, 150, 0))
	LineXY(34, 48, 34, 0, RGB(0, 150, 0))
StopDrawing()
*ElementPoteau = 0
*ElementPoteau = SetStatetoElement(*ElementPoteau, 0, 11)
SaveSprite(11, "test.bmp")
;Eau
*AnimEau = 0
For z = 1 To 10
	CreateSprite(z, 64, 64)
	StartDrawing(SpriteOutput(z))
		col = #Blue
		LineXY(0, 48, 32, 32, col)
		LineXY(32, 32, 64, 48, col)
		LineXY(64, 48, 32, 64, col)
		LineXY(32, 64, 0, 48, col)
		FillArea(32, 48, -1, #Blue)
		For n = 1 To 10
			Line(Random(64), 32 + Random(32), Random(16), 0, RGB(100, 100, 255))
		Next
	StopDrawing()
	*AnimEau = SetSpriteToAnimation(*AnimEau, z, 500)
Next

;creation d'une carte
*ElementEau = 0
*ElementEau = SetStatetoElement(*ElementEau, *AnimEau)
For x = 0 To 10
	For y = 0 To 16
		Map(x, y, 0)\Element = *ElementEau
	Next
Next

Map(2, 2, 0)\Element = *ElementPoteau
Map(5, 5, 0)\Element = *ElementSol
Map(5, 6, 0)\Element = *ElementSol
Map(6, 6, 0)\Element = *ElementSol
Map(5, 7, 0)\Element = *ElementSol

;Simple render de tile
#TILE_W=64

#TILE_H=32

;Simple render de tile

Procedure.f Real2IsoX(X.l, Y.l)
	ProcedureReturn X-Y
EndProcedure

Procedure.f Real2IsoY(X.l, Y.l)
	ProcedureReturn (Y + X)/2
EndProcedure


Procedure InitRenderingWindows(Width,Height)
EndProcedure

Procedure DrawTile(IsoX.l,IsoY.l,Color.l)
        X1 = IsoX
        Y1 = IsoY - #TILE_H/2
       
        X2 = IsoX + #TILE_W/2
        Y2 = IsoY
       
        X3 = IsoX
        Y3 = IsoY + #TILE_H/2
       
        X4 = IsoX - #TILE_W/2
        Y4 = IsoY
        
        LineXY(X1,Y1,X2,Y2,Color)
        LineXY(X2,Y2,X3,Y3,Color)
        LineXY(X3,Y3,X4,Y4,Color)
        LineXY(X4,Y4,X1,Y1,Color)
EndProcedure



Procedure Render(PointerXReal.l, PointerYReal.l)
  WindowWidth.l =520
	WindowHeight.l = 300
	WindowCenterX=Int(WindowWidth/2)
	WindowCenterY=Int(WindowHeight/2)
	WindowTileCenterX=Round(WindowCenterX/32,#PB_Round_Up )
	WindowTileCenterY=Round(WindowCenterY/16,#PB_Round_Up )
	
	 UnitIso.l=32;Round(Sqr(Pow(16,2)+Pow(32,2)),#PB_Round_Down );
  PointerX.l=PointerXReal/UnitIso
  PointerY.l=PointerYReal/UnitIso
  DeltaXReal.l = PointerXReal-PointerX*UnitIso
  DeltaYReal.l = PointerYReal-PointerY*UnitIso
	
	
	
CreateSprite(200, WindowWidth, WindowHeight)
UseBuffer(200)
  TileMapWidth=(WindowTileCenterX+WindowTileCenterY)  ;Retirer le /4 c'est juste pour voir si la map est bien centré
  MapWidth=WindowTileCenterX*32
	For Y = 0 To TileMapWidth
		For X = 0 To TileMapWidth
	      
	      
	  	 _X = (X*#TILE_W/2)
       _Y = (Y*#TILE_H)   
       IsoX = (_X-_Y)+WindowCenterX-Real2IsoX(DeltaXReal,DeltaYReal)
       IsoY = ((_X+_Y)/2)+WindowCenterY-Int(TileMapWidth/2)*32-Real2IsoY(DeltaXReal,DeltaYReal)
	  
	  If IsoX>=-64 And IsoX<=WindowWidth+64 And IsoY>=-64 And IsoY<=WindowHeight+64
	  

      
      Sprite = GetSpriteFromMap(PointerX + x-WindowTileCenterX, PointerY + y-WindowTileCenterY, 0)
			
			If Sprite> = 0 And IsSprite(Sprite)
			  
				DisplayTransparentSprite(Sprite, IsoX, IsoY-SpriteHeight(Sprite))
			EndIf
			
		
       EndIf 
	  	  
	  Next x
	Next y
	StartDrawing(SpriteOutput(200))
	For Y = 0 To TileMapWidth
		For X = 0 To TileMapWidth
		    _X = (X*#TILE_W/2)
       _Y = (Y*#TILE_H)   
       IsoX = (_X-_Y)+WindowCenterX-Real2IsoX(DeltaXReal,DeltaYReal)
       IsoY = ((_X+_Y)/2)+WindowCenterY-Int(TileMapWidth/2)*32-Real2IsoY(DeltaXReal,DeltaYReal)
	     If IsoX>=-64 And IsoX<=WindowWidth+64 And IsoY>=-64 And IsoY<=WindowHeight+64
	      ;DrawTile(IsoX,IsoY,RGB(255,255,255))
        ;Circle(IsoX,IsoY,5,#Green)
	     EndIf
		  Next x
	Next y
  

  Mx.f=MouseX()/#TILE_W*2
  My.f=MouseY()/#TILE_H
  ey.f=(2*My-Mx)/2
  ex.f=Mx+ey
  _X = (ex*#TILE_W/2)
  _Y = (ey*#TILE_H)   
  IsoX = (_X-_Y)-Real2IsoX(DeltaXReal,DeltaYReal)
  IsoY = ((_X+_Y)/2)+WindowCenterY-Int(TileMapWidth/2)*32-Real2IsoY(DeltaXReal,DeltaYReal)
  DrawTile(IsoX,IsoY,#Red)
  DrawText(10, 40, "X:" + Str(ex-WindowTileCenterX+PointerX) + "  Y:" + Str(ey+PointerY)+" PX:"+Str(PointerX)+" PY:"+Str(PointerY))
  
  	Circle(MouseX(),MouseY(),2,#Yellow)
  	Circle(WindowCenterX,WindowCenterY,2,#Red)
  	StopDrawing()
UseBuffer(-1)
	DisplaySprite(200, 0, 0)
EndProcedure



Repeat
	; Il est très important de traiter tous les événements restants dans la file d'attente à chaque tour
	;
	Repeat
	     
		Event = WindowEvent()
		If Event = #PB_Event_CloseWindow
			End
		EndIf
	Until Event = 0
	ExamineMouse()
	ExamineKeyboard()
	ExamineMouse()
	If KeyboardPushed(#PB_Key_Up) : PointerYReal + 1 : EndIf
	If KeyboardPushed(#PB_Key_Down) : PointerYReal-1 : EndIf
	If KeyboardPushed(#PB_Key_Left) : PointerXReal-1 : EndIf
	If KeyboardPushed(#PB_Key_Right) : PointerXReal + 1 : EndIf
	If KeyboardPushed(#PB_Key_Escape):End:EndIf
	FlipBuffers()
	ClearScreen(#Red)
	
	render(PointerXReal, PointerYReal)

	Delay(1)
ForEver

kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Message par kelebrindae »

@cpl_Bator
Cpl.Bator a écrit :Oublie pas les parenthèses , le - a la priorité sur le *
Comment ça, le "-" a la priorité sur le "*" ?! J'ai toujours cru l'inverse! 8O

D'ailleurs, dans ton exemple, "x*32-y*32" est strictement équivalent à (x*32)-(y*32), non ?

Code : Tout sélectionner

x=7
y=6

Debug x*32-y*32
Debug (x*32)-(y*32)

; ça donne 32 dans les 2 cas 
J'ai raté quelque chose ? :?
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Voilà la dernière version Ou le scrolling et le pointeur marche !
Le code n'est pas propre mais je vais bosser maintenant sur l'amélioration de celui si et sur son optimisation

Code : Tout sélectionner

;- #### Animation ####
;	*Animation  DataSheet
;	Offset	|	Size	|	Type	|	Description
;	0		 |	2		  |	.w		|	Frames
;	2		    |	1		  |	.b		|	0 No Loop Animation / 1 Loop Animation
;	3		    |	4		  |	*		  |	IdSprite	Frame[ 1]
;	7		    |	2		  |	.w		|	Temps d'affichage en milliseconde
;	9		    |	4		  |	*	  	|	IdSprite	Frame[ 2]
;	13		  |	2		  |	.w		|	Temps d'affichage en milliseconde
;	3+x*6	  |	4		  |	*		  |	IdSprite	Frame[ x]
;	7+x*6	  |	2	  	|	.w		|	Temps d'affichage en milliseconde
;etc....

;Ajout d'un sprite a une animation
Procedure SetSpriteToAnimation(*Anim, IdSprite.l, Time.w)
	If *Anim>0
		Size.l = MemorySize(*Anim)
	Else
		Size.l = 3
		*Anim = AllocateMemory(Size)
	EndIf
	*Anim = ReAllocateMemory(*Anim, Size + 6)
	PokeW(*Anim, PeekW(*Anim) + 1)
	PokeL(*Anim + Size, IdSprite)
	PokeW(*Anim + Size + 4, Time)
	ProcedureReturn *Anim
EndProcedure

;Retourne le sprite correspondant a l'image d'une Animation
Procedure.l GetSpriteFromAnimation(*Anim, Frame.w)
	Location.l = 3 + Frame*6
	If Location<MemorySize(*Anim)
		ProcedureReturn PeekL(*Anim + Location) : 
	Else
		ProcedureReturn #False
	EndIf
EndProcedure

;Retourne le temps d'affichage d'une imge dans une animation
Procedure.l GetTimeSpriteFromAnimation(*Anim, Frame.w)
	Location.l = 7 + Frame*6
	If Location<MemorySize(*Anim)
		ProcedureReturn PeekW(*Anim + Location) : 
	Else
		ProcedureReturn #False
	EndIf
EndProcedure

;Active ou desactive le bouclage de l'annimation
Procedure.b SetAnimationLoop(*Anim, Loop.b)
	If *Anim>0
		PokeB(*Anim + 2, Loop)
		ProcedureReturn #True
	Else
		ProcedureReturn #False
	EndIf
EndProcedure

;Retourne le nombre d'image dans une animation
Procedure GetFramesAnimation(*Anim)
	ProcedureReturn PeekW(*Anim)
EndProcedure

;Retourne 1 si l'animation est Bouclé et 0 dans le cas contraire
Procedure.b GetAnimationLoop(*Anim)
	If *Anim>0
		ProcedureReturn PeekB(*Anim + 2)
	EndIf
EndProcedure

;-#### Element ####
;	*Element  DataSheet
;	Offset	|	Size	|	Type	|	Description
;	0		    |	2		  |	.w		|	States
;	2		    |	1		  |	.b		|	0 l'animation est Global / 1 l'animation est unique
;	3		    |	2		  |	.w		|	CurrentFrame / Si l'animation est Global alors on utilise cet enplassement pour connaitre l'image actuel de l'animation
;	5		    |	4	  	|	.l		|	Si l'animation est Global alors on utilise cet enplassement pour connaitre le prochain temps de changement d'image
;	9		    |	1		  |	.b		|	0 IdSprite / 1 *Animation	State[1]
;	10		  |	4		  |	*		  |	IdSprite or *Animation 	State[1]
;	14		  |	1		  |	.b		|	0 IdSprite / 1 *Animation	State[2]
;	15		  |	4	  	|	*		  |	IdSprite or *Animation 	State[2]
;	9+x*5	  |	1	  	|	.b		|	0 IdSprite / 1 *Animation	State[x]
;	10+x*5	|	4	  	|	*		  |	IdSprite or *Animation 	State[x]

Procedure DebugElement(*Element)
	Debug"__________"
	Debug "Element:" + Str(*Element)
	Debug "States :" + Str(PeekW(*Element));	0		    |	2		  |	.w		|	States
	Debug "Animation Type :" + Str(PeekB(*Element + 2));	2		    |	1		  |	.b		|	0 l'animation est Global / 1 l'animation est unique
	Debug "CurrentFrame:" + Str(PeekW(*Element + 3));	3		    |	2		  |	.w		|	CurrentFrame / Si l'animation est Global alors on utilise cet enplassement pour connaitre l'image actuel de l'animation
	Debug "NextTime:" + Str(PeekL(*Element + 3));;	5		    |	4	  	|	.l		|	Si l'animation est Global alors on utilise cet enplassement pour connaitre le prochain temps de changement d'image
	For z = 0 To PeekW(*Element)-1
		Debug "Type" + Str(z + 1) + " :" + Str(PeekB(*Element + 9*z*5));	9		    |	1		  |	.b		|	0 IdSprite / 1 *Animation	State[1]
		Debug "Sprite/Anim" + Str(z + 1) + " :" + Str(PeekL(*Element + 10*z*5));	10		  |	4		  |	*		  |	IdSprite or *Animation 	State[1]
	Next
EndProcedure

;Rajoute une animation ou une image a un Element
Procedure SetStatetoElement(*Element, *Anim, IdSprite = 0)
	If *Element>0 ;si l'element existe on regarde sa taille
		Size.l = MemorySize(*Element)
	Else ;si l'element n'existe pas on le créer
		Size.l = 9
		*Element = AllocateMemory(Size)
		PokeB(*Element + 2, 0)
	EndIf
	*Element = ReAllocateMemory(*Element, Size + 5)
	PokeW(*Element, PeekW(*Element) + 1) ;Ajout d'un etat
	State = PeekW(*Element)-1
	If *Anim>0 ; Si c'est une Animation
		PokeB(*Element + 9 + State*5, 1)
		PokeL(*Element + 10 + State*5, *Anim)
	Else  ; Si c'est un Sprite
		PokeB(*Element + 9 + State*5, 0)
		PokeL(*Element + 10 + State*5, IdSprite)
	EndIf
	ProcedureReturn *Element
EndProcedure

;position l'animation d'un element
Procedure SetFrameToElement(*Element, Frame.w)
 	PokeW(*Element + 3, Frame)
EndProcedure

;-#### Map ####
;*Map(Coord X, Coord Y, Level)
#MapMaxWidth = 512
#MapMaxHeight = 512
#MapMaxLevel = 4
#TILE_W=64
#TILE_H=32
Structure Map
	*Element			;Pointeur vers l'element
	ElementState.w		;Etat de l'element
	Time.l				;Si l'animation est uniquel alors on utilise cet enplassement pour connaitre le prochain  temps de changement d'image
	IdScript.l			;Script lors d'un action sur cet Element
EndStructure

Global Dim Map.Map(#MapMaxWidth, #MapMaxHeight, #MapMaxLevel)

Procedure GetSpriteFromMap(X.l, Y.l, L.l)
	If X<0 Or X>#MapMaxWidth Or Y<0 Or Y>#MapMaxHeight
		ProcedureReturn 0
	EndIf
	*Element = Map(X, Y, L)\Element;
	If *Element>0
		State = (Map(X, Y, L)\ElementState + 1)-1
		If PeekB(*Element + 9 + State*5) = 0 ;Si c'est un Sprite
			ProcedureReturn PeekL(*Element + 10 + State*5);On retourne l'idsprite
		Else ;Si c'est une animation
			*Anim = PeekL(*Element + 10 + State*5)
			If PeekB(*Element + 2) = 0 ;Si l'animation est Global
				Frame.w = PeekW(*Element + 3)
				If PeekL(*Element + 5) = 0 : 
					PokeL(*Element + 5, ElapsedMilliseconds() + GetTimeSpriteFromAnimation(*Anim, Frame))
				EndIf
				
				If ElapsedMilliseconds()>PeekL(*Element + 5);Si le temps s'est écoulé pour cette image
					Frame.w + 1;on passe a l'image suivante
					If Frame>GetFramesAnimation(*Anim)-1 ; si on depasse le nombre d'image du film
						SetAnimationLoop(*Anim, #True)
						If GetAnimationLoop(*Anim) = #True ;Si  on boucle
							Frame = 0
						Else
							Frame-1
						EndIf
					EndIf
					SetFrameToElement(*Element, Frame);On rafraichit l'image courante
					PokeL(*Element + 5, ElapsedMilliseconds() + GetTimeSpriteFromAnimation(*Anim, Frame));(On note quand est ce qu'on passera a l'image suivante
				EndIf
			EndIf
			ProcedureReturn GetSpriteFromAnimation(*Anim, Frame.w)
		EndIf
	EndIf
EndProcedure

;###############################################################################
;On test
;###############################################################################

InitSprite()
InitMouse() 
InitKeyboard()
OpenWindow(0, 0, 0, 640, 480, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0)

;Creation d'un Element et attribution d'une animation

;Sol
CreateSprite(0, 64, 64)
StartDrawing(SpriteOutput(0))
	col = RGB(115, 53, 8)
	LineXY(0, 48, 32, 32, col)
	LineXY(32, 32, 64, 48, col)
	LineXY(64, 48, 32, 64, col)
	LineXY(32, 64, 0, 48, col)
	FillArea(32, 48, -1, RGB(115, 53, 8))
StopDrawing()
*ElementSol = 0
*ElementSol = SetStatetoElement(*ElementSol, 0, 0)

;Poteau
CreateSprite(11, 64, 64)
StartDrawing(SpriteOutput(11))
	col = RGB(115, 53, 8)
	LineXY(0, 48, 32, 32, col)
	LineXY(32, 32, 64, 48, col)
	LineXY(64, 48, 32, 64, col)
	LineXY(32, 64, 0, 48, col)
	FillArea(32, 48, -1, RGB(115, 53, 8))
	LineXY(30, 48, 30, 0, #Green)
	LineXY(31, 49, 31, 1, #Green)
	LineXY(32, 50, 32, 2, #Green)
	LineXY(33, 49, 33, 1, RGB(0, 150, 0))
	LineXY(34, 48, 34, 0, RGB(0, 150, 0))
StopDrawing()
*ElementPoteau = 0
*ElementPoteau = SetStatetoElement(*ElementPoteau, 0, 11)
SaveSprite(11, "test.bmp")
;Eau
*AnimEau = 0
For z = 1 To 10
	CreateSprite(z, 64, 64)
	StartDrawing(SpriteOutput(z))
		col = #Blue
		LineXY(0, 48, 32, 32, col)
		LineXY(32, 32, 64, 48, col)
		LineXY(64, 48, 32, 64, col)
		LineXY(32, 64, 0, 48, col)
		FillArea(32, 48, -1, #Blue)
		For n = 1 To 10
			Line(Random(64), 32 + Random(32), Random(16), 0, RGB(100, 100, 255))
		Next
	StopDrawing()
	*AnimEau = SetSpriteToAnimation(*AnimEau, z, 500)
Next

;creation d'une carte
*ElementEau = 0
*ElementEau = SetStatetoElement(*ElementEau, *AnimEau)
For x = 0 To 10
	For y = 0 To 16
		Map(x, y, 0)\Element = *ElementEau
	Next
Next

Map(2, 2, 0)\Element = *ElementPoteau
Map(5, 5, 0)\Element = *ElementSol
Map(5, 6, 0)\Element = *ElementSol
Map(6, 6, 0)\Element = *ElementSol
Map(5, 7, 0)\Element = *ElementSol

;Simple render de tile
#TILE_W=64

#TILE_H=32

;Simple render de tile

Procedure.f Real2IsoX(X.l, Y.l)
	ProcedureReturn X-Y
EndProcedure

Procedure.f Real2IsoY(X.l, Y.l)
	ProcedureReturn (Y + X)/2
EndProcedure


Procedure Iso2RealX(X.l,Y.l)
  Mx.f=(X-WindowCenterX)/#TILE_W*2
  My.f=(Y-WindowCenterY)/#TILE_H
  ey.f=(2*My-Mx)/2
  ex.f=Mx+ey
 ProcedureReturn  ex
EndProcedure

Procedure Iso2RealY(X.l,Y.l)
  Mx.f=(X-WindowCenterX)/#TILE_W*2
  My.f=(Y-WindowCenterY)/#TILE_H
  ey.f=(2*My-Mx)/2
  ex.f=Mx+ey
 ProcedureReturn  ey
EndProcedure


Procedure InitRenderingWindows(Width,Height)
EndProcedure

Procedure DrawTile(IsoX.l,IsoY.l,Color.l)
        X1 = IsoX
        Y1 = IsoY - #TILE_H/2
       
        X2 = IsoX + #TILE_W/2
        Y2 = IsoY
       
        X3 = IsoX
        Y3 = IsoY + #TILE_H/2
       
        X4 = IsoX - #TILE_W/2
        Y4 = IsoY
        
        LineXY(X1,Y1,X2,Y2,Color)
        LineXY(X2,Y2,X3,Y3,Color)
        LineXY(X3,Y3,X4,Y4,Color)
        LineXY(X4,Y4,X1,Y1,Color)
EndProcedure



Procedure Render(PointerXReal.l, PointerYReal.l)
  WindowWidth.l =520
	WindowHeight.l = 300
	WindowCenterX=Int(WindowWidth/2)
	WindowCenterY=Int(WindowHeight/2)
	WindowTileCenterX=Round(WindowCenterX/32,#PB_Round_Up )
	WindowTileCenterY=Round(WindowCenterY/16,#PB_Round_Up )
	
	 UnitIso.l=32;Round(Sqr(Pow(16,2)+Pow(32,2)),#PB_Round_Down );
  PointerX.l=PointerXReal/UnitIso
  PointerY.l=PointerYReal/UnitIso
  DeltaXReal.l = PointerXReal-PointerX*UnitIso
  DeltaYReal.l = PointerYReal-PointerY*UnitIso
	
	
	
CreateSprite(200, WindowWidth, WindowHeight)
UseBuffer(200)
  TileMapWidth=(WindowTileCenterX+WindowTileCenterY)  ;Retirer le /4 c'est juste pour voir si la map est bien centré
  MapWidth=WindowTileCenterX*32
	For Y = 0 To TileMapWidth
		For X = 0 To TileMapWidth
	      
	      
	  	 _X = (X*#TILE_W/2)
       _Y = (Y*#TILE_H)   
       IsoX = (_X-_Y)+WindowCenterX-Real2IsoX(DeltaXReal,DeltaYReal)
       IsoY = ((_X+_Y)/2)+WindowCenterY-Int(TileMapWidth/2)*32-Real2IsoY(DeltaXReal,DeltaYReal)
	  
	  If IsoX>=-64 And IsoX<=WindowWidth+64 And IsoY>=-64 And IsoY<=WindowHeight+64
	  

      
      Sprite = GetSpriteFromMap(PointerX + x-WindowTileCenterX, PointerY + y-WindowTileCenterY, 0)
			
			If Sprite> = 0 And IsSprite(Sprite)
			  
				DisplayTransparentSprite(Sprite, IsoX, IsoY-SpriteHeight(Sprite))
			EndIf
			
		
       EndIf 
	  	  
	  Next x
	Next y
	StartDrawing(SpriteOutput(200))
	For Y = 0 To TileMapWidth
		For X = 0 To TileMapWidth
		    _X = (X*#TILE_W/2)
       _Y = (Y*#TILE_H)   
       IsoX = (_X-_Y)+WindowCenterX-Real2IsoX(DeltaXReal,DeltaYReal)
       IsoY = ((_X+_Y)/2)+WindowCenterY-Int(TileMapWidth/2)*32-Real2IsoY(DeltaXReal,DeltaYReal)
	     If IsoX>=-64 And IsoX<=WindowWidth+64 And IsoY>=-64 And IsoY<=WindowHeight+64
	      DrawTile(IsoX,IsoY,RGB(255,255,255))
        ;Circle(IsoX,IsoY,5,#Green)
	     EndIf
		  Next x
	Next y
  

  Mx.f=(MouseX()-WindowCenterX)/#TILE_W*2
  My.f=(MouseY()-WindowCenterY)/#TILE_H
  ey.f=(2*My-Mx)/2
  ex.f=Mx+ey



;ex=(ex-WindowTileCenterX+PointerX)
;ey=ey+PointerY

DrawTile(Real2IsoX(ex,ey)*32+WindowCenterX-Real2IsoX(DeltaXReal,DeltaYReal),Real2IsoY(ex,ey)*32+WindowCenterY-Real2IsoY(DeltaXReal,DeltaYReal),#Red)


   
  DrawText(10, 40, "X:" + Str(ex+PointerX) + "  Y:" + Str(ey+PointerY)+" PX:"+Str(PointerX)+" PY:"+Str(PointerY))
  
  	Circle(MouseX(),MouseY(),2,#Yellow)
  	Circle(WindowCenterX,WindowCenterY,2,#Red)
  	StopDrawing()
UseBuffer(-1)
	DisplaySprite(200, 0, 0)
EndProcedure



Repeat
	; Il est très important de traiter tous les événements restants dans la file d'attente à chaque tour
	;
	Repeat
	     
		Event = WindowEvent()
		If Event = #PB_Event_CloseWindow
			End
		EndIf
	Until Event = 0
	ExamineMouse()
	ExamineKeyboard()
	ExamineMouse()
	If KeyboardPushed(#PB_Key_Up) : PointerYReal + 1 : EndIf
	If KeyboardPushed(#PB_Key_Down) : PointerYReal-1 : EndIf
	If KeyboardPushed(#PB_Key_Left) : PointerXReal-1 : EndIf
	If KeyboardPushed(#PB_Key_Right) : PointerXReal + 1 : EndIf
	If KeyboardPushed(#PB_Key_Escape):End:EndIf
	FlipBuffers()
	ClearScreen(#Red)
	
	render(PointerXReal, PointerYReal)

	Delay(1)
ForEver

Anonyme

Message par Anonyme »

kelebrindae a écrit :@cpl_Bator
Cpl.Bator a écrit :Oublie pas les parenthèses , le - a la priorité sur le *
Comment ça, le "-" a la priorité sur le "*" ?! J'ai toujours cru l'inverse! 8O

D'ailleurs, dans ton exemple, "x*32-y*32" est strictement équivalent à (x*32)-(y*32), non ?

Code : Tout sélectionner

x=7
y=6

Debug x*32-y*32
Debug (x*32)-(y*32)

; ça donne 32 dans les 2 cas 
J'ai raté quelque chose ? :?

oui , tu as raison , c'est l'inverse.

Code : Tout sélectionner

  Niveau de priorité  |    Opérateurs
  --------------------+---------------------
         8  (haute)   |        ~
         7            |    <<, >>, %, !
         6            |       |, &
         5            |       *, /
         4            |       +, -
         3            | >, >=, <, <=, =, <>
         2            |       Not
         1  (basse)   |   And, Or, XOr
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Juste pour vous parler de mon avancement. ça marche super bien j'arrive maintenant a dessiné et scroller ma map qui contient 4 layer ! Je suis pour l'instant en train d'essayer de faire un editeur !
Mais je me pose une question ! comment est identifier un escalier ou une pente qui permet de monter d'un étage! Quelqu'un sait ?
Image
edit: un petit exemple (taper un nom en haut et cliquez sur join
http://showcase.smartfoxserver.com/openspace2/
Répondre