; ; ;--------------------------------------------------------------------------; ; ; Step 10 ; ; ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,; ; ;,,,, ; Limiting the screen to the size of the background. ; All you need to do is alter the visual/screen positions. ; The world coordinates stay the same. ; Only the things that you see will be different. ; ; So it's basically as the program from step 8. ; Only new things are when reaching an edge ; of the background. ; What needs to be done is: ; ; 1) Altering the background position *on screen* ; 2) Altering the player position *on screen* ;---- ; ;,,,, ; First, we need to check when an edge is reached. ; ; B-------------------------------+··bpY····- ; | | ^ ; | S---=---=---=---+···········|··- | ; | | | | ^ | ; | ( ) | | | bsY ; | | | | | | ; | ( ) | | ssY | ; | | | | | v ; +---(- - - - - - - -)-----------+··|······- ; · | | v ; · +---=---=---=---+··············- ; · ; bpX ; ; Legend ; (bpX,bpY) Back_Pos ; (bsX,bsY) Back_Size ; (ssX,ssY) Screen_Size ; ; You see that the lower edge of the background has been crossed. ; What we want is this: ; ; B---S---=---=---=---+-----------+ ; | | | | ; | | | | ; | | | | ; | | | | ; | | | | ; | | | | ; | | | | ; +---+---=---=---=---+-----------+ ; ; So how do we do this? ; Below I've marked two vertical positions. ; Background limit bL and Screen limit sL. ; ; (bpX,bpY) ; \ ; B-------------------------------+·········- ; | | ^ ; | S---=---=---=---+···········|··- | ; | | | | ^ | ; | ( ) | | | bsY ; | | | | | | ; | ( ) | | ssY | ; | | | | | v ; +---(- - - - - - - -)-----------+··|······-··bL ; | | v ; +---=---=---=---+··············-··sL ; ; You can see that bL has a lower value than sL. ; So we need to set bL to sL if bL is lower than sL. ; ; Okay let's zoom in on these vertical points. ; ; The orientation is our screen, where (0,0) is exactly ; in the upperleft corner (on the 'S' in the picture). ; ; This means that sL is the screen height. ; ; Furthermore, zooming in on point bL.. ; ; -----------------+···-···········-··· bpY ; | | bpY ^ ; -------+············|···-······ 0 | ; | | | ; | background | | bsY ; | | | ; screen | | | ; | | v ; |------------+···············-··· bL ; | ; -----------+ ; ; In the picture above you can see that.. ; ; bL = bpY + bsY ; ; So, in english, in bL is lower than sL, set bL to sL. ; ; if bL < sL then bL = sL ; ; Let's fill in what we know.. ; ; sL = Screen_SizeY ; bL = Back_PosY + Back_SizeY ; ; if Back_PosY + Back_SizeY < Screen_SizeY then ; Back_PosY + Back_SizeY = Screen_SizeY ; ; The assignment is not yet correct, though. ; So let's flip Back_SizeY to the other side, ; since we want to change the background position, not the size. ; ; Back_PosY = Screen_SizeY - Back_SizeY ; ; Ofcourse, the same goes for the horizontal right edge. ; ; Let's continue with the upperleft corner, ; being the upper and left edge of the background. ; ; S---=---=---=---+··············-···· 0 ; | | | bpY ; B---(- - - - - - - -)-----------+··-···· bpY ; | | | | ; | ( ) | ; | | | | ; | ( ) | ; | | | | ; | +---=---=---=---+ | ; | | ; +-------------------------------+ ; ; You can see that bpY should not (visually) go below 0. ; So bpY should be set to 0 when its value its value is above 0. ; Remember, Y+ still means *down* on today's computer system. ; ; Still in english, if the value of bpY is higher than 0, set bpY to 0. ; ; if bpY > 0 then bpY = 0 ; ; Okay, what is bpY? ; ; bpY = Back_PosY ; ; Fill it in. ; ; if Back_PosY > 0 then Back_PosY = 0 ; ; And again the same goes for the horizontal dimension. ;---- ; ;,,,, ; Next, the player needs adjustment when nearing ; the edge of the background. ; ; E.g. before it always stayed in the middle of the screen. ; We want it to actually move away from the middle of the screen instead. ; ; You can do a lot of fancy stuff to pull this off. ; However, you could also use the background position we just calculated ; to find where to draw the player on screen. ; ; Remember the view point formula from step 9? ; ; Player_ScreenPos = Screen_Mid - View_WorldPos ; ; We used the middle of the screen as orientation. ; And an added (or subtracted) offset of the view point. ; ; This is the basics for what we're gonna do next. ; ; Take the following situation for example: ; ; S---=---=---=---+ ; | | ; B---(- - - - - - - -)-----------+ ; | | | | ; | ( P ) | ; | | | | ; | ( ) | ; | | | | ; | +---=---=---=---+ | ; | | ; +-------------------------------+ ; ; We can already apply the background position adjustment. ; But what we want is that the player keeps ; its relative position at this point. ; ; B---S---=---=---=---+-----------+ ; |o o|· · · · · · · ·|o o o o o o| ; b-o-(-·-·-·-P-·-·-·-)-o-o-o-o-o-+ ; |o o|· · · · · · · ·|o o o o o o| ; | o ( · · · p · · · ) o o o o o | ; |o o|· · · · · · · ·|o o o o o o| ; | o ( · · · · · · · ) o o o o o | ; |o o|· · · · · · · ·|o o o o o o| ; +---+---=---=---=---+-----------+ ; | | ; +- - - - - - - - - - - - - - - -+ ; ; Legend ; b Background pos before adjustment ; B Background pos after adjustment ; p Player pos before adjustment ; P Player pos after adjustment ; S Screen pos (0,0) ; ; You can quickly see that the change from b to B ; is exactly the same as the change from p to P! ; ; So we have to know the distance between b and B. ; Even though we do not directly know what b is, ; because we changed it to become B. ; ; Look at following equation: ; ; Computer = Board + Processor + Memory + Drive ; ; Now we add something: ; ; Computer = Computer + Power ; ; A neat trick we can do is we can remove all components ; from the computer and find our power supply back. ; ; FindPower = Computer - ( Board + Processor + Memory + Drive ) ; ; FindPower would now equal Power. ; The same technique we're gonna use to find 'b'. ; ; Only difference (gah!) is that we're using ; the alleged orientation point again. ; ; We can calculate the background screen position using: ; ; Back_ScreenPos = Back_WorldPos - Player_WorldPos + Screen_Mid ; ; Now check in which range this value will be.. ; ; ( 0 ) to ( Screen_Size - Back_Size ) ; ; Screen size minus background size? ; ; -··B-------------------------------+··- ; bpY | | | ^ ; -··|···S---=---=---=---+··- | | ; | | | ^ | | ; | ( ) | | | bsY ; | | | | | | ; | ( P ) | ssY | | ; | | | | | v ; +---(- - - - - - - -)--|--------+··- ; | | v ; +---=---=---=---+··- ; ; So it's *never* outside this range. ; ; That's why we can strip the entire original contents: ; ; n = Back_ScreenPos - ( Back_WorldPos - Player_WorldPos + Screen_Mid ) ; ; Now, you *know* this will always be *zero* ; when it is not influenced by something else. ; ; Suppose we let the player move up. ; ; S---=---=---=---+ ; | | ; B---(- - - - - - - -)-----------+ ; | | | | ; | ( P ) | ; | | | | ; | ( ) | ; | | | | ; | +---=---=---=---+ | ; | | ; +-------------------------------+ ; ; And we apply our background adjustment, ; e.g. let loose our four IF hounds err statements.. ; So the vertical position would be set to: 0. ; ; ^ S---=---=---=---+··· 0 ^ ; | | | | ; B---(- - - - - - - -)-----------+ ; | | | | ; | ( P ) | ; | | | | ; | ( ) | ; | | | | ; | +---=---=---=---+ | ; | | ; +-------------------------------+ ; ; Now let's fill in the vertical values in the formula: ; ; n = Back_ScreenPos - ( Back_WorldPos - Player_WorldPos + Screen_Mid ) ; ; Back_ScreenPos = 0 (capped) ; Back_WorldPos = 0 (constant) ; Player_WorldPos = Screen_Size * 1/4 (or something like that) ; Screen_Mid = Screen_Size * 1/2 (constant) ; ; Let's solve it. ; ; n = 0 - ( 0 - Screen_Size * 1/4 + Screen_Size * 1/2 ) ; n = 0 - ( Screen_Size * 1/2 - Screen_Size * 1/4 ) ; n = Screen_Size * 1/4 - Screen_Size * 1/2 ; n = Screen_Size * 1/4 - Screen_Size * 2/4 ; n = -Screen_Size * 1/4 ; ; So our player is (vertically) placed a quarter outside of the screen. ; What happened? ; ; Well, we used orientation (0,0). ; So just add half the screen and it'll be centered on screen again. ; ; n = Back_ScreenPos ; - ( Back_WorldPos - Player_WorldPos + Screen_Mid ) ; + Screen_Mid ; ; Yes, that can be simplied, as follows; ; ; n = 0 ; - ( Back_WorldPos + -Player_WorldPos + Screen_Mid ) ; + Back_ScreenPos + Screen_Mid ; ; n = 0 ; - Back_WorldPos + Player_WorldPos - ScreenMid ; + Back_ScreenPos + Screen_Mid ; ; n = Back_ScreenPos - Back_WorldPos + Player_WorldPos ; - Screen_Mid + Screen_Mid ; ; n = Back_ScreenPos - Back_WorldPos + Player_WorldPos ; ; The point is that when you know algebra well, ; it feels like your brain does this almost automatically. ; ; Anyway, our final equation is: ; ; Player_ScreenPos = Back_ScreenPos - Back_WorldPos + Player_WorldPos ; ; Which can be used continuously, after applying the background fix. ;---- ; -- Sizes -- Screen_SizeX = GraphicsWidth () Screen_SizeY = GraphicsHeight () Screen_MidX = Screen_SizeX / 2 Screen_MidY = Screen_SizeY / 2 ; Make background double size of screen to demonstrate the effect better. Back_SizeX = Screen_SizeX * 2 Back_SizeY = Screen_SizeY * 2 Player_SizeX = 20 Player_SizeY = 20 ; -- Positions -- Back_WorldPosX = 0 Back_WorldPosY = 0 Player_WorldPosX = 0 Player_WorldPosY = 0 ; Put player in middle of background. Player_WorldPosX = Back_SizeX / 2 Player_WorldPosY = Back_SizeY / 2 ; -- Loop -- SetBuffer BackBuffer () Repeat ; -- Input -- ; Arrow keys control player world position. If KeyDown ( 200 ) Then Player_WorldPosY = Player_WorldPosY - 3 If KeyDown ( 208 ) Then Player_WorldPosY = Player_WorldPosY + 3 If KeyDown ( 203 ) Then Player_WorldPosX = Player_WorldPosX - 3 If KeyDown ( 205 ) Then Player_WorldPosX = Player_WorldPosX + 3 ; -- Logic -- ; Background screen position calculation (2 lines). Back_ScreenPosX = Back_WorldPosX - Player_WorldPosX + Screen_MidX Back_ScreenPosY = Back_WorldPosY - Player_WorldPosY + Screen_MidY ; Background screen position fix (4 lines). If Back_ScreenPosX > 0 Then Back_ScreenPosX = 0 If Back_ScreenPosY > 0 Then Back_ScreenPosY = 0 ; If you can recall from the beginning; ; ; if Back_PosY + Back_SizeY < Screen_SizeY then ; Back_PosY = Screen_SizeY - Back_SizeY ; ; Note that the notation below does exactly the same thing :) If Back_ScreenPosX <= -Back_SizeX + Screen_SizeX Back_ScreenPosX = -Back_SizeX + Screen_SizeX End If If Back_ScreenPosY <= -Back_SizeY + Screen_SizeY Back_ScreenPosY = -Back_SizeY + Screen_SizeY End If ; Magical player screen position calculation (2 lines). Player_ScreenPosX = Back_ScreenPosX - Back_WorldPosX + Player_WorldPosX Player_ScreenPosY = Back_ScreenPosY - Back_WorldPosY + Player_WorldPosY ; -- Render -- Rect Back_ScreenPosX , Back_ScreenPosY , Back_SizeX , Back_SizeY , False Rect Player_ScreenPosX,Player_ScreenPosY,Player_SizeX,Player_SizeY,False Flip Cls Until KeyHit ( 1 ) End ;,,,, ; Now, when running the program, it may be a little disorienting. ; This is because you have to travel quite some time ; before you reach the end of the background. ; ; And please, tell me if something - *anything* - was unclear ;) ; The address is TheChance (TheChange@yahoo.com). ; Constructive spam can be useful too :P ;----