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