I've been thinking about the direction that I want to go with this game, and as of now, I am considering making it a game about a Q-bot (cube robot)* going around shooting things and jumping across platforms. Two games that I am taking inspiration from are Metal Slug and Megaman.
As we get deeper into the series, I want to add character upgrades, different types of platforms and power ups, and much more.
But first, let us talk about the game thread and the game loop.
(*Name not final)
Lesson #2-3: Implementing a Thread:
As mentioned in the previous unit, threads are a way of running simultaneous processes.
We will be adding a thread to our code like so:
As we get deeper into the series, I want to add character upgrades, different types of platforms and power ups, and much more.
But first, let us talk about the game thread and the game loop.
(*Name not final)
Lesson #2-3: Implementing a Thread:
As mentioned in the previous unit, threads are a way of running simultaneous processes.
We will be adding a thread to our code like so:
Figure 2-4: start() in StartingClass.java
@Override
public void start() {
Thread thread = new Thread();
thread.start();
}
Simple right? The first line creates a new instance of a thread (a Thread object called "thread"), and the second line starts the thread.
When you call: thread.start(); , however, nothing will happen. Why?
Refer to this example from Lesson #1-21:
Figure 2-5: Example of a Thread
Thread thread = new Thread() {
public void run() {
for (int i = 0; i < 10; i += 2) {
System.out.println("hello");
}
}
};
Threads require a run method that determines what will happen in that thread. In Figure 2-4 we never declared a run method. There's a reason for this. We will be extracting the run method from the thread and creating a separate method in the class by doing the following:
1. Implement the Runnable interface by adding: "implements Runnable" to the class declaration like so:
public class StartingClass extends Applet implements Runnable{...
2. Create a run() method in the class by typing out run and then pressing Ctrl + Space and selecting the first option: run() : void. It will auto complete the method for you.
When you try to create a run method, it will give you the following information:
1. Implement the Runnable interface by adding: "implements Runnable" to the class declaration like so:
public class StartingClass extends Applet implements Runnable{...
2. Create a run() method in the class by typing out run and then pressing Ctrl + Space and selecting the first option: run() : void. It will auto complete the method for you.
When you try to create a run method, it will give you the following information:
This tool tip describes that when we implement interface, we can extract the run method from the Thread that we created.
So to "bridge" or connect this newly created run() method and the thread that we have created above:
3. Go back to this statement in the start method:
Thread thread = new Thread();
and add "this":
Thread thread = new Thread(this);
We will talk more about "this" in the future. It is quite a flexible keyword, and therefore I think it's best if we talk about it from another perspective with more understanding. For now, think of it as "this" class. More specifically, "this" instance of the class.
The final result:
So to "bridge" or connect this newly created run() method and the thread that we have created above:
3. Go back to this statement in the start method:
Thread thread = new Thread();
and add "this":
Thread thread = new Thread(this);
We will talk more about "this" in the future. It is quite a flexible keyword, and therefore I think it's best if we talk about it from another perspective with more understanding. For now, think of it as "this" class. More specifically, "this" instance of the class.
The final result:
Figure 2-6: StartingClass.java
package kiloboltgame;
import java.applet.Applet;
public class StartingClass extends Applet implements Runnable {
@Override
public void init() {
}
@Override
public void start() {
Thread thread = new Thread(this);
thread.start();
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void run() {
// TODO Auto-generated method stub
}
}
Lesson #2-4: Creating the infinite game loop:
In this lesson, we will be creating a game loop. I mentioned in Day 1 that a game loop is the heartbeat of the game. It constantly checks for changes and makes updates to the game accordingly.
More sophisticated game loops will be used in our later games, but for our purposes, all our game loop needs to do is the following:
1. Update characters
2. Update environment
3. Repaint the scene.
4. Sleep for 17 milliseconds.
Why 17 milliseconds you ask? I'll tell you why.
I'm sure many of you know that when you go on YouTube and watch the Epic Rap Battles or something, you are seeing a sequence of still images that are changing fast enough to give your brain the illusion of fluid motion. The number of times that the image changes in one second is referred to as FPS or frames per second (frame rate).
At about ~30, we are able to see a smooth movement in games and movies; however, 60 fps is what most people consider an ideal to have no noticeable glitches or stuttering.
Sleeping for 17(1000/60) milliseconds each time that the game loop runs means that the game will update every 17 milliseconds (which results in 60 updates per second). Of course this assumes that the computer is capable of handling the processes every 17 milliseconds and can be disastrous when the machine slows down (hence this is a bad game loop), but for the purposes of our simple Java game on your modern day computer (and for this beginner's tutorial), it is simple, effective, easy to implement, and very intuitive.
So first we create a game loop in the run() method of the class:
1. This loop will be a while loop, and will run indefinitely. To make a while loop run forever, we just write true as the condition for the loop:
while(true){
}
2. Within this add the following segment of code:
repaint(); // this calls paint
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
Your run() method will look like this:
More sophisticated game loops will be used in our later games, but for our purposes, all our game loop needs to do is the following:
1. Update characters
2. Update environment
3. Repaint the scene.
4. Sleep for 17 milliseconds.
Why 17 milliseconds you ask? I'll tell you why.
I'm sure many of you know that when you go on YouTube and watch the Epic Rap Battles or something, you are seeing a sequence of still images that are changing fast enough to give your brain the illusion of fluid motion. The number of times that the image changes in one second is referred to as FPS or frames per second (frame rate).
At about ~30, we are able to see a smooth movement in games and movies; however, 60 fps is what most people consider an ideal to have no noticeable glitches or stuttering.
Sleeping for 17(1000/60) milliseconds each time that the game loop runs means that the game will update every 17 milliseconds (which results in 60 updates per second). Of course this assumes that the computer is capable of handling the processes every 17 milliseconds and can be disastrous when the machine slows down (hence this is a bad game loop), but for the purposes of our simple Java game on your modern day computer (and for this beginner's tutorial), it is simple, effective, easy to implement, and very intuitive.
So first we create a game loop in the run() method of the class:
1. This loop will be a while loop, and will run indefinitely. To make a while loop run forever, we just write true as the condition for the loop:
while(true){
}
2. Within this add the following segment of code:
repaint(); // this calls paint
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
Your run() method will look like this:
Figure 2-7: run() in StartingClass.java
@Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Let's look at this line by line:
repaint(); - built in method - calls the paint method (in which we draw objects onto the screen). We haven't created the paint method yet, but every 17 milliseconds, the paint method will be called..
Whenever we do something that may fail (like Thread.sleep(17);) the Java Compiler gives us an error saying that we need to surround the statement with a Try and Catch.
repaint(); - built in method - calls the paint method (in which we draw objects onto the screen). We haven't created the paint method yet, but every 17 milliseconds, the paint method will be called..
Whenever we do something that may fail (like Thread.sleep(17);) the Java Compiler gives us an error saying that we need to surround the statement with a Try and Catch.
What a try/catch does is the following.
1. In try, we attempt to do something, like sleep.
2. If something goes wrong, then the catch will save information regarding errors, and will print it to a console.
Don't worry too much about it. It's just a built-in fail-safe system. It won't fail here. Just click the suggested quick fix.
At this point the StartingClass.java will look like this:
1. In try, we attempt to do something, like sleep.
2. If something goes wrong, then the catch will save information regarding errors, and will print it to a console.
Don't worry too much about it. It's just a built-in fail-safe system. It won't fail here. Just click the suggested quick fix.
At this point the StartingClass.java will look like this:
Figure 2-8: StartingClass.java
package kiloboltgame;
import java.applet.Applet;
public class StartingClass extends Applet implements Runnable {
@Override
public void init() {
}
@Override
public void start() {
Thread thread = new Thread(this);
thread.start();
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Lesson #2-5: Defining size, background, and title.
This will be a short lesson that should wrap up most of our setup process.
We briefly talked about the four methods that we setup in Day 1: init(), start(), stop(), and destroy().
These four methods run according to the program's life cycle. We will now discuss the init() method.
When the applet runs for the first time, it will run the init() method (much like how a typical program runs the main(String args[]) method).
So within this method, we define certain parameters for the applet including:
1. Size of the applet
2. Background color.
3. Applet Title.
Inside this method, we will be adding
1. setSize(800, 480);
to change the size to 800 pixels by 480 pixels (the most common Android resolution)
2. setBackground(Color.BLACK);
to set background with the Color Black. NOTE: Color.BLACK refers to a constant called BLACK in the Color superclass, and hence you must import Color:
This will be a short lesson that should wrap up most of our setup process.
We briefly talked about the four methods that we setup in Day 1: init(), start(), stop(), and destroy().
These four methods run according to the program's life cycle. We will now discuss the init() method.
When the applet runs for the first time, it will run the init() method (much like how a typical program runs the main(String args[]) method).
So within this method, we define certain parameters for the applet including:
1. Size of the applet
2. Background color.
3. Applet Title.
Inside this method, we will be adding
1. setSize(800, 480);
to change the size to 800 pixels by 480 pixels (the most common Android resolution)
2. setBackground(Color.BLACK);
to set background with the Color Black. NOTE: Color.BLACK refers to a constant called BLACK in the Color superclass, and hence you must import Color:
3. setFocusable(true);
This statement makes sure that when the game starts, the applet takes focus and that our input goes directly into it. If this is not enabled, then you would have to click inside the applet before it starts handling keyboard events.
4. Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Q-Bot Alpha");
Here again, you must import Frame to create a Frame object called frame. This is slightly complicated, but just know that the first line assigns the applet window to the frame variable an the second line just sets the title to be Q-Bot Alpha.
At this point, you will have this:
This statement makes sure that when the game starts, the applet takes focus and that our input goes directly into it. If this is not enabled, then you would have to click inside the applet before it starts handling keyboard events.
4. Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Q-Bot Alpha");
Here again, you must import Frame to create a Frame object called frame. This is slightly complicated, but just know that the first line assigns the applet window to the frame variable an the second line just sets the title to be Q-Bot Alpha.
At this point, you will have this:
Figure # 2-9: StartingClass.java, end of Day 2
package kiloboltgame;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Frame;
public class StartingClass extends Applet implements Runnable {
@Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Q-Bot Alpha");
}
@Override
public void start() {
Thread thread = new Thread(this);
thread.start();
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Short Cut Reminders:
Ctrl+Shift+O: Auto import code (may import the wrong classes)
Ctrl+Shift+F: Auto format code into proper indents
Ctrl+Space: Open auto complete suggestions.
Thank you everyone for reading, and feel free to leave comments and questions below!
Ctrl+Shift+O: Auto import code (may import the wrong classes)
Ctrl+Shift+F: Auto format code into proper indents
Ctrl+Space: Open auto complete suggestions.
Thank you everyone for reading, and feel free to leave comments and questions below!
From now on, I will be including the project folder as a source code for people who don't want to write their own code, or just want to examine their own.

KiloboltGame - Day 2 |
Instructions on importing projects can be found here.