Whack A Java Mole
Whack A Java Mole
A Java Mole
Table of Contents
Introduction
Lesson 3: Loops
10
11
12
Lesson 6: File IO
13
14
Introduction
By the end of this tutorial you will have the skills necessary to be able to create a
modified version of the Whack A Mole game in Java.
We will guide you through 7 coding lessons which will guide you through step-bystep on how to make the whack a mole game.
For those of you who need some basic knowledge in Java, we also provide 7
lessons which teach the core concepts of Java programming and Object-oriented
principles.
Before we begin..
Make sure you are:
Motivated to learn new things
Mentally prepared for challenges
Ready to focus and avoid getting distracted
It will also be useful to have the following:
The basic principles of programming
Familiar with using a text editor such as Notepad or basic IDE such as
Introduction
Introduction
Before reading any further, it is highly recommended that you first read "Lesson
1: Get started with Java"
Unless you have prior experience with using Java and Eclipse IDE.
Just click on 'Finish' and the project should now appear on the side Package
Explorer
Great! You are now all set up and ready to begin coding.
First, we need to inherit Swing Library's JFrame class in order to make our Game
class represent our Game Window. If you are unfamiliar with the concepts of
inheritence, I recommend you to read Lesson 4.
So how do we do this?
Simply extend the JFrame class:
public class Game extends JFrame{
}
Eclipse should tell you that JFrame cannot be resolved to a type. This is
because we haven't imported the library to our class, so we can do this now by
adding the following code to the top:
import javax.swing.JFrame;
The next thing we need in this class is a main function, which is the first function
that is executed when the program starts. So let's go ahead and make a main
method:
Before we write the code for the main method, let's first create a constructor for
the game class like this:
public Game() {
}
In this constructor, we will initialise our JFrame attributes which will determine the
characteristics of our game window.
public Game() {
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
}
You should see an empty window on your screen with the title: WhackAMole
If you can't get this to show, do not worry, the full code for each coding lesson will
be posted at the bottom of the page.
10
import javax.swing.JFrame;
public class Game extends JFrame{
public Game() {
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
}
public static void main(String[] args) {
Game frame = new Game();
frame.setVisible(true);
}
}
11
What is a JPanel?
A JPanel is a container that can hold objects inside it. In order to display
something on our game window (JFrame) we need to create a content panel which is, as the name suggests, the container that displays the content of the
game window.
The content panel is the top-layer which will contain all the objects that are
displayed on the game window.
12
import javax.swing.JPanel;
Finally, let's set the Content Panel of our JFrame (window) to this contentPane
object we just created
setContentPane(contentPane);
If you run the program now, it should display a window with a green background.
13
Create a JLabel
To create a JLabel is very simple, it is the same procedure as creating a JPanel:
JLabel label = new JLabel();
Add a title
Let's now use the JLabel component to display a title on our game window:
JLabel lblTitle = new JLabel("Whack A Mole");
14
15
16
17
private simply means the panel object can only be accessed within this class:
Game
Now let's also set some attributes to this JPanel:
panel = new JPanel(); //initialise the object
panel.setBackground(new Color(0, 102, 0));
panel.setBounds(32, 105, 535, 546);
panel.setLayout(null);
Inside the panel we want to add the 16 holes which we will represent using
JLabels. For this we will first create an array of size 16 which will store the
JLabels.
If you do not know what an array is or you're unfamiliar with using arrays in
Java, it is highly recommended to read Lesson 2: Java basics
The array will also be declared as a global variable so it can be accessed by
other functions (which we will implement later):
18
As you can see here we created a one-dimensional array of JLabels called: holes
and initialised the array to be size 16.
Now inside the constructor we can start creating the 16 JLabels, for instance:
holes[0] = new JLabel("0");
holes[0].setName("0");
holes[0].setBounds(0, 396, 132, 132);
We simply have to repeat this 15 more times, only slightly modifying the numbers
each time (in setBounds the position would have to change so that the labels are
arranged in a 4x4 grid):
holes[0] = new JLabel("0");
19
20
21
22
Inside the function, we will first create an ImageIcon object, by calling it's
constructor with the relative path we give it.
Image image = new ImageIcon(this.getClass().getResource(path)).getImage();
Next, we need to scale (resize) our image to fit the Label dimension is
132x132 pixels
Finally, we can convert our scaled image back into an ImageIcon object and
return it
return new ImageIcon(scaledImage);
23
If you have this showing on your screen right now, congratulations you have
followed the steps correctly so far.
If not, do not worry.
Your code up to this point should look like this:
import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
24
25
26
27
Make sure it is a global variable (do not place it inside any function or the
constructor)
Now go back to the code that loops through the labels:
28
And add a line of code inside the loop which initialises the 'board' array values to
0:
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
board[i] = 0;
}
29
30
31
32
33
34
which initialises the icons and board array to display empty holes on all 16 labels.
It is a better idea to create a separate function for this, as we may need to
use it more than once.
So go ahead and make a function and copy-paste the code in there like this:
private void clearBoard(){
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
board[i] = 0;
}
}
Let's also group all the code in the constructor that is related to initialising the
GUI (Swing components) and call the function: initGUI:
35
36
37
Finally, in the constructor we can call the two functions we just created:
public Game() {
initGUI();
clearBoard();
}
Make sure to call: initGUI() first, so the label array is initialised. Then we can call
clearBoard() to set the values to 0 and set the imageicons to 'moleIn.png'
38
As this is beyond the scope of this tutorial, how the Mouse Listener Event works
will not be explained in detail.
We can now create a function: initEvents() which will contain all the code that
adds event listeners. For now, let's add the mouse click event listener to each
label.
private void initEvents(){
for(int i = 0; i < holes.length; i++){
holes[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
JLabel lbl = (JLabel)e.getSource();
int id = Integer.parseInt(lbl.getName());
pressedButton(id);
}
});
}
}
39
Note that we are calling the functions: clearBoard() and genRandMole() which
we created earlier.
40
41
genRandMole();
}
private void initEvents(){
for(int i = 0; i < holes.length; i++){
holes[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
JLabel lbl = (JLabel)e.getSource();
int id = Integer.parseInt(lbl.getName());
pressedButton(id);
}
});
}
}
private void initGUI(){
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
JPanel contentPane = new JPanel();
contentPane = new JPanel();
contentPane.setBackground(new Color(0, 51, 0));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
JLabel lblTitle = new JLabel("Whack A Mole");
lblTitle.setForeground(new Color(153, 204, 0));
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Century Gothic", Font.BOLD, 20));
lblTitle.setBounds(0, 0, 602, 47);
contentPane.add(lblTitle);
panel = new JPanel();
panel.setBackground(new Color(0, 102, 0));
panel.setBounds(32, 105, 535, 546);
panel.setLayout(null);
contentPane.add(panel);
42
43
44
setContentPane(contentPane);
}
private void clearBoard(){
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
board[i] = 0;
}
}
private void genRandMole(){
45
46
Notice that the argument values in setBounds is different for each object as this
determines the size and location of the object in the window.
Before we carry on, let's also create the global variables that will store the
highscore and time remaining:
Add the following to global space:
private int timeLeft = 30;
private int highscore = 0;
47
48
49
50
51
52
53
54
55
56
57
58
59
The line: bw.write("" + highscore); is writing the highscore to the text file as a
String
The "" + highscore essentially converts the integer highscore into a string
System.getProperty("user.dir") - gets the path of the current directory the
program is running in
60
This means that whenever a game ends, it will update the highscore and save it to
the text file.
Now go to the constructor
Inside the constructor, call the 'loadHighscore()' function:
61
public Game() {
...
...
loadHighscore();
}
Try running the program and play through the game once.
When the game finishes and you beat the highscore, try exiting the program and
restarting it. If you've done everything correctly, the highscore should appear
correctly.
Also, don't forget to save the following hammer image file as 'hammer.png'
and put it inside the 'res' folder as usual.
CONGRATULATIONS!
62
63
64
65
66
67
68
69
70
71
72
73
(img placeholder)
Now if you save the file (ctrl+s) and click on the green button (looks like a play
button), your 'Helloworld' program should execute.
You should now see 'Hello World!' printed to your console.
(img placeholder)
Congratulations! You have just created your first Java program!
Exercises:
1. Try printing out: I am 'yourname' in your console by editing the current code.
2. There is something wrong with the following lines of code, try fixing them:
System.out.println(What is your name?);
System.println("What is your name?");
System.out.println('What is your name?');
74
Here is an example:
75
/*
Basically what this program does is taking two integer numbers in and add them
up to print out the sum of them.
Data Type
Every variable we define must be declared with a data type, as java is known as a
strict data typing language. And you can not change the type of the date stored in
the variable.
Primitive data type
76
Like the previous example, we define two variables as int(Integer) in order to find
the sum of them. You will get an error if you try to input rational numbers, but if
you define them as float, you wont get the error when you input two integers.
Exercise
1 Play with the previous example to see what happen if you try to input two
rational numbers.
2 Define the two variables as float or double, see what happen if you try to input
two integer numbers.
3 Create a simple calculator that enables you to do addition, subtraction,
multiplication and division between any two real numbers.
Strings
String is technically not a primitive data type.
A sequence/array characters can be stored in a string variable.
For instance, we can say
String aString=Hello World; but not char achar=Hello World
Exercise
77
Arrays
Imagining that you are shopping in a supermarket, and you want to write a
program that create a list of the goods. You have to store the name of the product
as well as the price in some variables. It is okay if you have only a few items when
you only need to create a few variables to store them. But what if you have
hundreds or thousands of items to deal with?
Then you need a array.
An array uses one variable name for multiple values, and this is how we define an
array.
data type[] variable name= new data type[size];
the data type on the left hand side has to be the same as the data type on the
right hand side.
For instance, you can create arrays like
String[] Name=new String[1000];
float[] price=new float[1000];
To store the names and prices of 1001(why?) items. Note that an array can only
store the data type that it is declared with.
Array must be declared with the size. And it is accessed with an index
value(Integers)starting from 0. As a array always has a fixed size, if you want to
access the array with an index value which is larger than the size of array, you will
get an out of bounds exception.
Here is an example(it is used to calculate the total price as well as the average of
the items in the shopping list, and this version is not good enough. You will learn a
better approach when you get to the loop part)
78
package shoppinglist;
import java.util.Scanner;
public class ShoppingList {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
float[] price=new float[6];
float total,average;
System.out.println("Please input the prices of 6 items.");
price[0]=in.nextFloat();
price[1]=in.nextFloat();
price[2]=in.nextFloat();
price[3]=in.nextFloat();
price[4]=in.nextFloat();
price[5]=in.nextFloat();
total=price[0]+price[1]+price[2]+price[3]+price[4]+price[5];
average=total/6;
System.out.println("The total price of the items is "+total);
I have also included a line that it is trying to print the element of index 11 in the
price array. You can uncomment it and see what it does when running.
Exercise
1. Amend the example and make it do the calculation for ten items.
2. Write a program that asks for your home address line by line then prints it out
in the same order as you enter your address.
79
Lesson 3: Loops
Loops are the best things in the world. Imagine yourself having to write "1" to the
console 1000 times. You will find the job tedious, and soon want to quit. This is
where our programs kick in. Through loops, they repeat things over and over, until
we tell them to stop.
In our case, we will ask our program to stop printing 1 when one thousand "1"
have been printed on console. It will be:
for(int i=0;i<1000;i++){
System.out.println(1);
}
"for" is one of the most common loop that we see, along with while. Lets talk about
"for" first.
There are three parts to the for loop. (1) Variable initialization(that's used for
condition) (2) Condition ( True or False ) (3) Action every loop(eg. increment the
variable in (1))
for( (1) ; (2) ; (3) );
To explain our code above, (1) we first introduce a variable called i, which is a
common variable when used to iterate(loops), and initialize it to 0. (2) our
condition is when i < 1000. if i = 1000, the condition will return false, and loop will
end. (3) for each iteration, we increase the value of i by 1.
int i=0;
while(i!=1000){
System.out.println(1);
i++;
}
Lesson 3: Loops
80
While loops are pretty useful, but sometimes if the condition is false from the
beginning, the loop does not even execute. In such cases, we have "DO - WHILE"
loops, which will execute at least once.
Boolean insane = true;
do {
//something crazy
} while ( insane )
simply putting it, the condition is evaluated at the bottom of "do" section.
Therefore, whether insane is true or not, "something crazy" will happen at least
once.
Lesson 3: Loops
81
To clarify things and provide further insight into Classes and Objects, I quote
Steve Jobs (from a 1994 Rolling Stone interview):
"Objects are like people. They're living, breathing things that have knowledge
inside them about how to do things and have memory inside them so they can
remember things. And rather than interacting with them at a very low level, you
interact with them at a very high level of abstraction, like we're doing right now.
Here's an example: If Im your laundry object, you can give me your dirty clothes
and send me a message that says, Can you get my clothes laundered, please. I
Lesson 4: Classes and Objects
82
83
//a method used to change the value of an instance variable out of this
public setSpeed(int newSpeed){
speed = newSpeed;
}
//a method used to get the value of an instance variable out of this cla
public getSpeed(){
return speed;
}
public increaseSpeed(int increment){
speed += increment;
}
}
As shown in the example above, a class should include variables and methods
and I will explain it more particularly. Variable is a basic part of a class and it
includes static variables and instance variables. These variables can be equal to
the features of an object. For instance, if a class called people and it includes
following variables: eyes color, hair color and skin color, then each object of this
class will have different eyes color, hair color and skin color.
Lesson 4: Classes and Objects
84
Instance variables should always be written at the top of a class and it should
include the modifier, data type (int, char, string, etc) and the name of the variable.
For methods, these are functions in a class and these can be explained to the
motions of a class. In above code, increaseSpeed is a general method and when
an object of this class is instantiated in the main function, this object can use this
method to change its instance variable speed. In addition, you can find that there
has a method that has the same name with the class, called Car. Actually,
constructor is a special method and it will be called when an object is created, to
assign instance variables of this object.
modifier dataType methodName(dataType parameter){
method body
}
If you have learned C language, you will find that the Java method is quite similar
to the function in C. Since Java is a objective-oriented language, its methods have
objective features. Therefore, a method can be called by different objects if the
method is public. So, how can we use our class in the main function?
85
The code above is a simple instantiation of an object allen. Person is the type of
the object, allen is the object name and new Person() is the initialization. The
empty parenthesis: () means that there are no constructors in the class and the
instance variables in the class will all be set to its default value.
Take another example:
Car newCar = new Car(80, Benz, 4);
Car is the class I wrote above, and this code means I create a new object call
newCar and it has been initialized with speed 80, 4 wheels and its brand is Benz.
Why can this object initial with these parameters? That is because of constructor.
public Car(int startSpeed, string brand, int wheels){
this.speed = startSpeed;
this.brand = brand;
this.wheel_numbers = wheels;
}
This is a constructor and it must have the same name with the class. When we
use new Car(80, Benz, 4), these parameters will send to the constructor and the
startSpeed will be assigned 80, the brand will be assigned Benz and the wheels
will be assigned 4. Then these instance variables in the class: speed, brand and
wheel_numbers will be assigned. It is important to remember that if a class has a
constructor, we must initial instance variables when an object of this class be
created. If a class doesnt have a constructor we can just create an object and
leave the parameter brackets blank: Person allen = new Person();
After we created an object, we can access the method of the object:
86
It is quite simple since we just use dot to access these method and we can use
getSpeed and setSpeed to operate instance variables inside the class. Why cant
we just use newCar.speed to get the value of this instance variable? Because this
variable is private and we can only get the value of this private variable through
the getSpeed method.
When a static variable is declared, the program will allocate memory for this
variable and if this static variable changes in one object or in the class directly, this
static variable of all objects will be changed at the same time.
For instance: if we have an object personA and object personB and we also have
a static variable hairColor,
People personA = new Person();
People personB = new Person();
personA.hairColor = RED;
System.out.println(personB.hairColor);
From the code above, you will find that console will print RED on the screen.
Moreover, static variable can be used by class name directly in another class
without instantiating a new object.
People.hairColor = RED
Comparing with static variable, instance variable wont be allocated storage before
an object be created and it must be called after creating a object. In addition,
when this variable changed in an object, it wont affect others objects.
87
Exercise:
88
In our final project, we will create a real whack-a-mole game. Therefore, Let's try
to make a simplest console whack-a-mole game with our knowledge first! It will
involves all we learnt in Chapter 4. There is the requirements:
a) The game should have 9 holes and arranged into 3*3 matrix.
b) Allow users to hit the moles in console.
c) Every time users hit a mole, a new mole will come out from a random hole.
d) Every time users hit a mole, users will get scores and at the end of this game,
the total score will be shown.
e) The game need a timer to limit the length of this game.
f) When users hit wrong hole, game over. When the time out, game over.
Hints:
89
6. Tou can use Random class to get a random number between a range of num
90
Main.java:
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
public class Main {
91
92
93
94
95
Lesson 6: File IO
Introduction
Its time to play with some files. In this lessons, we will learn how to read and write
to text files. Basically, instead of having you to copy and paste the content of text
whatever you want to play with into the program, you can just use one of the
classes to do that for you.
Basically, the class reads the file for you, and stores the content of the file, which
you can use.
Lets have an example below.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
Lesson 6: File IO
96
String sCurrentLine;
br = new BufferedReader(new FileReader("C://testing.txt"));
while((sCurrentLine = br.readLine()) != null){
System.out.println(sCurrentLine);
}
Lesson 6: File IO
97
Lesson 6: File IO
98
We have
import java.io.File;<br>
import java.io.FileOutputStream;
This time. As the name suggests, they got to do with writing files. Let's begin with
creating the class called WrtieFileExample.
public class WriteFileExample {
public static void main(String[] args) {
Then, since we're writing to file, it exists or not does not matter.
File file = new File("c:/newfile.txt");
String content = "This is the text content";
What we're doing is pretty obvious in the syntax. We will use our try-catch we
learend previously, to prevent any malicious things happening.
try (FileOutputStream ops = new FileOutputStream(file)) {
if (!file.exists()) {
// if file doesn't exist, then we create it
file.createNewFile();
}
Lesson 6: File IO
99
We close the loop, at the same time we wrtie the contents. We first convert our
string into bytes, and we write the content to the file. Then, we "flush" our stream,
as we clear(empty) the stream we have used. Finally, we close the stream,
implying no more outputs to the file.
As usual, if there's an error, we catch it!
catch (IOException e) {
e.printStackTrace();
}
Lesson 6: File IO
100
package your.package.name;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteFileExample {
public static void main(String[] args) {
File file = new File("c:/newfile.txt");
String content = "This is the text content";
try (FileOutputStream ops = new FileOutputStream(file)) {
// if file doesn't exists, then create it
if (!file.exists()) {
file.createNewFile();
}
// get the content in bytes
byte[] contentInBytes = content.getBytes();
ops.write(contentInBytes);
ops.flush();
ops.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Lesson 6: File IO
101
Introduction to Swing
The main features of Swing are (Source: Swing website):
1. Swing is written in pure Java (except a few classes) and therefore is 100%
portable.
2. Swing components are lightweight.
3. Swing components (JComponents) are written in Java.
4. Swing components support pluggable look-and-feel. You can choose
between Java look-and-feel and the look-and-feel of the underlying OS (e.g.,
Windows, UNIX or Mac). If the later is chosen, a Swing button runs on the
Windows looks like a Windows' button and feels like a Window's button.
Similarly, a Swing button runs on the UNIX looks like a UNIX's button and
feels like a UNIX's button.
5. Swing supports mouse-less operation, i.e., it can operate entirely using
keyboard.
6. Swing components support "tool-tips".
7. Swing components are JavaBeans a Component-based Model used in
Visual Programming (like Visual Basic). You can drag-and-drop a Swing
component into a "design form" using a "GUI builder" and double-click to
attach an event handler.
102
103