Picture
Hello everyone, and welcome to Day 6 of Unit 2. In today's lesson, we will be adding an enemy to our game, because our main character is getting a bit lonely.
 
Our first enemy will look like this:
Picture
The Menacing Heliboy
Too add Heliboy to our game, we will first create an Enemy class (which will serve as the superclass for most enemy types), and also a Heliboy class, which will be the subclass of the Enemy class.
Lesson #2-17: Creating the Enemy Class
The Enemy class will be pretty simple. Since this will be a superclass, we will define commonly used variables and methods, so that our subclasses can inherit them.

Here's how we will proceed:

1. Create the Enemy class.
2. Declare variables
3. Create behavior related methods
4. Create helper methods (Getters and Setters)

I. Creating the Enemy Class

Picture
Creating the Enemy class.
1. Right-click on our kiloboltgame package >> New >> Class.
2. Name it "Enemy".
3. Press OK!

II. Declaring Variables

All the enemies that we create will probably have the following:

1. Max Health
2. Current Health
3. Power (damage output)
4. Speed
5. X coordinate
6. Y coordinate

In addition, whenever the background scrolls, the enemy should move in the same direction. So we will create a reference to the bg1 object in StartingClass.

Within the class definition, declare the following:

private int maxHealth, currentHealth, power, speedX, centerX, centerY;
private Background bg = StartingClass.getBg1();

III. Creating Behavioral Methods

As with all other game objects, we will need to first create a method that will constantly be running: update(); In addition, we will create a die(); and attack(); method for the enemy.

Add the following code below your variable declarations:

//Behavioral Methods
public void update() {
centerX += speedX;
speedX = bg.getSpeedX();
}

public void die() {
}
public void attack() {
}



TIP: In Eclipse, you can indent multiple lines of code at once by selecting multiple lines and pressing Tab. You can also dedent by pressing Shift + Tab. 

TIP #2: You can auto format your code (fix indents and such) by pressing Ctrl + Shift + F.

IV. Generate Getters and Setters

We will need to create methods that will allow us to retrieve and manipulate the variables declared in this class. 

1. Right-click on your code >> Source >> Generate Getters and Setters.
2. Select All, and press OK.
3. Eclipse will automatically add the following code:


public int getMaxHealth() {
return maxHealth;
}

public int getCurrentHealth() {
return currentHealth;
}

public int getPower() {
return power;
}

public int getSpeedX() {
return speedX;
}

public int getCenterX() {
return centerX;
}

public int getCenterY() {
return centerY;
}

public Background getBg() {
return bg;
}

public void setMaxHealth(int maxHealth) {
this.maxHealth = maxHealth;
}

public void setCurrentHealth(int currentHealth) {
this.currentHealth = currentHealth;
}

public void setPower(int power) {
this.power = power;
}

public void setSpeedX(int speedX) {
this.speedX = speedX;
}

public void setCenterX(int centerX) {
this.centerX = centerX;
}

public void setCenterY(int centerY) {
this.centerY = centerY;
}

public void setBg(Background bg) {
this.bg = bg;
}


And you are done with the Enemy class for now! It should now look like this:

Figure 2-28: Enemy Class

package kiloboltgame;


public class Enemy {


private int maxHealth, currentHealth, power, speedX, centerX, centerY;
private Background bg = StartingClass.getBg1();


// Behavioral Methods
public void update() {
centerX += speedX;
speedX = bg.getSpeedX();


}


public void die() {


}


public void attack() {


}


public int getMaxHealth() {
return maxHealth;
}


public int getCurrentHealth() {
return currentHealth;
}


public int getPower() {
return power;
}


public int getSpeedX() {
return speedX;
}


public int getCenterX() {
return centerX;
}


public int getCenterY() {
return centerY;
}


public Background getBg() {
return bg;
}


public void setMaxHealth(int maxHealth) {
this.maxHealth = maxHealth;
}


public void setCurrentHealth(int currentHealth) {
this.currentHealth = currentHealth;
}


public void setPower(int power) {
this.power = power;
}


public void setSpeedX(int speedX) {
this.speedX = speedX;
}


public void setCenterX(int centerX) {
this.centerX = centerX;
}


public void setCenterY(int centerY) {
this.centerY = centerY;
}


public void setBg(Background bg) {
this.bg = bg;
}



}

