2D Fundamentals
Godot Fundamentals
Chapter 4 · 2D Fundamentals
Every chapter so far has worked with an empty Node2D. This chapter makes something actually appear on
screen: displaying an image with Sprite2D, understanding exactly how Godot measures position in
2D space, and moving something across the screen using nothing more than what's already been covered.
Godot's 2D Coordinate System
Godot's 2D origin, (0, 0), sits at the top-left of the viewport. X increases
to the right, as you'd expect — but Y increases downward, not upward.
y value moves something down the screen, not up.
Increasing it moves an object right; decreasing it moves left.
Increasing it moves an object down; decreasing it moves up.
An (x, y) pair. position on every Node2D is itself a Vector2.
Position, Rotation & Scale
Every Node2D (and everything that extends it, including Sprite2D) automatically
has three built-in properties: position, rotation, and scale. These
were mentioned briefly in Chapter 1 — here's what each one actually does.
rotation is in radians — if degrees are more natural to think in, use
rotation_degrees instead; it's the same underlying value, just exposed in a different unit.
Sprite2D — Displaying an Image
Sprite2D is the node responsible for showing a 2D image (a "texture," in Godot's own
terminology). Add one as a child, assign it an image via its texture property, and it renders at
its parent's position.
More commonly, a texture is assigned directly in the editor's Inspector panel rather than from a script —
drag an image file onto the Sprite2D's own texture slot, and it's ready to go with
no code at all.
| Property | Does |
|---|---|
texture | The image to display |
centered | If true (the default), the image is centered on the node's own position; if false, its top-left corner sits at that position instead |
flip_h / flip_v | Mirror the image horizontally or vertically — useful for a character facing left vs. right |
Basic On-Screen Movement
Chapter 1 already showed the pattern for frame-rate-independent movement using _physics_process
and delta. Applied here to an actual visible sprite, the same idea makes something glide across
the screen.
Note this script extends Sprite2D directly, rather than a separate Node2D parent — since
Sprite2D already inherits position from Node2D, a script can be
attached straight to the sprite itself.
position works for a
simple demo, but it has no awareness of walls, floors, or other objects; it will happily move straight
through anything. Chapter 5 adds real input control, and Chapter 6 introduces CharacterBody2D
and collision — the node types built specifically for movement that actually respects the rest of the
game world.
Vector2(x, y) behaves a lot like a lightweight NumPy array of length 2 — you can add, subtract,
and scale two Vector2 values directly with +, -, and *, the same way
NumPy overloads those operators for arrays, rather than needing separate .x/.y
arithmetic every time. The Y-axis direction is the real trap to remember: a matplotlib plot or a
plain Cartesian mental model has Y increasing upward; Godot's 2D space does not.
Coding Challenges
position to Vector2(200, 300) and its scale to
Vector2(1.5, 1.5) in _ready(), and print the resulting position and scale.
_physics_process. Once its position.y passes 400, print "Reached the
bottom" exactly once (not on every frame after).
rotation in
_physics_process, making it spin steadily in place. Use rotation_degrees
instead of rotation and confirm the sprite still spins identically.
Quick Reference — 2D Fundamentals
- Origin (0, 0) is top-left; X increases right; Y increases down
position,rotation(radians;rotation_degreesfor degrees),scale— all on Node2D and everything that extends itSprite2D.texture— the image to display;centered,flip_h/flip_v- Direct movement:
position.x += SPEED * deltainside_physics_process - Directly setting
positionignores walls/collisions — real movement comes in Chapters 5-6