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
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.
Sunday, November 12, 2017
Monkey-X - Generator - Cartoon Clouds - code example
Monkey-X - Generator - 10 Print Chr - code example
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
Monkey-X - Beginners - Class in array - code example
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
Monkey-X - Lerp - Linear Interpolation - patrolling - code example
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
Friday, November 10, 2017
Monkey-X - Generator - Simple 2d Pixelart tree - code example
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
Thursday, November 9, 2017
Monkey-X - Generator - 2d Houses (town) - code example
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
Saturday, November 4, 2017
Monkey-X - Generator - 2D Fantasy maps (zelda ish) - code example
' 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
Thursday, November 2, 2017
Monkey-X - Generator - 2d Pixelart Potions - code example
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
Monkey-X - 2D Growing Slime Monster Mine - code example
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
Monkey-X - 2D Snake Style Water - code example
'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
Monday, October 30, 2017
Monkey-X - Generator - Tileable Textured Stones - code example
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
Monday, October 23, 2017
Monkey-x - Generator - 2d flasks and bottles - code example
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
Monkey-X - Generator - 2d Maps using Lines - code example
' 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
Monkey-X - Breath First Search(bfs) - code example
'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
Thursday, October 19, 2017
Monkey-X - Ai Taking Cover - Shooter - code example
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
Subscribe to:
Posts (Atom)