Lesson #2-18: Creating the Heliboy class.
We will now be creating the Heliboy class.
We will be creating this class slightly differently, so even if you know how to make classes in Eclipse, read the instructions below!
 
1. Right-click on kiloboltgame >> New >> Class
2. Name it "Heliboy"
3. Now, in the Superclass: option, press Browse.
4. Type "enemy" in Choose a type:
Picture
Choosing the Enemy Superclass
5. Press OK.
6. Check "Constructors from superclass:"
Picture
7. Press Finish.

Voila! The following code generates:

Figure 2-28: Heliboy Class

package kiloboltgame;

public class Heliboy extends Enemy {

public Heliboy() {
// TODO Auto-generated constructor stub
}


}

By taking steps 4 and 6 : choosing Enemy as a superclass and adding a constructor, Eclipse automatically generated the code in bold above. No other changes are made. It is just a shortcut. 

Replace the //TODO message with the following code:

setCenterX(centerX);
setCenterY(centerY);


And add the following parameters to the constructor so that we can use centerX and centerY:

public Heliboy(int centerX, int centerY) {
And now you have the completed Heliboy class. Whenever you create a new Heliboy object, you will pass in two parameters, which will define the central coordinate of your enemy.
Lesson #2-19: Displaying Heliboy
To display Heliboy in our game, we must do the following.

1. Create an Image object for Heliboy.
2. Define hb variables that will be objects created using the Heliboy constructor.
3. Call the update() method for these objects.
4. Paint hb objects with the Image object created in step 1.

I. Create Image Object - Heliboy

heliboy.png
File Size: 11 kb
File Type: png
Download File

1. Download the above image, place it in your data folder, and rebuild the project by going to Project >> Clean >> Clean All Projects >> OK.

2. Open StatingClass.java, and add heliboy to the Image declarations.

private Image image, currentSprite, character, characterDown, characterJumped, background, heliboy;

3. In the // Image Setups section, define the heliboy Image object:
 heliboy = getImage(base, "data/heliboy.png");

II. Create HB Variables

1. Below the private Robot robot; declaration, add the following:
private Heliboy hb, hb2;

We will be creating two Heliboy objects.

2. Within the start() method, add the two bolded lines BELOW the Background creation (the Enemy superclass looks for these backgrounds, so if they are not defined, your game will crash).

bg1 = new Background(0, 0);
...
hb = new Heliboy(340, 360);
hb2 = new Heliboy(700, 360);

...

Thread thread = new Thread(this);
...

This will create two Heliboy objects centered at (340, 360) and (700, 360).

III. Call the Update Method

Scroll down to the run() method, and add:

hb.update();
hb2.update();

Like so:
 
 @Override
public void run() {
while (true) {
robot.update();
if (robot.isJumped()){
currentSprite = characterJumped;
}else if (robot.isJumped() == false && robot.isDucked() == false){
currentSprite = character;
}
hb.update();
hb2.update();
bg1.update();
bg2.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

You might notice that we never defined update() in the Heliboy class; however, since the Heliboy class inherited the Enemy class, calling update() here will automatically call the update() method in the Enemy class. This is inheritance in action. :)

IV. Paint the HB objects

Finally, we have to make the newly created Heliboy objects appear on the screen.
1. Go to the paint() method and add the following at the end:

g.drawImage(heliboy, hb.getCenterX() - 48, hb.getCenterY() - 48, this);
g.drawImage(heliboy, hb2.getCenterX() - 48, hb2.getCenterY() - 48, this);


The Heliboy.png image you downloaded has dimensions 96 x 96. So, if we paint 48 pixels lower in both X and Y (by subtracting 48), then whatever numbers that we input in the constructor (e.g. hb = new Heliboy(340, 360);) will represent the centerX and centerY coordinates of the newly drawn images.

And that's it for Day 6! I hope you guys are beginning to pick up on the patterns, so you can add your own ideas to the game as they pop up! We will be adding a shooting mechanic in the next lesson. :)

Thank you for supporting Kilobolt and tell your friends about us! :)
Picture
kiloboltday6.zip
File Size: 711 kb
File Type: zip
Download File

Picture
 


Comments

Brendan
10/23/2012 10:39pm

How would we go about painting an enemy that is off the screen but will come into view as the background scrolls? Would we paint the enemy outside of the 800x480 area and then double his speed so that he actually moves into the viewing area instead of staying stationary outside of it? I probably have some of the logic mixed up but this is how I imagine it would work.

Reply
James
10/23/2012 11:07pm

Brendan, our current setup already handles that. The enemy's speed is going to be the background scrolling speed plus their actual speed, so it will work out.

So yes, you are right about painting outside the area, and yes we do mess with their speed a little bit, but not quite like you said.

Reply
Brendan
10/23/2012 11:10pm

My previous question was dumb, I was reading from my phone and thinking this out in my head. I should have just went downstairs and tried it on the computer.

Changing the x coordinate was the only thing I had to change to get the enemy into view. Look forward to the next unit!

Reply
knightkill
10/24/2012 2:34am

That's it.This tutorial is what I was searching for all over the net.
Dude,You really rock at teaching.
Hope u,carry on forward 2 teaching it as video tutorial.

Waiting for more... thanks for this nice tutos...!!

Reply
BMATroid
10/27/2012 4:46am

Excellent tutorial.

I'm just a beginner but I after I played around with the codes, game development tend to be so easy for me.

Do you have tutorials for Unity3D? I have a license but I don't know how to use since I'm new to gamedev.

Thank you so much.

Reply
Reece
11/20/2012 12:01am

Really good stuff again thank you!

Why do you declare everything as a private variable only to create getters and setters? -wouldn't making them public save you having to do that?

Cheers much!!

Reply
James C.
11/25/2012 1:25pm

You are right; however, it's just good practice in Java to keep variables private so that unwanted functions do not mess with them accidentally. :)

This is a more advanced topic that you learn, but it's good to get into the habit of doing that now.

Reply
Faheem
11/25/2012 1:17pm

Hey! First of all, FANTASTIC tutorials, I've been hitting at Java for ages, trying to get my head around it, only at a slow pace though. With your tutorials, I'm breezing through it! Thank-you! A donation is definitely coming your way from me!
I'm having a slight issue with Day 6. When ever I run the Applet, the 'heliboy' enemy doesn't seem to update and move along with the background when I move the character. I've checked it through letter by letter 3 times now, there are no errors. Then downloaded the source, copied and pasted it over to see if that would resolve it, but still the same issue? Any suggestions? I'm real confused right now :S

Reply
James C.
11/25/2012 1:24pm

Thanks for reading the tutorials! I am glad that you are getting something out of it.

If you could take the following steps, I can help you out more easily:

1.Right click your project folder, select Export >> General >> File System.

2. Make sure your project folder is checkmarked, and export it to a directory of your choice.

3. Compress the folder to a .zip or .rar and email it to jamescho7@kilobolt.com.

Thanks!

Reply
Aman
12/20/2012 5:31am

Hi james
i also have the same problem. my enemy doesnt move along with the background and once i press the right key for some time the enemies go out of view.... i hve checked my code again and again and i dont seem to get any solution,,,

plz help...

Reply
James C.
12/20/2012 10:07am

Hey Aman, this is normal behavior. We don't want enemies fixed to the background. Their movement should be independent. Please watch the video of Metal Slug to see what we are trying to accomplish.


-

Reply
ade
12/20/2012 6:23pm

Hi James,

Thanks for the great tutorial. I was wondering if you can detail a bit on the this statement:

private Background bg = StartingClass.getBg1();

Is it normal to access a method from a class without instantiating it? Also intrigues me the how is possible to use a method in declaring a variable.

Reply
James
12/21/2012 12:29am

StartingClass in this example refers to the class, and that is why we do not need to instantiate it. It does not refer to a particular StartingClass object.

As for methods, getter methods simply return a value and there is nothing in Java that prevents its usage in particular locations.

Hope that helps.

Reply
ade
12/21/2012 6:10am

I understand. Thanks for your answer!

Ziff Sedgewick
12/26/2012 11:28pm

This is a great series, thanks a lot!

My major was CS but I haven't worked in the field for a long time, this is a great refresher!

Reply
Muhammad Babar
12/30/2012 5:50am

Hi james im bit confused understanding you said enemy is 98x98 and we do hb.getCenterX()-48 and hb.getCenterY()-48 to get the center of the image,but this actually draws it a upper and towards X-axis,,please reply quick so i can understand,i have read drawImage(Image,x,y,observer) method it says x,y coordinates are the top left corners of the image to be drawn,

Reply
James C.
01/01/2013 8:12pm

Muhammad, sorry for the late reply!
g.drawImage(heliboy, hb.getCenterX() - 48, hb.getCenterY() - 48, this);

centerX() refers to the middle of the heliboy object. So when we place the top left corner at middle - 48, it creates the intended effect.

This is the same thing as drawing:

g.drawImage(heliboy, hb.getTopLeftX(), hb.getTopLeftY(), this);

And since TopLeftX and TopLeftY would be centerX - 48 and centerY - 48, respectively, it works just as intended.

Try drawing a diagram! :)

