Building Your First 2D Game in Godot Engine 4
Construct a mobile-ready 2D game scene from scratch. You will configure native mobile display viewports, construct hierarchical node trees, compose static terrain geometry, assemble physics-driven kinematic player bodies, write deterministic movement scripts in GDScript, and configure 2D collision layer masks so character bodies interact seamlessly with the physical world.
Interactive Milestone Progress Checklist
0% Completed (0/6)Project Creation & Mobile Display Configuration
1Create Project in Godot 4
- Launch Godot Engine 4.x and click New Project.
- Set Project Name:
Godot_2D_Mobile_Game. - Click Create Folder to ensure a dedicated project root.
- Select Renderer: Mobile (Vulkan) or Compatibility (OpenGL 3 - recommended for low-spec laptops).
- Click Create & Edit.
2Configure Mobile Resolution, Stretch Mode & Pixel Art Filter
Navigate to Project > Project Settings to configure display and rendering:
| Setting Path | Value | Tutorial Reference / Purpose |
|---|---|---|
| Display > Window > Size | 1280 × 720 | Standard 16:9 mobile landscape base resolution. |
| Display > Window > Stretch > Mode | canvas_items | Crisply scales 2D vector & pixel art across phone screens. |
| Display > Window > Stretch > Aspect | keep | Preserves screen ratio; eliminates aspect distortion. |
| Rendering > Textures > Canvas Textures > Default Texture Filter | Nearest | Critical for Pixel Art! Disables bilinear blur so Pixel Adventure sprites remain razor-sharp. |
| Input Devices > Pointing > Emulate Touch | ON | Allows testing mobile touch inputs using desktop mouse clicks. |
res://assets/.Blank Root Node & Seamless Background Setup (TextureRect Tiling)
In Godot, backgrounds can be made from a single full illustration or an infinitely repeating 64×64 PNG tile. We utilize a TextureRect with Tile stretch mode so small seamless textures repeat across any mobile screen size:
- In the Scene Dock (top-left), click 2D Scene to create a root
Node2D. Rename it toMain(orWorld). - Press Ctrl + S and save as
res://scenes/main.tscn. - Right-click
Main> Add Child Node... > search for TextureRect. Rename toBackground. - Drag your background tile (e.g.
Blue.pngorBrown.png) into the Texture property in the Inspector. - Under CanvasItem > Texture > Repeat, set to
Enabled. - Under TextureRect > Stretch Mode, set to
Tile(STRETCH_TILE). - Set Layout > Transform > Size to
1280 × 720(or click the green Layout button in the 2D viewport header > Full Rect). - Under CanvasItem > Ordering, set
Z Index = -10so all characters and terrain render in front.
Main [Node2D]
└ Background [TextureRect] — (Repeat: Enabled | Stretch: Tile | Size: 1280×720 | Z-Index: -10)
Static Terrain & Ground Setup (TileMap or TextureRect)
Terrain in platform games must be solid and unyielding so characters can stand securely without falling through infinity. In Godot 4, you can construct terrain surfaces using either a modular TileMap with 16×16 Physics Layer painting or a standalone StaticBody2D with TextureRect Tiling:
Method ATileMap with 16×16 Physics TileSet
Paint dynamic platforms and modular terrain directly onto the canvas with automatic collision geometry:
- Right-click
Main> Add Child Node... > search for TileMap (or TileMapLayer in Godot 4.3+). Rename it toTerrainTileMap. - In the Inspector > TileSet > click dropdown > New TileSet. Click into the newly created TileSet resource to open its properties.
- In TileSet properties in Inspector:
- Set Tile Size:
16 × 16px (matching the Pixel Adventure terrain tiles). - Expand Physics Layers > click Add Element (this registers Physics Layer 0 for collision detection).
- Set Tile Size:
- In the bottom TileSet dock, drag
Terrain (16x16).pngin. Click Yes when Godot prompts to automatically create tiles. - Click the Paint tab in the TileSet dock > select property Physics Layer 0 > click on each ground/platform tile to assign collision boundaries.
- Switch to the TileMap tab at the bottom, select your solid ground tiles, and paint platforms across the viewport!
Method BTextureRect Tiled Platform (StaticBody2D)
An alternative quick-setup approach using a standalone physical body with a repeating tiled texture:
- Right-click
Main> Add Child Node... > add a StaticBody2D. Rename toGround. - Right-click
Ground> add a CollisionShape2D. Set Shape → New RectangleShape2D with size1280 × 64. - Right-click
Ground> add a TextureRect (rename toGroundVisual). Assign your ground tile PNG into Texture, set Expand Mode: Ignore Size, set Stretch Mode: Tile, and set Size: 1280 × 64 with Position: (-640, -32) to center on the collider. - Set parent
Groundposition to(640, 688)to rest cleanly at the screen bottom.
Method A (TileMap):
Main [Node2D]
└ TerrainTileMap [TileMap / TileMapLayer] — (TileSet 16×16 | Physics Layer 0)
Method B (TextureRect):
Ground [StaticBody2D] — (Position: 640, 688)
└ CollisionShape2D — (RectangleShape2D 1280×64)
└ GroundVisual [TextureRect] — (Expand: Ignore Size | Stretch: Tile | Size: 1280×64)
Player Character Assembly (AnimatedSprite2D & Hitbox)
In this tutorial, the character (Ninja Frog) is assembled as a dedicated scene using an AnimatedSprite2D with multiple animation frames:
- Click Scene > New Scene > choose Other Node > search for CharacterBody2D. Rename root to
Player. Save asres://scenes/player.tscn. - Right-click
Player> Add Child Node... > add an AnimatedSprite2D. - In the Inspector under Animation > Sprite Frames, click dropdown > New SpriteFrames > click it to open the bottom SpriteFrames panel.
- Configure the 3 core platformer animations:
- idle: Click “Add frames from sprite sheet” > select
Idle (32x32).png> set 11 horizontal slices > select all > set Speed: 20 FPS > Loop: ON. - run: Click new animation icon > name it
run> add frames fromRun (32x32).png(12 frames) > set Speed: 20 FPS > Loop: ON. - jump: Click new animation icon > name it
jump> add frame fromJump (32x32).png(1 frame) > Loop: OFF.
- idle: Click “Add frames from sprite sheet” > select
- Right-click
Player> add a CollisionShape2D. In Inspector, select New CapsuleShape2D (Radius:10, Height:24) and position it snugly around the character torso. - Switch back to
main.tscnand click the Instantiate Child Scene icon (chain link) onMain> pickplayer.tscn. Position the player at(320, 400).
Player [CharacterBody2D]
└ AnimatedSprite2D — (SpriteFrames: idle, run, jump @ 20 FPS)
└ CollisionShape2D — (CapsuleShape2D radius: 10, height: 24)
GDScript Kinematic Movement Scripting
Select Player and click Attach Script. Save as res://scripts/player.gd. Paste the complete, production-ready script below:
extends CharacterBody2D
## 2D Kinematic Player Controller with Gravity, Jump, and Animations
## Godot Engine 4.x CharacterBody2D Implementation
# Movement Constants
const SPEED: float = 300.0
const JUMP_VELOCITY: float = -400.0
# Fetch default 2D gravity value from Project Settings (default: 980 px/s²)
var gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")
# Reference to the AnimatedSprite2D child node
@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D
func _physics_process(delta: float) -> void:
# 1. APPLY GRAVITY WHEN AIRBORNE (+Y is downward in Godot 2D)
if not is_on_floor():
velocity.y += gravity * delta
# 2. HANDLE JUMP IMPULSE
# ui_accept corresponds to Spacebar, Enter, or Virtual Mobile Jump Button
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
# 3. READ HORIZONTAL INPUT AXIS (-1.0 for Left, +1.0 for Right, 0.0 for Idle)
var direction: float = Input.get_axis("ui_left", "ui_right")
# 4. HANDLE MOVEMENT & ANIMATION STATES
if direction != 0.0:
velocity.x = direction * SPEED
# Flip sprite horizontally based on moving direction
animated_sprite.flip_h = direction < 0.0
# Play running animation when grounded
if is_on_floor():
animated_sprite.play("run")
else:
# Smooth deceleration towards 0 when no keys are held
velocity.x = move_toward(velocity.x, 0.0, SPEED)
# Play idle animation when standing on the ground
if is_on_floor():
animated_sprite.play("idle")
# 5. PLAY JUMP ANIMATION IN AIR
if not is_on_floor():
animated_sprite.play("jump")
# 6. EXECUTE KINEMATIC COLLISION RESOLUTION
# move_and_slide() automatically applies internal velocity and updates is_on_floor()!
move_and_slide()2D Physics Layer Names & Collision Mask Matrix
Open Project > Project Settings > Layer Names > 2D Physics and define:
- Layer 1: World (Terrain)
- Layer 2: Player
StaticBody2D (Ground)
Immovable world boundary.
CharacterBody2D (Player)
Kinematic moving character.
3Attach Camera2D Follow Node (Viewport Tracking)
Open player.tscn, right-click Player > Add Child Node... > add a Camera2D:
- Set Zoom:
(2.5, 2.5)or(3.0, 3.0)— zooms closely into the pixel art character for responsive mobile displays. - Under Position Smoothing: check
Enabled = ON(Speed: 5.0) for silky smooth camera panning when the player runs and jumps.
Submission Deliverables
1. Gameplay Screenshot
Capture running game showing the player standing securely on the ground with background PNG behind.
2. Complete GDScript File
Submit player.gd with gravity, jump, input axis, and comments.