Editor's Note: This article has also been translated to
Serbo-Croatian language by
WHG Team.
[hr]
The internet has become an excellent medium for game programmers. If you surf the internet chances are that you have seen at least a couple of java applet games. These games, besides making a great addition to a website, are a great place for beginners to learn and advanced programmers to hone and expand their skills.
Over the course of these articles I want to cover the basics of programming java applets, how to make some simple games, as well as some advanced topics including double buffering. A few of the simple games that I will use are tetris, nibbles, pacman, and pong. I will use these and others as examples to illustrate the thought process and steps that can and should be followed when approaching a game.
The Basics
Everyone loves to jump right in and start trying to code complicated, but cool programs. Without a little background knowledge this can be a frustrating experience which is why I am going to outline the basics here before we dive into writing full blown java applets and discussing more advanced topics. If you are already familiar with the basics I would encourage you to read on because you never know when you might read something interesting even if it is only a different perspective on something you already know.
Before I proceed, I want to mention how you can go about working through the ideas and concepts that I will be discussing. If you have a Java programming environment then you are set, but for those of you who don't there is another option. If you go to java.sun.com you can get a free copy of the Java Development Kit (JDK). You can use this in conjunction with notepad or some other text editor to produce all of the applets that I will discuss here. Ultimately it doesn't matter which route that you decide to take. I personally prefer the JDK when I am programming at home. I have used several visual programming environments for Java and haven't found one that impressed me enough to spend money on it. You may however find one that fits your needs.
Whenever you learn a new programming language the first program you always write is "Hello World!". I don't want to break with tradition so here is a Hello World applet.
import java.applet.*;
import java.awt.*;
public class HelloWorld extends Applet
{
public void paint (Graphics g)
{
g.drawString("Hello World!", 50, 25);
}
}
One important point to take note of here is that you need to call this file "HelloWorld.java". You will notice that this is identical to the name I gave my class on the fourth line of the program above. If these two names differ at all you will get an error during compilation.
If you have never seen any Java code before this may seem like Greek to you, but it really isn't that bad. Before we get into how to compile and run this applet lets take a look at what is going on.
Packages and the import statement
Java is totally based on classes. It allows related classes to be grouped together into something called a package. Two examples of packages are java.applet and java.awt. The import statement allows you to include in your program one or more classes from a package. It is similar to includes in C/C++ in its function. For example:
import java.applet.Applet; // includes the Applet class from the java.applet package
import java.applet.*; // includes all of the classes from the java.applet package
As we progress I will mention what we need to import to allow our programs to function. For now importing all of the classes from the java.applet and java.awt packages will do.
Classes
As I mentioned before, everything in Java is centered around the use of classes. You will notice that the next line in our sample program is a class declaration.
public class HelloWorld extends Applet
This is a class declaration which represents our applet. Two important points need to be noted here. First of all, the name of your class must be identical to the name of the file in which it is located. In this case, our class is called HelloWorld so the filename must be HelloWorld.java. I know that I just mentioned this a moment ago, but you would be surprised with the number of times simple errors like this crop up in people's programs. The other important point to take note of is the end of the class declaration, "extends Applet". For those of you familiar with programming in C++ the extends statement is the equivalent of inheritance in C++. If you aren't familiar with inheritance what it means is that our class (HelloWorld) receives and can expand on variables and methods found in the Applet class. The end result of this is that we will get a program which can function as an applet.
Methods
Methods in Java are the equivalents of functions in C++ which reside inside classes. Since this is only our first program and it is very basic we only have one method.
public void paint (Graphics g)
The "public" keyword allows the method to be called from within other classes. If the keyword "private" is used instead then the method cannot be called from within other classes. There exists a third possibility here, "protected", but we won't look at that for the time being. The next keyword after public is used to tell us what sort of information will be returned by the method. In this particular case we have used "void" which means that nothing will be returned. I could have used int, char, etc. instead, but given the nature of this method they were unnecessary. We will look at methods which require a return type as we advance into more complicated examples.
The paint method will be an important fixture in all of our programs since this is where we display on the screen everything we want the user to be able to see. The paint method is always passed a graphics context, "Graphics g", which is later used by the method to enable painting to the screen.
Displaying Information on the Screen
The last statement which we need to take a look at is g.drawString(....).
g.drawString("Hello World!",50,25);
Guess what this does? That's right! This statement draws a string to the screen (represented by the graphics context) at the x (50) and y (25) coordinates. The coordinate (0,0) would give you the top left of the applet not the top left of the web page the applet is on. One other important point to note here is that we don't have to draw strings to the screen. This will be an important fact when we get into double buffering later on, but for now lets move on.
Now you are probably saying "Adam, that is great, but how do we see our applet in action?". The first step toward running our applet is to compile it. You will remember at the start of the article I mention the two options you have for writing Java applets. If you choose to use the JDK then you can go into DOS and type "javac HelloWorld.java". If you use a visual environment such as VisualAge or Visual J++ then you will find a menu option somewhere that allows you to compile. Whichever method you use you should end up seeing a file created in called HelloWorld.class. Java is an interpreted language which means that it doesn't create standard executable files. Instead we get files with a .class ending.
The last step before we run our program is to create a HTML file which will display our applet. If you haven't used HTML before don't worry about it because you will be able to use the sample page I give you here over and over with one or two minor modifications. I would recommend that you look into learning it though because it is very useful. So without any further delay here is the code we want in our HTML file which I have called Hello.html.
[font='courier new', courier, monospace][color=#000080][bquote][lessthan]HTML>[/color][/font]
[font='courier new', courier, monospace][color=#000080][lessthan]HEAD>[/color][/font]
[font='courier new', courier, monospace][color=#000080][lessthan]TITLE>Hello World Applet[lessthan]/TITLE>[/color][/font]
[font='courier new', courier, monospace][color=#000080][lessthan]/HEAD>[/color][/font]
[font='courier new', courier, monospace][color=#000080][lessthan]BODY>[/color][/font]
[font='courier new', courier, monospace][color=#000080][lessthan]CENTER>[/color][/font]
[font='courier new', courier, monospace][color=#000080][lessthan]H1>Hello World Applet[lessthan]/H1>[/color][/font]
[font='courier new', courier, monospace][color=#000080][lessthan]APPLET CODE="HelloWorld.class" WIDTH=150 HEIGHT=25>[lessthan]/APPLET>[/color][/font]
[font='courier new', courier, monospace][color=#000080][lessthan]/BODY>[/color][/font]
[font='courier new', courier, monospace][color=#000080][lessthan]/HTML>[/bquote][/color][/font]
Once you have saved this HTML file you can then open it up in the browser of your choice.
The only part of the above HTML that you really need to be concerned with is the [lessthan]APPLET>..[lessthan]/APPLET> lines. You will notice that for the applet I have entered three pieces of information: width, height, and the name of the .class file. The width and height specify the dimensions of the applet on the web page and the code attribute specifies the name of the applet we want to display. For the code attribute you want to make sure that you have the full name of the compiled java applet with the proper capitalization.
There you have it. That is all there is to writing a basic java applet. Now that we know the basics lets pick up the pace and introduce some more interesting capabilities of java applets.
Altering the Appearance of Text
Java provides the ability to change the font of the text which you are displaying. While it only supports a small number of fonts it is still a useful capability which you may want to take advantage of in your games.
private Font a_Font;
public void init()
{
a_Font = new Font("Helvetica", Font.BOLD, 48);
setFont(a_Font);
}
The addition of the above lines to our applet will allow us to change the font in which our text appears. These lines should be placed after the opening curly brace of the class and before the paint method. You will also notice the use of a new method here. The init method is called automatically when the applet is first loaded. If you have some initialization code and code that only needs to happen when the applet is first loaded then this is the place to put it. You must make sure that you spell init the same way that I have done. If you spell it incorrectly or use improper capitalization then it will appear to Java as a different method and will not be called automatically. This problem will not be flagged for you by the compiler so you must be extremely careful when you write your methods to get spelling and capitalization perfect. Trying to track this problem down can be annoying.
The first parameter in the above font creation code is the name of the font that we want to use. These could be "TimesRoman", "Helvetica", "Courier", "Dialog", and "DialogInput" which work, but are being replaced by "Serif", "SansSerif", and "Monospaced". The second parameter specifies the style of our new font. This can be Font.BOLD, Font.PLAIN, Font.ITALIC, or Font.BOLD + Font.ITALIC. The last parameter specifies the size of the new font.
In order to put our new font to work we must use the setFont method with our new font passed as a parameter. This will change the font for the entire applet for the entire life span of the applet to our font. If you want to bounce back and forth between fonts you will set the font in the paint method instead using the setFont method prefixed by the graphics context (g.setFont(...);).
Another way you can alter the appearance of text is by changing the color of it.
g.setColor (Color.red);
This line of code is normally found in the paint method because you need a graphics context in order to use it. The code itself is not bad and some of the colors that are available to you are listed below.
[font='courier new', courier, monospace]
[color=#000080][bquote]Color.black[nbsp][nbsp][nbsp]Color.blue[nbsp][nbsp][nbsp][nbsp]Color.cyan[nbsp][nbsp][nbsp][nbsp][nbsp][nbsp][nbsp]Color.darkGray
Color.gray[nbsp][nbsp][nbsp][nbsp]Color.green[nbsp][nbsp][nbsp]Color.lightGray[nbsp][nbsp]Color.magenta
Color.orange[nbsp][nbsp]Color.pink[nbsp][nbsp][nbsp][nbsp]Color.red[nbsp][nbsp][nbsp][nbsp][nbsp][nbsp][nbsp][nbsp]Color.white
Color.yellow[/bquote][/color]
[/font]
The colors listed previously will probably suit your needs, but you may be interested in creating your own colors on occasion. The code to do this is very simple and you will probably notice similarities between it and the code used to create a new font.
Color adamBlue = new Color (80,124,224);
g.setColor(slateBlue);
The three numbers in the constructor of our new color are the RGB values. Each of the numbers must be between 0 and 255. If you are unsure about what a constructor is and why I use the keyword new don't worry for now. Take everything I say as unquestionable truth and we will talk about it later when we discuss classes and how they fit into our games. One thing that I didn't mention previously is that when you call the setColor method it also changes the color of everything you do after that point including more text and shapes which we will talk about in a minute.
Two other useful functions that are available for you use are setBackground(..) and setForeground(..).
setBackground(Color.yellow);
setForeground(Color.blue);
These two lines, if used, are generally found in the init method. The setForeground method has the same effect as the g.setColor statement except that the effect is permanent for everything in your applet. I recommend that you use g.setColor because as you make your games you are going to want to frequently change colors. The setBackground method is good for now, but in a little bit I will introduce the idea of double buffering and with it a new way to set the background color.
Shapes
Shapes are a very important topic because they will play a crucial role in quite a few of the games that you will write. There is no built in 3D segment in Java, but I may discuss a way around this later. Java provides several built-in methods to allow for quick and easy drawing of shapes. Each of these will usually be called from your paint method.
drawRect (int x, int y, int width, int height)
eg g.drawRect (5,8,49,29);
drawOval (int x, int y, int width, int height)
drawLine (int x1, int x2, int y1, int y2)
drawRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight)
drawArc (int x, int y , int width, int height, int startAngle, int arcAngle)
draw3DRect (int x, int y, int width, int height, boolean raised)
For all of the above shapes, except for the line, there is a filled alternative.
fillRect (....);
fillOval (....);
If you want to have different colors for each of your shapes then you must make sure that you call g.setColor before you draw the shape. I recommend going through and playing around with the above shapes a bit because they will be important in many games that you write and will be important in some of the examples that I show you.
Conditionals, Control Statements, and Operators
I will not be talking about any of these subjects here because there isn't any real big difference between those found in Java and those in C++. There will be plenty of examples of them later when I get into more coding related information about specific games.
Images
Image coolImage;
....
coolImage = getImage(getCodeBase(), "dx3d.GIF");
....
g.drawImage(coolImage,0,0,this);
Everyone likes images and it is relatively simple to display them in a java applet. The top line of sample code is our variable declaration which can go at the top of our applet class with our font variable and any others you may have inserted at that location. The second line of code will go in our init method and the last line will go in our paint method.
The syntax of the Java language is very intuitive with many of the method names it uses. For example, by just looking at the code above you can probably get a good idea of what is going on. As I mentioned before, the first line is our variable declaration. The next line involves the loading of our image from it's file. In this case the name of the file is dx3d.GIF. When you are loading images ensure that you have the right capitalization and spelling of the filename. As you start to write bigger applets you are going to be confronted with more and more errors so if you can eliminate some by being cautious in areas like this then your job will be easier. The last line of importance here is responsible for the drawing of the image. You will notice that we are using our graphic context and rather than drawing a string or filling an oval we are drawing an image. The first three parameters are what interest us here. The first parameter is our variable which holds the image that we want to display. Next we have the x and y coordinates of where we want the image to be located on the screen. You will notice that we don't have to give the size of the image at any point. When we load the image in we take on the width and height of the image as it was in the file.
It is a good idea to get familiar with images now because we will come back to images in a bit and add some new wrinkles when we talk about double buffering.
Random Numbers
Random numbers are used quite frequently in game programming as well as regular programming. To get random numbers in Java is a simple task as you can see in the code excerpt below.
public void paint(Graphics g)
{
int x;
int y;
x = (int)(Math.random()*100);
y = (int)(Math.random()*100);
g.setColor(Color.red);
g.drawString("Hello World",x,y);
}
Let's look at the code for the random numbers before we see how they are used in this particular bit of code. You will notice that we make a call to Math.random(). This returns a number between 0 and 1. We then multiply by the range of numbers that we want to have. In the example above I multiply by 100 to give myself a number between 0 and 100. If I wanted a number between 1 and 100 I would multiply by 99 and then add 1. The reason that works is because the multiplication by 99 gives me a number between 0 and 99 and then I add one to put it in the proper range. The last thing you will notice is the int keyword out in front of the random number code. This is called casting. If you are familiar with C/C++ you have probably seen this concept in action before. For those of you who haven't all that is happening is that I am telling the compiler that I am going to stick a float into an int and I am aware of the fact that I will lose some information by using this code.
The purpose of this applet is really simple. Every time it loads it will randomly place the string "Hello World" on the applet somewhere between 0 and 100 for the x and y coordinates. This may seem fairly bland at the moment, but take note of what we are doing because when we discuss threads we will be able to have text randomly appearing and disappearing on the screen and moving around with only slight modifications to the code above.
Coming Soon!!!
Well that is the end of this article. Hopefully you have learned a bit and are interested in what is to come. Next time I will start talking about threads, double buffering, and how to use the mouse and keyboard. To illustrate these concepts we will also talk about how to program a pong game and some other interesting applets. If you have any questions or comments feel free to email me at [email="kinga@cpsc.ucalgary.ca"]kinga@cpsc.ucalgary.ca[/email]. By the time you see the next article I will have my web page up and running with example applets that I have discussed as well as additional applets.
Do I have to my a new HTML file everytime I change something in my java document and when I update my class file?
Please answer this cause I am trying to find this out really long now alredy and I couldnt get an answer yet.