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.
Here a example where I create a image in a class and draw lines in it to form the shape of a asteroid. It then rotates the midhandled image. Uses bresenham's linealgorithm to draw in a array.
Import mojo Global numasteroids:Int=10 Global awidth:Int=64 Global aheight:Int=64 Class asteroid Field im:Image Field pixels:Int[awidth*aheight] Field x:Int,y:Int Field angle:Float=0 Field rotspeed:Float=Rnd(-3.3,3.3) Method New(x:Int,y:Int) im = CreateImage(awidth,aheight,1,Image.MidHandle) Self.x = x Self.y = y Local myan:Int=0 Local x1:Int,y1:Int Local x2:Int,y2:Int Local sx:Int,sy:Int x1 = awidth/2+((Cos(myan)*Rnd(16,32))) y1 = aheight/2+((Sin(myan)*Rnd(16,32))) sx=x1 sy=y1 For Local i=0 Until 10 myan+=350/10 x2 = awidth/2+((Cos(myan)*Rnd(16,32))) y2 = aheight/2+((Sin(myan)*Rnd(16,32))) bline(x1,y1,x2,y2) x1 = x2 y1 = y2 Next bline x1,y1,sx,sy im.WritePixels(pixels, 0, 0, awidth, aheight, 0) End Method Method update() angle+=rotspeed If angle > 359 Then angle = 0 If angle < 0 Then angle = 359 End Method Method draw() DrawImage im,x,y,angle,1.0,1.0,0 End Method Method bline:Void(x1:Int,y1:Int,x2:Int,y2:Int) Local dx:Int, dy:Int, sx:Int, sy:Int, e:Int dx = Abs(x2 - x1) sx = -1 If x1 < x2 Then sx = 1 dy = Abs(y2 - y1) sy = -1 If y1 < y2 Then sy = 1 If dx < dy Then e = dx / 2 Else e = dy / 2 End If Local exitloop:Bool=False While exitloop = False Local pc:Int = y1*awidth+x1 If pc>=0 And pc <awidth*aheight pixels[pc] = argb(255,255,255,255) End If If x1 = x2 If y1 = y2 exitloop = True End If End If If dx > dy Then x1 += sx ; e -= dy If e < 0 Then e += dx ; y1 += sy Else y1 += sy ; e -= dx If e < 0 Then e += dy ; x1 += sx Endif Wend End Method Function argb:Int(r:Int, g:Int, b:Int ,alpha:Int=255) Return (alpha Shl 24) | (r Shl 16) | (g Shl 8) | b End Function End Class Global myasteroids:List<asteroid> = New List<asteroid> Class MyApp Extends App Method OnCreate() SetUpdateRate(60) Local date := GetDate() Seed = date[5] For Local y=64 Until DeviceHeight Step 128 For Local x=64 Until DeviceWidth Step 128 myasteroids.AddLast(New asteroid(x,y)) Next Next End Method Method OnUpdate() For Local i:=Eachin myasteroids i.update Next End Method Method OnRender() Cls 0,0,0 For Local i:=Eachin myasteroids i.draw Next SetColor 255,255,255 DrawText "Monkey-X Class Image Asteroids example.",10,10 End Method End Class Function Main() New MyApp End Function
Useful thing this bresenham line function.
Import mojo Class MyApp Extends App Method OnCreate() SetUpdateRate(60) Local date := GetDate() Seed = date[5] End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 DrawText "Monkey-X Bresenham's line algorithm - function.",10,10 For Local i=0 Until 32 bline Rnd(0,640),Rnd(0,480),Rnd(0,640),Rnd(0,480) Next End Method End Class Function bline:Void(x1:Int,y1:Int,x2:Int,y2:Int) Local dx:Int, dy:Int, sx:Int, sy:Int, e:Int dx = Abs(x2 - x1) sx = -1 If x1 < x2 Then sx = 1 dy = Abs(y2 - y1) sy = -1 If y1 < y2 Then sy = 1 If dx < dy Then e = dx / 2 Else e = dy / 2 End If Local exitloop:Bool=False While exitloop = False SetColor 255,255,255 DrawPoint x1,y1 If x1 = x2 If y1 = y2 exitloop = True End If End If If dx > dy Then x1 += sx ; e -= dy If e < 0 Then e += dx ; y1 += sy Else y1 += sy ; e -= dx If e < 0 Then e += dy ; x1 += sx Endif Wend End Function Function Main() New MyApp End Function
Sometimes you need the width of the text that you have on the screen. See below how this can be done.
Import mojo Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 Local s:String="This is a string." Local tw:Int=TextWidth(s) SetColor 255,255,255 DrawText s,DeviceWidth()/2,100,0.5,0.5 DrawText "Width of text is :"+tw,DeviceWidth()/2,125,0.5,0.5 SetColor 255,255,255 DrawText "Monkey-X - TextWidth Example.",10,10 End Method End Class Function Main() New MyGame() End Function
Here something I read in a ai book. There are movement instructions in a array that the unit uses to move around. Patrol in a square like pattern here. You can also put coordinates in a array and move them like that.
Import mojo ' x : -1 = left , 1 = right ' y : -1 = up , 1 = down Global path1x:Int[] = [1,1,0,0,-1,-1,0,0] Global path1y:Int[] = [0,0,1,1,0,0,-1,-1] Global tilewidth:Int=32 Global tileheight:Int=32 Class ai Field x:Int,y:Int Field cpathpos:Int=0 Field delay Field delay2:Int Method New(x:Int,y:Int,delay:Int) Self.x = x Self.y = y Self.delay2 = delay Self.delay = 0 End Method Method update() delay-=1 If delay>0 Then Return delay = delay2 Select path1x[cpathpos] Case 1;x+=1 Case -1;x-=1 End Select Select path1y[cpathpos] Case 1;y+=1 Case -1;y-=1 End Select cpathpos+=1 If cpathpos >= path1x.Length Then cpathpos=0 End If End Method Method draw() SetColor 255,0,0 DrawOval x*tilewidth,y*tileheight, tilewidth,tileheight End Method End Class Global myai:List<ai> = New List<ai> Class MyApp Extends App Method OnCreate() SetUpdateRate(60) Local cnt:Int=10 For Local y=0 Until 5 For Local x=0 Until 5 cnt+=1 myai.AddLast(New ai(x*5,y*5,cnt)) Next Next End Method Method OnUpdate() For Local i:= Eachin myai i.update Next End Method Method OnRender() Cls 0,0,0 For Local i:=Eachin myai i.draw Next SetColor 255,255,255 DrawText "Monkey-X Pattern Movement example.",10,10 End Method End Class Function Main() New MyApp End Function
To not get the same random behaviour each time you start the game you can set the seed to use the GetDate current second.
Import mojo Global color:Int[] = New Int[3] Class MyApp Extends App Method OnCreate() SetUpdateRate(60) ' here Local date := GetDate() ' set the random seed to ' current second Seed = date[5] color[0] = Rnd(255) color[1] = Rnd(255) color[2] = Rnd(255) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 DrawText "Monkey-X different random seed each time.",10,10 For Local i=0 Until 3 SetColor color[i],0,0 DrawRect i*DeviceWidth()/3,0,DeviceWidth()/3,DeviceHeight() Next End Method End Class Function Main() New MyApp End Function
Here a example of how to move units that are grouped.
Import mojo Class ai ' unit locations Field x:Float,y:Float ' destination coords Field dx:Int,dy:Int ' movement speed Field ms:Float ' angle of x/y and dx/dy Field angle:Int Method New(x:Int,y:Int) Self.x = x Self.y = y Self.ms = Rnd(0.5,1.5) Self.dx = DeviceWidth()/2 Self.dy = DeviceHeight()/2 End Method Method update() angle = getangle(dx,dy,x,y) If distance(x,y,dx,dy) > 5 Local nx:Float = x+Cos(angle)*(ms*4) Local ny:Float = y+Sin(angle)*(ms*4) Local nxt:Bool=False For Local i:=Eachin myai If i.x <> x If i.y <> y If rectsoverlap(nx,ny,16,16,i.x,i.y,16,16) = True nxt = True End If End If End If Next If nxt = False x += Cos(angle)*ms y += Sin(angle)*ms End If End If End Method Method draw() SetColor 255,0,0 DrawOval x,y,16,16 End Method Method rectsoverlap:Bool( x1:Int, y1:Int, w1:Int, h1:Int, x2:Int, y2:Int, w2:Int, h2:Int) If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False Return True End Method Method getangle:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return ATan2(y1-y2, x1-x2) End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class Global numai:Int=10 Global myai:List<ai> = New List<ai> ' waittime before random new destination Global dxchangecountdown:Int=500 ' hold the destination of the units Global mydx:Int,mydy:Int Class MyApp Extends App Method OnCreate() SetUpdateRate(60) For Local i=0 To numai Local exitloop:Bool=False Local nx:Int,ny:Int While exitloop = False exitloop = True nx=Rnd(640) ny=Rnd(480) For Local ii:=Eachin myai If distance(nx,ny,ii.x,ii.y) < 32 exitloop = False End If Next Wend myai.AddLast(New ai(nx,ny)) Next Local date := GetDate() Seed = date[6] End Method Method OnUpdate() dxchangecountdown-=1 If dxchangecountdown < 0 dxchangecountdown = 500 mydx = Rnd(32,DeviceWidth()-64) mydy = Rnd(32,DeviceHeight()-64) For Local i:=Eachin myai i.dx = mydx i.dy = mydy Next End If For Local i:=Eachin myai i.update Next If MouseHit(MOUSE_LEFT) dxchangecountdown = 500 For Local i:=Eachin myai i.dx = MouseX() i.dy = MouseY() Next End If End Method Method OnRender() Cls 0,0,0 For Local i:=Eachin myai i.draw mydx = i.dx mydy = i.dy Next SetColor 255,255,0 DrawLine mydx,mydy,mydx-5,mydy DrawLine mydx,mydy,mydx+5,mydy DrawLine mydx,mydy,mydx,mydy-5 DrawLine mydx,mydy,mydx,mydy+5 SetColor 255,255,255 DrawText "Monkey-X group movement ai.",10,10 DrawText "Press the left mouse to change dx,dy",10,25 End Method End Class Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function Function Main() New MyApp End Function
This I learned about a long time ago. Basically you leave a trail and if the ai finds the trail then he starts to follow that trail.
Import mojo Global tilewidth:Int=16 Global tileheight:Int=16 Global aiwidth:Int=16 Global aiheight:Int=16 Class ai Field x:Int,y:Int Field readcountdown:Int Field state:String Field bcx:Int,bcy:Int Method New(x:Int,y:Int) Self.x = x Self.y = y readcountdown=Rnd(0,60) state="search" End Method Method update() If state="search" And distance(x,y,myplayer.x,myplayer.y) > 16 ' readcountdown-=1 If readcountdown<0 readcountdown=60 For Local i:=Eachin myplayercrumb If distance(i.x,i.y,x,y) < 32 DebugLog "Found crumbs" state="following" bcx = i.x bcy = i.y Exit End If Next End If End If If state="following" If x < bcx Then x+=1 If x > bcx Then x-=1 If y < bcy Then y+=1 If y > bcy Then y-=1 If x = bcx And y = bcy setnextbread() If distance(x,y,bcx,bcy) > 32 DebugLog "Out of range.." state="search" End If If distance(x,y,myplayer.x,myplayer.y) < 16 DebugLog "engaging player.." state="search" End If End If End If End Method Method setnextbread() Local prx:Int Local pry:Int For Local i:=Eachin myplayercrumb If i.x = x And i.y = y bcx = prx bcy = pry Return End If prx = i.x pry = i.y Next End Method Method draw() SetColor 255,0,0 DrawOval x,y,aiwidth,aiheight 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:Int,y:Int Field playerwidth:Int=16 Field playerheight:Int=16 Field playerspeed:Int=4 Field otx:Int,oty:Int Method New(x:Int,y:Int) otx = x oty = y Self.x = x*tilewidth Self.y = y*tileheight End Method Method update() For Local i=0 Until playerspeed Local newx:Int=x Local newy:Int=y If KeyDown(KEY_RIGHT) newx+=1 End If If KeyDown(KEY_LEFT) newx-=1 End If If KeyDown(KEY_UP) newy-=1 End If If KeyDown(KEY_DOWN) newy+=1 End If If newx>0 And newx<DeviceWidth()-playerwidth If newy>0 And newy<DeviceHeight()-playerheight x = newx y = newy End If End If If x = otx And y=oty Else myplayercrumb.AddFirst(New crumb(x,y)) If myplayercrumb.Count() > 196 Then myplayercrumb.RemoveLast() End If otx = x oty = y End If Next End Method Method draw() SetColor 0,0,255 DrawOval x,y,playerwidth,playerheight End Method End Class Class crumb Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Global myplayercrumb:List<crumb> = New List<crumb> Global myplayer:player = New player(10,10) Global myai:List<ai> = New List<ai> Class MyApp Extends App Method OnCreate() SetUpdateRate(60) myai.AddLast(New ai(100,100)) End Method Method OnUpdate() myplayer.update For Local i:=Eachin myai i.update Next End Method Method OnRender() Cls 0,0,0 drawplayerbreadcrumbs() For Local i:=Eachin myai i.draw Next myplayer.draw SetColor 255,255,255 DrawText "Monkey-X Bread crumb ai.",10,10 DrawText "Use cursors to move (blue) and leave trail..",10,25 End Method End Class Function drawplayerbreadcrumbs:Void() SetColor 100,100,100 For Local i:=Eachin myplayercrumb DrawPoint i.x+tilewidth/2,i.y+tileheight/2 Next End Function Function Main() New MyApp End Function
Here a example where turrets try to aim towards the path of the player so the bullet wil have more chance of hitting the player. There are 2 bullet speeds for the turrets. Control the player with the cursor keys.
Import mojo Class bullet Field x:Float,y:Float Field angle:Int Field speed:Float Field delete:Bool=False Method New(x:Int,y:Int,angle:Int,speed:Float) Self.x = x Self.y = y Self.angle = angle Self.speed = speed End Method Method update() x+=Cos(angle)*speed y+=Sin(angle)*speed If x<0 Then delete = True If x>DeviceWidth() Then delete = True If y<0 Then delete = True If y>DeviceHeight() Then delete = True End Method Method draw() SetColor 255,255,0 DrawOval x,y,8,8 End Method End Class Class turret Field x:Int,y:Int Field firecountdown:Int=30 Method New(x:Int,y:Int) Self.x = x Self.y = y End Method Method update() firecountdown-=1 If firecountdown<0 Then firecountdown = 30 Local firedist:Int=4 If distance(myplayer.x, myplayer.y,x,y) > 256 Then firedist=10 mybullet.AddLast(New bullet(x,y, getangle(myplayer.tx, myplayer.ty,x+Rnd(-16,16), y+Rnd(-16,16)), firedist)) End If End Method Method draw() SetColor 255,0,0 DrawOval x,y,32,32 End Method Method getangle:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return ATan2(y1-y2, x1-x2) End Method Function distance:Int(x1:Int,y1:Int,x2:Int,y2:Int) Return Abs(x2-x1)+Abs(y2-y1) End Function End Class Class player Field x:Float=100,y:Float=100 Field w:Float=32,h:Float=32 Field angle:Int Field speed:Float=0 Field tx:Int,ty:Int Method New() End Method Method update() If speed>0.0 Then speed-=0.05 If KeyDown(KEY_RIGHT) angle+=2 End If If KeyDown(KEY_LEFT) angle-=2 End If If angle<0 Then angle=360 If angle>360 Then angle=0 If KeyDown(KEY_UP) If speed < 2 Then speed+=.1 End If x+=Cos(angle)*speed y+=Sin(angle)*speed ' get the target coords for the turrets tx=x+(Cos(angle)*speed*32) ty=y+(Sin(angle)*speed*32) End Method Method draw() SetColor 100,100,0 For Local i=0 Until speed*20 Local y2=Int(Sin(angle)*i) Local x2=Int(Cos(angle)*i) DrawOval x+x2,y+y2,32,32 Next SetColor 255,255,255 DrawOval x,y,w,h Local y2:Int=(Sin(angle)*48) Local x2:Int=(Cos(angle)*48) DrawLine x+16,y+16,x+16+x2,y+16+y2 End Method End Class Global myturret:List<turret> = New List<turret> Global mybullet:List<bullet> = New List<bullet> Global myplayer:player = New player Class MyApp Extends App Method OnCreate() SetUpdateRate(60) myturret.AddLast(New turret(200,200)) myturret.AddLast(New turret(400,400)) End Method Method OnUpdate() For Local i:=Eachin myturret i.update Next For Local i:=Eachin mybullet i.update Next myplayer.update For Local i:=Eachin mybullet If i.delete = True Then mybullet.Remove i Next End Method Method OnRender() Cls 0,0,0 For Local i:=Eachin mybullet i.draw Next For Local i:=Eachin myturret i.draw Next myplayer.draw SetColor 255,255,255 DrawText "Monkey-X Targeting example.",10,10 DrawText "Cursor left and Right = turn , cursor up = move",10,30 End Method End Class Function Main() New MyApp End Function
Here a example with Copper Bars (old demo effect) It uses classes and Lists.
Import mojo Global numbars:Int=6 Class bar Field y:Float Field height:Int Field yspeed:Float Field direction:String Field incr:Float,incg:Float Field incb:Float Method New(ri:Float,gi:Float,bi:Float) height=Rnd(16,90) y = Rnd(height,DeviceHeight()-height) incr = 255/height incg = gi incb = bi If Rnd(10)<5 Then direction="up" Else direction="down" End If yspeed = Rnd(1,4) End Method Method update() If direction = "down" y+=yspeed Else y-=yspeed End If If y<0 Then direction = "down" If y>DeviceHeight()-90 Then direction = "up" End Method Method draw() Local ypos:Int=y Local r:Float,g:Float,b:Float For Local n:Int=0 To 1 For Local i=0 Until height/2 SetColor r,g,b DrawLine 0,ypos+i,DeviceWidth(),ypos+i r+=incr g+=incg b+=incb Next For Local i=0 Until height/2 SetColor r,g,b DrawLine 0,ypos+i+height/2, DeviceWidth(),ypos+i+height/2 r-=incr g-=incg b-=incb Next Next End Method End Class Global mybar:List<bar> = New List<bar> Class MyGame Extends App Method OnCreate() SetUpdateRate(60) For Local i=0 Until numbars mybar.AddLast(New bar(Rnd(155,255)/45,Rnd(0.5,2),Rnd(0.2,2))) Next End Method Method OnUpdate() For Local i:=Eachin mybar i.update Next End Method Method OnRender() Cls 0,0,0 For Local i:=Eachin mybar i.draw Next SetColor 255,255,255 DrawText "Monkey-X - Copper Bars and Classes/Lists Example.",10,10 End Method End Class Function Main() New MyGame() End Function
Here a small example of how to get a nice background effect on the screen. Here lines are drawn downwards and every step the color is slightly increased or decreased creating a rainbow like effect.
Import mojo Global bar1y:Float=0 Global bar1d:String="down" Global bar2y:Float=100 Global bar2d:String="down" Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() If bar1d="down" bar1y+=2.5 Else bar1y-=2.5 End If If bar2d="down" bar2y+=4 Else bar2y-=4 End If If bar1y<0 Then bar1d="down" If bar1y>DeviceHeight()-90 Then bar1d="up" If bar2y<0 Then bar2d="down" If bar2y>DeviceHeight()-90 Then bar2d="up" End Method Method OnRender() Cls 0,0,0 Local ypos:Int=bar1y For Local n:Int=0 To 1 If n=1 Then ypos=bar2y Local r:Float=0 Local g:Float=0 Local b:Float=0 For Local i=0 Until 45 SetColor r,g,b DrawLine 0,ypos+i,DeviceWidth(),ypos+i r+=2.5 g+=0.5 b+=0.2 If n=1 Then g+=2 Next For Local i=0 Until 45 SetColor r,g,b DrawLine 0,ypos+i+45,DeviceWidth(),ypos+i+45 r-=2.5 g-=0.5 b-=0.2 If n=1 Then g-=2 Next Next SetColor 255,255,255 DrawText "Monkey-X - Copperbar) Example.",10,10 End Method End Class Function Main() New MyGame() End Function
KeyDown is different then KeyHit. It will stay true for as long as the key is held down.
Import mojo Global lastpressed:Int=10 Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() lastpressed+=1 If KeyDown(KEY_SPACE) lastpressed = 0 End If End Method Method OnRender() If lastpressed < 10 Then Cls 200,200,200 Else Cls 0,0,0 End If SetColor 255,255,255 DrawText "Monkey-X - KeyDown(key) Example.",10,10 DrawText "Press the space bar....",10,30 DrawText "Space last held down "+lastpressed/60+" second(s) ago",100,100 DrawText "KeyDown(KEY_SPACE)",100,130 End Method End Class Function Main() New MyGame() End Function
KeyHit is different then KeyDown. Look at this example to understand it.
Import mojo Global lastpressed:Int=10 Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() lastpressed+=1 If KeyHit(KEY_SPACE) lastpressed = 0 End If End Method Method OnRender() If lastpressed < 10 Then Cls 200,200,200 Else Cls 0,0,0 End If SetColor 255,255,255 DrawText "Monkey-X - KeyHit(key) Example.",10,10 DrawText "Press the space bar....",10,30 DrawText "Space last pressed "+lastpressed/60+" second(s) ago",100,100 DrawText "KeyHit(KEY_SPACE)",100,130 End Method End Class Function Main() New MyGame() End Function
The screen of your game/application is like a piece of paper where the more right you go the more the x value gets. Same with the y value and the height of the screen. DeviceWidth has the total width. To draw something in the middle you can / (devide) by 2 and then draw the text using the .5, .5 settings (.5 = 1/2(center))
Import mojo Class MyGame Extends App Method OnRender() Cls 0,0,0 SetColor 255,255,255 DrawText "Monkey-X Beginner Example",10,10 DrawText "Center text on the screen.",10,30 DrawText "Center of Screen.",DeviceWidth()/2,DeviceHeight()/2,.5,.5 End Method End Class Function Main() New MyGame() End Function
DeviceWidth() and DeviceHeight hold the width and the height of your screen.
Import mojo Class MyGame Extends App Method OnRender() Cls 0,0,0 SetColor 255,255,255 DrawText "Monkey-X Beginner Example",10,10 DrawText "DeviceWidth and DeviceHeight...",10,20 DrawText "DeviceWidth() = "+DeviceWidth(),100,100 DrawText "DeviceHeight() = "+DeviceHeight(),100,200 End Method End Class Function Main() New MyGame() End Function
Here a function that you can use to see if lines collide. I ported the code from the old blitzcoder site. Link in the code.
collide x1,y1,x2,y2,x3,y3,x4,y4
' Ported from ' http://iadbungler.free.fr/bcoder/cgi-bin/code/Wc5f42637ead45.htm ' By ashcroftman Import mojo Global x1:Int=320-25 Global y1:Int=240-25 Global x2:Int=320+25 Global y2:Int=240+25 Global x3:Int,y3:Int Global x4:Int,y4:Int Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() x3 = MouseX() y3 = MouseY() x4=x3+25 y4=y3-25 End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 DrawLine x1,y1,x2,y2 DrawLine x3,y3,x4,y4 Local col:String="No Collision" If lineintersect(x1,y1,x2,y2,x3,y3,x4,y4) col = "Collision" End If DrawText "Line Collision example. Move the mouse on the line.",10,0 DrawText col,10,30 End Method End Class Function lineintersect:Bool( x1:Float,y1:Float,x2:Float,y2:Float, u1:Float,v1:Float,u2:Float,v2:Float) Local b1:Float = (y2 - y1) / (x2 - x1) Local b2:Float = (v2 - v1) / (u2 - u1) Local a1:Float = y1 - b1 *x1 Local a2:Float = v1 - b2 *u1 Local xi:Float = - (a1-a2)/(b1-b2) Local yi:Float = a1+b1*xi If (x1 - xi)*(xi-x2)> -1 And (u1-xi)*(xi - u2)> 0 And (y1-yi)*(yi-y2)>-1 And (v1-yi)*(yi-v2)>-1 Return True End Function Function Main() New MyGame End Function
I remember a game in the arcades that had this big spaceship that you could shoot and it would be destroyed block by block. I remade that here. The player automatically moves and shoots.
Import mojo ' this is the laser class Class laser Field x:Float,y:Float Field lw:Int=4 Field lh:Int=6 Field laserspeed:Int=4 Field delete:Bool=False Method New(x:Int,y:Int) Self.x=x Self.y=y End Method Method update() For Local i=0 Until laserspeed y-=1 Next If y<-10 Then delete = True End Method Method draw() SetColor 0,0,255 DrawRect x,y,lw,lh End Method End Class Class player Field x:Int Field y:Int ' player height and width Field ph:Int=16 Field pw:Int=16 Field playerspeed:Int=4 Field targetx:Int Field laserdelay:Int=0 Method New() Self.x = (DeviceWidth()/2)-(ph/2) Self.y = DeviceHeight()-ph End Method Method update() ' move the player around For Local i=0 Until playerspeed If x < targetx Then x+=1 If x > targetx Then x-=1 If x = targetx Then findtarget Next ' fire a laser every now and then laserdelay+=1 If laserdelay>10 Then laserdelay = 0 mylaser.AddLast(New laser(x,y)) End If End Method ' find new position to move to Method findtarget() targetx = Rnd(0,DeviceWidth()-pw) End Method Method draw() SetColor 255,255,0 DrawRect x,y,pw,ph End Method End Class Class enemy ' location where the sprite it at Field x:Int,y:Int ' Tile width and height Field tw:Int=16 Field th:Int=16 ' enemy movement Field edir:String="right" ' the sprite Field map:Int[][] = [ [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0], [1,1,1,2,2,1,1,1,1,1,1,1,2,2,1,1,1], [1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1], [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0], [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,1,1,1,0,0,1,2,2,2,2,1,0,0,1,1,1], [0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0], [0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0]] Field allgone:Bool=False Method New() ' Position the sprite Self.x = DeviceWidth()/2-((map[0].Length*tw)/2) Self.y = th*3 End Method Method update() ' move the enemy If edir="right" Then x+=1 Else x-=1 End If If x+(map[0].Length*tw) > DeviceWidth() Or x<0 Then If edir = "left" Then edir="right" Else edir="left" End If End If ' collision between the lasers and the enemy For Local i:=Eachin mylaser For Local y1=0 Until map.Length For Local x1=0 Until map[0].Length If map[y1][x1] > 0 Local x2:Int=(x1*tw)+x Local y2:Int=(y1*th)+y If rectsoverlap(i.x,i.y,i.lw,i.lh,x2,y2,tw,th) map[y1][x1]=0 i.delete = True End If End If Next Next Next ' if the enemy is completely gone then ' put this in the allgone variable allgone=True For Local y1=0 Until map.Length For Local x1=0 Until map[0].Length If map[y1][x1] > 0 allgone = False End If Next Next End Method Method draw() For Local y1=0 Until map.Length For Local x1=0 Until map[0].Length If map[y1][x1] = 1 SetColor 255,0,0 DrawRect x+(x1*tw),y+(y1*th),tw,th End If If map[y1][x1] = 2 SetColor 255,100,0 DrawRect x+(x1*tw),y+(y1*th),tw,th End If Next Next End Method Method rectsoverlap:Bool( x1:Int, y1:Int, w1:Int, h1:Int, x2:Int, y2:Int, w2:Int, h2:Int) If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False Return True End Method End Class Global myenemy:enemy Global myplayer:player Global mylaser:List<laser> Class MyApp Extends App Method OnCreate() SetUpdateRate(60) ' set up the stuff for ' the first time. myenemy = New enemy() myplayer = New player() mylaser = New List<laser> End Method Method OnUpdate() ' if the big sprite is destroyed ' then make him new again If myenemy.allgone = True myenemy = New enemy() End If ' update the classes myplayer.update myenemy.update For Local i:=Eachin mylaser i.update Next ' if a laser is set to delete ' then delete it from the list For Local i:=Eachin mylaser If i.delete = True Then mylaser.Remove i Next End Method Method OnRender() Cls 0,0,0 myenemy.draw For Local i:=Eachin mylaser i.draw Next myplayer.draw End Method End Class Function Main() New MyApp End Function
Sometimes you would want something unexpected to happen. You can do that with the Rnd Command. Press the space bar and see the text change on the screen. (The enemy might drop a item every now and then and how would we want to know this)
Import mojo Global mysetting1:Bool=False Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method OnUpdate() If KeyHit(KEY_SPACE) If Int(Rnd(0,3)) = 1 Then mysetting1 = True Else mysetting1 = False End If End If End Method OnRender() Cls 0,0,0 'set the color SetColor 255,255,255 DrawText "Press space bar to create random value.",10,10 If mysetting1 = True DrawText "Last random value was 1",100,50 End If If mysetting1 = False DrawText "Last random value was other then 1",100,50 End If End End Function Main() New MyGame() End
Here a short example of how to use a bool variable. Sometimes you need to remember something in your program and this shows how you can do something like that.
Import mojo Global mysetting1:Bool = False Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method OnUpdate() If KeyHit(KEY_SPACE) If mysetting1 = False Then mysetting1=True Else mysetting1=False End If End Method OnRender() Cls 0,0,0 'set the color SetColor 255,255,255 DrawText "Press space bar to change variable.",10,10 If mysetting1 = True DrawText "Variable bool set to true",100,50 End If If mysetting1 = False DrawText "Variable bool set to false",100,50 End If End End Function Main() New MyGame() End