Sprites, TileMapLayer & Cameras

For pixel art: *Project Settings → Rendering → Textures → Default Texture Filter = Nearest*, and use *Stretch Mode = viewport* or *canvas_items* with integer scaling.

23.1 Sprite2D

For pixel art: *Project Settings → Rendering → Textures → Default Texture Filter = Nearest*, and use *Stretch Mode = viewport* or *canvas_items* with integer scaling.

$Sprite2D.texture = preload("res://art/player.png")
$Sprite2D.flip_h = true
$Sprite2D.hframes = 4; $Sprite2D.vframes = 2; $Sprite2D.frame = 5   # sprite sheet
$Sprite2D.region_enabled = true
$Sprite2D.region_rect = Rect2(0, 0, 32, 32)
$Sprite2D.centered = true
$Sprite2D.offset = Vector2(0, -16)

23.2 TileMapLayer (Godot 4.3+)

A TileSet resource defines tiles (atlas sources, physics, navigation, custom data, terrains). Each TileMapLayer node is one layer of tiles.

Other API: get_used_cells(), get_used_rect(), get_cell_source_id(cell), get_cell_atlas_coords(cell), get_surrounding_cells(cell), clear().

Note: the older TileMap node with numbered layers (set_cell(layer, coords, ...)) is deprecated since 4.3; convert via the TileMap's toolbar ("Extract TileMap layers as individual TileMapLayer nodes"). In Godot 3, set_cell(x, y, tile_id) and autotiles were used.

@onready var ground: TileMapLayer = $Ground

func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventMouseButton and event.pressed:
		var cell: Vector2i = ground.local_to_map(ground.get_local_mouse_position())
		if event.button_index == MOUSE_BUTTON_LEFT:
			ground.set_cell(cell, 0, Vector2i(1, 0))      # source_id, atlas coords
		else:
			ground.erase_cell(cell)

func is_cell_deadly(cell: Vector2i) -> bool:
	var data: TileData = ground.get_cell_tile_data(cell)
	return data != null and data.get_custom_data("deadly")   # custom data layer in the TileSet

func world_to_cell_center(world_pos: Vector2) -> Vector2:
	var cell := ground.local_to_map(ground.to_local(world_pos))
	return ground.to_global(ground.map_to_local(cell))

func paint_path(cells: Array[Vector2i]) -> void:
	ground.set_cells_terrain_connect(cells, 0, 0)            # terrain_set, terrain (autotiling)

23.3 Camera2D

Make the camera a child of the player to follow it, or move it in code. Use get_screen_center_position() and get_viewport().get_visible_rect() for bounds.

Godot 3 note: current = true became make_current() / enabled; zoom semantics were inverted (in 3.x a zoom of 0.5 zoomed in).

extends Camera2D

@export var shake_decay := 5.0
var shake_strength := 0.0

func _ready() -> void:
	make_current()
	position_smoothing_enabled = true
	position_smoothing_speed = 6.0
	limit_left = 0; limit_top = 0; limit_right = 3200; limit_bottom = 1200
	zoom = Vector2(2, 2)           # >1 zooms in (Godot 4)

func shake(amount: float) -> void:
	shake_strength = amount

func _process(delta: float) -> void:
	shake_strength = lerpf(shake_strength, 0.0, shake_decay * delta)
	offset = Vector2(randf_range(-1, 1), randf_range(-1, 1)) * shake_strength

23.4 Parallax, particles and lights in 2D

Parallax2D (4.3+) replaces ParallaxBackground/ParallaxLayer: set scroll_scale and repeat_size.

GPUParticles2D / CPUParticles2D with emitting, one_shot, restart().

PointLight2D, DirectionalLight2D, LightOccluder2D, CanvasModulate for 2D lighting.