I am making a metroidvania game in godot, it’s my first time. Right now I have one scene that has a layout of the whole world, something that I find challenging with this is managing how the camera can move in the space, I tried using area2d’s and where it would grab the dimensions of the collisonshape2d and and apply the camera limits to those dimension, but when it would switch from room to room i would notice a weird glitch and i feel like there is a better way to go about this.
Its a very broad question and there is no one way. I can’t help you with the ‘glitch’ and I don’t know exactly what you want to achieve but here is a general idea. Now I find getting camera movement just right extremely challenging but worth the effort. It can completely change a games feel and is as difficult as getting the player movement right if not harder. So don’t panic if it is not perfect first time.
I usually have a state manager for my camera, where I define different movements for different states. The game controller tells the camera to switch states, but other places can too sometimes, like that quick peak from a player to a goal point and back, or to an incoming enemy and back.
My state names should explain what each does:
follow player
move to target
freeze
follow target
peak at target
I also have additional behaviours like shake, freeze, zoom out, zoom in that can be enacted too on the camera driven by signals of course.
And my move-to-target is usually a couple of different ones like
glide to target
swoosh to target
cut to target
So I add a statemanager to my camera and switch states. For you one of the states would be for instance ‘move to new room’ or something similar before ‘follow player’ enacts again.
Anyway, I hope that helped in some way. If you have a more exact question I would be glad to help further.
Assign the Camera2D to the player as a child node.
You can then add code to keep the camera from leaving the tilemap.
## Sets the camera's boundaries to be that of the used tiles on the passed
## TileMapLayer.
func update_camera_boundaries(tile_map_layer: TileMapLayer) -> void:
var map_boundaries: Rect2i = tile_map_layer.get_used_rect()
var tile_size: Vector2i
tile_size.x = tile_map_layer.tile_set.tile_size.x
tile_size.y = tile_map_layer.tile_set.tile_size.y
map_boundaries.position *= tile_size
map_boundaries.size *= tile_size
limit_top = map_boundaries.position.y
limit_left = map_boundaries.position.x
limit_bottom = map_boundaries.end.y
limit_right = map_boundaries.end.x
Literally just pass the TileMapLayer that you are using, and the camera won’t move beyond it.
Limiting to Rooms
If you want to limit it to a room like Metroid, add this code to your Camera2D:
Then, figure out the size of each room in pixels and pass it in as a Rect2i when they enter the room. You set a Rect2i by passing the top left corner as position and then a Vector2i as the width and height (in pixels) of the room.
Then place Aera2D nodes outside the room, so when the player passes through the boundary, you trigger a room change. Once you get that working, you can work on a smoother camera transition.
I’m working on an easier way to do this in a plugin. All that code is from a plugin I’m working on.