Import mojo Class bullet ' bullet x and y and radius Field bx:Float,by:Float,br:Int=4 Field angle:Int Field bulletspeed:Float=3 Field bulletmaxdist:Int=1200 Field bullettraveled:Int Field deleteme:Bool=False ' start location and target location for getting angle Method New(x1:Int,y1:Int,x2:Int,y2:Int) bx = x1 by = y1 angle = getangle(x1,y1,x2,y2) End Method Method update() ' update the bullet position bx += Cos(angle)*bulletspeed by += Sin(angle)*bulletspeed ' if distance to long then flag bullet for removal bullettraveled+=1 If bullettraveled > bulletmaxdist Then deleteme = True ' check collision with zombies For Local i:=Eachin myzombie If circleoverlap(bx,by,br,i.zx,i.zy,i.zr) deleteme = True i.hitpoints-=1 ' Bounce them a bit back i.zx += Cos(angle+Rnd(-20,20))*Rnd(5,13) i.zy += Sin(angle+Rnd(-20,20))*Rnd(5,13) i.flash = True ' If they are dead then flag them If i.hitpoints<=0 Then i.deleteme = True End If End If Next End Method Method draw() SetColor 255,255,0 DrawCircle bx,by,br End Method End Class Class turret ' turret x and y and radius Field tx:Int,ty:Int,tr:Int=16 Field targetx:Int,targety:Int Field deleteme:Bool=False Field shootdelay:Int Field maxshootdelay:Int=10 Field currentangle:Int,shootangle:Int Field notarget:Bool=True Field turnspeed:Int=3 'turn speed of the turret Field shakex:Int,shakey:Int Field shaketime:Int Method New(x:Int,y:Int) tx = x ty = y turnspeed = Rnd(1,10) End Method Method update() shootdelay += 1 ' shooting here ' check if there are zombies on the map If Not myzombie.IsEmpty Local ntx:Int,nty:Int ' New target x And y Local sdist:Int=1000 'shortest distance ' find zombie closest to turret For Local i:=Eachin myzombie Local d:Int=distance(tx,ty,i.zx,i.zy) If d<sdist Then sdist = d ntx = i.zx nty = i.zy End If Next shootangle = getangle(tx,ty,ntx,nty) targetx = ntx targety = nty notarget = False Else notarget = True End If 'if we have a target If notarget = False Then 'turn the turrent to target For Local i:=0 Until turnspeed If currentangle <> shootangle currentangle += turndirection(shootangle) If currentangle>180 Then currentangle = -180 If currentangle<-180 Then currentangle = 180 End If Next ' if we are aimed and reloaded then shoot If shootdelay > maxshootdelay shootdelay = 0 If currentangle = shootangle ' add a shake in the opposite direction ' of the barrel. shakex = -Cos(currentangle)*2 shakey = -Sin(currentangle)*2 shaketime = 4 mybullet.AddLast(New bullet(tx+Cos(shootangle)*16,ty+Sin(shootangle)*16,targetx,targety)) End If End If End If End Method ' returns -1(left) or 1 right to turn towards the closest turn Method turndirection(destangle:Int) Local myangle:Int=currentangle Local d1:Int 'turn left While myangle <> destangle myangle-=1 If myangle<-180 Then myangle = 180 d1+=1 Wend myangle = currentangle Local d2:Int While myangle <> destangle myangle+=1 If myangle>180 Then myangle = -180 d2+=1 Wend If d2>d1 Then Return -1 Else Return 1 End Method Method draw() Local tx:Int = tx+shakex Local ty:Int = ty+shakey shaketime-=1 If shaketime < 0 Then shakex = 0 ; shakey = 0 SetColor 0,255,255 DrawCircle tx,ty,tr Local x2:Int,y2:Int x2 = Cos(currentangle)*20 y2 = Sin(currentangle)*20 DrawCircle tx+x2,ty+y2,10 End Method End Class Class zombie ' zombie x and y and radius Field zx:Float,zy:Float,zr:Int=16 Field tx:Int,ty:Int Field angle:Int Field movementspeed:Float=.5 Field deleteme:Bool=False Field hitpoints:Int Field flash:Bool=False Field flashtime:Int Method New(x:Int,y:Int) zx = x zy = y hitpoints = Rnd(1,4) If Rnd(100)<2 Then hitpoints*=5 movementspeed = Rnd(0.1,0.3) End Method Method update() If Not myturret.IsEmpty Local ntx:Int,nty:Int Local cdist:Int=1000 For Local i:=Eachin myturret Local d:Int=distance(zx,zy,i.tx,i.ty) If d<cdist d = cdist ntx = i.tx nty = i.ty End If Next tx = ntx ty = nty angle = getangle(zx,zy,ntx,nty) End If 'move the zombie zx += Cos(angle) * movementspeed zy += Sin(angle) * movementspeed End Method Method draw() If flash = False SetColor 255,0,0 flashtime = 4 Else SetColor 255,255,255 flashtime -= 1 If flashtime < 0 Then flash = False End If DrawCircle zx,zy,zr End Method End Class Global myturret:List<turret> = New List<turret> Global myzombie:List<zombie> = New List<zombie> Global mybullet:List<bullet> = New List<bullet> Class MyGame Extends App Method OnCreate() Seed = GetDate[4] + GetDate[5] SetUpdateRate(60) myturret.AddLast(New turret(DeviceWidth/2,DeviceHeight/2)) myturret.AddLast(New turret(DeviceWidth/2-50,DeviceHeight/2)) myturret.AddLast(New turret(DeviceWidth/2+50,DeviceHeight/2)) End Method Method OnUpdate() ' If press space then reset level If KeyHit(KEY_SPACE) Or MouseHit(MOUSE_LEFT) Then restart() 'update the turrents zombies and bullets For Local i:=Eachin myturret i.update() Next For Local i:=Eachin myzombie i.update() Next For Local i:=Eachin mybullet i.update() Next ' remove any that are gone For Local i:=Eachin myturret If i.deleteme = True Then myturret.Remove(i) Next For Local i:=Eachin myzombie If i.deleteme = True Then myzombie.Remove(i) Next For Local i:=Eachin mybullet If i.deleteme = True Then mybullet.Remove(i) Next ' add zombies to the map If Rnd(200)<5 Then addzombie(DeviceWidth,DeviceHeight) ' End Method Method OnRender() Cls 0,0,0 For Local i:=Eachin myturret i.draw() Next For Local i:=Eachin myzombie i.draw() Next For Local i:=Eachin mybullet i.draw() Next SetColor 255,255,255 DrawText "Zombies and Turrent - Press Space/Mouse to reset map",0,0 End Method End Class Function restart() myturret = New List<turret> myzombie = New List<zombie> mybullet = New List<bullet> myturret.AddLast(New turret(DeviceWidth/2,DeviceHeight/2)) myturret.AddLast(New turret(DeviceWidth/2-50,DeviceHeight/2)) myturret.AddLast(New turret(DeviceWidth/2+50,DeviceHeight/2)) End Function Function addzombie(Width:Int,Height:Int) Local l:Int=Rnd(4) Local x:Int,y:Int Select l Case 0 x = 0 y = Rnd(Height) Case 1 x = Width y = Rnd(Height) Case 2 x = Rnd(Width) y = 0 Case 3 x = Rnd(Width) y = Height End Select myzombie.AddLast(New zombie(x,y)) End Function Function Main() New MyGame() 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) Local dx = x2 - x1 Local dy = y2 - y1 Return ATan2(dy,dx)+360 Mod 360 End Function Function circleoverlap:Bool(x1:Int,y1:Int,r1:Int,x2:Int,y2:Int,r2:Int) Local dx:Int = x1-x2 Local dy:Int = y1-y2 Local r:Int = r1+r2 If dx*dx+dy*dy <= r*r Then Return True Else Return False End
Artificial intelligence/templates/examples/rts/rpg/strategy ect. in MonkeyX/CerberusX language. You can download the free version of MonkeyX from itch.io or Cerberus-x.com The Flash applets will stop working in around 2020.
Tuesday, August 1, 2017
Monkey-X - Turrets and Zombies - code example
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.