Kilobolt
  • Home
  • Tutorials
    • Game Development Tutorial >
      • Unit 1: Beginning Java >
        • Before you begin...
        • Day 1: Setting Up
        • Day 2: Java Basics
        • Day 3: More Basics
        • Day 4: Java Math
        • Day 5: More Math
        • Day 6: If... else...
        • Day 7: More Control Flow
        • Day 8: Looping
        • Day 9: More on Looping
        • Day 10: Inheritance, Interface
        • Day 11: Threads and Graphics
      • Unit 2: Creating a Game I >
        • Day 1: Foundations
        • Day 2: Basic Framework
        • Day 3: Taking User Input
        • Day 4: Enter the Robot
        • Day 5: Background and Sprites
        • Day 6: Adding Enemies
        • Day 7: Shooting Bullets
        • Day 8: Animations
        • Day 9: 2D-Arrays
        • Day 10: Painting the Tilemap
      • Unit 3: Creating a Game II >
        • Day 1: Level Creation - Part 1
        • Day 2: Level Creation - Part 2
        • Day 3: Level Creation - Part 3
        • Collision Detection Basics
        • Day 4: Collision Detection Part 1
        • Day 5: Collision Detection Part 2
        • Day 6: Collision Detection Part 3
        • Day 7: Health System & Death
        • Day 8: Basic AI & Final Touches
      • Unit 4: Android Game Development >
        • Day 1: Introduction to Android
        • Day 2: Setting up for Development
        • Day 3: Creating our First Android Application
        • Day 4: Parts of an Android Application
        • Day 5: The Android Game Framework: Part I
        • Day 6: The Android Game Framework: Part II
        • Create an Android Game From Scratch (or port your existing game)
        • Day 7: Creating an Android Game (From Start to Finish)
      • Reference Sheet
    • Zombie Bird Tutorial (Flappy Bird Remake) >
      • Unit 1: Building the Game >
        • Introduction
        • Day 1: Flappy Bird - An In-depth Analysis
        • Day 2: Setting up libGDX
        • Day 3: Understanding the libGDX Framework
        • Day 4: GameWorld and GameRenderer and the Orthographic Camera
        • Day 5: The Flight of the Dead - Adding the Bird
        • Day 6: Adding Graphics - Welcome to the Necropolis
        • Day 7: The Grass, the Bird and the Skull Pipe
        • Day 8: Collision Detection and Sound Effects
        • Day 9: Finishing Gameplay and Basic UI
        • Day 10: GameStates and High Score
        • Day 11: Supporting iOS/Android + SplashScreen, Menus and Tweening
        • Day 12: Completed UI & Source Code
    • Android Application Development Tutorial >
      • Unit 1: Writing Basic Android Apps >
        • Before you begin...
        • Day 1: Android 101
        • Day 2: Getting to Know the Android Project
        • Day 3: The Development Machine
        • Day 4: Building a Music App - Part 1: Building Blocks
        • Day 5: Building a Music App - Part 2: Intents
        • Day 6: Building a Music App - Part 3: Activity Lifecycles
  • New Forum
  • About Us
    • Contact Us
  • Our Games
    • TUMBL: FallDown
  • Facebook
  • Twitter

GAME DEVELOPMENT TUTORIAL: DAY 2-10: Painting Tilemap

11/15/2012

47 Comments

 
Picture
Hello and welcome! This is the last lesson of Unit 2. 

More fun is just around the corner in Unit 3. Let's finish strong!

In today's lesson, we will be building upon what we covered in Day 9.
If you have not looked at Day 9 yet, please do so before proceeding!

What we will be covering:
1. We will be creating a two-dimensional Array that holds a random set of values.
2. Using this two-dimensional array, we will print colored squares to the screen.

What is the significance of this lesson?
When we continue our 2D game development, we will be creating levels (maps) using text files. In each text file, we will represent objects in the game with keyboard characters, and our game will parse the file to create levels that we can interact with.

This lesson will be an application of what we learned in Day 9. After this, we should be able to accomplish the above task with ease in the coming lessons.

Note: We will be creating a NEW class today. You do not need to open any previous files.
Let's begin.

Lesson #2-28: Creating the Tilemap
1. Begin by creating a class named Renderer in any test Project. 
(Tip: You can create a new Project by right-clicking on the Package Explorer >> New >> Java Project.)

2. Extend Applet and import it.
- add "extends Applet" at the end of the class declaration.
- Press Ctrl+Shift+O to organize imports automatically.

It should look like this:
import java.applet.Applet;


public class Renderer extends Applet{

}


3. Override the init() and paint() methods.
Since we have extended an Applet (inheritance), Java will look for the paint() and init() methods. As we will be defining these methods ourselves rather than using the one in the Applet method, so we use the "@Override" keyword.

The two methods will look like this (Make sure to import Graphics) (changes in Bold):
import java.applet.Applet;
import java.awt.Graphics;

public class Renderer extends Applet{

@Override
public void init() {

}

@Override
public void paint(Graphics g) {

}

}
4. Define the init() method.


In the init() method, we want to do the following:

- Set the size of the window.
- Set the color of the Background
- Create the Tilemap.

So we add the following lines of code:

setSize(800, 480);
setBackground(Color.BLACK);
createTilemap();

Eclipse will give you an error as follows:
Picture
Since we have never created a createTilemap() method, we must do so right now.

5. Click on the 1 quickfix: Create method 'createTilemap()'.

This should create a method as follows:


private void createTilemap() {



}


We must do two things in the Tilemap() method.

1. We need to create a two-dimensional array. We will call it tilemap and call its height rows and its width columns.
2. Using a random number generator, we will fill tilemap with integers between 0 and 4, inclusive.



