Code archives/Graphics/2D Grid Class

This code has been declared by its author to be Public Domain code.

Download source code

2D Grid Class by codermax2015
NOTE: Strict and SuperStrict compatible!

This is a class I developed to help me create map editors.
It supports the drawing and selection of grid cells inside a 2D grid, which can be scaled and divided to your needs. You can also use it to draw unfilled rectangles, which can also function as simple ON/OFF buttons(toggled with the RMB).

Thought I'd share it here, since I couldn't find such a thing in the code archives already. It's also commented for no reason, just in case you wanna edit the class to your desired specs. :)

No credit is required or wanted, so use it as you wish!

The 2D grid class requires the included Vector2 class and Clamp(), RectsOverlap() functions to work.
(which you should already have btw, but they're included here so there's no extra tinkering to make the grids work)

Arguments:
A=X position
B=Y position
C=Grid Width
D=Grid Height
E=Vertical Divisions(Columns)
F=Horizontal Divisions(Rows)

Example Usage:
1. Declare the grid contents.
	Global MainGrid:GridData=GridData.Create(A,B,C,D,E,F)

2. Place the grid's update method in the main update function.
	Function Update()
		MainGrid.Update()
	End Function

3. Place the grid's draw method in the main draw function. Keep in mind that the method is affected by commands such as SetColor and SetLineWidth!
	Function Draw()
		MainGrid.Draw()
	End Function

And that's all you need to draw the grid and enable selection of the grid's cells!

Here's another cool thing you can do with this class.

1. Create 2 images, one non-animated and another which is animated(contains frames).
Global Tileset:TImage=LoadImage("C:\directory\tileset.png")
Global TilesetPiece:TImage=LoadAnimImage("C:\directory\tileset.png",32,32,0,8)

2. Draw your desired 1-frame image at the grid's position.
	DrawImage Tileset, MainGrid.X, MainGrid.Y

3. Draw the grid(you'll need to tinker with the grid to line up with your 1-frame image).
	MainGrid.Draw()

4. Get the grid's cursor position as a single integer. Remember to cap this value at the maximum # of frames your multi-frame image has, to avoid errors!
	Local SelectedTile:Int=MainGrid.GetRowPos()

5. Draw the multi-frame image with your desired frame using this value.
	DrawImage TilesetPiece, 100,100, SelectedTile

And you now have the basics for a tile placement UI!

The source code is below.
Type GridData
	Field X:Float,Y:Float,W:Float,H:Float, VS:Float,HS:Float
	Field CW:Float, CH:Float, CursorPos:Vector2, Deselect:Int=0
	
	'Allows users to create specific grids in the main loop with one only line of code.
	Function Create:GridData(A:Float,B:Float,C:Float,D:Float,E:Float,F:Float)
		Local tmp:GridData=New GridData
			tmp.CursorPos=Vector2.Create(0,0)
			tmp.X=A tmp.Y=B tmp.W=C tmp.H=D
			tmp.VS=E tmp.HS=F
			tmp.CW=tmp.W/tmp.VS tmp.CH=tmp.H/tmp.HS
		Return tmp
	End Function

	'Updates grid selection.
	Method Update()
		Local MV2:Vector2=Vector2.Create(0,0)	
			MV2=SnapToGrid()
		If MouseDown(1) And MV2.X<>-1 
			CursorPos.Set(MV2.X,MV2.Y) Deselect=0
		EndIf
		If MouseHit(2) And MV2.X<>-1 
			Deselect:+1 If Deselect>1 Then Deselect=0
		EndIf
	End Method
	
	'Draws a 2D grid and draws the grid cursor.
	Method Draw()
		'calculate the grid cell size.
			Local divX:Float=W/VS, divY:Float=H/HS
		
		'draw the vertical lines.
			For Local x1:Int=0 To VS
				DrawLine(X+(divX*x1),Y,X+(divX*x1),Y+H)
			Next
			
		'draw the horizontal lines.
			For Local y1:Int=0 To HS
				DrawLine(X,Y+(divY*y1),X+W,Y+(divY*y1))
			Next
			
			SetAlpha 0.3 SetColor 0,0,255
				If Deselect=0
					DrawRect X+(CW*CursorPos.X),Y+(CH*CursorPos.Y),CW,CH
				EndIf
				
			SetAlpha 1 SetColor 255,255,255
	End Method
	
	Rem
		Makes sure the mouse selects cells inside the grid properly.
		Outputs a 2D vector representing the mouse's current cell position on the grid.
		A 2D Vector value of -1,-1, that means that the mouse cursor is outside the grid.
	End Rem
	Method SnapToGrid:Vector2()
		Local V2:Vector2=Vector2.Create(-1,-1), MX:Float, MY:Float
		Local divX:Float=W/VS, divY:Float=H/HS
			
		If RectsOverlap(MouseX(),MouseY(),1,1, X,Y,W,H)=True
			V2.X=Int( (MouseX()-X)/divX ) V2.X=Clamp( V2.X, 0, VS-1 )
			V2.Y=Int( (MouseY()-Y)/divY ) V2.Y=Clamp( V2.Y, 0, HS-1 )
		EndIf
		
		Return V2	
	End Method

	Rem
		Outputs an integer that represents the cumulative grid cursor position.
		Purpose is for determining image frames, based on grid selection.
	End Rem
	Method GetRowPos:Int()
		Local i:Int=0
			i=(HS*CursorPos.Y)+CursorPos.X
		Return i
	End Method
	
End Type

'REQUIRED FOR 2D GRID CLASS TO WORK.
'extra 2D vector class.
Type Vector2
	Field X:Float,Y:Float
	
	Function Create:Vector2(A:Float,B:Float)
		Local tmp:Vector2=New Vector2
			tmp.X=A tmp.Y=B
		Return tmp
	End Function
	
	Method Set(A:Float,B:Float)
		X=A Y=B
	End Method
End Type

'extra functions.
Function RectsOverlap:Int(x0:Double,y0:Double,w0:Double,h0:Double,x2:Double,y2:Double,w2:Double,h2:Double)
            If (x0 > (x2 + w2) Or (x0 + w0) < x2)
        	    Return 0
			EndIf
            If (y0 > (y2 + h2) Or (y0 + h0) < y2)
          	 	Return 0
			EndIf
          	  Return 1
End Function

Function Clamp:Float(V:Float,MinV:Float,MaxV:Float)
	If V<MinV Then V=MinV
	If V>MaxV Then V=MaxV
	Return V
End Function

Comments

None.

Code Archives Forum