#monkey-X #gamedev Here a small example of how ai flies to asteroids to mine them. They fly back to their base planet and continue to mine until all asteroids are gone. The map resets to a random new map at random intervals. In this example there can be up to 50 ai mining ships per map. Code below :
Import mojo Const screenwidth:Int=640 Const screenheight:Int=480 Global numships:Int=45 Global minerals:Int=0 Global resettime:Int=Millisecs()+15000 Class ship Field x:Float Field y:Float Field angle:Int Field destangle:Int Field incx:Float Field incy:Float Field homex:Int Field homey:Int Field destx:Int Field desty:Int Field state:String="evaluate" Field laststate:String Field cargo:Int=0 Field minetime:Int Method New(_x:Float,_y:Float,_angle:Int) x = _x y = _y homex = x homey = y angle = _angle End Method Method update() Select state Case "evaluate" ; eval Case "findasteroidtomine" ; findasteroid Case "flytotarget" ; flytot Case "mineasteroid" ; mineasteroid End Select End Method Method mineasteroid() If minetime < Millisecs() Then For Local i:=Eachin a If i.x = destx And i.y = desty i.s -=1 If i.s < 1 Then i.delete = True Exit End If Next cargo = 1 laststate=state destx = homex desty = homey state="flytotarget" End If End Method Method flytot() destangle = getangle(x,y,destx,desty) If leftangle(angle,destangle) = True Then angle-=5 Else angle+=5 If angle<-180 Then angle=180 If angle>180 Then angle = -180 incx = Cos(angle) incy = Sin(angle) x+=incx y+=incy If distance(x,y,destx,desty) < 5 Then If laststate = "findasteroidtomine" Then laststate = state ; state = "mineasteroid" minetime = Millisecs()+2000 End If If laststate = "mineasteroid" cargo = 0 minerals+=1 laststate = state ; state = "evaluate" End If End If End Method Method findasteroid() Local sd:Int = 100000 Local afound:Bool=False Local taken:Bool=False For Local i:=Eachin a Local d:Int = distance(i.x,i.y,x,y) If d<sd Then Local taken = False For Local ii:=Eachin sh If ii.destx = i.x And ii.desty=i.y taken = True End If Next If taken=False sd=d destx=i.x desty=i.y afound=True End If End If Next If afound = True Then laststate= state ; state="flytotarget" 'Print "found asteroid to mine"+Millisecs() Else 'Print "Nothing state ship"+Millisecs state="evaluate" End If End Method Method eval() If Rnd(200)<2 And cargo = 0 Then laststate=state ; state="findasteroidtomine" End Method Method draw() SetColor 255,255,0 DrawPoint x,y End Method End Class Class star Field x:Int Field y:Int Method New(_x:Int,_y:Int) x=_x y=_y End Method Method draw() SetColor 255,255,255 DrawPoint x,y End Method End Class Class asteroid Field x:Float Field y:Float Field s:Float Field rotangle:Float Field rotangles:Float Field delete:Bool=False Method New(_x:Float,_y:Float,_s:Float) x = _x y = _y s = _s rotangle = 0.0 rotangles = Rnd(-1,1) End Method Method update() rotangle += rotangles If rotangle <-180 Then rotangle = 180 If rotangle >180 Then rotangle = -180 For Local i:=Eachin a If i.delete = True Then a.Remove i Next End Method Method draw() PushMatrix() Translate x,y Rotate(-rotangle) Translate -x,-y SetColor 100,100,100 DrawRect x-s/2,y-s/2,s,s PopMatrix() End Method End Class Class planet Field x:Float Field y:Float Field s:Float Field t:Int ' planet type Method New(_x:Float,_y:Float,_s:Float,_t:Int) x = _x y = _y s = _s t = _t End Method Method update() End Method Method draw() Select t Case 1 'earthlike SetColor 0,200,0 Case 2 'gas SetColor 255,0,0 End Select DrawOval x-s/2,y-s/2,s,s End Method End Class Global p:List<planet> = New List<planet> Global a:List<asteroid> = New List<asteroid> Global s:List<star> = New List<star> Global sh:List<ship> = New List<ship> Class MyGame Extends App Method OnCreate() SetUpdateRate(60) createmap End Method Method OnUpdate() If Rnd(1600)<2 And resettime<Millisecs() Then createmap ; resettime=Millisecs()+15000 For Local i:=Eachin p 'update planets i.update Next For Local i:=Eachin a 'update asteroids i.update Next For Local i:=Eachin sh i.update Next End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 DrawText "Minerals Mined : " + minerals,0,0 For Local i:=Eachin s 'draw stars i.draw Next For Local i:=Eachin p 'draw planets i.draw Next For Local i:=Eachin a 'draw asteroids i.draw Next For Local i:=Eachin sh 'draw ships i.draw Next End Method End Class Function createmap() a.Clear() sh.Clear() s.Clear() p.Clear() minerals = 0 numships = Rnd(10,300) Seed = Millisecs() 'Make planets For Local i=0 Until 3 Local x1 = Rnd(25,screenwidth-50) Local y1 = Rnd(25,screenheight-50) p.AddLast(New planet(x1,y1,Rnd(5,10),2)) Next Local x1 = 320 Local y1 = 240 p.AddLast(New planet(x1,y1,Rnd(5,25),1)) ' Make asteroids Local numfields:Int=Int(Rnd(3,6)) For Local i=0 Until numfields Local x1 = Rnd(50,screenwidth-50) Local y1 = Rnd(50,screenheight-50) Local numa:Int=Rnd(3,45) For Local ii=0 Until numa Local x2 = Rnd(-50,50) Local y2 = Rnd(-50,50) a.AddLast(New asteroid(x1+x2,y1+y2,Rnd(2,8))) Next Next 'Make stars For Local i=0 Until 100 s.AddLast(New star(Rnd(screenwidth),Rnd(screenheight))) Next 'Make ships For Local i=0 Until numships Local v:Int=Rnd(360) Local x1:Float Local y1:Float x1=320+(Cos(v)*32)+Rnd(-2,2) y1=240+(Sin(v)*32)+Rnd(-2,2) sh.AddLast(New ship(x1,y1,Rnd(-180,180))) Next End Function Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1) + Abs(y2-y1) End Function Function getangle:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return ATan2(y1-y2, x1-x2) End Function Function leftangle:Bool(_angle:Int,_destinationangle:Int) Local cnt1 = 0 Local a1 = _angle While a1<>_destinationangle a1+=1 If a1>180 Then a1=-180 cnt1+=1 Wend If cnt1<180 Then Return True Else Return False End Function Function Main() New MyGame() End Function
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.