Reply
Mukul
01/06/2013 4:49am

hey,thank you vey much for the great tutorial,but I am having a little problem.my enemies won't repaint.i just have two heliboys printed.and as my robot moves to the right they are gone with the background.but no new enemies are printed again.tried copy pasting your source,but didn't work.

Reply
James C.
01/06/2013 5:46am

This is normal. We do not want the enemies to teleport back.

Reply
Dennis
01/06/2013 6:26pm

excelent I'm so excited for learning more :D thanks a lot

Reply
Jesse
01/07/2013 8:21pm

Great tutorials! You Explain very well and for that i thank you

Reply
Vlad
01/10/2013 7:45am

Great Tut, my contribution we´ll be getting to you soon ;) . I have all the code from day 6. The applet draws background enemies and the robot but the only thing it does is jump... nothing else

Reply
Vlad
01/10/2013 3:22pm

Sorry, my mistake... the gamer in me trying to use w,a,s,d to move the robot... duh :D works just fine

Reply
Joe
02/23/2013 6:37am

Hey James, great tutorials, I'm really enjoying them. I have a bit of a problem with this weeks code. The window is just empty and black when I run it.
I can see the background, the robot and a heliboy if I maximize the window but I can't move the robot at all. I've downloaded your source code and I can't find any differences.

