Skip to main content

Step 1: Basic Setup

Let's create the foundation for our Worm game. We'll set up a grid system and draw the worm's initial position.

Understanding the Grid System​

Unlike Cookie Clicker where things move smoothly, Worm uses a grid-based system. The worm moves in discrete steps, one cell at a time.

// Grid settings
let cellSize = 20; // Each cell is 20x20 pixels
let cols, rows; // Number of columns and rows

Why use a grid?

  • Makes movement predictable and game-like
  • Simplifies collision detection
  • Classic retro game feel
  • Easy to align food and worm segments

Setting Up the Worm​

The worm is made of segments. We'll store each segment as an object with x and y coordinates:

let worm = [];  // Array to hold all worm segments

Global Variables​

Start by declaring all the variables we'll need:

// Grid settings
let cellSize = 20;
let cols, rows;

// Worm
let worm = [];

Breaking it down:

  • cellSize = 20 - Each grid cell is 20×20 pixels
  • cols, rows - Will calculate how many cells fit on screen
  • worm = [] - Empty array that will hold worm segment positions

The setup() Function​

function setup() {
createCanvas(400, 400);

// Calculate grid dimensions
cols = width / cellSize;
rows = height / cellSize;

// Initialize worm in the center
let startX = floor(cols / 2);
let startY = floor(rows / 2);
worm.push({x: startX, y: startY});
}

Breaking it down:

Grid Calculation​

cols = width / cellSize;
rows = height / cellSize;
  • width is 400 (canvas width)
  • 400 / 20 = 20 columns
  • Same for rows: 20 rows
  • This creates a 20×20 grid

Starting Position​

let startX = floor(cols / 2);
let startY = floor(rows / 2);
  • cols / 2 gives us the middle column (10)
  • floor() rounds down to ensure it's a whole number
  • Starting position: (10, 10) - dead center of grid

Creating the Worm​

worm.push({x: startX, y: startY});
  • push() adds a segment to the worm array
  • {x: startX, y: startY} is an object storing the position
  • Worm starts as just one segment (the head)
tip

Using an array for the worm makes it easy to add more segments later when it grows!

The draw() Function​

Now let's draw the worm on screen:

function draw() {
background(50); // Dark gray background

// Draw grid lines (optional - helps visualize)
stroke(80);
strokeWeight(1);
for (let i = 0; i < cols; i++) {
line(i * cellSize, 0, i * cellSize, height);
}
for (let i = 0; i < rows; i++) {
line(0, i * cellSize, width, i * cellSize);
}

// Draw the worm
noStroke();
fill(0, 255, 0); // Green color
for (let i = 0; i < worm.length; i++) {
let segment = worm[i];
rect(segment.x * cellSize, segment.y * cellSize, cellSize, cellSize);
}
}

Breaking it down:

Background​

background(50);
  • Dark gray background (50 on a 0-255 scale)
  • Creates nice contrast with the green worm

Grid Lines (Optional)​

stroke(80);
strokeWeight(1);
for (let i = 0; i < cols; i++) {
line(i * cellSize, 0, i * cellSize, height);
}
  • Draws vertical lines to visualize the grid
  • i * cellSize positions each line
  • You can remove this once you understand the grid

Drawing the Worm​

noStroke();
fill(0, 255, 0);
for (let i = 0; i < worm.length; i++) {
let segment = worm[i];
rect(segment.x * cellSize, segment.y * cellSize, cellSize, cellSize);
}
  • Loops through each segment in the worm array
  • segment.x * cellSize converts grid position to pixel position
    • Example: segment at grid (10, 10) → pixel (200, 200)
  • Draws a green square for each segment
info

Grid position vs Pixel position

  • Grid: (10, 10) means 10th cell across, 10th cell down
  • Pixels: (200, 200) means 200 pixels from left, 200 from top
  • Multiply by cellSize to convert: 10 × 20 = 200

Complete Code​

// Grid settings
let cellSize = 20;
let cols, rows;

// Worm
let worm = [];

function setup() {
createCanvas(400, 400);

// Calculate grid dimensions
cols = width / cellSize;
rows = height / cellSize;

// Initialize worm in the center
let startX = floor(cols / 2);
let startY = floor(rows / 2);
worm.push({x: startX, y: startY});
}

function draw() {
background(50);

// Draw grid lines (optional)
stroke(80);
strokeWeight(1);
for (let i = 0; i < cols; i++) {
line(i * cellSize, 0, i * cellSize, height);
}
for (let i = 0; i < rows; i++) {
line(0, i * cellSize, width, i * cellSize);
}

// Draw the worm
noStroke();
fill(0, 255, 0);
for (let i = 0; i < worm.length; i++) {
let segment = worm[i];
rect(segment.x * cellSize, segment.y * cellSize, cellSize, cellSize);
}
}

Test It Out!​

Run this code. You should see:

  • ✅ A dark gray canvas with grid lines
  • ✅ A green square in the center
  • ✅ Grid is 20×20 cells

The worm isn't moving yet - that's coming in the next step!

What You Learned​

  • How to create a grid-based game system
  • How to convert between grid coordinates and pixel coordinates
  • How to use arrays to store game object positions
  • How to use objects to store x,y coordinates
  • How to loop through arrays to draw multiple objects
  • How to use floor() to ensure integer values