Making the camera follow the character around the map
Root / Programming Questions / [.]
spaceturtlesCreated:
How exactly do I make the "camera" follow the player around a map until the camera reaches an edge of the map using the circle pad? I figured out how to do it one axis at a time but when the character reaches for instance the left edge the camera doesn't follow the character up or down. The same goes for any other edge. Code showing exactly how to do this properly is appreciated.
That does make it follow the player around until it hits an edge but how do I keep the camera centered on the player when it's not at an edge? Also my player distance is limited to the screen size so I can't scroll over the whole map with that.
How do I scroll the bg map until it hits an edge, move the sprite when the map can't move, allow the map to move along the border it touches, and make the map move again when the player is in the middle of the screen moving away from the edge so that it looks like the view follows the player around with the player in the center of the view until it reaches a border and then the player can move freely towards the border without the area outside of the map being visible? Basically like how player and camera movement works in starbound and terraria.
I haven't actually put this in SmileBasic just a notepad window, so there might be bugs, etc. Anyway, will something like this help?
OPTION STRICT 'Variable declarations VAR SCREEN_W% = 400, SCREEN_H% = 240 'The size of the screen (width is 320 on the bottom screen) VAR TILE_W% = 16, TILE_H% = 16 'Tile size, 16 is the default. VAR MAP_W% = 64, MAP_H% = 64 'The size of our map. Chose the default from the smile tool editor VAR CAM_MIN_X% = 0 'This the the smallest we allow the camera position. VAR CAM_MIN_Y% = 0 VAR CAM_MAX_X% = (MAP_W% * TILE_W%) - SCREEN_W% - 1 'This is the largest we allow the camera position. VAR CAM_MAX_Y% = (MAP_H% * TILE_H%) - SCREEN_H% - 1 VAR CAM_OFFS_X% = (SCREEN_W% - TILE_W%) / 2 'Offset of the camera from the player. Half a screen away minus have a sprite away VAR CAM_OFFS_Y% = (SCREEN_H% - TILE_H%) / 2 VAR CAM_X% = 0 'Where is the camera right now. VAR CAM_Y% = 0 VAR PLAYER% 'Player sprite VAR PLAYER_SPEED% = 3 'How fast does the player move. VAR PLAYER_X% = ((MAP_W% * TILE_W%) - TILE_W%) / 2 'Put the player is the center of the map. VAR PLAYER_Y% = ((MAP_H% * TILE_H%) - TILE_H%) / 2 VAR DX%, DY%, SX#, SY#, B% 'DX, DY = movement offset, SX, SY = circle pad status, B = Button status VAR GAME_OVER% = FALSE 'Are we still playing the game VAR I%, J% 'Generic loop counter variables. ACLS 'Reset everything to default BGSCREEN 1, MAP_W%, MAP_H% 'Resize the screen 'Fill the background with random junk. FOR J% = 0 TO MAP_H% - 1 FOR I% = 0 TO MAP_W% - 1 BGPUT 1, I%, J%, RND(64) + 127 NEXT I% NEXT J% 'Make a sprite for the camera to follow around. SPSET 413 OUT PLAYER% WHILE GAME_OVER% = FALSE 'Get Button Status B% = BUTTON() 'Get CirclePad Status STICK OUT SX#, SY# 'Reset DX/DY to not moving DX% = 0 DY% = 0 'Calculate how we are moving. IF (SX# < -0.5) OR ((B% AND #LEFT) != 0) THEN DX% = -1 ENDIF IF (SX# > 0.5) OR ((B% AND #RIGHT) != 0) THEN DX% = -1 ENDIF IF (SY# > 0.5) OR ((B% AND #UP) != 0) THEN DY% = -1 ENDIF IF (SY# < -0.5) OR ((B% AND #DOWN) != 0) THEN DY% = -1 ENDIF 'Check if game over IF (B% AND #X) != 0 THEN GAME_OVER% = TRUE ENDIF 'This could be more compact. Aiming for readability here. ' 'Update player position based on the input PLAYER_X% = PLAYER_X% + (DX% * PLAYER_SPEED%) PLAYER_Y% = PLAYER_Y% + (DY% * PLAYER_SPEED%) 'Clip their (world) location to the size of the map PLAYER_X% = MIN((MAP_W% * TILE_W%) - TILE_W% - 1, PLAYER_X%) PLAYER_X% = MAX(0, PLAYER_X%) PLAYER_Y% = MIN((MAP_Y% * TILE_H%) - TILE_H% - 1, PLAYER_Y%) PLAYER_Y% = MAX(0, PLAYER_Y%) 'Make the camera follow the player. CAM_X% = PLAYER_X% - CAM_OFFS_X% CAM_Y% = PLAYER_Y% - CAM_OFFS_Y% 'Clip the camera location to the map minus screen size. CAM_X% = MIN(CAM_MAX_X%, CAM_X%) CAM_X% = MAX(CAM_MIN_X%, CAM_X%) CAM_Y% = MIN(CAM_MAX_Y%, CAM_Y%) CAM_Y% = MAX(CAM_MIN_Y%, CAM_Y%) 'Move the background to the camera coordinates BGOFS 1, CAM_X%, CAM_Y% 'Move the player to the correct location on screen. 'PLAYER_X - CAM_X converts things from world coordinates to screen coordinates SPOFS PLAYER%, PLAYER_X% - CAM_X%, PLAYER_Y% - CAM_Y% 'Don't go too fast. VSYNC WEND 'CLEAN UP ACLS END
I think that works but the character keeps moving. I'm trying to find what got messed up.
I'm still not sure why.
Thanks @seggiepants! I've figured it out and adapted the code.
It looks like the bug was in my circle pad handling. left and down should check that SX# < -0.5 and SY# < -0.5. I will see if I can go back and edit the post.