Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Import "<std>"
- #Import "<mojo>"
- #Import "<mojox>"
- Using std..
- Using mojo..
- Using mojox..
- Class MyWindow Extends Window
- Global pathPlaceStep:Int
- Method New()
- Super.New("Simple Mojo Gui App",640,480,WindowFlags.Resizable)
- Node.camera.X=640/2
- Node.camera.Y=480/2
- For Local i:Int=0 Until 25
- New Node(Rnd(-640,640),Rnd(-480,480))
- Next
- ClearColor=Color.DarkGrey
- ClearEnabled=True
- End
- Method OnRender(canvas:Canvas) Override
- App.RequestRender()
- canvas.DrawText("Click & Drag to Move node",0,0)
- canvas.DrawText("Ctrl & Drag to Link node",0,15)
- canvas.DrawText("Shift & Click to Insta-Link node",0,15*2)
- canvas.DrawText("Alt & Click to Remove node",0,15*3)
- canvas.DrawText("W,A,S,D to Move camera",0,15*4)
- canvas.DrawText("Numpad Minus to Remove node",0,15*5)
- canvas.DrawText("Numpad Plus to Add node",0,15*6)
- If Self.pathPlaceStep Then
- canvas.DrawText("Space to Place path end",0,15*7)
- Else
- canvas.DrawText("Space to Place path start",0,15*7)
- Endif
- If Keyboard.KeyDown(Key.W) Then Node.camera.Y+=2
- If Keyboard.KeyDown(Key.S) Then Node.camera.Y-=2
- If Keyboard.KeyDown(Key.A) Then Node.camera.X+=2
- If Keyboard.KeyDown(Key.D) Then Node.camera.X-=2
- If Keyboard.KeyHit(Key.KeypadPlus) Then
- New Node(Mouse.X-Node.camera.X,Mouse.Y-Node.camera.Y,Node.selectedNode)
- Node.selectedNode=Node.lastAddedNode
- Endif
- If Keyboard.KeyHit(Key.KeypadMinus) Then
- If Node.selectedNode Then
- Node.selectedNode.Remove()
- Else
- Node.MouseNode()
- If Node.lastMouseNode Then Node.lastMouseNode.Remove()
- Endif
- Endif
- If Keyboard.KeyHit(Key.Space) Then
- If Self.pathPlaceStep then
- Self.pathPlaceStep=0
- Node.FindPath(Node.pathStartPos.x,Node.pathStartPos.y,Mouse.X-Node.camera.X,Mouse.Y-Node.camera.Y)
- Else
- Node.ClearPath()
- Self.pathPlaceStep=1
- Node.pathStartPos=New Vec2f(Mouse.X-Node.camera.X,Mouse.Y-Node.camera.Y)
- Node.pathEndPos=New Vec2f(Mouse.X-Node.camera.X,Mouse.Y-Node.camera.Y)
- endif
- Endif
- Node.Update()
- Node.Draw(canvas)
- If Node.dragLink Or Node.moveNode Then
- If SwapInterval<>0 Then SwapInterval=0
- Else
- If SwapInterval<>1 Then SwapInterval=1
- Endif
- End
- End
- Function Main()
- New AppInstance
- New MyWindow
- App.Run()
- End
- Class Node
- Global list:List<Node>
- Global path:List<Node>
- Global camera:Vec2f
- Global selectedNode:Node
- Global lastMouseNode:Node
- Global lastAddedNode:Node
- Global lastCloseNode:Node
- Global dragLink:Bool
- Global moveNode:Bool
- Global pathStartNode:Node
- Global pathEndNode:Node
- Global pathStartPos:Vec2f
- Global pathEndPos:Vec2f
- Field id:Int
- Field x:Float
- Field y:Float
- Field links:List<Node>
- Field color:Color
- Field size:Int=12
- Method New(x:Float,y:Float,link:Node=Null)
- If Not Node.list Then Node.list=New List<Node>
- If Not Node.path Then Node.path=New List<Node>
- 'Find unique ID for node
- Local n:Node
- Local freeId:Int
- Local checkId:Int
- Repeat
- freeId=checkId
- For n=Eachin Node.list
- If n.id=checkId Then
- 'RETRY!!
- freeId=-1
- Exit
- Endif
- Next
- checkId+=1
- Until freeId>=0
- Self.id=freeId
- Self.x=x
- Self.y=y
- If Not Self.links Then Self.links=New List<Node>
- If link Then Self.AddLink(link)
- Node.lastAddedNode=Self
- Node.list.AddLast(self)
- End
- Method MouseHover:Bool()
- If Mouse.X-Node.camera.X>=Self.x-Self.size/2 And Mouse.Y-Node.camera.Y>=Self.y-Self.size/2 Then
- If Mouse.X-Node.camera.X<=Self.x+Self.size/2 And Mouse.Y-Node.camera.Y<=Self.y+Self.size/2
- Return True
- Endif
- End
- Return False
- End
- Method AddLink(node:Node)
- If Not node Then
- Print "No link node!"
- Return
- Endif
- 'Check if self
- If Self=node Then
- Print "Link node is self!"
- Return
- Endif
- 'Check if link already exists
- Local n:Node
- For n=Eachin node.links
- If n=Self Then
- Print "Link already exists!"
- Return
- Endif
- Next
- For n=Eachin Self.links
- If n=node Then
- Print "Link already exists!"
- Return
- Endif
- Next
- node.links.AddLast(Self)
- Self.links.AddLast(node)
- End
- Method RemoveLink(node:Node)
- Self.links.Remove(node)
- node.links.Remove(Self)
- End
- Method Remove()
- If Node.selectedNode=Self Then Node.selectedNode=Null
- If Node.lastMouseNode=Self Then Node.lastMouseNode=Null
- If Node.lastAddedNode=Self Then Node.lastAddedNode=Null
- If Node.lastCloseNode=Self Then Node.lastCloseNode=Null
- If Self.links Then
- For Local n:Node=Eachin Self.links
- n.RemoveLink(Self)
- Next
- Endif
- Node.list.Remove(Self)
- End
- Function MouseNode:Node()
- Node.lastMouseNode=Null
- For Local n:Node=Eachin Node.list
- If n.MouseHover() Then
- Node.lastMouseNode=n
- Return Node.lastMouseNode
- Endif
- Next
- Return Null
- End
- Function NodeClose:Node(x:Float,y:Float)
- Node.lastCloseNode=Null
- Local dx:Float
- Local dy:Float
- Local dist:Float
- Local bestDist:Float
- For Local n:Node=Eachin Node.list
- dx=x-n.x
- dy=y-n.y
- dist=Sqrt(dx*dx + dy*dy)
- If Not Node.lastCloseNode Or dist<bestDist Then
- bestDist=dist
- Node.lastCloseNode=n
- Endif
- Next
- Return Node.lastCloseNode
- End
- Function NodeId:Node(id:int)
- For Local n:Node=Eachin Node.list
- If n.id=id Then Return n
- Next
- Return Null
- End
- Function Update()
- For Local n:Node=Eachin Node.list
- If Node.selectedNode = n Then
- n.color=Color.Green
- Else
- n.color=Color.Orange
- Endif
- Next
- If Mouse.ButtonHit(MouseButton.Left) Then
- Node.MouseNode()
- If Node.selectedNode Then
- If Not Node.lastMouseNode Then
- Node.selectedNode=Null
- Else
- If Node.selectedNode=Node.lastMouseNode Then
- If Keyboard.KeyDown(Key.LeftControl) Or Keyboard.KeyDown(Key.RightControl) Then
- Node.dragLink=True
- Else
- Node.moveNode=True
- Endif
- Else
- If Keyboard.KeyDown(Key.LeftShift) Or Keyboard.KeyDown(Key.RightShift) Then
- Node.selectedNode.AddLink(Node.lastMouseNode)
- Else
- If Keyboard.KeyDown(Key.LeftAlt) Or Keyboard.KeyDown(Key.RightAlt) Then
- Node.selectedNode.RemoveLink(Node.lastMouseNode)
- Else
- Node.selectedNode=Node.lastMouseNode
- Endif
- Endif
- Endif
- Endif
- Else
- Node.selectedNode=Node.lastMouseNode
- Endif
- Else
- If Mouse.ButtonDown(MouseButton.Left) Then
- If Node.dragLink Then
- Node.MouseNode()
- If Node.lastMouseNode And Node.lastMouseNode<>Node.selectedNode Then
- Node.lastMouseNode.color=Color.Blue
- Endif
- Endif
- If Node.moveNode Then
- Node.selectedNode.x=Mouse.X-Node.camera.X
- Node.selectedNode.y=Mouse.Y-Node.camera.Y
- Endif
- Else
- If Node.dragLink Then
- If Node.lastMouseNode Then Node.selectedNode.AddLink(Node.lastMouseNode)
- Node.dragLink=False
- Endif
- If Node.moveNode Then
- Node.moveNode=False
- Endif
- Endif
- Endif
- End
- Function Draw(canvas:Canvas)
- canvas.Translate(Node.camera.X,Node.camera.Y)
- Local n:Node
- Local n2:Node
- canvas.LineSmoothing=True
- canvas.LineWidth=3
- 'Draw links
- For n=Eachin Node.list
- canvas.Color=Color.Blue
- For n2=Eachin n.links
- canvas.DrawLine(n.x,n.y,n2.x,n2.y)
- Next
- Next
- 'Draw nodes
- For n=Eachin Node.list
- canvas.Color=n.color
- canvas.DrawOval(Int(n.x-n.size/2),Int(n.y-n.size/2),n.size,n.size)
- canvas.Color=Color.White
- canvas.DrawText(n.id,n.x,n.y,0.5,0.5)
- Next
- 'Draw dragging line
- If Node.dragLink Then
- canvas.Color=Color.Blue
- canvas.DrawLine(selectedNode.x,selectedNode.y,Mouse.X-Node.camera.X,Mouse.Y-Node.camera.Y)
- Endif
- 'Draw path
- canvas.Color=Color.Puce
- If Node.path.Count()<=0 Then
- canvas.DrawLine(Node.pathStartPos.X,Node.pathStartPos.Y,Node.pathEndPos.X,Node.pathEndPos.Y)
- Else
- canvas.DrawLine(Node.pathStartPos.X,Node.pathStartPos.Y,Node.path.First.x,Node.path.First.y)
- Local lastNode:Node=Node.path.First
- For n=Eachin Node.path
- If lastNode=n Then Continue
- canvas.DrawLine(n.x,n.y,lastNode.x,lastNode.y)
- lastNode=n
- Next
- canvas.DrawLine(Node.pathEndPos.X,Node.pathEndPos.Y,Node.path.Last.x,Node.path.Last.y)
- Endif
- canvas.Color=Color.Pink
- canvas.DrawText("S",Int(Node.pathStartPos.X),Int(Node.pathStartPos.Y),0.5,0.5)
- If Int(Node.pathStartPos.X)<>Int(Node.pathEndPos.X) And Int(Node.pathStartPos.Y)<>Int(Node.pathEndPos.Y) then
- canvas.DrawText("E",Int(Node.pathEndPos.X),Int(Node.pathEndPos.Y),0.5,0.5)
- Endif
- End
- Function ClearPath()
- Node.path.Clear()
- End
- Function FindPath(startX:Float,startY:Float,endX:Float,endY:Float)
- ClearPath()
- Node.pathStartNode=Node.NodeClose(startX,startY)
- Node.pathEndNode=Node.NodeClose(endX,endX)
- Node.pathStartPos.X=startX
- Node.pathStartPos.Y=startY
- Node.pathEndPos.X=endX
- Node.pathEndPos.Y=endY
- 'Super pathfinding code here...
- 'Just add some random path for now
- Node.path.AddLast(Node.NodeId(8))
- Node.path.AddLast(Node.NodeId(5))
- Node.path.AddLast(Node.NodeId(11))
- Node.path.AddLast(Node.NodeId(17))
- Node.path.AddLast(Node.NodeId(0))
- 'Print path
- For Local n:Node=Eachin Node.path
- Print n.id
- Next
- End
- End
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement