2d world with zoom ?

BlitzMax Forums/BlitzMax Programming/2d world with zoom ?

slenkar(Posted 2008) [#1]
has anyone got an idea how I would create a playing field like the battle part of star control?

2d with zoomable point of view,

I tried using just setscale but the 'camera' is fixed at the top left of the playing area


Warpy(Posted 2008) [#2]
From my 'how to do things' folder:

Global gwidth#,gheight#

Global panx#=0,pany#=0,zoom#=1,tzoom#=zoom





Function transformpoly#[](poly#[] , px# , py# , an# , scale# = 1) 

	'px, py: translate

	'an: rotate

	'scale: duhhh thicko

	

	Local opoly#[Len(poly)]

	

	can# = Cos(an)

	san#=Sin(an)

	For n=0 To Len(poly)-1 Step 2

		x#=poly[n]*scale

		y#=poly[n+1]*scale

		opoly[n]=x*Can-y*San+px

		opoly[n+1]=x*San+y*Can+py

	Next

	Return opoly

End Function



Function zoompoly#[](poly#[])

	Local opoly#[Len(poly)]

	For n=0 To Len(poly)-1 Step 2

		opoly[n]=zoomx(poly[n])

		opoly[n+1]=zoomy(poly[n+1])

	Next

	Return opoly

End Function



Function drawrotatedline#(x1# , y1# , x2# , y2# , px# , py# , an# , scale# = 1)

	'px,py: translate

	'an: rotate

	'scale: duhhh thicko

	

	can# = Cos(an)

	san# = Sin(an)

	

	nx1#=(x1*can-y1*san)*scale+px

	ny1#=(x1*san+y1*can)*scale+py

	nx2#=(x2*can-y2*san)*scale+px

	ny2#=(x2*san+y2*can)*scale+py

	DrawLine nx1,ny1,nx2,ny2

End Function



Function drawoutline(poly#[],thickness=1)

	'DrawPoly poly

	SetLineWidth thickness

	l = Len(poly)

	For n=0 To l-3 Step 2

		x1#=poly[n]

		y1#=poly[n+1]

		x2#=poly[(n+2) Mod l]

		y2#=poly[(n+3) Mod l]

		DrawZoomLine x1,y1,x2,y2

	Next

	SetLineWidth 1

End Function





Function ZoomX#(x#)

	Return (x - panx) * zoom + gwidth / 2

End Function

Function ZoomY#(y#)

	Return (y - pany) * zoom + gheight / 2

End Function



Function UnzoomX#(x#)

	Return (x - gwidth / 2) / zoom + panx

End Function

Function UnzoomY#(y#)

	Return (y - gheight / 2) / zoom + pany

End Function



Function DrawZoomPoly(poly#[],outline=False)

	poly=poly[..]

	While i < Len(poly)

		poly[i] = zoomx(poly[i])

		poly[i + 1] = zoomy(poly[i + 1]) 

		i:+ 2

	Wend

	If outline

		ox# = poly[0]

		oy# = poly[1]

		i = 2

		While i < Len(poly)

			DrawLine ox , oy , poly[i] , poly[i + 1]

			ox = poly[i]

			oy=poly[i+1]

			i:+ 2

			DrawLine poly[0],poly[1],ox,oy

		Wend

	Else

		DrawPoly poly

	EndIf

End Function



Function DrawZoomLine(ax# , ay# , bx# , by#)

	ax = zoomx(ax)

	ay = zoomy(ay)

	bx = zoomx(bx)

	by = zoomy(by)

	DrawLine ax,ay,bx,by

End Function



Function DrawZoomRect(x# , y# , width# , height#,zoomdimensions=1,filled=1)

	x = zoomx(x)

	y = zoomy(y)

	If zoomdimensions

		width:* zoom

		height:* zoom

	EndIf

	If filled

		DrawRect x , y , width , height

	Else

		DrawLine x , y , x + width , y

		DrawLine x + width , y , x + width , y + height

		DrawLine x , y , x , y + height

		DrawLine x , y + height , x + width , y + height

	EndIf

End Function



Function DrawZoomCircle(x# , y# , radius#)

	x = zoomx(x) 

	y = zoomy(y)

	radius:* zoom

	DrawOval x - radius , y - radius , 2 * radius , 2 * radius

End Function



Function DrawZoomText(txt$ , x# , y#)

	x = ZoomX(x)

	y = ZoomY(y)

	DrawText txt , x , y

End Function



Function DrawZoomImage(image:TImage , x# , y#,width#,heighto=0)

	If heighto

		w# = width / ImageHeight(image)

	Else

		w# = width / ImageWidth(image)

	EndIf

	SetScale w*zoom , w*zoom

	DrawImage image , zoomx(x) , zoomy(y)

	SetScale 1,1

End Function





'graphics init

Function initgfx()

	Graphics gwidth , gheight

End Function


Seems I haven't got round to putting this in the code archives yet... I use it all the time, so I'll add it now.


Digital Anime(Posted 2008) [#3]
I just posted this small example somewhere else :

http://server.dedicatedservices.org/upload/zip/retro.zip

Use cursor keys to move UFO,
and other keys to move stretch and rotate it all.

Might give an idea on how it works, even tho I think it could be written better.


slenkar(Posted 2008) [#4]
thanks guys ill check em out


Will(Posted 2008) [#5]
This thing is what I use for offsetting, rotating and zooming the view in my games.



'View Orientations

SetGraphicsDriver(GLMax2DDriver()) 'make sure we are in openGL as these only work for OGL


Type ViewOrientation
	Global initialized
	
	Global current:viewOrientation
	
	Field selfInitialized
	
	Field leftEdge#
	Field rightEdge#
	Field bottomEdge#
	Field topEdge#
	
	Field XPos#, YPos#, Zoom#=1, Rotation#=0
	Field vpSavedX#, vpSavedY#
	
	Global realwidth#
	Global realheight#
	
	Global vpX, vpY
	Global currentWidth#
	Global currentHeight#
	
	Global naturalZoom#
	
	Function init()
		If realwidth <> GraphicsWidth() Or realheight <> GraphicsHeight() Or (initialized = False And GraphicsHeight() <> 0) Then
			initialized = True
			naturalZoom = GraphicsHeight() / 768.0
			realwidth = GraphicsWidth()
			realheight = GraphicsHeight()
			currentWidth = realWidth
			currentHeight = realHeight
		End If
	End Function
	
	Function clear:viewOrientation()
		nv:viewOrientation = New vieworientation
		nv.apply()
		Return nv
	End Function
	
	Method New()
		init()
		selfInit()
	End Method
	
	Method selfInit()
		If selfInitialized = True Or GraphicsHeight() = 0 Then Return
		
		selfInitialized = True
		
		leftEdge = 0
		rightEdge = GraphicsWidth()
		topedge = 0
		bottomEdge = GraphicsHeight()
		
		XPos = GraphicsWidth()/2
		YPos = GraphicsHeight()/2
	End Method
	
	Method move(x#, y#, rot#=0)
		setXYZoomRot(XPos + x, Ypos + y, Zoom, Rotation + rot)
	End Method
	
	Method setXY(x#, y#)
		setX(x); setY(y)
	End Method
	
	Method setXYZoomRot(x#, y#, Z#, R#)
		setX(x); setY(y)
		setZoom(Z); SetRotation(R)
	End Method
	
	Method setXYH(x#, y#, h#)
		setZoom(realheight / h)
		setxy(x + (rightEdge-leftEdge)*.5, y + (bottomEdge-topedge)*.5)
	End Method
	
	Method setX(x#)
		XPos = x
		calculate()
	End Method
	
	Method setY(y#)
		YPos = y
		calculate()
	End Method
	
	Method setZoom(Z#)
		Zoom = Z
		calculate()
	End Method
	
	Method SetRotation(rot#)
		Rotataion = rot
		calculate()
	End Method
	
	Method Apply()
		selfInit()
		init()
		
		calculate()
		
		glMatrixMode(GL_PROJECTION)
		glLoadIdentity()
		gluOrtho2D(LeftEdge, rightEdge, bottomEdge, TopEdge)
		glMatrixMode(GL_MODELVIEW)
		glLoadIdentity()
		glTranslateF(xpos,ypos,0)
		glrotateF(Rotation, 0, 0, 1)
		glTranslateF(-xpos,-ypos,0)
		
		current = Self
		
	End Method
	
	Method calculate()
		selfInit()
		
		realZoom# = Zoom
		
		vpSavedX = vpX
		vpSavedY = vpY

		If realZoom = 0 Then Zoom = .00001
		LeftEdge = xpos - ((currentWidth / Zoom) / 2)
		rightEdge = xpos + ((currentWidth / Zoom) / 2)
		topEdge = ypos - ((currentHeight / Zoom) / 2)
		bottomEdge = ypos + ((currentHeight / Zoom) / 2)		
	End Method
	
	Method screenSpaceToWorldSpace(wx# Var, wy# Var)
		wx:-vpSavedX
		wy:-vpSavedY
		wx:/zoom
		wy:/zoom
		wx:+leftEdge
		wy:+topEdge
	End Method
	
	Method worldSpaceToScreenSpace(wx# Var, wy# Var)
		wx:-leftEdge
		wy:-topedge
		wx:*zoom
		wy:*zoom
		wx:+vpSavedX
		wy:+vpSavedY
	End Method
	
	Method onScreen(wx#, wy#, radius#)
		wx:-leftEdge
		wy:-topedge
		wx:*zoom
		wy:*zoom
		radius:*zoom
		
		If wy + radius < 0 Or wy - radius > realheight Then Return 0
		If wx + radius < 0 Or wx - radius > realwidth Then Return 0
		
		Return 1
	End Method
	
	Function SetViewport(x,y,width,height)
		GLViewPort(x, GraphicsHeight() - y - height, width, height)
		
		vpX = x; vpY = y
		currentHeight = height
		currentWidth = width
		
		If current <> Null Then current.apply()
		
	End Function
	
	Function ClearViewport()
		ViewOrientation.SetViewport(0,0,GraphicsWidth(), GraphicsHeight())
		currentWidth = realWidth
		currentHeight = realheight
	End Function
	
End Type



ImaginaryHuman(Posted 2008) [#6]
Can't you use SetOrigin to change the center of rotation?