Here's a new version of the editor/map engine.
Added proper smooth scrolling.(Hold in rmb and drag mouse on map to scroll, even while editing)
Added line paste, this lets you drag a line(And scroll, it's not limited to the screen, it anchors to the tile under the mouse when you started)..it highlights what it'll draw, just drag and let go to paste.
Means you can now do most walls in two clicks, rather than manually doing each tile.
doing lightmapping part, now..here's where it gets intresting ;)
Added proper smooth scrolling.(Hold in rmb and drag mouse on map to scroll, even while editing)
Added line paste, this lets you drag a line(And scroll, it's not limited to the screen, it anchors to the tile under the mouse when you started)..it highlights what it'll draw, just drag and let go to paste.
Means you can now do most walls in two clicks, rather than manually doing each tile.
doing lightmapping part, now..here's where it gets intresting ;)
;For ;Top Down; ; ; ;Map and fx editor. ; ;Set up code by Rob Farley. ; ;Editor V2.0 Coded by Antony Wells. ; ;Open Source. ;-[setup by Rob farley.] Include "M_Engine.bb" Graphics 800,600,32,2 HidePointer Global overBase.base,hitBase.base Global tileW#=32,tileH#=32 Global maxtile = 190 Global tiles = LoadAnimImage("gfx/tiles.png",tileW,tileH,0,maxtile) Global cursor = LoadImage("gfx/cursor.png") MaskImage cursor,255,0,255 SetBuffer BackBuffer() font = LoadFont("Arial.tff",15) SetFont font ;-------------] Global cTile.tile genTiles() Color 128,128,128 newButton( 10,540,60,20,"Load") newButton( 80,540,60,20,"Save") Color 255,0,0 newbutton( 150,540,60,20,"Clear") ;newButton( 220,540,60,20,"U tileV.tile=First tile viewY=300 ViewX=600 fromX=20 fromY=20 dragB.base=newButton(GraphicsWidth()/2-40,viewY-10,80,20,"Drag") dragC.base=newButton(ViewX-20,viewY/2-20,40,40,"Pull") dragA.base=newButton(20-10,20-10,20,10,"#") dragD.base=newButton(fromX+viewX-10,fromY+viewY-10,20,20,"//") Color 20,128,128 newText(GraphicsWidth()-100,5,"Edit Modes") aMode.base=newText(GraphicsWidth()-150,40,"Mode:Paste") pasteM.base=newButton(GraphicsWidth()-80,20,50,20,"Paste") fillM.base=newButton(GraphicsWidth()-80,50,50,20,"Fill") lineM.base=newButton(GraphicsWidth()-80,80,50,20,"Line") lightM.base=newbutton(GraphicsWidth()-80,110,50,20,"Lights") ;lightM.base=newButton(GraphicsWidth()-80,130,50,20," Global overTile.tile ;--- ;---[ Map Specific] ;set up default blank map initMap(555,555) ;- Repeat Cls:uiCycle(); mx#=MouseX() my#=MouseY() If MouseHit(1) Select state Case 0 If overTile<>Null cTile=overTile End Select EndIf If MouseHit(2) Select state Case 0 If overTile<>Null If ctile<>Null tnTile.tile=Before cTile Insert cTile Before overTile Insert overTile After tnTile EndIf EndIf End Select EndIf mxs=MouseXSpeed() mys=MouseYSpeed() FlushMouse Select uiHit() Case "Paste" cMode=1 rename(amode,"Mode:Paste") Case "Fill" cMode=2 rename(amode,"Mode:Fill") Case "Line" cMode=3 rename(amode,"Mode:Line") Case "Lights" cMode=4 rename(aMode,"Mode:Lights") Case "Drag" viewY=mY-fromY Case "Pull" viewX=mX-fromX Case "#" fromX=mx-viewX/2 fromY=my dragA\x=mx+20 dragA\y=my-10 ; viewX=fromX Case "//" viewY=mY-fromY viewX=mX-fromX Default If MouseDown(3) If overTile<>Null If Not MouseDown(1) fromX=fromX+mxs fromY=fromY+mys dragA\Y=draga\y+mys Else viewX=viewX+mxs viewY=viewY+mys EndIf EndIf EndIf End Select FlushMouse dragA\w=viewX draga\x=fromX dragD\x=viewX-10+fromX dragD\y=viewY-10+fromY dragB\y=viewY-10+fromY DragB\x=viewX/2-40+fromX dragC\x=viewX-20+fromX dragC\y=viewY/2-20+fromY mz=MouseZSpeed() If mz>0 For mz=mz To 0 Step -1 tileV=After tileV If tileV=Null tileV=First tile Next Else If mz<0 For mz=Abs(mz) To 0 Step -1 tileV=Before tileV If tileV=Null tileV=Last tile Next EndIf ;-[ The following code contains the parts that actually edit the map) renderMap() dumpTiles(tileV,fromX,fromY,viewX,viewY) If cTile<>Null DrawImage cTile\id,MouseX(),MouseY() If Not ((mx>fromx And mx<(fromx+viewX) And my>fromY-10 And my<fromy+viewY) Or overBase<>Null Or hitBase<>Null) tileX=mapx+Int(mx+xoff)/Int(tileW) tileY=mapy+Int(my+yoff)/Int(tileH) Color 255,0,0 Rect (tileX-mapX)*tileW-xoff,(tiley-mapY)*tileH-yoff,tileW,tileH,0 If MouseDown(1) Select cMode Case 4 If nullLights=False ; addLight() nullLights=True EndIf Case 2 fillTile(cTile,tileX,tileY) Case 3 If lineIn=False startX=mx startY=my tileSX=tileX tileSY=tileY lineIn=True Else tileEX=tileX tileEy=tileY endX=mx endY=my lineHighLight(tileSx,tileSy,tileEx,tileEy) EndIf Default pasteTile(cTile,tileX,tileY) End Select Else If lineIn ;Line startx,starty,endx,endy lineTile(ctile,tilesx,tilesy,tileex,tileey) lineIn=False EndIf EndIf If MouseDown(2) Select cMode Case 2,1,3,4 scrollMap(-mxs*0.7,-mys*0.7) End Select EndIf EndIf Color 255,255,255 ; Rect fromX,fromY+viewY,ViewX,4 ; Rect fromX+viewX,fromY,4,viewY Rect fromX,fromY,viewX,viewY,0 renderGui() ;This lets you shift the mouse cursor to the closet button ;in the direction the mouse is moving when you press TAB ;This speeds up editing a lot. If KeyDown(15) cx#=Float(MouseX())+Float(mxs)*6 cy#=Float(MouseY())+Float(mys)*6 xb=Sgn(mxs) yb=Sgn(mys) cbase.base=Null sd#=999999 If MilliSecs()>ws+500 For b.base =Each base If b\is=ui_button And b<>overBase ix#=b\x+b\w/2 iy#=b\y+b\h/2 xd#=ix-cx yd#=iy-cy bx=Sgn(xd) by=Sgn(yd) If bx=xb And by=yb td#=Sqr(xd*xd+yd*yd) If td<sd cbase.base=b sd=td ws=MilliSecs() EndIf EndIf EndIf Next If cbase<>Null lockX=cbase\x+cbase\w/2 lockY=cbase\y+cbase\h/2 DrawImage cursor,lockx,lockY Flip Repeat Until KeyDown(15)=0 MoveMouse lockX,lockY FlushMouse EndIf EndIf EndIf DrawImage cursor,MouseX(),MouseY() Color 255,0,0 If lineIn Line (tilesx-mapx)*tileW+tileW/2-xoff,(tilesy-mapy)*tileh+tileH/2-yoff,endx,endy EndIf Color 255,255,255 Text 1,1,mxs+" >"+mys ;-- Flip Until KeyDown(1) Function saveMap() End Function Function loadMap() End Function Function genTiles() For j=0 To maxTile-1 t.tile =New tile t\id=CreateImage(tileW,tileH) CopyRect 0,0,tileW,tileH,0,0,ImageBuffer(tiles,j),ImageBuffer(t\id) If imageEmpty(t\id) FreeImage t\id Delete t EndIf Next End Function Function dumpTiles(t.tile,x,y,maxWidth=250,maxHeight=250,smartDump=True,checkMouse=True) ox#=x oy#=y If t=Null t=First tile mx#=MouseX() my#=MouseY() Viewport x,y,maxWidth,maxHeight If checkMouse overTile=Null dispW=GraphicsWidth() dispH=GraphicsHeight() start.tile=t Repeat tc=tc+1 DrawImage t\id,x,y If checkMouse If mx>x And mx<x+tileW If my>y And my<y+tileH overTile=t EndIf EndIf EndIf If t=cTile Color 255,255,255 Rect x,y,tilew,tileh,0 EndIf x=x+tileW If smartDump If x=>ox+maxWidth x=ox y=y+tileH If y=>oy+maxHeight-1 Exit ;y=0 EndIf EndIf t=After t If t=Null t=First tile Until t=start Viewport 0,0,GraphicsWidth(),GraphicsHeight() ;DebugLog tc End Function Function uiCycle() mx=MouseX() my=MouseY() Local but[3] but[0]=MouseDown(1) but[1]=MouseDown(2) but[2]=MouseDown(3) If but[0]=False hitBase=Null overBase=Null For b.base=Each base If mx>b\x And mx<b\x+b\w If my>b\y And my<b\y+b\h overBase=b If but[0] If hitbase=Null hitBase=overBase EndIf EndIf EndIf Next End Function Function uiHit$() If hitBase<>Null Return hitbase\id End Function Function uiOver$() If overBase<>Null Return overBase\id End Function ;--- DO CUBIC LIGHTING FOR CRYO NEXT< YO Function imageEmpty(image,imagePoint=5000,maskR=255,maskG=0,maskB=255,resetMask=True) SetBuffer ImageBuffer(image) LockBuffer iw=ImageWidth(tiles) ih=ImageHeight(tiles) For x=0 To ImageWidth(image)-1 For y=0 To ImageHeight(image)-1 rgb=ReadPixelFast(x,y) r#=(rgb Shr 16) And 255 g#=(rgb Shr 8) And 255 b#=(rgb And 255) If resetMask If r=maskR And b=maskB And g=MaskG WritePixelFast(x,y,0 Or (0 Shl 8) Or (0 Shl 16)) r=0 g=0 b=0 EndIf EndIf rd#=r-lr# gd#=g-lg# bd#=b-lb# shift#=shift+Sqr(rd*rd+gd*gd+bd*bd) lr#=r lg#=g lb#=b Next Next UnlockBuffer SetBuffer BackBuffer() If shift>imagePoint Return False Return True End Function ;-SmallGUI ;just buttons for now, but will expand for the game it's self. Type cache Field img Field x,y,width,height End Type Type base Field is Field x,y,w,h Field id$,r,g,b End Type Global doCache=0 Const ui_button=1,ui_text=2 Function newButton.base(x,y,w,h,title$) b.base= New base b\is=ui_button b\x=x b\y=y b\w=w b\h=h b\r=ColorRed() b\g=ColorGreen() b\b=ColorBlue() b\id=title doCache=True Return b ; Return Handle(b) End Function Function newText.base(x,y,txt$) b.base=New base b\x=x b\y=y b\is=ui_text b\id=txt b\r=ColorRed() b\g=ColorGreen() b\b=ColorBlue() doCache=True Return b End Function Function rename(in.base,txt$) in\id=txt End Function Function renderGui() For b.base =Each base Select b\is Case ui_button Color 20,20,20 Rect b\x+5,b\y+5,b\w,b\h,1 If hitbase=b xm#=5 ym#=5 Else xm=0 ym=0 EndIf Color b\r,b\g,b\b Rect b\x+xm,b\y+ym,b\w,b\h Color 255,255,255 Rect b\x+xm,b\y+ym,b\w-1,b\h-1,0 Color 40,40,40 Rect b\x+xm+1,b\y+ym+1,b\w-1,b\h-1,0 Color 10,10,10 Text b\x+xm+b\w/2,b\y+ym+b\h/2,b\id,True,True Color 255,255,255 Text b\x+xm+b\w/2,b\y+ym+b\h/2-3,b\id,True,True Case ui_text Color 5,5,5 Text b\x+4,b\y+4,b\id Color b\r,b\g,b\b Text b\x,b\y,b\id End Select Next End Function Function genCaches() sx#=9999 sy#=9999 bx#=-9999 sy#=-9999 For b.base =Each base x2#=b\x+b\w y2#=b\y+b\h If b\x<sx sx=b\x If b\y<sy sy =b\y Next End Function
;Map Engine 2 ; ;Original coded by Antony Wells Type tile Field id End Type Dim map.tile(0,0,0) Dim info#(0,0,0,15) ;just temp info for the map editor alone. Global mapWidth,mapHeight,mapDepth Global xoff#,yoff#,mapX#,mapY# ;mapx,y in tiles, xoff/yoff offset in pixels(Within range of 0 to tileWidth-1) Global tileWidth,tileHeight Function scrollMap(x#,y#) ;in pixels. xOff=xOff+x yOff=yOff+y If xOff<0 mapX=mapX-1 xoff=tileWidth-Abs(xoff) Else If xOff>tileWidth mapX=mapX+1 xoff=xoff-tileWidth EndIf ; Return If yOff<0 mapy=mapY-1 yoff=tileHeight-Abs(yoff) Else If yOff>tileHeight mapy=mapy+1 yoff=yoff-tileHeight EndIf ; xoff=Wrap(xoff,tileWidth) ; ypff=Wrap(yoff,tileHeight) End Function ;recursive wrap. Function Wrap#(val#,top#) If val<0 val=top-Abs(val) EndIf If val>top val=val-top EndIf Return val End Function Function initMap(width,height,tileW2=32,tileH2=32,depth=4) Dim map.tile(width,height,depth) Dim info(width,height,depth,15) mapWidth=width mapHeight=height tileWidth=tileW2 tileHeight=tileH2 mapDepth=depth End Function Function pasteTile(tile.tile,x,y,layer=1) If x<0 Or x>mapWidth Or y<0 Or y>mapheight Or layer<0 Or layer>mapDepth Return map(x,y,layer)=tile End Function Function fillTile(tile.tile,x,y,layer=1,smartFill=False) If smartFill Else For mx=0 To mapWidth-1 For my=0 To mapHeight-1 map(mx,my,layer)=tile Next Next EndIf End Function Function highLight(sx,sy,layer=1) info(sx,sy,layer,1)=True End Function Function lineHighlight(sx#,sy#,ex#,ey#,layer=1) xd#=ex-sx yd#=ey-sy If Abs(xd)>Abs(yd) steps=Abs(xd) Else steps=Abs(yd) xi#=xd/Float(steps) yi#=yd/Float(steps) For steps=steps To 0 Step -1 highlight(sx,sy,layer) sx=sx+xi sy=sy+yi Next End Function Function lineTile(tile.tile,sx#,sy#,ex#,ey#,layer=1) xd#=ex-sx yd#=ey-sy If Abs(xd)>Abs(yd) steps=Abs(xd) Else steps=Abs(yd) xi#=xd/Float(steps) yi#=yd/Float(steps) For steps=steps To 0 Step -1 pasteTile(tile,sx,sy,layer) sx=sx+xi sy=sy+yi Next End Function Function clearMap() Dim map.tile(mapWidth,mapHeight,mapDepth) End Function Function renderMap() tileHorz=GraphicsWidth()/tileWidth ;how many tiles we can see horizontally. tileVert=GraphicsHeight()/tileHeight ;vertically speaking, this is the same. For td=1 To mapDepth For tx=mapX To mapX+TileHorz If tx>-1 And tx<mapWidth For ty=mapY To mapY+tileVert If ty>-1 And ty<mapheight tile.tile=map(tx,ty,td) If tile<>Null ax=rx*tileWidth-xoff ay=ry*tileHeight-yoff DrawImage tile\id,ax,ay If info(tx,ty,td,1) info(tx,ty,td,1)=False Color 255,255,255 Rect ax,ay,tileW,tileH,0 EndIf EndIf EndIf ry=ry+1 Next ry=0 EndIf rx=rx+1 Next Next End Function