6.5 Rendering a Tile Map

Rendering a Tile Map in Greenfoot

Unit 6: 2D Arrays and Tile Maps · Lesson 6.5 · about 35 minutes · no coding experience needed

Every idea in this course arrives here at once: a 2D array, nested loops, an if chain, a coordinate swap, and addObject. Twelve lines, and you have a level editor.

What you will be able to do

  • Render a multi-tile map from an array
  • Use a legend of codes and keep it beside the map
  • Explain why code 0 should usually add nothing

Words you will need

Tile code
In plain words A number standing for a kind of tile.
More precisely An integer value mapped to an actor type by the renderer.
Legend
In plain words The comment saying which number means what.
More precisely The documented mapping between codes and tile types.

Build it step by step

Every step below leaves a scenario that compiles and runs. If you stop halfway you will have something that works, not something broken. Follow along in Greenfoot rather than reading straight through.

  1. Step 1

    On your screen A map array with a legend comment above it, using several different tile codes.

    // 0 floor, 1 wall, 2 coin, 3 player start
    private int[][] map = {
        {1, 1, 1, 1, 1, 1},
        {1, 3, 0, 2, 0, 1},
        {1, 0, 1, 1, 0, 1},
        {1, 2, 0, 0, 0, 1},
        {1, 1, 1, 1, 1, 1}
    };

    The legend comment is not decoration. Come back in a week and `2` means nothing without it.

    Keep it directly above the map, always. If the two ever drift apart, the map becomes unreadable and the only way to work out what a number means is to run it.

    You can already see the level: a walled room, a couple of coins, an interior wall, and the player at top left.

  2. Step 2

    On your screen The renderer method with an if chain creating a different actor for each code.

    public void buildMap()
    {
        for (int row = 0; row < map.length; row++)
        {
            for (int col = 0; col < map[row].length; col++)
            {
                int code = map[row][col];
                if (code == 1)      { addObject(new Wall(),   col, row); }
                else if (code == 2) { addObject(new Coin(),   col, row); }
                else if (code == 3) { addObject(new Player(), col, row); }
            }
        }
    }

    The whole renderer. Look at what is in it and where it came from:

    Nested loops from 6.3. The index swap from 6.4. An else if chain from 2.5. addObject from 3.7. A method from 3.2.

    Nothing here is new. This lesson is the assembly, and that is worth noticing: the hardest-looking thing in the course is five familiar pieces stacked up.

  3. Step 3

    On your screen The rendered level in the world, matching the array laid out in the code beside it.

    Notice there is no branch for code 0. Floor adds nothing.

    That is deliberate. A 30 by 20 map is 600 cells, and adding a floor actor for every empty one would put 600 actors in a world that needs about 80. On a 1 GB box that matters, and it makes getObjects slower for no benefit.

    If you want a visible floor, use a background image on the world instead.

  4. Step 4

    On your screen The constructor calling buildMap, and the world sized from the map.

    public MazeWorld()
    {
        super(map[0].length, map.length, 32);
        buildMap();
    }

    And the constructor ties it together, exactly as prepare() did in 3.7.

    The world is sized from the map, then the map is rendered. Press Reset and the whole level rebuilds itself, because the constructor runs again.

    To design a new level, edit the numbers. That is the payoff for the entire unit, and it is how real tile-based games are built.

Mistakes almost everyone makes here

These are the wrong ideas students actually build at this point. Read them even if you think you understand, because a wrong idea you have not noticed is the expensive kind.

Common wrong idea Every cell needs an actor, including floor.

What is actually true Add nothing for 0. Use a background image if you want visible floor.

Why it matters Hundreds of pointless actors slow the scenario and make every getObjects call worse.

Common wrong idea The legend is optional.

What is actually true Without it, the map is unreadable within a week.

Why it matters The readability of the map as a map is the whole reason for this design.

Common wrong idea Adding a tile type means rewriting the renderer.

What is actually true It is one more `else if` and one more number.

Why it matters This is what makes the design worth having.

Common wrong idea buildMap can go in act().

What is actually true It goes in the constructor. In act() it rebuilds the level every frame.

Why it matters Exactly the 4.7 failure again: a finite loop run every frame.

Check your understanding

Answer these before moving on. They are graded instantly and you can retry.

  1. 1. Why is there no branch for code 0?

  2. 2. You want to add spikes as code 4. What do you change?

  3. 3. Where should buildMap be called from?

  4. 4. What happens if buildMap is called from act()?

  5. 5. Why keep the legend comment directly above the map?

Fill in the code

Complete the renderer so a 1 becomes a wall and a 2 becomes a coin. Watch the coordinate order.

int code = map[row][col];
if (code == 1)
{
    addObject(new Wall(), , );
}
 (code == 2)
{
    addObject(new Coin(), col, row);
}
Stuck? Open a hint for each blank
  • Blank 1: The world wants x first, which is the horizontal index.
  • Blank 2: And then the vertical one.
  • Blank 3: Two keywords, to continue the chain rather than start a new decision.

Lesson quiz

This one counts toward your progress. Take it when the section above makes sense.

  1. 1. A tile renderer is made of:

  2. 2. A 30 by 20 map with a floor actor per empty cell would create roughly:

  3. 3. To design a new level you:

  4. 4. The world is sized with `super(map[0].length, map.length, 32)`. Why that order?

The short version

  • Nested loops, read the code, if chain, addObject with col and row swapped.
  • Keep the legend comment directly above the map.
  • Add nothing for 0. Use a background image for visible floor.
  • Call the renderer from the CONSTRUCTOR, never from act().

If you get stuck

These pages cover the problems that come up most often in this lesson. Opening one is not cheating and it is not counted against you.

Get in Touch

Whether you're a student, parent, or teacher — I'd love to hear from you.

Just want free AP CS resources?

Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.

Typically responds within 24 hours

Message Sent!

Thanks for reaching out. I'll get back to you within 24 hours.

🏫 Welcome, fellow educator!

I offer curriculum resources, practice materials, and study guides designed for AP CS teachers. Let me know what you're looking for — whether it's classroom materials, a guest speaker, or Teachers Pay Teachers resources.

Email

[email protected]

📚

Courses

AP CSA, CSP, & Cybersecurity

Response Time

Within 24 hours

Prefer email? Reach me directly at [email protected]