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.
Import mojo Class cloud Field px:Float,py:Float Field pw:Int,ph:Int Field mx:Float Field sw:Int Method New(x:Int,y:Int,w:Int,h:Int,sw:Int) px = x py = y pw = w ph = h Self.sw = sw mx = Rnd(0.05,0.2) End Method Method update() px += mx If px > sw+pw Then px = 0-(pw*2) End Method ' This method draws a cloud/ ' at x,y with width w and height h Method draw() ' Draw 7 plumps (go around in a circle) For Local angle:Int=0 Until 360 Step 360/7 Local x2:Float=Cos(angle)*pw Local y2:Float=Sin(angle)*ph SetColor 0,0,0 DrawOval(x2+px,y2+py,pw,ph) SetColor 255,255,255 DrawOval(x2+px+4,y2+py+4,pw-8,ph-8) Next ' Draw a white oval to erase the center of the cloud SetColor 255,255,255 DrawOval(px-pw/2,py-ph/2,pw+pw,ph+ph) End Method End Class Class MyGame Extends App Field mycloud:List<cloud> = New List<cloud> Method OnCreate() SetUpdateRate(60) Seed = GetDate[4]*GetDate[5] For Local i:Int = 0 Until 15 mycloud.AddLast(New cloud(Rnd(-DeviceWidth*.5,DeviceWidth),Rnd(DeviceHeight),Rnd(30,130),Rnd(20,50),DeviceWidth)) Next End Method Method OnUpdate() For Local i:=Eachin mycloud i.update() Next End Method Method OnRender() Cls 0,0,255 For Local i:=Eachin mycloud i.draw() Next End Method End Class Function Main() New MyGame() End Function
Import mojo Class MyGame Extends App Field x:Int,y:Int Field spacing:Int=10 Field map:Int[][] Method OnCreate() SetUpdateRate(60) map = New Int[100][] For Local i:Int=0 Until 100 map[i] = New Int[100] Next makemaze() End Method Method OnUpdate() If KeyHit(KEY_SPACE) Or MouseHit(MOUSE_LEFT) makemaze() End If End Method Method OnRender() Cls 0,0,0 drawmaze() DrawText "Press Space or Mouse for new maze",0,0 End Method Method drawmaze() For Local y:Int=0 Until 100 For Local x:Int=0 Until 100 Select map[x][y] Case 0 DrawLine x*10,y*10,x*10+10,y*10+10 Case 1 DrawLine x*10+10,y*10,x*10,y*10+10 End Select Next Next End Method Method makemaze() For Local y:Int=0 Until 100 For Local x:Int=0 Until 100 If Rnd(1)<.5 Then map[x][y] = 1 Else map[x][y] = 0 Next Next End Method End Class Function Main() New MyGame() End Function
Import mojo ' ' This is our enemy class ' Class enemy Field px:Int,py:Int Method New(x:Int,y:Int) Self.px = x Self.py = y End Method Method move(x:Int,y:Int) px += x py += y End Method End Class Class MyGame Extends App ' How many enemies are there Field numenemies:Int=10 ' Set up the array using the enemy class Field myenemy:enemy[] Method OnCreate() ' Create the enemies in the array myenemy = New enemy[numenemies] For Local i:Int=0 Until numenemies myenemy[i] = New enemy(Rnd(DeviceWidth()),Rnd(DeviceHeight)) Next End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' Loop through all array containers (numenemies) ' and draw them. For Local i:=Eachin myenemy DrawRect i.px,i.py,32,32 Next ' We can acces arrays directly and call/modify anything inside it. myenemy[0].move(5,0) If myenemy[0].px > DeviceWidth Then myenemy[0].px = -10 End Method End Class Function Main() New MyGame() End Function
Import mojo Class MyGame Extends App Field enemyx:Int,enemyy:Int Field startx:Int=100,starty:Int=100 Field destx:Int=320,desty:Int=230 Field percentage:Float=0 ' how far in the path are we Field stp:Float=0.01 ' how fast do we move Method OnCreate() SetUpdateRate(60) ' Fps enemyx = startx enemyy = starty End Method Method OnUpdate() ' Get our new x and y position enemyx = lerp(percentage,startx,destx) enemyy = lerp(percentage,starty,desty) ' Set the new position percentage+=stp ' Keep inside the value of 0.0 and 1.0 If percentage<=0 Or percentage>=1 Then stp=-stp End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' Draw the enemy sprite DrawRect enemyx,enemyy,32,32 ' DrawText "Lerp(Linear Interpolation) Patrolling - example",0,0 End Method ' Percentage 0 to 1 returns number between a and b Function lerp:Int(t:Float , a:Float, b:Float) Return a + t * (b - a) End Function End Class Function Main() New MyGame() End Function
Import mojo Class tree Field px:Int,py:Int Field pw:Float,ph:Float Field mapone:Int[][] Field treecolor1:Int=Rnd(230,255) Field treecolor1r:Int=Rnd(50,200) Field treecolor2:Int=Rnd(190,220) Field treecolor3:Int=Rnd(130,180) Field treecolor4:Int=Rnd(70,120) Field basecolor1:Int=150 Field basecolor2:Int=190 Field basecolor3:Int=220 Method New(x:Int,y:Int,w:Int,h:Int) If Rnd(3)<2 Then treecolor1r = 0 px = x py = y pw = w ph = h mapone = New Int[w][] For Local i:Int=0 Until w mapone[i] = New Int[h] Next maketree() End Method Method maketree() Local mx:Float=0.05 Local my:Float=.1 Local y:Float=1 Local x:Float=pw/2+1 Local base:Float=0 Local bounce:Float=.1 Local col:Int Local num:Float=2 Local stap:Float=Rnd(0.001,0.005) Local stap2:Float=Rnd(0.01,0.2) Local stap3:Float=Rnd(0.5,1.5) ' Place two black pixels at the top of the tree mapone[x-1][0] = 1 mapone[x-2][0] = 1 ' create the tree While (y+5)<=(ph-(ph/20)) y+=my x+=mx ' stay inside the image If x>=pw Then x=pw-2 If x<=0 Then x=0 ' change color of the tree depending ' on the current y location If y<ph/1.4 Then col = treecolor4 If y<ph/1.6 Then col = treecolor3 If y<ph/1.9 Then col = treecolor2 If y<ph/4 Then col = treecolor1 ' fill the current line filltoleft(x,y,pw-x,col) ' black pixel to the left and right mapone[x][y] = 1 mapone[pw-x][y] = 1 ' next step in the tree shape mx-=stap If y<ph/1.45 Then If mx<0 If x < ((pw/2)+num) Then mx=bounce ; bounce+=stap2 ; num+=stap3 End If Else If mx<0 If x<((pw/2)+num) Then bounce=.1 ; mx=bounce ; num-=stap3 Endif End If Wend ' Make sure the bottom of the tree is also drawn filltoleft(x,y,pw-x,1) ' Make the tree trunk maketreebase() End Method ' ' Fill from x to tox on y line using col(or) ' We go from right to left and fill the line with ' a number. (tree inside color) ' Method filltoleft(x:Int,y:Int,tox:Int,col:Int) Local ls:Int=(pw/2) Local len1:Int=(x-ls)/2 Local len2:Int=(x-ls)/1.7 For Local x2:Int=x To tox Step -1 mapone[x2][y] = col If col = treecolor2 Then If Rnd(4) < 1 And distance(x2,0,tox,0) < len1 And y<ph/2 Then mapone[x2][y] = treecolor1 If Rnd(4) < 1 And distance(x2,0,x,0)< len1 And y<ph/2 Then mapone[x2][y] = treecolor1 If Rnd(2)<1.3 And distance(x2,0,ls-len1,0) < 2 And y<ph/2 Then mapone[x2][y] = treecolor1 If Rnd(2)<1.3 And distance(x2,0,ls+len1,0) < 2 And y<ph/2 Then mapone[x2][y] = treecolor1 End If If col=treecolor1 If Rnd(2) < 1 And y>5 And distance(x2,0,ls,0) < 3 Then mapone[x2][y] = treecolor2 End If If col=treecolor3 If Rnd(2)<1.3 And distance(x2,0,ls,0) < len2 And y<ph/1.8 Then mapone[x2][y] = treecolor2 End If If col=treecolor4 If Rnd(2)<1.3 And distance(x2,0,ls,0) < len2 And y<ph/1.45 Then mapone[x2][y] = treecolor3 End If Next End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function Method maketreebase() ' treebase For Local y:Int=ph-(ph/5) Until ph For Local x:Int=(pw/2)-(pw/8) Until (pw/2)+(pw/8) If x<0 Or y<0 Or x>=pw Or y>= ph Then Continue mapone[x][y] = basecolor1 If x=(pw/2)-(pw/8) Then mapone[x][y] = 1 If x=(pw/2)+(pw/8)-1 Then mapone[x][y]=1 If y=ph-1 Then mapone[x][y]=1 Next Next For Local y:Int=ph-(ph/5) Until ph-(ph/5) For Local x:Int=(pw/2)-(pw/8) Until (pw/2)+(pw/8) If x<0 Or y<0 Or x>=pw Or y>= ph Then Continue mapone[x][y] = 1 Next Next ' tree base center lighting For Local y:Int=ph-(ph/7) Until ph-1 For Local x:Int=(pw/2)-(pw/30) Until (pw/2)+(pw/30) If x<0 Or y<0 Or x>=pw Or y>= ph Then Continue mapone[x][y] = basecolor3 Next Next For Local y:Int=ph-(ph/7) Until ph-1 For Local x:Int=(pw/2) Until (pw/2)+(pw/30) If x<0 Or y<0 Or x>=pw Or y>= ph Then Continue mapone[x][y] = basecolor2 Next Next 'Remove two black pixels from the bottom of the treebase mapone[(pw/2)-(pw/8)][ph-1] = 0 mapone[(pw/2)+(pw/8)-1][ph-1] = 0 End Method Method draw() For Local y:Int=0 Until ph For Local x:Int=0 Until pw If mapone[x][y] = 0 Then Continue Select mapone[x][y] Case 1 SetColor 0,0,0 Case treecolor1 SetColor treecolor1r/2,treecolor1,0 Case treecolor2 SetColor treecolor1r/1.5,treecolor2,0 Case treecolor3 SetColor treecolor1r/1.2,treecolor3,0 Case treecolor4 SetColor treecolor1r,treecolor4,0 Case basecolor1 SetColor basecolor1,basecolor1/2,0 Case basecolor2 SetColor basecolor2,basecolor2/2,0 Case basecolor3 SetColor basecolor3,basecolor3/2,0 End Select DrawRect px+(x*1),py+(y*1),1,1 Next Next End Method End Class Class MyGame Extends App Field mytree:List<tree> Field time:Int=Millisecs() Field hw:Int=48,hh:Int=64 Method OnCreate() Seed = GetDate[4]*GetDate[5] SetUpdateRate(1) maketrees() End Method Method OnUpdate() If KeyHit(KEY_SPACE) Or Millisecs() > time time=Millisecs()+2000 maketrees End If End Method Method OnRender() Cls 0,0,0 SetColor 50,125,235 DrawRect 0,0,DeviceWidth,150+hh SetColor 50,155,255 DrawRect 0,100,DeviceWidth,(150+hh)-100 SetColor 5,250,5 DrawRect 0,150+hh,DeviceWidth,DeviceHeight-(150+hh) SetColor 125,250,125 DrawRect 0,150+hh,DeviceWidth,2 For Local i:=Eachin mytree i.draw() Next End Method Method maketrees() mytree = New List<tree> For Local x:Int=0 Until DeviceWidth Step 64 If Rnd(3)<2 Then mytree.AddLast(New tree(x,150,48,64)) Next Local sy:Int=0 For Local i:Int=0 Until 35 mytree.AddLast(New tree(Rnd(DeviceWidth),150+sy,48,64)) sy+=8 Next End Method End Class Function Main() New MyGame() End Function
Import mojo Class building Field px:Int,py:Int Field totalwidth:Int Field blockhouse:Int=1 Field blockdoor:Int=2 ' For collision (enter/flee in home/shop) Field doorx:Int,doory:Int Field doorwidth:Int,doorheight:Int Field blocksmallwindow:Int=3 Field blockwidewindow:Int=4 Field blockcrateleft:Int=5 Field blockcrateright:Int=6 Field blockiceboxleft:Int=7 Field blockiceboxright:Int=7 Field blocktoiletleft:Int=8 Field blocktoiletright:Int=9 Field blockfrontcrate:Int=10 Field blockrooftop:Int=11 Field blockchimney:Int=12 Field blockshopsign:Int=13 Field houselayer:Int[]=New Int[3] 'base blocks Field rooftoplayer:Int[]=New Int[3] Field chimneylayer:Int[]=New Int[3] Field doorlayer:Int[] = New Int[3] Field windowlayer:Int[] = New Int[3] '011010' Field housesidelayer:Int[] = New Int[2] Field shopsignlayer:Int[] = New Int[3] Field frontlayer:Int[] = New Int[6] Method New(x:Int,y:Int,w:Int,isshop:Bool) px = x py = y totalwidth = w makehouse(w,isshop) End Method Method makehouse(w:Int,isshop:Bool) ' Make the base house blocks For Local i:Int=0 Until w houselayer[i] = blockhouse Next ' Create the items at the side of the houses If Rnd(10)<5 ' add to which side(s) Local sides:String="left" If Rnd(10)<3 Then sides="right" If Rnd(10)<3 Then sides="both" ' Add items to side(s) If sides="left" Or sides="both" Then housesidelayer[0] = blocktoiletleft If Rnd(10)<3 Then housesidelayer[0] = blockcrateleft End If If Rnd(10)<3 Then housesidelayer[0] = blockiceboxleft End If Endif If sides="right" Or sides="both" Then housesidelayer[1] = blocktoiletright If Rnd(10)<3 Then housesidelayer[1] = blockcrateright End If If Rnd(10)<3 Then housesidelayer[1] = blockiceboxright End If Endif End If 'Create the crates at the front of the house For Local i:Int= 0 Until (w*2)-2 If Rnd(10)<2 Then frontlayer[i] = blockfrontcrate End If Next 'Create windows Select w Case 2 windowlayer[0] = blocksmallwindow Case 3 windowlayer[0] = blockwidewindow End Select ' create door Select w Case 1 doorlayer[0] = blockdoor If isshop Then shopsignlayer[0] = blockshopsign Case 2 doorlayer[1] = blockdoor If isshop Then shopsignlayer[1] = blockshopsign Case 3 doorlayer[2] = blockdoor If isshop Then shopsignlayer[2] = blockshopsign End Select ' rooftop Select w Case 1 rooftoplayer[0] = blockrooftop Case 2 rooftoplayer[0] = blockrooftop rooftoplayer[1] = blockrooftop Case 3 rooftoplayer[0] = blockrooftop rooftoplayer[1] = blockrooftop rooftoplayer[2] = blockrooftop End Select ' chimney Select w Case 1 chimneylayer[0] = blockchimney Case 2 chimneylayer[Rnd(0,2)] = blockchimney Case 3 chimneylayer[Rnd(0,3)] = blockchimney End Select End Method Method draw(w:Int,h:Int) Local bw:Int=w Local bh:Int=h ' Draw the house blocks For Local i:Int=0 Until 3 If houselayer[i] = blockhouse Then SetColor 150,140,150 DrawRect px+(i*bw),py,bw+1,bh SetColor 200,200,200 DrawRect px+(i*bw),py,bw,bh 'SetColor 230,230,230 'shadow top SetColor 60,60,60 DrawRect px+(i*bw),py,bw,bh/15 'shadow bottom SetColor 150,150,150 DrawRect px+(i*bw),py+bh/1.1,bw,bh/8 'highlight left If i=0 SetColor 220,220,220 DrawRect px+(i*bw),py,1,bh/3 Endif End If Next ' Draw the rooftop For Local i:Int=0 Until 3 If rooftoplayer[i] = blockrooftop Then 'SetColor 200,100,100 SetColor 170,70,60 DrawRect px+(i*bw),py-(bh/1.5),bw,bh-(bh/3) ' Bottom shade SetColor 130,50,30 'SetColor 200,100,100 DrawRect px+(i*bw),py-(bh/8),bw,bh/8 ' top shade SetColor 190,90,80 DrawRect px+(i*bw),py-(bh/1.5),bw,1 ' top shade If i=0 'horizontal SetColor 220,120,110 DrawRect px+(i*bw),py-(bh/1.5),bw/2,1 'vertical SetColor 200,100,100 DrawRect px+(i*bw),py-(bh/1.5),1,bh/3 End If End If Next ' Draw the chimney For Local i:Int=0 Until 3 If chimneylayer[i] = blockchimney Then SetColor 100,100,100 DrawRect px+(i*bw)+(bw/4),py-(bh/1.2),bw/2.5,bh/4 'chimney highlight SetColor 140,130,120 DrawRect px+(i*bw)+(bw/4),py-(bh/1.2),bw/6,1 End If Next 'Draw the windows For Local i:Int=0 Until 3 If windowlayer[i] = blocksmallwindow SetColor 0,100,200 DrawRect px+(i*bw)+(bw/3),py+(bh/5),bw-(bw/3),bh-(bh/2.5) ' light bottom SetColor 0,115,210 DrawRect px+(i*bw)+(bw/3),py+(bh/2),bw-(bw/3),(bh/3.3) ' dark bottom SetColor 180,125,20 DrawRect px+(i*bw)+(bw/3),py+(bh*.7),bw-(bw/3),(bh/8.3) End If If windowlayer[i] = blockwidewindow SetColor 0,100,200 DrawRect px+(i*bw)+(bw/3),py+(bh/5),(bw*2)-(bw/3),bh-(bh/2.5) 'light bottom SetColor 0,115,210 DrawRect px+(i*bw)+(bw/3),py+(bh/2),(bw*2)-(bw/3),(bh/3.3) 'dark bottom SetColor 180,125,20 DrawRect px+(i*bw)+(bw/3),py+(bh*.7),(bw*2)-(bw/3),(bh/8.3) End If Next ' Draw the door For Local i:Int=0 Until 3 If doorlayer[i] = blockdoor SetColor 100,50,50 If shopsignlayer[i] = blockshopsign SetColor 250,200,50 End If DrawRect px+(i*bw)+(bw/5),py+(bh/5),bw-(bw/2),bh-(bh/4) ' doorknob SetColor 200,210,210 DrawRect px+(i*bw)+(bw/2),py+(bh/1.7),(bw/9),(bh/9) 'numberplate SetColor 200,250,250 DrawRect px+(i*bw)+(bw/1.3),py+(bh/3),(bw/9),(bh/9) SetColor 10,50,50 DrawRect px+(i*bw)+(bw/1.25),py+(bh/2.8),(bw/18),(bh/14) End If Next ' Draw the sides If housesidelayer[0] = blocktoiletleft Then drawtoilet(px,py,bw,bh,"left") If housesidelayer[1] = blocktoiletright Then drawtoilet(px,py,bw,bh,"right") If housesidelayer[0] = blockcrateleft Then drawsidecrate(px,py,bw,bh,"left") If housesidelayer[1] = blockcrateright Then drawsidecrate(px,py,bw,bh,"right") If housesidelayer[0] = blockiceboxleft Then drawsideicebox(px,py,bw,bh,"left") If housesidelayer[1] = blockiceboxright Then drawsideicebox(px,py,bw,bh,"right") 'Draw the crates at the front of the house For Local i:Int=0 Until (totalwidth*2)-2 If frontlayer[i] = blockfrontcrate SetColor 100,50,50 DrawRect px+((bw/2)*i),py+bh/1.2,bw/4,bh/6.4 End If Next 'Draw the shop sign For Local i:Int=0 Until totalwidth If shopsignlayer[i] = blockshopsign SetColor 255,40,30 Local x:Int=px+(bw*i)-bw/8 Local y:Int=py-bh/5 DrawRect x,y,bw*1.2,bh/3 SetColor 255,255,255 'DrawText "Shop X",x+5,y+5 DrawRect x+bh/10,y+bh/12,4,4 End If Next End Method Method drawtoilet(x:Int,y:Int,w:Int,h:Int,side:String) If side = "left" Local ltx:Float=x-w/2 Local lty:Float=y+(h/4) Local rtx:Float=ltx+(w/2) Local rty:Float=lty Local lbx:Float=ltx Local lby:Float=lty+(h-h/4) Local rbx:Float=ltx+(w/2) Local rby:Float=lby Local toil:Float[8] toil[0] = ltx toil[1] = lty-(h/6) toil[2] = rtx toil[3] = rty toil[4] = rbx toil[5] = rby toil[6] = lbx toil[7] = lby SetColor 150,50,50 DrawPoly(toil) 'DrawRect x-w/2,y+10,w/2,h-10 Elseif side="right" Local ltx:Float=(x)+(totalwidth*w) Local lty:Float=y+(h/4) Local rtx:Float=ltx+(w/2) Local rty:Float=lty Local rbx:Float=ltx+(w/2) Local rby:Float=rty+(h-h/4) Local lbx:Float=ltx Local lby:Float=rby SetColor 150,50,50 Local box:Float[8] box[0] = ltx box[1] = lty box[2] = rtx box[3] = rty-(h/6) box[4] = rbx box[5] = rby box[6] = lbx box[7] = lby DrawPoly(box) ' SetColor 100,50,50 ' DrawRect (x)+totalwidth*w,y+10,w/2,h-10 End If End Method Method drawsidecrate(x:Int,y:Int,w:Int,h:Int,side:String) If side = "left" ' pipe SetColor 120,120,120 DrawRect x-w/8,y,w/8,h 'barrel SetColor 100,50,50 DrawRect x-w/3,y+(h/1.5),w/3,h-(h/1.5) Elseif side="right" 'pipe SetColor 120,120,120 DrawRect (x)+totalwidth*w,y,w/8,h 'barrel SetColor 100,50,50 DrawRect (x)+totalwidth*w,y+(h/1.5),w/3,h-(h/1.5) End If End Method Method drawsideicebox(x:Int,y:Int,w:Int,h:Int,side:String) If side = "left" Local ltx:Float=x-w/2 Local lty:Float=y+(h/1.5) Local rtx:Float=ltx+(w/2) Local rty:Float=lty Local lbx:Float=ltx Local lby:Float=lty+(h-h/1.5) Local rbx:Float=ltx+(w/2) Local rby:Float=lby SetColor 200,200,200 Local box:Float[8] box[0] = ltx box[1] = lty+(h/6) box[2] = rtx box[3] = rty box[4] = rbx box[5] = rby box[6] = lbx box[7] = lby 'DrawRect ltx,lty,w/2,h-(h/1.5) DrawPoly(box) Elseif side="right" Local ltx:Float=(x)+(totalwidth*w) Local lty:Float=y+(h/1.5) Local rtx:Float=ltx+(w/2) Local rty:Float=lty Local rbx:Float=ltx+(w/2) Local rby:Float=rty+(h-h/1.5) Local lbx:Float=ltx Local lby:Float=rby SetColor 200,200,200 Local box:Float[8] box[0] = ltx box[1] = lty box[2] = rtx box[3] = rty+h/6 box[4] = rbx box[5] = rby box[6] = lbx box[7] = lby DrawPoly(box) 'DrawRect (x)+totalwidth*w,y+(h/1.5),w/2,h-(h/1.5) End If End Method End Class Class MyGame Extends App Field mybuilding:List<building> Field time:Int=Millisecs() Field hw:Int=48,hh:Int=64 Method OnCreate() Seed = GetDate[4]*GetDate[5] SetUpdateRate(2) makehouses() End Method Method OnUpdate() If KeyHit(KEY_SPACE) Or Millisecs() > time time=Millisecs()+2000 makehouses End If End Method Method OnRender() Cls 0,0,0 SetColor 50,155,255 DrawRect 0,0,DeviceWidth,150+hh SetColor 50,125,235 DrawRect 0,100,DeviceWidth,(150+hh)-100 SetColor 5,250,5 DrawRect 0,150+hh,DeviceWidth,DeviceHeight-(150+hh) SetColor 125,250,125 DrawRect 0,150+hh,DeviceWidth,2 For Local i:=Eachin mybuilding i.draw(hw,hh) Next End Method Method makehouses() mybuilding = New List<building> hw = Rnd(20,50) hh = hw Local st:Int=hw*4 Local x:Int=0 While x<DeviceWidth Local z1:Bool If Rnd(5)<1 Then z1 = True Local w:Int = Rnd(1,4) st = hw*(w+2) ' mybuilding = New building(x,150,Rnd(1,4),z1) mybuilding.AddLast(New building(x,150,w,z1)) x+=st Wend End Method End Class Function Main() New MyGame() End Function
' Based somewhat on http://www.squidi.net/three/entry.php?id=164 Import mojo Class map Field sw:Int,sh:Int Field tw:Float,th:Float Field mw:Int,mh:Int Field map:Int[][] Field grassmap:Int[][] Field bridgemap:Int[][] Field tileroad:Int=999 Field numzones:Int Method New(sw:Int,sh:Int,mw:Int,mh:Int,numzones:Int) Self.numzones = numzones Self.sw = sw Self.sh = sh Self.mw = mw Self.mh = mh Self.tw = Float(sw) / Float(mw) Self.th = Float(sh) / Float(mh) map = New Int[mw][] grassmap = New Int[mw][] bridgemap = New Int[mw][] For Local i:Int=0 Until mw map[i] = New Int[mh] grassmap[i] = New Int[mh] bridgemap[i] = New Int[mh] Next createmap() End Method Method createmap() 'Create a number of zones (area's) For Local zone:Int=0 Until numzones map[Rnd(mw)][Rnd(mh)] = zone+1 Next 'Grow the zones Local cangrow:Bool=True Local mx:Int[]=[-1,0,1,0] Local my:Int[]=[-1,0,0,1] While cangrow=True Local x:Int=Rnd(mw) Local y:Int=Rnd(mh) If map[x][y] > 0 Local tile:Int=map[x][y] For Local i:Int=0 Until mx.Length Local x2:Int=mx[i]+x Local y2:Int=my[i]+y If x2<0 Or y2<0 Or x2>=mw Or y2>=mh Then Continue If Rnd(10)<2 And map[x2][y2] = 0 map[x2][y2] = tile End If Next End If ' Every now and then check if every spot is taken If Rnd(mw)<mw/10 cangrow = False For Local y2:Int=0 Until mh For Local x2:Int=0 Until mw If map[x2][y2] = 0 Then cangrow = True;Exit Next Next End If Wend ' Create the roads For Local y:Int=0 Until mh For Local x:Int=0 Until mw Local t:Int=map[x][y] If x+1 < mw And map[x+1][y] <> t And grassmap[x+1][y] = 0 Then grassmap[x][y] = 1 If y+1 < mh And map[x][y+1] <> t And grassmap[x][y+1] = 0 Then grassmap[x][y] = 1 If x+1 < mw And y+1 < mh And map[x+1][y+1] <> t And grassmap[x+1][y+1] = 0 Then grassmap[x][y] = 1 Next Next 'create the bridges For Local y:Int=0 Until mh For Local x:Int=0 Until mw If grassmap[x][y] <> 1 Then Continue Local cnt:Int=0 For Local y2:Int=y-1 To y+1 For Local x2:Int=x-1 To x+1 If x2<0 Or y2<0 Or x2>=mw Or y2>=mh Then Continue If map[x2][y2] >= numzones/3 Then cnt+=1 Next Next If cnt=0 Then bridgemap[x][y] = 1 Next Next End Method Method draw() ' map pass 1 For Local y:Int=0 Until mh For Local x:Int=0 Until mw If map[x][y] = 0 Then Continue Local x2:Int = x*tw Local y2:Int = y*th If map[x][y] < numzones/3 Or map[x][y] = 1 Then ' water SetColor 44,140,200 DrawRect x2,y2,tw+1,th+1 SetColor 46,165,225 DrawOval x2+tw/3,y2+th/5,tw/4,th/2 SetColor 56,195,255 DrawOval x2+tw/3,y2+th/4,tw/5,th/7 Else 'grass SetColor 160,200,105 DrawRect x2,y2,tw+1,th+1 'treebase dark SetColor 10,45,0 DrawOval x2+tw/3,y2+th/2,tw/2,th/1.5 'treebase light SetColor 200,55,0 DrawOval x2+tw/2.2,y2+th/2,tw/4,th/1.5 ' tree top dark SetColor 0,55,0 DrawOval x2+tw/8,y2+th/10,tw/1.1,th/1.3 ' tree top SetColor 0,190,0 DrawOval x2+tw/8+1,y2+th/10,tw/1.2-2,th/1.3 ' highlight top SetColor 200,255,200 DrawOval x2+tw/4+1,y2+th/5,tw/3,th/3 End If Next Next 'grass For Local y:Int=0 Until mh For Local x:Int=0 Until mw If grassmap[x][y] = 0 Then Continue Local x2:Int = x*tw Local y2:Int = y*th SetColor 80,230,20 DrawRect x2,y2,tw+1,th+1 Next Next 'bridges For Local y:Int=0 Until mh For Local x:Int=0 Until mw If bridgemap[x][y] = 0 Then Continue Local x2:Int = x*tw Local y2:Int = y*th SetColor 150,120,15 DrawRect x2,y2,tw+1,th+1 'plank SetColor 200,170,20 DrawRect x2+tw/10,y2,tw/3,th+1 DrawRect x2+tw/1.8,y2,tw/3,th+1 'plank shadow and light SetColor 240,200,200 DrawRect x2+tw/10,y2,1,th+1 DrawRect x2+tw/1.8,y2,1,th+1 SetColor 0,0,0 DrawRect x2+tw/10+tw/3,y2,1,th+1 DrawRect x2+tw/1.8+tw/3,y2,1,th+1 Next Next ' map pass 2 (shadow under trees/grass and highlight up water) For Local y:Int=1 Until mh For Local x:Int=0 Until mw If map[x][y] = 0 Then Continue Local x2:Int = x*tw Local y2:Int = y*th 'shadow under trees If grassmap[x][y] = 1 And grassmap[x][y-1] = 0 And map[x][y] > numzones/3 SetColor 40,160,30 DrawRect x2+tw/4,y2,tw-th/2,th/3 End If 'shadow under water If grassmap[x][y] = 0 And grassmap[x][y-1] = 1 And map[x][y] < numzones/3 SetColor 0,0,0 DrawRect x2,y2,tw+1,th/8 End If Next Next End Method End Class Class MyGame Extends App Field refresh:Int Field mymap:map Field plumps Method OnCreate() SetUpdateRate(1) Seed = GetDate[4] * GetDate[5] Local s:Int=Rnd(30,100) If s<40 Then plumps = s/1.5 Else plumps = s*2 mymap = New map(DeviceWidth,DeviceHeight,s,s,plumps) refresh = Millisecs()+3000 End Method Method OnUpdate() If Millisecs() > refresh Local s:Float=Rnd(30,100) If Rnd(10)<8 Then s = Rnd(20,40) If s<40 Then plumps = s/1.5 Else plumps = s*2 mymap = New map(DeviceWidth,DeviceHeight,s,s,plumps) refresh = Millisecs()+3000 End If End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 mymap.draw() End Method End Class Function Main() New MyGame() End Function
Import mojo Class tile Field width:Int,height:Int Field map:Int[][] Field map2:Int[][] Method New(w:Int,h:Int) Self.width = w Self.height = h map = New Int[width][] map2 = New Int[width][] For Local i:Int=0 Until width map[i] = New Int[height] map2[i] = New Int[height] Next End Method ' Here we create the flasks or bottles ' or what else. Method generate() Local x:Float=width/2 Local y:Float=height/4 Local angle:Int=0 While angle<200 angle+=Rnd(1,10) For Local i:Int=0 Until 5 x+=Cos(angle)*.2 y+=Sin(angle)*.2 If x>=width Then x=width-1 If x<=0 Then x=1 If y>=height Then y=height-1 If y<=0 Then y=1 map[x][y] = 1 fillleftside(x-1,y) Next Wend clearleftside() mirrorrightside() shaderightside() shadecenter() createbottlelight() bottletop End Method Method bottletop() Local x:Float=width/2 Local y:Float=2 Local angle:Int=0 While angle<200 angle+=Rnd(5,20) For Local i:Int=0 Until 5 x+=Cos(angle)*.2 y+=Sin(angle)*.2 If x>=width Then x=width-1 If x<=0 Then x=1 If y>=height Then y=height-1 If y<=0 Then y=1 map2[x][y] = 1 fillleftsidetop(x-1,y) Next Wend clearleftsidetop() mirrorrightsidetop() addbottleceiling() darkshadebottletop() bottletopbottomshade() mergebottletop End Method Method bottletopbottomshade() Local b:Int=0 'bottom y of bottletop Local t:Int=0 'start y of bottletop While map2[width/2][t] = 0 t+=1 Wend b=t While map2[width/2][b] <> 0 b+=1 Wend For Local y:Int=b Until b-3 Step -1 For Local x:Int=0 Until width If map2[x][y] = 1 Then map2[x][y+1] = 4 Next Next End Method Method darkshadebottletop() Local b:Int=0 'bottom y of bottletop Local t:Int=0 'start y of bottletop While map2[width/2][t] = 0 t+=1 Wend b=t While map2[width/2][b] <> 0 b+=1 Wend For Local x:Int=0 Until width For Local y:Int=t+3 Until b If map2[x][y] = 6 Then map2[x][y] = 7 Next Next End Method Method addbottleceiling() For Local y:Int=1 Until height-1 For Local x:Int=0 Until width If map2[x][y+1] = 5 And map2[x][y] = 0 Then map2[x][y] = 1 ; map2[x][y+1] = 6 Next Next End Method Method fillleftsidetop(fx:Int,fy:Int) For Local x:Int=fx Until 0 Step -1 map2[x][fy] = 5 Next map2[fx][fy] = 6 End Method Method mirrorrightsidetop() For Local y:Int=0 Until height For Local x:Int=0 Until width/2 map2[x][y] = map2[width-1-x][y] Next Next End Method Method clearleftsidetop() For Local y:Int=0 Until height For Local x:Int=0 Until width/2 map2[x][y] = 0 Next Next End Method Method mergebottletop() For Local y:Int=0 Until height For Local x:Int=0 Until width If map2[x][y] > 0 map[x][y] = map2[x][y] End If Next Next End Method Method createbottlelight() For Local y:Int=height-height/2 Until height/2-height/4 Step -1 For Local x:Int=width/2 Until width If map[x][y] = 1 Then map[x-5][y+5] = 1 End If Next Next End Method Method shadecenter() Local sw:Int=0 For Local y:Int=height/1.7 Until height For Local x:Int=0 Until width If map[x][y] = 2 If x Mod 2 = sw map[x][y] = 4 End If End If Next If sw=1 Then sw=0 Else sw=1 Next End Method Method shaderightside() For Local y:Int=0 Until height For Local x:Int=0 Until width If x<width/2 If map[x][y] = 3 Then map[x][y] = 4 End If Next Next End Method Method mirrorrightside() For Local y:Int=0 Until height For Local x:Int=0 Until width/2 map[x][y] = map[width-1-x][y] Next Next End Method Method clearleftside() For Local y:Int=0 Until height For Local x:Int=0 Until width/2 map[x][y] = 0 Next Next End Method ' here we put the value of ' 2 inside the map from inputted ' coords to most left position Method fillleftside(fx:Int,fy:Int) For Local x:Int=fx Until 0 Step -1 map[x][fy] = 2 Next map[fx][fy] = 3 End Method Method draw(sx:Int,sy:Int,tw:Int,th:Int,r:Int,g:Int,b:Int) Local x:Int Local y:Int ' For Local y:Int=0 Until height ' SetColor ((255/height)*y)/2,100,100 ' DrawRect 0+sx,y+sy,width,1 ' Next For y=0 Until height For x=0 Until width Local t:Int=map[x][y] Local x2:Int=x*tw Local y2:Int=y*th x2+=sx y2+=sy If t = 1 Then 'white outline SetColor 170,170,170 End If ' bottle color 2 = main 3 is light 4 is dark If t = 2 Then 'SetColor 255,0,0 SetColor r,g,b Elseif t = 3 Then 'light Local r2:Int=r+r/6 Local g2:Int=g+g/6 Local b2:Int=b+b/6 If r2>255 Then r2=255 If g2>255 Then g2=255 If b2>255 Then b2=255 'SetColor 255,150,150 SetColor r2,g2,b2 Elseif t = 4 Then 'dark 'SetColor 200,0,0 Local r2:Int=r-r/4 Local g2:Int=g-g/4 Local b2:Int=b-b/4 If r2<0 Then r2=0 If g2<0 Then g2=0 If b2<0 Then b2=0 SetColor r2,g2,b2 End If If t = 5 'bottle top color 6 is light 7 is dark SetColor 155,100,0 Elseif t=6 SetColor 200,120,0 Elseif t=7 SetColor 100,70,0 End If If t>0 DrawRect x2,y2,tw,th End If Next Next End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class Class MyGame Extends App Field mytile:tile Method OnCreate() Seed = GetDate[4]*GetDate[5] SetUpdateRate(1) mytile = New tile(32,32) mytile.generate() End Method Method OnUpdate() End Method Method OnRender() Cls 110,110,110 For Local y:Int=0 Until DeviceHeight() Step 40 For Local x:Int=0 Until DeviceWidth() Step 40 mytile = New tile(32,32) mytile.generate() Local r:Int=Rnd(0,255) Local g:Int=Rnd(0,255) Local b:Int=Rnd(0,255) mytile.draw(x,y,1,1,r,g,b) Next Next End Method End Class Function Main() New MyGame() End Function
Import mojo Global mapwidth:Int=200 Global mapheight:Int=100 ' ' This is a growing slime entity. ' ' Class growslime Field map:Int[][] Field w:Float,h:Float Field tw:Float,th:Float Field openx:Stack<Int> Field openy:Stack<Int> Field slimetile:Int=10 Field slimestartx:Int,slimestarty:Int Method New() w = mymaptest.w * 2 h = mymaptest.h * 2 tw = 640 / w th = 480 / h map = New Int[w][] For Local i:Int=0 Until w map[i] = New Int[h] Next 'copy the map from the game into this map For Local y:Int=0 Until mymaptest.h For Local x:Int=0 Until mymaptest.w For Local y2:Int=0 Until 2 For Local x2:Int=0 Until 2 map[(x*2)+x2][(y*2)+y2] = mymaptest.map[x][y] Next Next Next Next 'create the active slime list openx = New Stack<Int> openy = New Stack<Int> findslimestartpos() openx.Push(slimestartx) openy.Push(slimestarty) map[slimestartx][slimestarty]=slimetile End Method Method findslimestartpos() For Local y:Int=h-1 To 0 Step -1 For Local x:Int=0 Until w If map[x][y] = 1 Then slimestartx = x slimestarty = y Return End If Next Next End Method Method update(speed:String) Local freq:Int If speed = "slow" Then freq = 120 Else freq = 20 ' Expand Slime For Local i:Int=0 Until openx.Length If Rnd(freq) > 2 Then Continue Local x2:Int=openx.Get(i) Local y2:Int=openy.Get(i) 'bottom bleft or bright first Local r:Int=Rnd(0,6) If r=0 And y2+1<h And map[x2][y2+1] = 1 Then addslime(x2,y2+1) ; Continue If r=1 And x2-1 >=0 And y2+1 <h And map[x2-1][y2+1] = 1 Then addslime(x2-1,y2+1) ; Continue If r=2 And y2+1<h And map[x2+1][y2+1] = 1 Then addslime(x2+1,y2+1) ; Continue ' left Or right Then r = Rnd(0,2) If r=0 And x2-1>=0 And map[x2-1][y2] = 1 Then addslime(x2-1,y2) ; Continue If r=1 And x2+1<w And map[x2+1][y2] = 1 Then addslime(x2+1,y2) ; Continue ' up lup and rup r = Rnd(0,23) If r=0 And y2-1>=0 And map[x2][y2-1] = 1 Then addslime(x2,y2-1);Continue If r=1 And x2-1>=0 And y2-1>=0 And map[x2-1][y2-1] = 1 Then addslime(x2-1,y2-1);Continue If r=2 And x2+1<w And y2-1>=0 And map[x2+1][y2-1] = 1 Then addslime(x2+1,y2-1);Continue Next ' Remove Obsolete slime For Local i:Int=0 Until openx.Length Local cnt:Int=0 For Local y:Int=-1 To 1 For Local x:Int=-1 To 1 Local x2:Int=openx.Get(i)+x Local y2:Int=openy.Get(i)+y If x2<0 Or y2<0 Or x2>=w Or y2>=h Then cnt+=1 Continue End If If map[x2][y2] = slimetile Then cnt+=1 Next Next If cnt=9 Then openx.Remove(i) openy.Remove(i) End If Next End Method Method addslime(sx:Int,sy:Int) openx.Push(sx) openy.Push(sy) map[sx][sy] = slimetile End Method Method update_vine(speed:String) Local freq:Int If speed = "slow" Then freq = 200 Else freq = 20 ' Expand Slime For Local i:Int=0 Until openx.Length For Local y:Int=-1 To 1 For Local x:Int=-1 To 1 If Rnd(freq)>2 Then Continue Local x2:Int=openx.Get(i)+x Local y2:Int=openy.Get(i)+y If x2<0 Or y2<0 Or x2>=w Or y2>=h Then Continue If map[x2][y2] = 1 Then openx.Push(x2) openy.Push(y2) map[x2][y2] = slimetile End If Next Next Next ' Remove Obsolete slime For Local i:Int=0 Until openx.Length Local cnt:Int=0 For Local y:Int=-1 To 1 For Local x:Int=-1 To 1 Local x2:Int=openx.Get(i)+x Local y2:Int=openy.Get(i)+y If x2<0 Or y2<0 Or x2>=w Or y2>=h Then cnt+=1 Continue End If If map[x2][y2] = slimetile Then cnt+=1 Next Next If cnt=9 Then openx.Remove(i) openy.Remove(i) End If Next End Method Method draw() ' Draw the solid slimes () For Local y:Float=0 Until h For Local x:Float=0 Until w Local x1:Float=x*tw Local y1:Float=y*th If map[x][y] = slimetile SetColor 20,200,10 DrawOval x1,y1,tw+1,th+1 End If Next Next End Method End Class Class maptest Field tw:Float,th:Float Field w:Int,h:Int 'bottom x and y contain the coords of the next 'shaft to be created. center of room last pass Field bottomy:Int Field bottomx:Int Field map:Int[][] Method New(w:Int,h:Int) Self.w = w Self.h = h tw = DeviceWidth()/w th = DeviceHeight()/h map = New Int[w][] For Local i=0 Until w map[i] = New Int[h] Next drawmaprect(0,0,w-1,15) For Local i=0 Until h map[1][i] = 0 map[w-2][i] = 0 Next ' x,y,number of tunnels>> makemine(w/2,15,Rnd(1,3)) makemine(bottomx,bottomy,Rnd(1,3)) If bottomy<(Float(mapheight)/2) makemine(bottomx,bottomy,Rnd(1,3)) End If End Method Method makemine(x:Int,y:Int,depth:Int) Local vy:Int=y For Local mydepth=0 Until depth Local d1:Int=Rnd(8,16)'depth tunneldown(x,y,d1) y+=d1 Local d2:Int=Rnd(1,4)'direction If d2=1 Then sidetunnel(x,y,"left") End If If d2=2 Then sidetunnel(x,y,"right") End If If d2=3 Then sidetunnel(x,y,"left") sidetunnel(x,y,"right") End If Next 'For Local y1=vy Until bottomy+2 ' map[x][y1] = 2 ' Next End Method Method sidetunnel(x:Int,y:Int,d:String) If d="left" Local width:Int=Rnd(5,15) drawmaprect(x-width+2,y,width,3) Local roomw:Int=Rnd(5,15) drawmaprect(x-width+2-roomw,y-1,roomw,5) For Local x1=0 Until roomw/3 map[(x-width+2-roomw)+x1][y+4] = 3 Next bottomx = x-width-(roomw/2) bottomy = y End If If d="right" Local width:Int=Rnd(5,15) drawmaprect(x-1,y,width,3) Local roomw:Int=Rnd(5,15) drawmaprect(x+width,y-1,roomw,5) For Local x1=roomw Until roomw/1.5 Step -1 map[(x+width)+x1][y+4] = 3 Next bottomx = x+width+(roomw/2) bottomy = y End If End Method Method tunneldown(x:Int,y:Int,d:Int) drawmaprect(x-2,y,4,d) End Method Method drawmaprect(x:Int,y:Int,w:Int,h:Int) For Local y1=y To y+h For Local x1=x To x+w map[x1][y1] = 1 Next Next End Method Method draw() For Local y=0 Until h For Local x=0 Until w Local x1:Float=DeviceWidth()/Float(mapwidth)*Float(x) Local y1:Float=DeviceHeight/Float(mapheight)*Float(y) If map[x][y] = 1 SetColor 255,255,255 DrawRect x1,y1,tw+1,th+1 End If If map[x][y] = 3 SetColor 200,200,10 DrawOval x1,y1,tw+1,th+1 End If Next Next End Method End Class ' ----------------------------------------------------------------------------------------------- Global mymaptest:maptest Global mygrowslime:growslime Class MyGame Extends App Field nmap:Int=0 Method OnCreate() Local date := GetDate() Seed = date[5] SetUpdateRate(60) restartgame End Method Method OnUpdate() nmap+=1 If KeyDown(KEY_SPACE)=True Or nmap>3500 restartgame nmap=0 End If mygrowslime.update("fast") End Method Method OnRender() Cls 0,0,0 mymaptest.draw() mygrowslime.draw() SetColor 255,255,0 DrawText "MonkeyX - Growing Slime in the Mines Example",20,0 End Method End Class Function Main() New MyGame() End Function Function restartgame() mymaptest = New maptest(mapwidth,mapheight) mygrowslime = New growslime() End Function Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function Function 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 Function
'snake(style) 2d water Import mojo Global mapwidth:Int=200 Global mapheight:Int=100 Class watertest Field map:Int[][] Field w:Float,h:Float Field tw:Float,th:Float Field flowx:Int,flowy:Int Field dir:String="down" Method New() Self.w = mymaptest.w*4 Self.h = mymaptest.h*4 Self.tw = 640/w Self.th = 480/h map = New Int[w][] For Local i=0 Until w map[i] = New Int[h] Next flowx = 10 flowy = 10 For Local y:Int=0 Until mymaptest.h For Local x:Int=0 Until mymaptest.w If mymaptest.map[x][y] = 1 For Local y2:Int=0 Until 4 For Local x2:Int=0 Until 4 map[x*4+x2][y*4+y2] = 1 Next Next End If Next Next End Method Method update() Local a:Bool=False dir = "new" If map[flowx][flowy+1] = 1 Then dir="down" ; a=True If a=False And map[flowx+1][flowy] = 1 Then dir="right"; a=True If a=False And map[flowx-1][flowy] = 1 Then dir="left" ; a = True If a=False And map[flowx][flowy-1] = 1 Then dir="up" ; a = True If dir="left" And map[flowx-2][flowy] = 10 Then map[flowx-2][flowy] = 1 If dir="right" And map[flowx+2][flowy] = 10 Then map[flowx+2][flowy] = 1 map[flowx][flowy]=10 If dir="left" If map[flowx-1][flowy-1]=10 Then map[flowx-1][flowy-1]=1 Elseif dir="right" If map[flowx+1][flowy-1]=10 Then map[flowx+1][flowy-1]=1 End If Select dir Case "up" flowy-=1 Case "left" flowx-=1 Case "right" flowx+=1 Case "down" flowy+=1 End Select If dir="new" Or Rnd(60*20) < 2 Then ' if the snake got stuck then ' find a new spot dir = "done" For Local y:Int=h-1 Until 1 Step -1 For Local x:Int=0 Until w If map[x][y] = 1 And map[x][y+1] = 10 Then flowx = x flowy = y Return End If Next Next End If End Method Method draw() For Local y:Int=0 Until h For Local x:Int=0 Until w Local x1:Float=x*tw Local y1:Float=y*th If map[x][y] = 10 SetColor 0,0,255 DrawRect x1,y1,tw+1,th+1 End If Next Next End Method End Class Class maptest Field tw:Float,th:Float Field w:Int,h:Int 'bottom x and y contain the coords of the next 'shaft to be created. center of room last pass Field bottomy:Int Field bottomx:Int Field map:Int[][] Method New(w:Int,h:Int) Self.w = w Self.h = h tw = DeviceWidth()/w th = DeviceHeight()/h map = New Int[w][] For Local i=0 Until w map[i] = New Int[h] Next drawmaprect(0,0,w-1,15) For Local i=0 Until h map[1][i] = 0 map[w-2][i] = 0 Next ' x,y,number of tunnels>> makemine(w/2,15,Rnd(1,3)) makemine(bottomx,bottomy,Rnd(1,3)) If bottomy<(Float(mapheight)/2) makemine(bottomx,bottomy,Rnd(1,3)) End If End Method Method makemine(x:Int,y:Int,depth:Int) Local vy:Int=y For Local mydepth=0 Until depth Local d1:Int=Rnd(8,16)'depth tunneldown(x,y,d1) y+=d1 Local d2:Int=Rnd(1,4)'direction If d2=1 Then sidetunnel(x,y,"left") End If If d2=2 Then sidetunnel(x,y,"right") End If If d2=3 Then sidetunnel(x,y,"left") sidetunnel(x,y,"right") End If Next ' For Local y1=vy Until bottomy+2 ' map[x][y1] = 2 ' Next End Method Method sidetunnel(x:Int,y:Int,d:String) If d="left" Local width:Int=Rnd(5,15) drawmaprect(x-width+2,y,width,3) Local roomw:Int=Rnd(5,15) drawmaprect(x-width+2-roomw,y-1,roomw,5) For Local x1=0 Until roomw/3 map[(x-width+2-roomw)+x1][y+4] = 3 Next bottomx = x-width-(roomw/2) bottomy = y End If If d="right" Local width:Int=Rnd(5,15) drawmaprect(x-1,y,width,3) Local roomw:Int=Rnd(5,15) drawmaprect(x+width,y-1,roomw,5) For Local x1=roomw Until roomw/1.5 Step -1 map[(x+width)+x1][y+4] = 3 Next bottomx = x+width+(roomw/2) bottomy = y End If End Method Method tunneldown(x:Int,y:Int,d:Int) drawmaprect(x-2,y,4,d) End Method Method drawmaprect(x:Int,y:Int,w:Int,h:Int) For Local y1=y To y+h For Local x1=x To x+w map[x1][y1] = 1 Next Next End Method Method draw() For Local y=0 Until h For Local x=0 Until w Local x1:Float=DeviceWidth()/Float(mapwidth)*Float(x) Local y1:Float=DeviceHeight/Float(mapheight)*Float(y) If map[x][y] = 1 SetColor 255,255,255 DrawRect x1,y1,tw+1,th+1 End If If map[x][y] = 3 SetColor 200,200,10 DrawOval x1,y1,tw+1,th+1 End If Next Next End Method End Class ' ----------------------------------------------------------------------------------------------- Global mymaptest:maptest Global mywatertest:watertest Class MyGame Extends App Field nmap:Int=0 Method OnCreate() Local date := GetDate() Seed = date[5] SetUpdateRate(60) restartgame End Method Method OnUpdate() For Local i:Int=0 Until 6 mywatertest.update() Next If levelfilled() Then restartgame End Method Method OnRender() Cls 0,0,0 mymaptest.draw() mywatertest.draw() SetColor 255,255,0 DrawText "MonkeyX - 2d Mining map and snake style water.",20,0 End Method End Class Function Main() New MyGame() End Function Function levelfilled:Bool() If Rnd(120)>2 Then Return False Local cnt:Int=0 For Local y:Int=10 Until 60 For Local x:Int= 0 Until mywatertest.w If mywatertest.map[x][y] = 10 Then cnt+=1 If cnt>100 Then Return True Next Next Return False End Function Function restartgame() mymaptest = New maptest(mapwidth,mapheight) mywatertest = New watertest() End Function Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function Function 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 Function
Import mojo ' ' This is the tile class. ' Here a stone tile is created ' using the generate method Class tile Field width:Int,height:Int Field map:Int[][] Method New(w:Int,h:Int) Self.width = w Self.height = h map = New Int[width][] For Local i:Int=0 Until width map[i] = New Int[height] Next End Method Method generate(spacing:Int) ' Put a number of stone points on the map ' try to keep a distance between them Local numpoints:Int=Rnd(width/5,width/2) For Local i:Int=0 Until numpoints Local x:Int=Rnd(width) Local y:Int=Rnd(height) Local exitloop:Bool=False While exitloop=False exitloop = True If disttootherstone(x,y,i) < spacing x=Rnd(width) y=Rnd(height) exitloop=False End If Wend map[x][y] = i Next ' ' Grow the stone points For Local i:Int=0 Until (width*height)*10 Local x:Int=Rnd(width) Local y:Int=Rnd(height) If map[x][y] > 0 If disttootherstone(x,y,map[x][y]) < spacing Then Continue For Local y2:Int=y-1 To y+1 For Local x2:Int=x-1 To x+1 If x2<0 Or y2<0 Or x2>=width Or y2>=height Then Continue If Rnd(5)<2 Then If map[x2][y2] = 0 If x2 = 0 Then map[width-1][y2] = map[x][y] If x2 = width-1 Then map[0][y2] = map[x][y] If y2 = 0 Then map[x2][height-1] = map[x][y] If y2 = height-1 Then map[x2][0] = map[x][y] map[x2][y2] = map[x][y] End If End If Next Next End If Next shadeedges() End Method ' Add ligther and darker pixels ontop of the stones ' value 1 to <100 is each seperate stone ' value 200 is light color 100 is dark color Method shadeedges() For Local y:Int=0 Until height For Local x:Int=0 Until width If map[x][y] > 0 And map[x][y] <> 200 If x-1 >=0 And map[x-1][y] = 0 For Local x2:Int=x+2 To x+4 If Rnd(2)<1 If x2>=0 And x2<width And map[x2][y] >0 Then map[x2][y] = 100 End If Next End If If x-1 >=0 And y-1>=0 And map[x-1][y-1] = 0 map[x][y] = 100 End If If x+1 < width And map[x+1][y] = 0 For Local x2:Int=x-4 To x+2 If Rnd(2)<1 If x2>=0 And x2<width And map[x2][y] >0 Then map[x2][y] = 200 End If Next End If End If Next Next End Method ' Returns the shortest distance to any other stone part then ' the currentstore Method disttootherstone:Int(sx:Int,sy:Int,currentstone:Int) Local shortest:Int=9999 For Local y:Int=0 Until height For Local x:Int=0 Until width If map[x][y] <> 0 And map[x][y] <> currentstone Local d:Int=distance(sx,sy,x,y) If d<shortest Then shortest = d End If Next Next Return shortest End Method ' Draw the tile at x and y position and tw=size Method draw(sx:Int,sy:Int,tw:Int,th:Int) Local x:Int Local y:Int For y=0 Until height For x=0 Until width Local t:Int=map[x][y] Local x2:Int=x*tw Local y2:Int=y*th x2+=sx y2+=sy If t >= 1 Then 'grey base color SetColor 100,100,100 End If If t=100 Then SetColor 40,40,40 'dark shade color If t=200 Then SetColor 140,140,140 'light shade color If t>0 ' draw a rect (part of the stone) DrawRect x2,y2,tw,th End If Next Next End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class Class MyGame Extends App Field mytile:tile Field cnt:Int=0 Method OnCreate() Seed = GetDate[4]*GetDate[5] SetUpdateRate(1) mytile = New tile(32,32) mytile.generate(6) End Method Method OnUpdate() cnt+=1 If KeyHit(KEY_SPACE) Or cnt>3 cnt = 0 mytile = New tile(32,32) 'reset/create new tile Local spacing:Int=Rnd(4,10) ' set random spacing If Rnd(3)<1 Then spacing=4 mytile.generate(spacing) ' generate the tile End If End Method Method OnRender() Cls 0,0,0 'draw the tiles in 4x the size For Local y:Int=0 Until DeviceHeight Step 32*4 For Local x:Int=0 Until DeviceWidth Step 32*4 mytile.draw(x,y,4,4) Next Next ' draw the tiles in 1x size SetColor 0,0,0 DrawRect 320,240,320,240 For Local y:Int=240 Until DeviceHeight Step 32 For Local x:Int=320 Until DeviceWidth Step 32 mytile.draw(x,y,1,1) Next Next End Method End Class Function Main() New MyGame() End Function
Import mojo Class tile Field width:Int,height:Int Field map:Int[][] Method New(w:Int,h:Int) Self.width = w Self.height = h map = New Int[width][] For Local i:Int=0 Until width map[i] = New Int[height] Next End Method ' Here we create the flasks or bottles ' or what else. Method generate() 'make right side ' from the center top to center bottom Local x:Float=width/2 Local y:Float=0 Local angle:Int=0 While y<=height For Local i:Int=0 Until 20 x+=Cos(angle)*.5 y+=Sin(angle)*.5 If x>=width Then x-=1 If x<0 Or y<0 Or x>=width Or y>=height Then Exit map[x][y] = 1 ' create border point fillleftside(x-1,y) ' fill left side Next angle=Rnd(0,120) Wend If y>height Then y=height-1 For Local x1:Int=x Until width/2-1 Step -1 map[x1][y] = 1 Next 'make left side (mirror right side) For y = 0 Until height For x = width/2 Until width map[width-x][y] = map[x][y] Next Next Return End Method ' here we put the value of ' 2 inside the map from inputted ' coords to most left position Method fillleftside(fx:Int,fy:Int) For Local x:Int=fx Until 0 Step -1 map[x][fy] = 2 Next End Method Method draw(sx:Int,sy:Int,ar:Int,ag:Int,ab:Int) Local c:Int Local g:Int Local b:Int Local lightpointx:Int=Rnd(5,width-5) For Local y:Int=0 Until height For Local x:Int=0 Until width If map[x][y] = 0 Then c=0+((ag/height)*y) g=0+((ab/height)*y) b=0+((ar/height)*y) If c>255 Then c=255 If g>255 Then g=255 If b>255 Then b=255 If c<0 Then c=0 If g<0 Then g=0 If b<0 Then b=0 SetColor c,g,b DrawRect sx+x,sy+y,1,1 Continue End If ' here we draw the border ' and the red (rainbowish color) Select map[x][y] Case 1'border c = 255-((255/height)*y) If x>width/2 Then c/=2 SetColor c,c,c Case 2 c = ar-((ar/height)*y) g = ag-((ag/height)*y) b = ab-((ab/height)*y) c=-distance(lightpointx,0,x,0)+c g=-distance(lightpointx,0,x,0)+g b=-distance(lightpointx,0,x,0)+b If c>255 Then c=255 If g>255 Then g=255 If b>255 Then b=255 If c<0 Then c=0 If g<0 Then g=0 If b<0 Then b=0 SetColor c,g,b End Select DrawRect sx+x,sy+y,1,1 Next Next End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class Class MyGame Extends App Field mytile:tile Method OnCreate() Seed = GetDate[4]*GetDate[5] SetUpdateRate(1) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 For Local y:Int=0 Until DeviceHeight Step 55 For Local x:Int=0 Until DeviceWidth Step 55 mytile = New tile(48,48) mytile.generate() mytile.draw(x,y,Rnd(24,255),Rnd(24,255),Rnd(24,255)) Next Next End Method End Class Function Main() New MyGame() End Function
' Create a map with lines. ' It works by randomly selecting a point on the map ' and the drawing into a random direction. We stop ' drawing if we are close to a previously drawn line. ' Import mojo Class map Field screenwidth:Int Field screenheight:Int Field mapwidth:Int Field mapheight:Int Field tilewidth:Float Field tileheight:Float Field map:Int[][] Method New(sw:Int,sh:Int,mw:Int,mh:Int) Self.screenwidth = sw Self.screenheight = sh Self.mapwidth = mw Self.mapheight = mh Self.tilewidth = Float(sw) / Float(mw) Self.tileheight = Float(sh) / Float(mh) map = New int[mapwidth][] For Local i:Int=0 Until mapwidth map[i] = New Int[mapheight] Next createmap() End Method Method createmap() ' Loop a number of times For Local i:Int=0 Until (mapwidth+mapheight) ' Get a random x and y spot on the map Local x:Float=Rnd(mapwidth) Local y:Float=Rnd(mapheight) ' Chose an angle Local angle:Int=Rnd(360) ' We will draw d into angle it's direction Local d:Int=Rnd(3,35) Local xitloop:Bool=False ' We change the angle and distance 3 times For Local iii:Int=0 Until 3 ' Loop the distance For Local ii:Int=0 Until d ' If spot taken with 1 or out of screen ' then exit the loop If maptaken(x-4,y-4,8,8) Then xitloop=True ; Exit ' Put value 2 into the map map[x][y] = 2 ' Next x and y position x+=Cos(angle)*1 y+=Sin(angle)*1 Next ' Exit the loop(spot taken) If xitloop=True Then Exit ' Change angle and distance angle+=Rnd(-90,90) d=Rnd(3,35) Next ' Turn all new drawn 2 value's into ' value of 1 For Local y:Int=0 Until mapheight For Local x:Int=0 Until mapwidth If map[x][y] = 2 Then map[x][y] = 1 Next Next Next End Method ' See if the area selected is outside the ' screen or if the map value is 1 Method maptaken:Bool(x:Int,y:Int,w:Int,h:Int) For Local y2:Int=y Until y+h For Local x2:Int=x Until x+w If x2<0 Or x2>=mapwidth Or y2<0 Or y2>=mapheight Then Return True If map[x2][y2] = 1 Then Return True Next Next Return False End Method ' Draw the map Method draw() For Local y:Int=0 Until mapheight For Local x:Int=0 Until mapwidth If map[x][y] = 0 Then Continue SetColor 255,255,255 Local x2:Int=x*tilewidth Local y2:Int=y*tileheight DrawRect x2,y2,tilewidth+1,tileheight+1 Next Next End Method End Class Class MyGame Extends App Field mymap:map Field cnt:Int=0 Method OnCreate() Seed = GetDate[4] * GetDate[5] SetUpdateRate(1) createrandommap() End Method Method OnUpdate() cnt+=1 If KeyHit(KEY_SPACE) Or cnt > 1 cnt=0 createrandommap() End If End Method Method OnRender() Cls 0,0,0 ' Draw the map mymap.draw() SetColor 255,255,255 Local mw:Int=mymap.mapwidth Local mh:Int=mymap.mapheight DrawText "Width : "+mw+" Height : "+mh,0,0 End Method Method createrandommap() Local size:Int=Rnd(20,200) mymap = New map(DeviceWidth,DeviceHeight,size,size) End Method End Class Function Main() New MyGame() End Function
'Is this the breath first search? Not to familiar with it. Import mojo Class search Field screenwidth:Int,screenheight:Int Field mapwidth:Int,mapheight:Int Field tilewidth:Float,tileheight:Float Field sx:Int,sy:Int Field ex:Int,ey:Int Field map:Int[][] Field myopenlist:List<node> Field myclosedlist:List<node> Field mypath:List<path> Field mx:Int[]=[0,-1,1,0] Field my:Int[]=[-1,0,0,1] Method New(screenwidth:Int,screenheight:Int,mapwidth:Int,mapheight:Int) Self.screenwidth = screenwidth Self.screenheight = screenheight Self.mapwidth = mapwidth Self.mapheight = mapheight Self.tilewidth = Float(screenwidth) / Float(mapwidth) Self.tileheight = Float(screenheight) / Float(mapheight) map = New Int[mapwidth][] For Local i:Int=0 Until mapwidth map[i] = New Int[mapheight] Next makemap() End Method Method makemap:Void() For Local i:Int=0 Until mapwidth/3 Local x1:Float=Rnd(0,mapwidth) Local y1:Float=Rnd(0,mapheight) Local angle:Int=Rnd(360) Local dist:Int=Rnd(3,7) For Local ii:Int=0 Until dist x1+=Cos(angle)*1 y1+=Sin(angle)*1 If x1<0 Or y1<0 Or x1>=mapwidth Or y1>=mapheight Then Exit map[x1][y1] = 1 Next Next End Method Method search:Bool(sx:Int,sy:Int,ex:Int,ey:Int) If sx=ex And sy=ey Then Return False If map[sx][sy] <> 0 Or map[ex][ey] <> 0 Then Return False Self.sx = sx Self.sy = sy Self.ex = ex Self.ey = ey myopenlist = New List<node> myclosedlist = New List<node> mypath = New List<path> myopenlist.AddFirst(New node(sx,sy,sx,sy)) ' the search While Not myopenlist.IsEmpty Local cx:Int=myopenlist.First.x Local cy:Int=myopenlist.First.y Local px:Int=myopenlist.First.parentx Local py:Int=myopenlist.First.parenty myclosedlist.AddFirst(New node(cx,cy,px,py)) If cx = ex And cy = ey Then findpathback() Return True End If myopenlist.RemoveFirst() For Local i:Int=0 Until mx.Length Local nx:Int=cx+mx[i] Local ny:Int=cy+my[i] If nx<0 Or ny<0 Or nx>=mapwidth Or ny>=mapheight Then Continue If map[nx][ny] = 0 'if the map is not obstructed If isonclosedlist(nx,ny) = False And isonopenlist(nx,ny) = False myopenlist.AddLast(New node(nx,ny,cx,cy)) End If End If Next Wend Return False End Method ' Here we calculate back from the end back to the ' start and create the path list. Method findpathback:Bool() Local x:Int=ex Local y:Int=ey mypath.AddFirst(New path(x,y)) Repeat For Local i:=Eachin myclosedlist If i.x = x And i.y = y x = i.parentx y = i.parenty mypath.AddFirst(New path(x,y)) End If Next If x = sx And y = sy Then Return True Forever End Method Method drawpath() If Not mypath Then Return For Local i:=Eachin mypath SetColor 255,0,0 DrawOval i.x*tilewidth+(tilewidth/4),i.y*tileheight,tilewidth/4,tileheight/2 Next End Method Method drawclosedlist() If Not myclosedlist Then Return For Local i:=Eachin myclosedlist DrawText "loc:"+i.x+","+i.y, i.x*tilewidth,i.y*tileheight+15 DrawText "par:"+i.parentx+","+i.parenty, i.x*tilewidth,i.y*tileheight+30 Next End Method Method isonopenlist:Bool(x:Int,y:Int) For Local i:=Eachin myopenlist If x = i.x And y = i.y Then Return True End If Next Return False End Method Method isonclosedlist:Bool(x:Int,y:Int) For Local i:=Eachin myclosedlist If x = i.x And y = i.y Then Return True End If Next Return False End Method Method draw() SetColor 255,255,255 For Local y:Int = 0 Until mapheight For Local x:Int = 0 Until mapheight If map[x][y] = 1 SetColor 155,155,155 DrawRect x*tilewidth,y*tileheight,tilewidth,tileheight End If If sx = x And sy = y SetColor 255,0,0 DrawOval x*tilewidth+10,y*tileheight,10,10 End If If ex = x And ey = y SetColor 255,255,0 DrawOval x*tilewidth+10,y*tileheight,10,10 End If Next Next End Method End Class Class node Field x:Int Field y:Int Field parentx:Int Field parenty:Int Method New(x:Int,y:Int,parentx:Int,parenty:Int) Self.x = x Self.y = y Self.parentx = parentx Self.parenty = parenty End Method End Class Class path Field x:Int Field y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class MyGame Extends App Field pathfound:Bool=False Field mysearch:search Field cnt:Int=0 Method OnCreate() Seed = GetDate[5] * GetDate[4] SetUpdateRate(10) mysearch = New search(DeviceWidth,DeviceHeight,10,10) pathfound = mysearch.search(2,2,6,6) End Method Method OnUpdate() cnt+=1 If KeyHit(KEY_SPACE) Or cnt>15 pathfound=False cnt=0 Local w:Int=Rnd(10,50) mysearch = New search(DeviceWidth,DeviceHeight,w,w) pathfound = mysearch.search(Rnd(w),Rnd(w),Rnd(w),Rnd(w)) End If End Method Method OnRender() Cls 0,0,0 mysearch.drawclosedlist mysearch.draw mysearch.drawpath SetColor 255,255,255 If pathfound DrawText "Path Found",0,0 End If End Method End Class Function Main() New MyGame() End Function
Import mojo Class enemy Field x:Int,y:Int Field w:Int,h:Int Field state:String Field deleteme:Bool Field cooldown:Int Field waittime:Int Field path:List<pathnode> = New List<pathnode> Method New() w = mymap.tilewidth-4 h = mymap.tileheight-4 findstartpos() End Method Method update() ' enemy shoot diagnal If Rnd(100)<2 Then Local px:Int=myplayer.x Local py:Int=myplayer.y If distance(px,py,x,y) < 200 If px<x And py<y And mymap.mapcollide(x-5,y-5,w/3,h/3) = False mybullet.AddLast(New bullet(x,y,"leftup","enemy")) End If If px>x And py<y And mymap.mapcollide(x+5,y-5,w/3,h/3) = False mybullet.AddLast(New bullet(x,y,"rightup","enemy")) End If If px<x And py>y And mymap.mapcollide(x-5,y+5,w/3,h/3) = False mybullet.AddLast(New bullet(x,y,"leftdown","enemy")) End If If px>x And py>y And mymap.mapcollide(x+5,y+5,w/3,h/3) = False mybullet.AddLast(New bullet(x,y,"rightdown","enemy")) End If End If End If 'enemy shoot horizontal vertical If Rnd(100)<2 Then Local px:Int=myplayer.x Local py:Int=myplayer.y If distance(px,py,x,y) < 200 If px<x And mymap.mapcollide(x-5,y,w/3,h/3) = False mybullet.AddLast(New bullet(x,y,"left","enemy")) End If If px>x And mymap.mapcollide(x+5,y-5,w/3,h/3) = False mybullet.AddLast(New bullet(x,y,"right","enemy")) End If If py>y And mymap.mapcollide(x,y+5,w/3,h/3) = False mybullet.AddLast(New bullet(x,y,"down","enemy")) End If If py<y And mymap.mapcollide(x,y-5,w/3,h/3) = False mybullet.AddLast(New bullet(x,y,"up","enemy")) End If End If End If ' move around the enemy If path.IsEmpty = False ' add 2 to the destination coords or gets stuck Local dx:Int=path.First.x*mymap.tilewidth+2 Local dy:Int=path.First.y*mymap.tileheight+2 If x<dx And mymap.mapcollide(x+1,y,w,h) = False Then x+=1 If x>dx And mymap.mapcollide(x-1,y,w,h) = False Then x-=1 If y<dy And mymap.mapcollide(x,y+1,w,h) = False Then y+=1 If y>dy And mymap.mapcollide(x,y-1,w,h) = False Then y-=1 'if near destination If distance(x,y,dx,dy) < 2 Then path.RemoveFirst x = dx y = dy End If End If 'if no more moves left find new cover spot If path.IsEmpty If waittime>0 Then waittime-=1 If waittime<=0 For Local i:Int=0 Until 100 Local dx:Int=Rnd(2,mymap.mapwidth-2) Local dy:Int=Rnd(2,mymap.mapheight-2) If mymap.covermap[dx][dy] = 1 Then createpath(dx,dy) waittime=200 Exit End If Next End If End If 'if player is nearby then move to closest cover spot If distance(myplayer.x,myplayer.y,x,y) < 160 If cooldown>0 Then cooldown-=1 If cooldown=0 cooldown=100 Local d:Int=10000 Local destx:Int,desty:Int Local fnd:Bool=False ' random spots until coverspot, log closest For Local i:Int=0 Until 250 Local dx:Int=Rnd(2,mymap.mapwidth-2) Local dy:Int=Rnd(2,mymap.mapheight-2) If mymap.covermap[dx][dy] = 1 Then Local d2:Int = distance(dx,dy,x/mymap.tilewidth,y/mymap.tileheight) If d2 < d Then d = d2 destx = dx desty = dy fnd=True End If End If Next ' if we have a new dest then plan it If fnd=True Then createpath(destx,desty) End If End If End Method Method createpath(ex:Int,ey:Int) path = New List<pathnode> Local dx:Int=x/mymap.tilewidth Local dy:Int=y/mymap.tileheight ' x = dx*mymap.tilewidth ' y = dy*mymap.tileheight myastar.findpath(dx,dy,ex,ey) For Local i:=Eachin myastar.path path.AddLast(New pathnode(i.x,i.y)) Next End Method Method drawpath() SetColor 255,0,0 For Local i:=Eachin path DrawOval i.x*mymap.tilewidth,i.y*mymap.tileheight,w/2,h/2 Next End Method Method findstartpos() Local cnt:Int=400 Local cnt2:Int=0 Repeat Local nx:Int=Rnd(0,mymap.screenwidth-20) Local ny:Int=Rnd(0,mymap.screenheight-20) Local found:Bool=True ' if the map position a tile If mymap.mapcollide(nx,ny,w,h) Then found = False ' if the position is to close other enemy For Local i:=Eachin myenemy If i=Self Then Continue If distance(i.x,i.y,nx,ny) < 30 Then found = False ;Exit Next ' if the position to close to player If distance(myplayer.x,myplayer.y,nx,ny) < cnt Then found = False If found = True Then x = nx y = ny Exit Else If cnt>32 Then cnt -=1 End If Forever End Method Method draw() SetColor 255,0,255 DrawOval x,y,w,h End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class Class bullet Field x:Float,y:Float Field w:Int,h:Int Field mx:Int,my:Int Field direction:String Field deleteme:Bool=False Field speed:Int=2 Field shooter:String Method New(x:Int,y:Int,direction:String,shooter:String) Self.x = x Self.y = y Self.w = myplayer.w/3 Self.h = myplayer.h/3 Self.shooter = shooter Self.direction = direction If direction = "left" Then mx = -1 If direction = "right" Then mx = 1 If direction = "up" Then my = -1 If direction = "down" Then my = 1 If direction = "leftup" Then mx = -1 ; my = -1 If direction = "rightup" Then mx = 1 ; my = -1 If direction = "leftdown" Then mx = -1 ; my = 1 If direction = "rightdown" Then mx = 1 ; my = 1 End Method Method update() 'move the bullet and see collision with walls For Local i:Int=0 Until speed x += mx y += my If x < 0 Or x > mymap.screenwidth Then deleteme = True If y < 0 Or y > mymap.screenheight Then deleteme = True If mymap.mapcollide(x,y,w,h) Then deleteme = True Next ' collision with bullet vs enemy ' delete bullet and delete enemy If shooter = "player" For Local i:=Eachin myenemy If distance(i.x+(i.w/2),i.y+(i.h/2),x,y)<myplayer.w/1.5 Then deleteme = True i.deleteme = True End If Next End If ' collision with bullet vs player ' delete bullet and kill player If shooter = "enemy" If distance(myplayer.x+(myplayer.w/2),myplayer.y+(myplayer.h/2),x,y)<myplayer.w/1.5 Then deleteme = True myplayer.died = True End If End If End Method Method draw() SetColor 255,255,0 DrawOval x,y,w,h End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class Class player Field x:Float,y:Float Field w:Int,h:Int Field direction:String="up" Field died:Bool=False Method New() w = mymap.tilewidth-4 h = mymap.tileheight-4 findstartingpos() End Method Method update() playercontrols() makecovermap() End Method Method playercontrols() ' movement If KeyDown(KEY_UP) And Not mymap.mapcollide(x,y-1,w,h) y-=1 direction = "up" End If If KeyDown(KEY_LEFT) And Not mymap.mapcollide(x-1,y,w,h) x-=1 direction = "left" End If If KeyDown(KEY_RIGHT) And Not mymap.mapcollide(x+1,y,w,h) x+=1 direction = "right" End If If KeyDown(KEY_DOWN) And Not mymap.mapcollide(x,y+1,w,h) y+=1 direction = "down" End If If KeyDown(KEY_LEFT) And KeyDown(KEY_UP) Then direction = "leftup" If KeyDown(KEY_RIGHT) And KeyDown(KEY_UP) Then direction = "rightup" If KeyDown(KEY_LEFT) And KeyDown(KEY_DOWN) Then direction = "leftdown" If KeyDown(KEY_RIGHT) And KeyDown(KEY_DOWN) Then direction = "rightdown" ' shooting If KeyHit(KEY_F) mybullet.AddLast(New bullet(x,y,direction,"player")) End If End Method Method makecovermap() If Rnd(60)>2 Then Return For Local y:Int=0 Until mymap.mapheight For Local x:Int=0 Until mymap.mapwidth mymap.covermap[x][y] = 1 If mymap.map[x][y] <> 0 Then mymap.covermap[x][y] = 2 Next Next ' shoot bullets into random directions around ' the player and see if any position is a cover position For Local i:Int=0 Until 600 Local x2:Float=x Local y2:Float=y Local xa:Float=Rnd(-1,1) Local ya:Float=Rnd(-1,1) For Local d:Int=0 Until 40 x2+=xa*Float(mymap.tilewidth/2) y2+=ya*Float(mymap.tileheight/2) Local mx:Int=x2/mymap.tilewidth Local my:Int=y2/mymap.tileheight If mx>=0 And my>=0 And mx<mymap.mapwidth And my<mymap.mapheight mymap.covermap[mx][my] = 0 Else Exit End If If mymap.mapcollide(x2,y2,w/3,h/3) Then Exit Next Next ' ' Remove every coverpoint except if they ' are near a wall. For Local y2:Int=0 Until mymap.mapheight For Local x2:Int=0 Until mymap.mapwidth Local remove:Bool=True For Local y3:Int=y2-1 To y2+1 For Local x3:Int=x2-1 To x2+1 If x3<0 Or y3<0 Or x3>=mymap.mapwidth Or y3>=mymap.mapheight Then Continue If mymap.map[x3][y3] <> 0 Then remove = False ; Exit Next Next If remove = True Then mymap.covermap[x2][y2] = 0 End If Next Next 'if closer to the player then higher movement cost per tile For Local y2:Int=0 Until mymap.mapheight For Local x2:Int=0 Until mymap.mapwidth If myastar.map[x2][y2] <> 1000 Then myastar.map[x2][y2] = 100-distance(myplayer.x/mymap.tilewidth,myplayer.y/mymap.tileheight,x2,y2) If myastar.map[x2][y2] < 85 Then myastar.map[x2][y2] = 0 If mymap.covermap[x2][y2] = 1 Then myastar.map[x2][y2] = 0 Next Next End Method Method findstartingpos() Repeat Local x1:Int = Rnd(0,mymap.mapwidth) Local y1:Int = Rnd(0,mymap.mapheight) Local istaken:Bool=False For Local x2:Int=x1-4 To x1+4 For Local y2:Int=y1-4 To y1+4 If x2<0 Or y2<0 Or x2>=mymap.mapwidth Or y2>=mymap.mapheight Then Continue If mymap.map[x2][y2] <> 0 Then istaken = True ; Exit Next Next If istaken=False Then x = x1*mymap.tilewidth y = y1*mymap.tileheight Exit End If Forever End Method Method draw() SetColor 255,255,255 DrawOval x,y,w,h End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class Class astar Field mapwidth:Int,mapheight:Int Field sx:Int,sy:Int Field ex:Int,ey:Int Field olmap:Int[][] Field clmap:Int[][] Field map:Int[][] Field ol:List<openlist> = New List<openlist> Field cl:List<closedlist> = New List<closedlist> Field path:List<pathnode> = New List<pathnode> Field xstep:Int[] = [0,-1,1,0] Field ystep:Int[] = [-1,0,0,1] Method New() mapwidth = mymap.mapwidth mapheight = mymap.mapheight olmap = New Int[mapwidth][] clmap = New Int[mapwidth][] map = New Int[mapwidth][] For Local i:Int=0 Until mapwidth olmap[i] = New Int[mapheight] clmap[i] = New Int[mapheight] map[i] = New Int[mapheight] Next ' Copy the map into the astar class map For Local y:=0 Until mapheight For Local x:=0 Until mapwidth map[x][y] = mymap.map[x][y] Next Next End Method ' This creates the map and copies the ' path in the path list Method findpath:Bool(sx:Int,sy:Int,ex:Int,ey:Int) If sx = ex And sy = ey Then Return False Self.sx = sx Self.sy = sy Self.ex = ex Self.ey = ey For Local y=0 Until mapheight For Local x=0 Until mapwidth olmap[x][y] = 0 clmap[x][y] = 0 Next Next ol.Clear cl.Clear path.Clear ol.AddFirst(New openlist(sx,sy)) Local tx:Int Local ty:Int Local tf:Int Local tg:Int Local th:Int Local tpx:Int Local tpy:Int Local newx:Int Local newy:Int Local lowestf:Int olmap[sx][sy] = 1 While ol.IsEmpty() = False lowestf = 100000 For Local i:=Eachin ol If i.f < lowestf lowestf = i.f tx = i.x ty = i.y tf = i.f tg = i.g th = i.h tpx = i.px tpy = i.py End If Next If tx = ex And ty = ey cl.AddLast(New closedlist(tx,ty,tpx,tpy)) findpathback Return True Else removefromopenlist(tx,ty) olmap[tx][ty] = 0 clmap[tx][ty] = 1 cl.AddLast(New closedlist(tx,ty,tpx,tpy)) For Local i:Int=0 Until xstep.Length Local x:Int=xstep[i] Local y:Int=ystep[i] newx = tx+x newy = ty+y If newx>=0 And newy>=0 And newx<mapwidth And newy<mapheight If olmap[newx][newy] = 0 If clmap[newx][newy] = 0 olmap[newx][newy] = 1 Local gg = map[newx][newy]+1 Local hh = distance(newx,newy,ex,ey) Local ff = gg+hh ol.AddLast(New openlist(newx,newy,ff,gg,hh,tx,ty)) End If End If End If Next End If Wend Return False End Method Method drawpath:Void() Local cnt:Int=1 For Local i:=Eachin path SetColor 255,255,0 DrawOval i.x*mymap.tilewidth,i.y*mymap.tileheight,4,4 SetColor 255,255,255 DrawText cnt,i.x*mymap.tilewidth,i.y*mymap.tileheight cnt+=1 Next End Method ' Here we calculate back from the end back to the ' start and create the path list. Method findpathback:Bool() Local x=ex Local y=ey path.AddFirst(New pathnode(x,y)) Repeat For Local i:=Eachin cl If i.x = x And i.y = y x = i.px y = i.py path.AddFirst(New pathnode(x,y)) End If Next If x = sx And y = sy Then Return True Forever End Method Method removefromopenlist:Void(x1:Int,y1:Int) For Local i:=Eachin ol If i.x = x1 And i.y = y1 ol.Remove i Exit End If Next End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class Class map Field mapwidth:Int Field mapheight:Int Field screenwidth:Int Field screenheight:Int Field tilewidth:Float Field tileheight:Float Field map:Int[][] Field covermap:Int[][] Method New(screenwidth:Int,screenheight:Int,mapwidth:Int,mapheight:Int) Self.screenheight = screenheight Self.screenwidth = screenwidth Self.mapwidth = mapwidth Self.mapheight = mapheight tilewidth = Float(screenwidth) / Float(mapwidth) tileheight = Float(screenheight) / Float(mapheight) map = New Int[mapwidth][] covermap = New Int[mapwidth][] For Local i:Int=0 Until mapwidth map[i] = New Int[mapheight] covermap[i] = New Int[mapheight] Next makemap(10) End Method Method makemap:Void(numobstacles:Int) For Local y=0 Until mapheight For Local x=0 Until mapwidth map[x][y] = 0 Next Next ' Here we create short lines on the map ' and sometimes draw some random blocks near them. For Local i:Int=0 Until numobstacles Local x1:Int=Rnd(4,mapwidth-4) Local y1:Int=Rnd(4,mapheight-4) Local dist:Int=Rnd(3,5) Local angle:Int=Rnd(0,360) Local x2:Float=x1 Local y2:Float=y1 While dist >= 0 x2 += Cos(angle) * 1 y2 += Sin(angle) * 1 dist -= 1 If x2<0 Or y2<0 Or x2>=mapwidth Or y2>=mapheight Then continue map[x2][y2] = 1000 ' If Rnd(10) < 2 Then ' If x2>2 And x2<mymap.mapwidth-2 And y2>2 And y2<mymap.mapheight-2 Then ' map[x2+Rnd(-1,1)][y2+Rnd(-1,1)] = 10 ' end if ' End If Wend Next End Method Method mapcollide:Bool(x:Int,y:Int,w:Int,h:Int) Local lefttopx:Int =((x)/tilewidth) Local lefttopy:Int =((y)/tileheight) Local righttopx:Int =((x+w)/tilewidth) Local righttopy:Int =((y)/tileheight) Local leftbottomx:Int =((x)/tilewidth) Local leftbottomy:Int =((y+h)/tileheight) Local rightbottomx:Int =((x+w)/tilewidth) Local rightbottomy:Int =((y+h)/tileheight) If lefttopx < 0 Or lefttopx >= mapwidth Then Return True If lefttopy < 0 Or lefttopy >= mapheight Then Return True If righttopx < 0 Or righttopx >= mapwidth Then Return True If righttopy < 0 Or righttopy >= mapheight Then Return True If leftbottomx < 0 Or leftbottomx >= mapwidth Then Return True If leftbottomy < 0 Or leftbottomy >= mapheight Then Return True If rightbottomx < 0 Or rightbottomx >= mapwidth Then Return True If rightbottomy < 0 Or rightbottomy >= mapheight Then Return True If map[lefttopx][lefttopy] <> 0 Then Return True If map[righttopx][righttopy] <> 0 Then Return True If map[leftbottomx][leftbottomy] <> 0 Then Return True If map[rightbottomx][rightbottomy] <> 0 Then Return True Return False End Method Method drawmap:Void() For Local y=0 Until mapheight For Local x=0 Until mapwidth If map[x][y] = 1000 SetColor 255,255,255 DrawRect x*tilewidth,y*tileheight,tilewidth,tileheight End If Next Next End Method Method drawcovermap:Void() For Local y=0 Until mapheight For Local x=0 Until mapwidth If covermap[x][y] = 1 SetColor 0,15,0 DrawOval x*mymap.tilewidth,y*mymap.tileheight,tilewidth,tileheight End If Next Next End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class ' The open list used by the astar Class openlist Field x:Int Field y:Int Field f:Int Field g:Int Field h:Int Field px:Int Field py:Int Method New( x:Int=0,y:Int=0,f:Int=0, g:Int=0,h:Int=0,px:Int=0,py:Int=0) Self.x=x Self.y=y Self.f=f Self.g=g Self.h=h Self.px=px Self.py=py End Method End Class ' The closed list used by the astar Class closedlist Field x:Int Field y:Int Field px:Int Field py:Int Method New(x:Int,y:Int,px:Int,py:Int) Self.x = x Self.y = y Self.px = px Self.py = py End Method End Class ' the pathnodes (x and y variables) ' used by the astar Class pathnode Field x:Int Field y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Global mymap:map Global myastar:astar Global myplayer:player Global mybullet:List<bullet> = New List<bullet> Global myenemy:List<enemy> = New List<enemy> Class MyGame Extends App Field playerwins:Int Field enemywins:Int Method OnCreate() Seed = GetDate[4] * GetDate[5] SetUpdateRate(60) ' Create a new map mymap = New map(DeviceWidth(),DeviceHeight(),30,30) myastar = New astar() myplayer = New player() For Local i:Int=0 Until 10 myenemy.AddLast(New enemy()) Next End Method Method OnUpdate() myplayer.update() For Local i:=Eachin myenemy i.update() Next For Local i:=Eachin myenemy If i.deleteme = True Then myenemy.Remove(i) Next For Local i:=Eachin mybullet i.update() Next For Local i:=Eachin mybullet If i.deleteme = True Then mybullet.Remove(i) Next ' if no more enemies then reset level If myenemy.IsEmpty Or myplayer.died Or KeyHit(KEY_TILDE) If myplayer.died Then enemywins+=1 If myenemy.IsEmpty Then playerwins+=1 mymap = New map(DeviceWidth(),DeviceHeight(),30,30) myastar = New astar() myenemy = New List<enemy> mybullet = New List<bullet> myplayer = New player() For Local i:Int=0 Until 10 myenemy.AddLast(New enemy()) Next End If End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 mymap.drawmap() mymap.drawcovermap() For Local i:=Eachin myenemy i.draw() Next For Local i:=Eachin mybullet i.draw() Next myplayer.draw() 'drawdebug SetColor 255,255,255 DrawText "AI - 'Taking Cover' Locations - Example.`(Tilde = new level)",0,DeviceHeight-15 DrawText "Controls - cursor u/d/l/r and F - fire",0,15 DrawText "Matches Player Wins : " + playerwins + " vs Enemy Wins : " + enemywins,DeviceWidth/2,0,.5,0 End Method End Class Function drawdebug() SetColor 255,255,255 For Local i:=Eachin myenemy i.drawpath() Next Return Scale(.7,.7) For Local y:Int=0 Until mymap.mapwidth For Local x:Int=0 Until mymap.mapheight DrawText myastar.map[x][y],(x*mymap.tilewidth)*1.4,(y*mymap.tileheight)*1.4 Next Next End Function Function Main() New MyGame() End Function