I made one of my older group movement examples a little bit smarter. The units will now move a short time either left or right from the target direction if their path is blocked. If all paths are blocked then it will wait a second.
Import mojo Class ai ' unit locations Field x:Float,y:Float ' destination coords Field dx:Int,dy:Int ' movement speed Field ms:Float ' angle of x/y and dx/dy Field angle:Int ' state Field state:String="Direct Line" Field aroundang:Int Field countdown1:Int Method New(x:Int,y:Int) Self.x = x Self.y = y Self.ms = Rnd(0.5,1.5) Self.dx = DeviceWidth()/2 Self.dy = DeviceHeight()/2 End Method Method update() If state = "Wait" countdown1-=1 If countdown1 < 1 state="Direct Line" End If End If If state="Move Around" countdown1-=1 If countdown1 < 1 state="Direct Line" End If Local nx:Float = x+Cos(aroundang)*(ms*4) Local ny:Float = y+Sin(aroundang)*(ms*4) Local nxt:Bool=False For Local i:=Eachin myai If i.x <> x If i.y <> y If rectsoverlap(nx,ny,16,16,i.x,i.y,16,16) = True nxt = True state="Wait" End If End If End If Next If nxt = False x += Cos(aroundang)*ms y += Sin(aroundang)*ms End If End If If state="Direct Line" angle = getangle(dx,dy,x,y) If distance(x,y,dx,dy) > 5 Local nx:Float = x+Cos(angle)*(ms*4) Local ny:Float = y+Sin(angle)*(ms*4) Local nxt:Bool=False For Local i:=Eachin myai If i.x <> x If i.y <> y If rectsoverlap(nx,ny,16,16,i.x,i.y,16,16) = True nxt = True state="Move Around" countdown1 = 32 findopenspot() End If End If End If Next If nxt = False x += Cos(angle)*ms y += Sin(angle)*ms End If End If End If End Method Method findopenspot() Local sel:Int=Rnd(10) If sel<5 Then If rightturn() = False leftturn End If Else If leftturn() = False rightturn End If End If End Method Method rightturn:Bool() aroundang=angle+90 Local nx:Float = x+Cos(aroundang)*(ms*4) Local ny:Float = y+Sin(aroundang)*(ms*4) Local nxt:Bool=False For Local i:=Eachin myai If i.x <> x If i.y <> y If rectsoverlap(nx,ny,16,16,i.x,i.y,16,16) = True nxt = True state="Wait" countdown1 = 60 Return False End If End If End If Next Return True End Method Method leftturn:Bool() aroundang=angle-90 Local nx:Float = x+Cos(aroundang)*(ms*4) Local ny:Float = y+Sin(aroundang)*(ms*4) Local nxt:Bool=False For Local i:=Eachin myai If i.x <> x If i.y <> y If rectsoverlap(nx,ny,16,16,i.x,i.y,16,16) = True nxt = True state = "Wait" countdown1 = 60 Return False End If End If End If Next Return True End Method Method draw() SetColor 255,0,0 DrawOval x,y,16,16 If state="Move Around" SetColor 255,255,0 DrawOval x+(Cos(aroundang)*16), y+(Sin(aroundang)*16),16,16 End If End Method Method rectsoverlap:Bool( x1:Int, y1:Int, w1:Int, h1:Int, x2:Int, y2:Int, w2:Int, h2:Int) If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False Return True End Method Method getangle:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return ATan2(y1-y2, x1-x2) End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class Global numai:Int=10 Global myai:List<ai> = New List<ai> ' waittime before random new destination Global dxchangecountdown:Int=500 ' hold the destination of the units Global mydx:Int,mydy:Int Class MyApp Extends App Method OnCreate() SetUpdateRate(60) For Local i=0 To numai Local exitloop:Bool=False Local nx:Int,ny:Int While exitloop = False exitloop = True nx=Rnd(640) ny=Rnd(480) For Local ii:=Eachin myai If distance(nx,ny,ii.x,ii.y) < 32 exitloop = False End If Next Wend myai.AddLast(New ai(nx,ny)) Next Local date := GetDate() Seed = date[6] End Method Method OnUpdate() dxchangecountdown-=1 If dxchangecountdown < 0 dxchangecountdown = 500 mydx = Rnd(32,DeviceWidth()-64) mydy = Rnd(32,DeviceHeight()-64) For Local i:=Eachin myai i.dx = mydx i.dy = mydy Next End If For Local i:=Eachin myai i.update Next If MouseHit(MOUSE_LEFT) dxchangecountdown = 500 For Local i:=Eachin myai i.dx = MouseX() i.dy = MouseY() Next End If End Method Method OnRender() Cls 0,0,0 For Local i:=Eachin myai i.draw mydx = i.dx mydy = i.dy Next SetColor 255,255,0 DrawLine mydx,mydy,mydx-5,mydy DrawLine mydx,mydy,mydx+5,mydy DrawLine mydx,mydy,mydx,mydy-5 DrawLine mydx,mydy,mydx,mydy+5 SetColor 255,255,255 DrawText "Monkey-X Smarter group movement ai.",10,10 DrawText "Press the left mouse to change dx,dy",10,25 End Method End Class Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function Function Main() New MyApp End Function
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.