I am following a book example of Chris Bradfield "Godot 4 Gave Development Projects - Build Five cross platform 2D and 3D games 2nd Edition".
I am at the stage of having a very simple game "Coin Dash" where an animated fox can collect randomly spawn animated coins. Next stage is to take a green grass tile background image and stretch it over entire gameplay field, the author of the book claims:
Add the following nodes as children of Main:
• A TextureRect node named Background – for the background image
• A Timer node named GameTimer – for the countdown timer
>
Make sure Background is the first child node by dragging it above the player in the node list. Nodes are drawn in the order shown in the tree, so if Background is first, that ensures it’s drawn behind the player. Add an image to the Background node by dragging the grass.png image from the assets folder into the Texture property. Change Stretch Mode to Tile, and then set the size to Full Rect by clicking the layout button at the top of the editor window:
https://i.stack.imgur.com/5mtOL.png
My project structure looks like
And yet the 2D screen after setting the stretch mode to tile looks like
While the game works no problem, that little square in the top left screen corner should cover entire game play field and it doesn't. The frustration of a noob following a deceiving book is real since I have so little knowledge to juggle what is wrong in here:
The main script is as follows:
extends Node
@export var coin_scene : PackedScene
@export var playtime = 30
var level = 1
var score = 0
var time_left = 0
var screensize = Vector2.ZERO
var playing = false
func _ready():
screensize = get_viewport().get_visible_rect().size
$Player.screensize = screensize
$Player.hide()
new_game()
func new_game():
playing = true
level = 1
score = 0
time_left = playtime
$Player.start()
$Player.show()
$GameTimer.start()
spawn_coins()
func spawn_coins():
for i in level + 4:
var c = coin_scene.instantiate()
c.screensize = screensize
add_child(c)
c.position = Vector2(randi_range(0, screensize.x), randi_range(0, screensize.y))
Setting up full rect as anchor size and set "Stretch Mode" to "Tile"
The issue is that
Main
(the roof of the scene) is aNode2D
(I know it is aNode2D
because it has a blue circle icon).And as
Node2D
it does not have an size (yes, someNode2D
have a concept of size by virtue of having a texture, but that is not true forNode2D
in general, nor would it help here).So when
Background
tries to expand to the "Full Rect" of its parent, it can't. Because, to reiterate, its parentMain
does not have a size.I have three options for you…
Option A
Main
to be aNode
I believe this is the intention of the author, given that your script is defined to extend
Node
.The way this works is that the
Control
will disregard the parentNode
, so it takes the size of the parentViewport
(which is the root of the scene tree, the same one you get withget_viewport
).Option B
Main
to be aControl
The way this works is that the
Main
node will take the size of the parent viewport, so the background can take the size from it.Option C
Background
from theMain
script.You are already getting the size for the purpose of limiting the area where the coins can spawn. You can also set that size to
Background
.By the way, you might want to handle the
size_changed
signal of theViewport
, you can connect to it via code, see Using Signals.