Below a code example of a simple scrolling topdown rpg. You can collect coins and keys. With the eys you can open doors. There is nothing much else to do.
code below : ' Import mojo ' 1 = wal, 2 = door, 3 = key, 4 = coin, 5 = tree, 6 = water, 7 = rock Global map:Int[][] = [ [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,1,3,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,1,0,0,0,5,5,5,5,0,0,1,1], [1,1,4,0,0,0,2,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,4,1,0,0,0,0,5,5,5,0,0,1,1], [1,1,4,0,0,0,1,0,0,0,0,2,0,0,0,0,0,0,1,0,4,1,0,0,0,1,1,1,1,0,0,0,0,0,5,5,0,0,1,1], [1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,1,2,1,1,0,0,0,0,0,0,0,5,5,0,0,0,1,1], [1,1,3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,5,5,5,5,0,0,1,1], [1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,5,5,0,0,0,1,1], [1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,1,1], [1,1,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,1,1], [1,1,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1], [1,1,5,5,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,7,0,0,0,1,1], [1,1,5,5,5,0,0,0,0,0,0,5,5,5,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,1,1], [1,1,5,5,5,5,0,0,0,0,0,0,5,5,0,0,0,0,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,1,1], [1,1,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,7,7,7,0,0,0,0,0,1,1], [1,1,0,0,5,5,5,7,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,7,0,0,0,0,1,1], [1,1,0,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,1,1], [1,1,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1], [1,1,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,1,1], [1,1,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1], [1,1,6,6,6,6,6,6,6,6,6,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,1,1,1,2,1,1,1,1], [1,1,6,6,6,6,6,6,6,6,6,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1], [1,1,6,6,6,6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,1,0,0,0,0,3,1,1], [1,1,3,0,6,6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,7,0,0,0,0,1,1,1,2,1,1,1,1], [1,1,4,0,0,0,6,6,6,6,6,0,0,0,0,0,7,0,0,0,0,0,5,5,5,0,0,0,0,0,0,0,1,4,4,4,4,4,1,1], [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,1,4,4,4,4,4,1,1], [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,4,4,4,4,1,1], [1,1,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,4,4,4,4,1,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ] Class player Field x:Float=3*tilewidth Field y:Float=3*tileheight Field width:Int = tilewidth Field height:Int = tileheight Field keys:Int = 0 Field coins:Int = 0 Field lives:Int = 3 End Class ' the player class in p Global p:player = New player Const mapwidth:Int=40 Const mapheight:Int=30 Const tilewidth:Int=32 Const tileheight:Int=32 Global mapx:Int=0 Global mapy:Int=0 Global mapsx:Int=0 Global mapsy:Int=0 Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() ' p.x = MouseX() ' p.y = MouseY() For Local i=0 Until 2 If p.x > DeviceWidth / 2 If mapx+20 < mapwidth-1 mapsx-=1 If mapsx < 0 Then mapsx = 31 mapx += 1 Endif p.x-=1 End If End If Next For Local i=0 Until 2 If p.x < DeviceWidth / 2 If mapx > 0 mapsx+=1 If mapsx > 32 Then mapsx = 0 mapx -= 1 Endif p.x+=1 End If End If Next ' scrolling down For Local i=0 Until 2 If p.y > DeviceHeight / 2 If mapy+14 < mapheight-1 mapsy-=1 If mapsy < 0 Then mapsy = 31 mapy += 1 Endif p.y-=1 End If End If Next ' scrolling up For Local i=0 Until 2 If p.y < DeviceHeight / 2 If mapy > 0 mapsy+=1 If mapsy > 31 Then mapsy = 0 mapy -= 1 Endif p.y+=1 End If End If Next If KeyDown(KEY_RIGHT) ptcs(1,0) For Local i=0 Until 2 If ptc(1,0) = False p.x+=1 End If Next End If If KeyDown(KEY_LEFT) ptcs(-1,0) For Local i=0 Until 2 If ptc(-1,0) = False p.x-=1 End If Next End If If KeyDown(KEY_UP) ptcs(0,-1) For Local i=0 Until 2 If ptc(0,-1) = False p.y-=1 End If Next End If If KeyDown(KEY_DOWN) ptcs(0,1) For Local i=0 Until 2 If ptc(0,1) = False p.y+=1 End If Next End If End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 drawmap SetColor 255,255,0 DrawOval p.x,p.y,p.width,p.height SetColor 0,0,0 DrawRect 0,0,DeviceWidth,32 SetColor 255,255,255 DrawText "Keys : "+p.keys,10,0 DrawText "Coins : "+p.coins,10,16 DrawText "Lives : "+p.lives,96,0 DrawText "Use Cursor keys to move.",DeviceWidth/2,0 DrawText "Collect keys/coins, open doors",DeviceWidth/2,16 End Method End Class ' player collide with special blocks. Function ptcs:Int(offsetx:Int=0,offsety:Int=0) Local cx = (p.x+offsetx)/tilewidth+mapx Local cy = (p.y+offsety)/tileheight+mapy For Local y2=cy-1 Until cy+4 For Local x2=cx-1 Until cx+4 If x2>=0 And x2<mapwidth And y2>=0 And y2<mapheight If map[y2][x2] > 0 Local x3 = (x2-mapx)*tilewidth-32+mapsx Local y3 = (y2-mapy)*tileheight+mapsy If rectsoverlap(p.x+offsetx,p.y+offsety,p.width,p.height,x3,y3,tilewidth,tileheight) = True Select map[y2][x2] Case 2 If p.keys > 0 map[y2][x2] = 0 p.keys-=1 End If Case 3 'keys map[y2][x2] = 0 p.keys+=1 Case 4 'coins map[y2][x2] = 0 p.coins+=1 End Select End If End If End If Next Next Return 0 End Function 'player collide with solid blocks true/false Function ptc:Bool(offsetx:Int=0,offsety:Int=0) Local cx = (p.x+offsetx)/tilewidth+mapx Local cy = (p.y+offsety)/tileheight+mapy For Local y2=cy-1 Until cy+4 For Local x2=cx-1 Until cx+4 If x2>=0 And x2<mapwidth And y2>=0 And y2<mapheight If map[y2][x2] = 1 Or map[y2][x2] = 2 Or map[y2][x2] = 5 Or map[y2][x2] = 6 Or map[y2][x2] = 7 Local x3 = (x2-mapx)*tilewidth-32+mapsx Local y3 = (y2-mapy)*tileheight+mapsy If rectsoverlap(p.x+offsetx,p.y+offsety,p.width,p.height,x3,y3,tilewidth,tileheight) = True Return True End If End If End If Next Next Return False End Function Function drawmap:Void() For Local y=0 To 14 For Local x=0 To 20 Local x1 = ((x*tilewidth)+mapsx)-tilewidth Local y1 = ((y*tileheight)+mapsy) Select map[y+mapy][x+mapx] Case 1'Wall SetColor 100,100,100 DrawRect x1,y1,tilewidth,tileheight Case 2'Door SetColor 200,100,0 DrawRect x1,y1,tilewidth,tileheight Case 3'Key SetColor 200,200,0 DrawOval x1+4,y1+4,tilewidth-8,tileheight-8 SetColor 255,255,255 DrawText "K",x1+tilewidth/2,y1+tileheight/2,0.5,0.5 Case 4'Coin SetColor 255,255,0 DrawOval x1+4,y1+4,tilewidth-8,tileheight-8 SetColor 255,255,255 DrawText "$",x1+tilewidth/2,y1+tileheight/2,0.5,0.5 Case 5'tree SetColor 0,200,0 DrawPoly([Float(x1+16),y1 ,x1+tilewidth,y1+tileheight , x1,y1+tileheight]) Case 6'water SetColor 0,0,200 DrawRect x1,y1,tilewidth,tileheight Case 7'rock SetColor 150,50,0 DrawRect x1,y1+10,tilewidth,tileheight-10 End Select Next Next 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 Function drawboxedrect:Void(x:Int,y:Int,w:Int,h:Int) DrawLine x,y,x+w,y DrawLine x,y,x,y+h DrawLine x,y+h,x+w,y+h DrawLine x+w,y,x+w,y+h End Function Function Main() New MyGame() End Function
This comment has been removed by the author.
ReplyDeleteYou should look up more on tilemaps and tiles. You draw a checkers board on the screen fillled with drawings. You draw with the for command. You set the amount of images are drawn horizontally and Vertically. I have a tilemap example on this blog.
ReplyDeleteDon't know if you already know this, but "XYZ = True" is redundant, completely unnecessary, code. The function already evaluates as True or False. It's the same as writing "True = True" or "False = True". In both cases, the "True = True" a single True from the left-hand value would return the same value and "False = True" a single False from the left-hand value would return the same value.
ReplyDeleteAlso, I wouldn't recommend using "Then" in the If statements since it was removed in MX2, unless you don't care about easier portability.
On a related to your example here note, tilemap layers can be done in a single layer. It's faster and easier to process (well, for the computer, maybe not humans). Also using map chunking can really help, especially if you want to do things like map looping easily and extreme resource management. There's a few other things I can add, but I know this is just a quick example. So it's fine. I've been working on a large RPG for years and so I learned a lot over the years about how to optimize it to the maximum extent. Tilemaps took me a long time to get ultra fast loading and rendering and thanks to Mojo2, various tricks can be used to speed it up further.