Make 2D Games with Tiniest2D
Complete Game Example
Lesson 10 of 11 • 10 XP
Keep your place in this quest
Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.
Example: Complete Game
This lesson builds a small collection game. The player moves around a scene, bumps into walls, collects coins, and prints a final score when the game ends.
Instead of pasting the whole script at once, the example is split into the same parts you will use in most Tiniest2D projects:
- asset and state variables
start()onUpdate(dt)onCollision(objA, objB)end()
1. Assets and Game State
The first section creates the assets and variables the rest of the script will use. Sprites are images, the scene is the level, the player is an object placed into that scene, and the score/speed variables store simple game state.
// Create assets
var playerImg = Sprite(16, 16)
var wallImg = Sprite(16, 16)
var coinImg = Sprite(8, 8)
var level = Scene()
// Create player object
var player = Object("Player")
// Game state
var score = 0
var speed = 100
At this point, the variables exist, but the game has not placed anything into the scene yet. That setup happens in start().
2. The start() Function
start() runs once when the game begins. Use it to configure objects, set the first scene, position the camera, and prepare any starting values.
func start() {
// Setup player
setSprite(player, playerImg)
setCollisionType(player, COLLISION_DYNAMIC())
setX(player, 50)
setY(player, 50)
addObject(level, player)
// Set starting scene
setScene(level)
// Center camera on player
setCameraX(level, getX(player))
setCameraY(level, getY(player))
setCameraZoom(level, 3)
print("Collect the coins!")
}
The player uses COLLISION_DYNAMIC() because it should collide and be pushed out of walls. The camera starts centered on the player so the level view begins in the right place.
3. The onUpdate(dt) Function
onUpdate(dt) runs every frame. This is where the player reads input, moves, updates the camera, and checks for reset keys.
dt means "delta time": the amount of time since the previous frame. Multiplying movement by dt makes movement speed more consistent across different frame rates.
func onUpdate(dt) {
// Player movement
var moveX = 0
var moveY = 0
if (isKeyHeld(KEY_LEFT()) || isKeyHeld(KEY_A())) {
moveX = -1
}
if (isKeyHeld(KEY_RIGHT()) || isKeyHeld(KEY_D())) {
moveX = 1
}
if (isKeyHeld(KEY_UP()) || isKeyHeld(KEY_W())) {
moveY = -1
}
if (isKeyHeld(KEY_DOWN()) || isKeyHeld(KEY_S())) {
moveY = 1
}
// Apply movement
setX(player, getX(player) + moveX * speed * dt)
setY(player, getY(player) + moveY * speed * dt)
// Camera follows player
setCameraX(level, getX(player))
setCameraY(level, getY(player))
// Reset level with R key
if (isKeyPressed(KEY_R())) {
resetScene(level)
setX(player, 50)
setY(player, 50)
score = 0
print("Level reset!")
}
}
The movement code builds a direction from keyboard input. Then it adds that direction to the player's current position. The camera is updated after movement so it follows the new position.
4. The onCollision(objA, objB) Function
onCollision(objA, objB) runs when two objects collide. In this example, coins should use COLLISION_TRIGGER(). Trigger objects report overlaps, but they do not block movement.
func onCollision(objA, objB) {
var nameB = getName(objB)
var typeB = getCollisionType(objB)
// Coin collection (coins should be TRIGGER type in scene editor)
if (typeB == COLLISION_TRIGGER()) {
removeObject(level, objB)
score = score + 1
print("Score: " + score)
}
}
When the player touches a trigger, the script removes that object from the scene and increases the score. This is the basic pattern for pickups, keys, powerups, and checkpoints.
5. The end() Function
end() runs when the game stops. This example only prints the final score, but larger games can use this function for cleanup or final debug messages.
func end() {
print("Final score: " + score)
}
Setting Up the Example
- Create the sprites:
- Ctrl+Click on
playerImg, draw a character (for example, a simple stick figure) - Ctrl+Click on
wallImg, draw a solid block -
Ctrl+Click on
coinImg, draw a small circle or diamond -
Design the scene:
- Ctrl+Click on
level - Select
wallImgin the left panel, set collision to "Static" - Paint walls around the edges and create a maze
- Select
coinImg, set collision to "None" for decorative coin tiles -
Place coins around the level as visual guides
-
Create trigger coin objects:
Sprites stamped into the scene are useful for tiles and decoration, but collectible coins should be objects so collision callbacks can remove them. Add coin objects like this:
var coin1 = Object("Coin1")
var coin2 = Object("Coin2")
func start() {
// ... player setup ...
// Setup coins as triggers
setSprite(coin1, coinImg)
setCollisionType(coin1, COLLISION_TRIGGER())
setX(coin1, 100)
setY(coin1, 80)
addObject(level, coin1)
setSprite(coin2, coinImg)
setCollisionType(coin2, COLLISION_TRIGGER())
setX(coin2, 150)
setY(coin2, 120)
addObject(level, coin2)
// ... rest of start ...
}
This same pattern can be expanded for more coins, enemies, doors, or any object that needs script behavior.