Let's do these two things:

1. Creating a 2D Array
Before we begin, to make things easier, we will create three static variables at the top of the class.

- Directly below "public class Renderer extends Applet {", add the following:


   static int[][] tilemap;
   static int rows, columns;

This creates a static (class-wide) two-dimensional Array called tilemap and two integers called rows and columns.

Scroll back inside the createTilemap() method. We will now define the three variables by declaring the following:


   tilemap = new int[50][30];
   rows = tilemap.length;
   columns = tilemap[1].length;


- The first line creates a new 2D Array with 50 elements, which each contain 30 elements.
- tilemap.length is 50, as tilemap contains 50 elements.
- Each of these 50 elements contain 30 elements. Therefore, tilemap[1] refers to the element with index 1 in this 50 element list (the second element of fifty).

Note: Remember that indexes start at 0.
Note 2: We can refer to all 50 elements in tilemap using the indexes: 0 through 49.


2. Randomly Fill tilemap Array


- To fill the tilemap Array randomly, we first create a new Random object:
Random r = new Random();


- Then we use two for loops to fill each index with a random number between 0 and 4, inclusive:

               for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
tilemap[i][j] = r.nextInt(5);
}
}


Note: Recall that tilemap[i][j] refers to the spot with coordinates (i, j) inside the 2D array. 
Refer to this simplified illustration if you are confused!
Picture
Here's what the code will look like as of now:

FIGURE 2-36: Renderer Class, createTilemap()

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

public class Renderer extends Applet {

static int[][] tilemap;
static int rows, columns;

@Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
createTilemap();
}

private void createTilemap() {

tilemap = new int[50][30];


rows = tilemap.length;
columns = tilemap[49].length;


Random r = new Random();


for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
tilemap[i][j] = r.nextInt(5);
}
}
}

@Override
public void paint(Graphics g) {

}

}

With the tilemap created, we can now paint it to the screen!

Lesson #2-29: Painting the Tilemap
This is what we are trying to accomplish:

1. Create a square with side length 16 pixels - 50 across and 30 down (800 x 480).
2. Give this square a random color based on the integer value (0 to 4, inclusive) inside the tilemap.

- We begin Scroll to the paint(Graphics g) method. - Add the following code inside the method: 


for (int i = 0; i < rows; i++) {
   for (int j = 0; j < columns; 
   
   }
}


This is the same nested for loop we saw in the createTilemap() method. We will use i and j to refer to locations in the 2D Array.

We want to translate this (i, j) location into a coordinate system of (16*i, 16*j), because we want to represent, for example, (50, 30), as (800, 480).

So within the inner for loop, we add the following in BOLD:

for (int i = 0; i < rows; i++) {
   for (int j = 0; j < columns; 
      int mod_i = 16*i;
      int mod_j = 16*j;
   }
}

Note: The underscore "_" does not have any meaning. It is just part of the variable names, which stand for modified I and modified J.


Now directly below the two variable declarations (and still within the inner for loop), we need to create a switch that takes tilemap[i][j] as the key (recall that switches are used to compare the value of a key against cases) and compare with the integers 0 through 4, inclusive.

For each case, we will set the color of g, which needs to be set directly before you paint an object, and then paint a rectangle on the screen at the coordinates (mod_i, mod_j).

The full class will now look like this:

FIGURE 2-37: RENDERER CLASS, Completed

import java.applet.Applet;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.util.Random;

public class Renderer2 extends Applet {

static int[][] tilemap;
static int rows, columns;

@Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
createTilemap();

}

@Override
public void paint(Graphics g) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {

int mod_i = 16*i;
int mod_j = 16*j;

switch (tilemap[i][j]) {
case 0:
g.setColor(Color.RED);
g.fillRect(mod_i, mod_j, 16, 16);
break;
case 1:
g.setColor(Color.BLUE);
g.fillRect(mod_i, mod_j, 16, 16);
break;
case 2:
g.setColor(Color.YELLOW);
g.fillRect(mod_i, mod_j, 16, 16);
break;
case 3:
g.setColor(Color.WHITE);
g.fillRect(mod_i, mod_j, 16, 16);
break;
case 4:
g.setColor(Color.GREEN);
g.fillRect(mod_i, mod_j, 16, 16);
break;

}

}

}

}

private void createTilemap() {

tilemap = new int[50][30];

rows = tilemap.length;
columns = tilemap[49].length;


Random r = new Random();

for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
tilemap[i][j] = r.nextInt(5);
}
}
}

}

Now press Play! You should see a beautiful painting like this:
Picture

And with that, our mini-break from 2D game development (Days 9 and 10) is over, and so concludes Unit 2! 

In the next lessons, we will be applying these techniques to create our levels, and eventually introduce collision detection.

I hope that this lesson made sense to everyone! I know that everyone is at different levels of Java experience and understanding, and I try to find a good balance as to not bore people and to not leave people behind. I might assume that you remember something from a previous lesson, but you might have forgotten it already. So let me know if you need anything better explained. I'd be glad to do that for you.

And thank you to everyone who liked Kilobolt Studios on Facebook! We have surpassed 1,000 likes and it is all because of your help.

In the next few months, Kilobolt will expand and offer more tutorials, better games, and a super-cool website. If you would like to help us, please consider donating!

Go to Day 9: 2-D Arrays
Continue to Unit 3
47 Comments

    Author

    James Cho is the lead developer at Kilobolt Studios. He is a college student at Duke University and loves soccer, music, and sharing knowledge. 


© 2014 Kilobolt, LLC. All rights reserved.