Community Project - Alien Breed game

Miscellaneous Forums/Blitz Showcase/Community Project - Alien Breed game

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

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 ;)
;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