I have been working on a vertically scrolling shooting game in Godot for a few months and learned a few things that may help you:
The way my scrolling works is that the background along with ground enemies are (sub)children to a node that moves down the screen. This allows for things such as player movement and enemy behavior to use their global_position with screen coordinates; e.g:
extends Pseudocode2D #not checked for errors
Player_Character = $Player_Node2D
_Scroll_Node = $Scroll_Node2D
_Enemy_NPC = _Scroll_Node.get_child("Enemy_Node2D")
_Background_Node = _Scroll_Node.get_child("Background_Tilemap")
const SCREEN_SIZE : Vector2 = Vector2(240,320) #vertical aspect ratio
var _Stop_Scroll_for_Boss : bool = false
func _process(delta):
if _Stop_Scroll_for_Boss == false:
_Scroll_Node.position.y += delta #scrolls screen down
#^ remember: larger y values are further down the screen in godot
#Move character inside the screen using global coords:
var _Player_Translation = Input.get_vector("left","right","up","down") * Vector2(delta,delta) #idk off the top of my head if get_vector is normalized or not. if it isn't; add .normalized() to Input,get_vector()
Player_Character.global_position = clamp(Player_Character.global_position + Input.Controller_Vector, Vector2.ZERO, SCREEN_SIZE)
# ^ in practice, you'll probably want to add some 'cushion pixels' to the clamp for game feel
#Make an enemy change state right before it scrolls onto the screen:
if _Enemy_NPC.global_position.y > -10:
_Enemy_NPC._do_enemy_activate_function()
if _Enemy_NPC.is_a_boss == true and _Enemy_NPC.global_position > 40: #stop the scroll when the boss is 40px from the top of the screen
_Enemy_NPC.emit_signal("Scroll_Stop_Signal") #imply signal is connected to this script
#Seal enemies from shooting when offscreen:
if _Enemy_NPC.global_position != clamp(_Enemy_NPC.global_position, Vector2.ZERO, SCREEN_SIZE):
_Enemy_NPC.can_shoot = false
# ^ again, for game feel, you'll probably want to add some cushion pixels to this clamp
func Scroll_Stop_Signal():
_Stop_Scroll_for_Boss = true
In a way this is 'backwards': the whole world moves down instead of the player and camera moving up, but it really should be considered for an arcade autoscroller. I'm certainly open to any better ideas if anyone has any.
Also, in my game I also have some side to side horizontal scrolling. This X position is determined by the player's global_position divided by some_number. All bullets should move independently of the vertical scrolling, but SHOULD move with horizontal scrolling, if you choose to have it (not a necessary mechanic)
Hope this helps