Basic

Objects

A game needs things described by several named features at once, position, size, speed, state. Learn objects with named keys and read the real Entity and Player shapes the game builds from.

What you will see

960 100

About 4 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

A game needs things described by several features at once, a player's position, size, and lives. An object bundles those named key-value pairs into one shape I can read and write by name. I want to build the real Entity and Player objects the game ships, storing values with this.x = x, so I can read real game code the moment I meet it.

1

An object pairs named keys with values in curly braces. I build a player with a name, position, size, and lives, then read two values back with dot notation. Reading is object.key; writing is object.key = ... . The same dot you use on Math.random and obstacles.length means "reach into this thing".

const player = { name: "runner", x: 120, y: 300, width: 40, height: 56, lives: 3, } console.log(player.x) console.log(player.lives)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
120 3
Dot notation reaches into the object by its key name. player.x is 120 and player.lives is 3. Each key is a label; the value under it is what that label holds.
2

I write to the object the same way I read it. player.x = 150 changes the stored value, and player.lives -= 1 takes a life away. I print both before and after to prove the object actually changed, not just a copy.

const player = { name: "runner", x: 120, y: 300, width: 40, height: 56, lives: 3 } player.x = 150 player.lives = player.lives - 1 console.log(player.x) console.log(player.lives)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
150 2
x moved from 120 to 150 and lives dropped from 3 to 2, and the object remembers those changes. This is how a player moves around the screen: write a new x each frame.
3

The real Entity the game builds every drawable thing from, simplified to the core fields. I construct one and confirm each incoming value lands in the right place. The pattern that matters is this.x = x, the parameter x is the incoming value, and this.x stores it inside this object under the key x.

function makeEntity(x, y, w, h) { return { x: x, y: y, w: w, h: h, vx: 0, vy: 0, active: false, } } const coin = makeEntity(100, 300, 24, 24) console.log(coin.x, coin.y, coin.w, coin.active)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
100 300 24 false
this.x = x means "store the incoming x inside this object under the key x." Each object I build gets its own separate x, y, w, h from the same template, a coin and a spike share the shape but hold different values.
4

The player is a richer object with booleans, numbers, and names that read like questions, onGround, jumpsLeft, sliding. This mix of types is the same pattern as if conditions in the Conditionals lesson. I build a Player and read its state fields.

const player = { onGround: false, jumpsLeft: 2, sliding: false, invulnTimer: 0, facing: 1, walkPhase: 0, } console.log(player.jumpsLeft, player.facing, player.onGround)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
2 1 false
jumpsLeft is a number (2), facing is a number (1), onGround is a boolean (false). Booleans like onGround and sliding start with is or read like a question, the exact shape of if conditions. A coin is the same shape but with fewer fields.
5

An object can hold another object or a list, which is how a whole level is described: a level holds a width, a height, and an array of entity objects. I read a deep value by chaining dots, level.entities[0].x reaches into the first entity's x.

const level = { width: 960, height: 540, entities: [] } level.entities.push({ type: "coin", x: 100, y: 300 }) level.entities.push({ type: "spike", x: 400, y: 300 }) console.log(level.width) console.log(level.entities[0].x)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
960 100
level.entities[0].x chains through: the level holds an entities array, and the first item in that array has its own x of 100. Nesting is everywhere in games, a game state holds a player, the player holds an animation, the animation holds frames.

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

Key-value pairs are bundled into one object, read and written by their names, and nested to build larger structures.
1 Write an object with { key: value, ... }
↓
2 Read a value with object.key
↓
3 Write a value with object.key = ...
↓
4 Nest objects inside lists or other objects
↓
5 Chain dots to reach into the nesting
Why this works
The Player's real state

The player is a richer object. Its real fields (from app1/js/entities/Player.js) are exactly the things you'd track for a character:

this.onGround = false;      // am I touching ground?
this.jumpsLeft = 2;         // double jump -> 2 jumps available
this.sliding = false;       // am I currently sliding?
this.invulnTimer = 0;       // i-frame countdown after a hit
this.facing = 1;            // 1 = right, -1 = left
this.walkPhase = 0;         // animation phase

Notice the mix of types: booleans (onGround), numbers (jumpsLeft, facing), and names that read like questions (onGround, sliding), the same pattern as if conditions in Group 4.

Every game entity is just an object shaped like this. The difference between a coin and a player is only which fields they hold and what methods they have.

Objects can hold other objects

An object's value can itself be an object or a list, which is how a whole level is described:

const level = {
  width: 960,
  height: 540,
  entities: [],              // an array of objects
  highScore: 0,
};
level.entities.push({ type: "coin", x: 100, y: 300 });

This nesting is everywhere in games: a game state holds a player, the player holds an animation, an animation holds a list of frames. To read a deep value you chain dots:

level.entities[0].x      // the first entity's x
player.walkPhase         // the player's animation phase

The lesson from Group 7 still applies, build a list by pushing, then loop over it. Now the list just holds richer objects instead of strings.

Examples

Creating an object

An object pairs named keys with values. Consider the player, position, size, lives. Storing that as an array (["player", 120, 300, 3]) is fragile: what does index 3 mean? An object makes it obvious.

const player = {
  name: "runner",
  x: 120,
  y: 300,
  width: 40,
  height: 56,
  lives: 3,
};

  • The keys (name, x, y, ...) are labels.
  • The values ("runner", 120, 3, ...) are what those labels hold.

Curly braces { } make the object. Keys can mix types, strings, numbers, booleans in one shape.

Reading and writing object values

Use dot notation (.) to reach into an object. The same . you've seen in Math.random and obstacles.length: it means "reach into this thing."

console.log(player.x);        // 120  (read)
console.log(player.lives);    // 3

player.x = 150;               // write
player.lives -= 1;            // change (3 -> 2)
console.log(player.x);        // 150

Read = player.x. Write = player.x = .... You can also write with brackets when the key is dynamic:

const key = "x";
console.log(player[key]);     // 120  (same as player.x)

We use the bracket form when the key comes from a variable, common in games.

The real Entity builder

Every drawable thing in the game, player, coin, spike, ground, is an object built from the same shared shape. Here's the real Entity from app1/js/entities/Entity.js:

export class Entity {
  constructor(x, y, w, h) {
    this.x = x;          // position
    this.y = y;
    this.w = w;          // size
    this.h = h;
    this.vx = 0;         // velocity x
    this.vy = 0;         // velocity y
    this.active = false; // is it on screen / in use?
  }
}

The pattern that matters most is this.x = x:

  • The parameter x is the incoming value.
  • this means "the specific object I'm building right now."
  • this.x = x stores the incoming x inside this object under the key x.

So when you make a coin or a spike, each gets its own x, y, w, h: separate objects from the same template.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Arrays
Previous Lesson
Arrays
Next Lesson
Data Patterns (map, filter, find)
Data Patterns (map, filter, find) →