Reply
Joe
02/23/2013 3:11pm

Wait, fixed it, I forgot to add the 2 to the second hb in the start method. Its what I get for programming on such little sleep. Anyways, keep up the good work!

Reply
S-Markt
03/03/2013 12:35am

"You might notice that we never defined update() in the Heliboy class; however, since the Heliboy class inherited the Enemy class, calling update() here will automatically call the update() method in the Enemy class. This is inheritance in action. :)"

instead of using a superclass, would it be possible to copy and paste the code and use it in the new class? of course it would but it will mean less occupied memory when you use a superclass, right? are there any other advantages? or does java do the same when compiling the sourcecode? therefore it would be less confusing not to uses superclasses.

Reply
JonNal
03/15/2013 2:19pm

How can you make a combo. For example i want to make the robot jump and the boost forward. How do i do that?

Reply
JonNal
03/15/2013 2:21pm

How do can you do combos. For example, i want the robot to jump and the boost forward a little bit. How do i do that?

Reply
Brad
04/08/2013 5:11am

Hey, first fantastic tutorial, i've been looking at getting into java game development for a while alongside my current C++ that i'm doing at University and i'm finding your tutorial extremely easy to follow and easy to learn.

Also you probably already know about this but you can make your code slightly easier to read by editing the syntax for some of your conditions, for example:

"robot.isJumped() == false" is the same as "!robot.isJumped()" likewise "robot.isJumped() == true" is the same as "robot.isJumped()"

just trying to help out :)

Brad

Reply
Mike
05/06/2013 10:12am

Great Series James! Question though. Is there a particular reason the currentSprite value is tracked by StartingClass? I would think this to be more a job for the Robot class, perhaps in the update() method?

Reply
rushi
05/31/2013 7:27am

setCenterX(centerX);
setCenterY(centerY);

on setting these methods in heliboy class it has red underline saying to change private to protected centerX,centerY

Reply
Grae
08/07/2013 11:31am

Has anyone else had the issue of running the applet and the applet screen being completely black? I check my code multiple times and downloaded the source code and compared it with that, and everything matches up, but when I run it, even if I use full screen, It still displays nothing but black.

Reply
tom link
08/12/2013 8:01pm

Don't be a n00b. Make enemy abstract.

Reply
Peter
08/17/2013 4:09am

Hi kilobolt and i wanna thank you for everything. I just wanna say that I DID recomend this to my friends, as i always dreamed of making a game or an android app with a friend of mine and my dream is comming true. I already knew some basics, so im already on unit 2 going to day 7 now (yey) and he is on day 4 or 5 of the first unit, but this rithm, will be ready to create a game in no time lol THANKS YOU A LOT YOU GOT 2 NEW READERS

Reply



Leave a Reply

    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.