- Learning Java by Building Android Games
- John Horton
- 889字
- 2021-07-23 19:02:32
Creating your first class
After creating the new project we create a new class called Soldier
. Select File | New | Java Class. You will see the following dialog box.
Name the class as Soldier as I have done in the previous image and click OK.
The new class is created for us with a code template ready to put our implementation within. Just like the next image shows.
Also, notice that Android Studio has put the class in the same package as the rest of our app. And now we can write its implementation.
Write the class implementation code below within the opening and closing curly braces of the Soldier
class as shown. The new code is highlighted.
public class Soldier { int health; String soldierType; void shootEnemy(){ //let's print which type of soldier is shooting Log.d(soldierType, " is shooting"); } }
You will have one error and the Log…
code will be red. We need to import the Log
class. Select the error with the mouse pointer and hold the ALT key and tap Enter to import the class.
Now we have a class, a blueprint for our future objects of type Soldier
, we can start to build our army. In the editor window left-click the tab of RTSActivity.java. We will write this code, as so often, within the onCreate
method just after the call to super.onCreate. Type this code.
// first we make an object of type soldier Soldier rambo = new Soldier(); rambo.soldierType = "Green Beret"; rambo.health = 150; // It takes allot to kill Rambo // Now we make another Soldier object Soldier vassily = new Soldier(); vassily.soldierType = "Sniper"; vassily.health = 50; // Snipers have less health // And one more Soldier object Soldier wellington = new Soldier(); wellington.soldierType = "Sailor"; wellington.health = 100; // He's tough but no green beret
Tip
If you aren't doing so already, this is a really good time to start taking advantage of the auto-complete feature in Android Studio. Notice after you have declared and created a new object, all you must do is begin typing the object's name and all the auto-complete options present themselves. The next image shows that when you type the letters we
Android Studio suggests you might mean wellington. You can then just click, or press Enter to select wellington.
Now we have our extremely varied and somewhat unlikely RTS army, we can use it and also verify the identity of each object. Type this code below the code in the previous step.
Log.i("Rambo's health = ", "" + rambo.health); Log.i("Vassily's health = ", "" + vassily.health); Log.i("Wellington's health = ", "" + wellington.health); rambo.shootEnemy(); vassily.shootEnemy(); wellington.shootEnemy();
Tip
You will need to import the Log
class into RTSActivity
just as you did previously for Soldier
.
Now we can run our game. All the output will be in the logcat window.
This is how it works. First, we created a template for our new Soldier
class. Then we implemented our class including declaring two fields (member variables), an int
and a String
called health
and soldierType
respectively.
We also have a method in our class called shootEnemy
. Let's look at it again and examine what is going on.
void shootEnemy(){ // Let's print which type of soldier is shooting Log.d(soldierType, " is shooting"); }
In the body of the method, we print to the logcat. First, the String soldierType
and then the arbitrary " is shooting"
. What is neat here is that the String soldierType
will be different depending upon which object we call the shootEnemy
method on. This demonstrates that each of the objects of type Soldier
is different and stored in their own memory slot.
Next, we declared and created three new objects of type Soldier
. They were rambo
, vassily
, and wellington
. Finally, we initialized each with a different value for health
as well as soldierType
.
Here is the output:
Rambo's health =﹕ 150 Vassily›s health =﹕ 50 Wellington›s health =﹕ 100 Green Beret﹕ is shooting Sniper﹕ is shooting Sailor﹕ is shooting
Notice that each time we access the health
variable of each Soldier
object, it prints the value we assigned it, demonstrating that although the three objects are of the same type, they are separate, individual instances/objects.
Perhaps more interesting is the three calls to shootEnemy
. One by one, each of our Soldier
object's shootEnemy
methods is called and we print the soldierType
variable to the console. The method has the appropriate value for each individual object. Further demonstrating that we have three distinct objects (instances of the class), albeit created from the same Soldier
class.
We saw how each object is completely independent of the other objects. However, if we imagine whole armies of Soldier
objects in our app then we realize that we are going to need to learn new ways of handling large numbers of objects (and regular variables too).
Think about managing just 100 separate Soldier
objects. What about when we have thousands of objects? In addition, this is not very dynamic. The way we are writing the code now relies on us (the game developers) knowing the exact details of the soldiers that the player will be commanding. We will see the solution for this in Chapter 12, Handling Lots of Data with Arrays.
More things we can do with our first class
We can treat classes/objects much like we can other types/variables. For example, we can use a class as a parameter in a method signature.
public void healSoldier(Soldier soldierToBeHealed){…
And when we call the method we must, of course, pass an object of that type. Here is a hypothetical call to the healSoldier
method.
// Perhaps healSoldier could add to the health instance variable healSoldier(rambo);
Of course, the above example might raise questions like, should the healSoldier
method be a method of a class?
fieldhospital.healSoldier(rambo);
It could be or not. It would depend upon what is the best solution for the situation. We will look at more OOP and then the best solution for lots of similar conundrums should present themselves more easily.
And, as you might guess we can also use an object as the return value of a method. Here is what the updated hypothetical healSoldier
signature and implementation might look like now.
Soldier healSoldier(Soldier soldierToBeHealed){ soldierToBeHealed.health++; return soldierToBeHealed; }
In fact, we have already seen classes being used as parameters. For example, in the SubHunter
class, in the onCreate
method, we instantiated an object of type Point
called point
and passed it as an argument to the getSize
method using the display
object. Here is the code again for easy reference.
Point size = new Point(); display.getSize(size);
All this information will likely raise a few questions. OOP is like that. Let's try and consolidate all this class stuff with what we already know by taking another look at variables and encapsulation.