2d world with zoom ?
BlitzMax Forums/BlitzMax Programming/2d world with zoom ?
| ||
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 |
| ||
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. |
| ||
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. |
| ||
thanks guys ill check em out |
| ||
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 |
| ||
Can't you use SetOrigin to change the center of rotation? |