Game Development
2D Rendering
Hollow Knight - an indie game by two developers on a budget of 57 thousand Australian dollars. Sales: 3 million copies in year one. The secret sauce? 10 parallax layers, 300+ character animations, and a tilemap holding up 10 hours of nonlinear world. Built from four technical primitives: sprite, tilemap, animation, parallax.
- **Tilemaps** are used in cartography (Google Maps), level design (Tiled editor), and even ASCII games (Dwarf Fortress)
- **Sprite animation** underpins UI animations in mobile apps: loaders, transitions, micro-interactions
- **Parallax scrolling** is used on websites to create a sense of depth as the user scrolls
- **Atlas batching** is the same technique used in WebGL renderers like Three.js and PixiJS for browser-based games
Parallax was born in 1981 - on an arcade cabinet
The first documented parallax scrolling appeared in Moon Patrol (Irem, 1981) - an arcade shooter with two background layers. Before this, game backgrounds were either static or scrolled at the same speed as the main level. The technique evolved: Super Mario Bros (1985) had background clouds moving slower than the platforms. Sonic the Hedgehog (1991) added 6 parallax layers with a rotation effect. By the 2010s, Rayman Origins had elevated the technique to cinematic levels of beauty.
Предварительные знания
Sprites
A **sprite** is the atom of 2D graphics: a rectangular image with a position, size, and rotation. Every visible object in a 2D game - the player, an enemy, a bullet, a coin - is a sprite. Sprite drawing is square one for every 2D renderer.
Loading hundreds of individual files is wasteful, so sprites get packed into a **sprite sheet** (texture atlas) - one big image holding every frame. GPUs love one large texture and hate many small ones. Unity ships TexturePacker-compatible atlases; Godot has its own format. One atlas per scene means one draw call instead of a thousand.
**Batching** is the lever that makes or breaks 2D performance. Every draw call hammers the GPU. If 100 sprites share one atlas, they ship in a single draw call instead of a hundred. Hollow Knight holds 60 FPS with 300+ sprites on screen because batching is cranked to the maximum.
Draw order (z-order) decides who covers whom. Platformer stack: background, platforms, enemies, player, UI. A sprite with a higher z-order draws later and paints over everything below.
Why are sprites packed into a sprite sheet (atlas)?
Tilemaps
Rendering a massive level with thousands of objects out of individual sprites? No chance. A **tilemap** is a grid of small square images (tiles) assembled into a level - a mosaic. Twenty tile types are enough for an infinite-variety world. Terraria stores its entire world as a 2D array of integers. Stardew Valley does the same. One int per cell instead of one sprite.
**Auto-tiling** picks the right tile variant from the neighbors automatically. Skip placing a "top-left wall corner" by hand - paint "wall" and the engine snaps the correct variant in. Unity (Rule Tiles), Godot (TileMap autotile), and Tiled all ship auto-tiling.
A tilemap is not just graphics - it carries **collision** data too. Each tile type gets a property: passable, solid, one-way platform (passable from below), ladder, water. The level's physics ships side-by-side with its visuals.
Big worlds need **chunking**: the map is sliced into chunks (e.g., 16x16 tiles) and only the visible ones get rendered. Minecraft, Terraria, and Stardew Valley all chunk to keep their worlds effectively infinite.
What does auto-tiling do?
2D Animation
2D animation is either swapping frames in sequence (sprite animation) or smoothly changing properties (tweening). Both run under an **animation state machine** - a finite automaton that picks which animation plays right now. Dead Cells juggles 300+ animations per character, switching between them inside a single frame with no visible seams.
**Tweening** (short for "in-betweening") is smooth interpolation of a value from A to B. Skip drawing every frame; let the object glide, scale, or fade. Easing functions decide the personality of the motion: linear, ease-in, ease-out, bounce, elastic.
**Animation State Machine** drives transitions: idle -(button pressed)-> run -(released)-> idle; run -(jump)-> jump -(landing)-> idle. Each state pairs an animation with transition rules. Unity Animator and Godot AnimationTree expose all of it visually.
How does tweening differ from sprite animation?
Parallax Scrolling
In the real world, distant objects drift past slower than nearby ones - look out a train window: fence posts flash by while mountains barely move. **Parallax scrolling** smuggles that effect into 2D: multiple background layers scroll at different speeds, faking depth. Ori and the Blind Forest runs 7 parallax layers. Hollow Knight runs 10. Not a single polygon in sight.
Endless parallax wants **tileable** layers - the right edge of the texture seams cleanly into the left. Draw two copies side by side; the one that scrolls off screen jumps back to the front. The player sees a seamless, infinite panorama.
Advanced parallax pulls in **vertical offset** (layers slide when the camera moves up or down) and **scaling** (distant layers shrink a touch). Some games drop layers in front of the camera too - foliage, snowflakes - and that foreground parallax slams the depth illusion home.
Parallax is nearly free on the GPU - a handful of extra draw calls with different offsets. The perceptual payoff is huge: Hollow Knight, Ori, and Celeste all stack multi-layer parallax to push 2D into "2.5D" territory.
Looping back: a sprite is the atom of 2D graphics, tilemaps assemble those atoms into worlds, animation breathes life into characters, and parallax adds depth. These four techniques cover the rendering needs of most 2D games.
2D rendering is simpler than 3D in every way
2D rendering is technically simpler (no z-buffer, projections, or lighting), but game design, level design, and game feel in 2D are just as demanding. Celeste and Hollow Knight prove that "simple" 2D graphics demand enormous artistry.
A game's complexity is determined by its design, not the number of dimensions. 2D animation requires hand-crafting every frame, tile design demands well-thought-out collisions, and game feel requires fine-tuning controls.
How does parallax scrolling create the illusion of depth?
Key Takeaways
- **Sprites** + atlases (sprite sheets) + batching = efficient rendering of thousands of objects in one draw call
- **Tilemaps** build worlds from small tiles: auto-tiling, layers, collisions, chunking for large worlds
- **Animation:** frame-by-frame (sprite) for characters, tweening for properties, state machine for transition control
- **Parallax** creates the illusion of depth through layers scrolling at different speeds - nearly free on the GPU
Related Topics
2D rendering is one of the pillars of game development, connected to many other areas:
- Game Engines — Unity, Godot, and Unreal all implement the techniques covered here: sprite renderer, tilemap, animator, parallax
- Introduction to Game Development — The render() function from the game loop is exactly what this lesson describes
Вопросы для размышления
- Why are 2D games experiencing a renaissance (Celeste, Hollow Knight, Stardew Valley) despite the capabilities of 3D?
- How to organize a tilemap for a game with destructible environments (like Terraria)?
- Can parallax scrolling work in a top-down game rather than just a side-scroller?
Связанные уроки
- gd-02 — Engines implement the sprite renderer, tilemap, and animator covered here
- gd-04 — Physics and collision systems build on top of tilemaps and sprites
- gd-07 — Shader-based animation extends what sprite animation can do
- cg-01 — Computer graphics provides the theory behind GPU batching
- se-05 — The State Machine pattern governs animation state transitions
- alg-01 — Z-order sorting is a direct application of sorting algorithms
- la-06-transformations