Code archives/Graphics/2D Grid Class
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
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