Tower Defense in JavaFX (4)

Ok, so far we’ve created a TileMap, displayed it on screen and made it editable in the first part. In the second part we implemented calculation of the attack path using the A* algorithm and made the enemies follow that path. In part three we created some custom TileSetAnimations so we can rotate the Insectoids around their center by an angle. We then applied this to the Insectoids, so they look forward when they fly, and to the turrets, so they always aim at the closest target. Time to make the turrets shoot at their enemies.

First we need TileSets for an explosion and a bullet for the Pellet gun. I found a nice free explosion sheet here. It’s a bit larger (128*128) than the sprites, and the explosion doesn’t start in the center, but after a bit of fiddling with the position relative to the exploding insectoid it works quite nicely. I created the bullet myself and I know I have to come up with something better :-), but at least it’s something that is visible on the screen. After some fiddling with the correct initial position I created this BulletLaunching Behavior:

new SpriteBehavior() {
@Override
public boolean perform(Sprite sprite) {
double angle = rotateAnimation.getAngle();
double xVelocity = Math.cos(Math.toRadians(angle));
double yVelocity = Math.sin(Math.toRadians(angle));
final double centerX = x + (width / 2);
final double centerY = y + (height / 2);
double startX = centerX + (xVelocity * (width / 2)) - 4;
double startY = centerY + (yVelocity * (height / 2)) - 4;
Sprite bullet = new Sprite(getParent(), shoot, "bullet" + (bulletCounter++), startX, startY,
8, 8, Lookup.EMPTY);
bullet.setVelocityX(xVelocity);
bullet.setVelocityY(yVelocity);
// add bullet behavior

return true;
}

@Override
public long getEvaluationInterval() {
return 2000000000; //To change body of generated methods, choose Tools | Templates.
}
});

Most of the code is calculating the initial position and making sure the bullet heads off in the right direction. Now we need to add some collision detection. Some systems do have a centralized collision system, and allow to add listeners. I prefer to again do this via behaviors, because I find it more natural and intuitive that the bullet itself checks if it has hit something:

bullet.addBehaviour(new SpriteBehavior() {
private double range = 75;

@Override
public boolean perform(Sprite sprite) {
Collection checkCollisions = sprite.getParent().checkCollisions(sprite);
for (Collision collision : checkCollisions) {
if (collision.getSpriteOne() instanceof EnemySprite) {
sprite.getParent().removeSprite(sprite);
((EnemySprite) collision.getSpriteOne()).hit(6);
return false;
} else if (collision.getSpriteTwo() instanceof EnemySprite) {
sprite.getParent().removeSprite(sprite);
((EnemySprite) collision.getSpriteTwo()).hit(6);
return false;
}
}
if (distance(sprite.getX(), sprite.getY(), centerX, centerY) > range) {
sprite.getParent().removeSprite(sprite);
return false;
}
return true;
}
});

What we do here is simply ask the GameCanvas for collisions of this specific Sprite and try to cause damage if it’s an enemy. The anonymous inner bullet Sprite and the Behavior will be converted later to regular classes to make the code nicer and to make them easier to create and configure. On the side of the Enemy Sprite we need to implement the “hit” method:

public void hit(int impact) {
power = power - impact;
if (power getParent().removeSprite(this);
getParent().addSprite(new Sprite(getParent(), explosionAnimation, "explosion", getX() - 30, getY() - 80, 128, 128, Lookup.EMPTY));
}
}

Very simple: in case the hit was deadly, we remove the Sprite and add an Explosion Sprite. If the sprite sizes would match, we could have simply set the explosionAnimation on the existing Sprite. If you can create your own SpriteSheets, you should do that, it makes live much easier. The ExplosionAnimation is configured to run only once, and it has an EventHandler that removes the Sprite, once the Animation is complete:

explosionAnimation = new TileSetAnimation(explosion, 100f);
explosionAnimation.setRepeat(1);
explosionAnimation.setOnFinished(new AnimationEventHandler() {
@Override
public void handleEvent(AnimationEvent event) {
Sprite target = event.getTarget();
target.getParent().removeSprite(target);
getParent().removeSprite(EnemySprite.this);
}
});

That’s it. Our Turrets will now fire Bullets at the Enemies and try to hurt them until they explode:
 

 
In the video you also see a DebugLayer. Currently it tracks some performance data, mainly FPS and if the time between two pulses is too long. I’ve also added a bullet to the top of the screen, to visually detect stuttering animations. You can safely ignore that…

So we’ve got almost everything we need for a Tower Defense Type game now. In the next part of this Tutorial, we’ll add damage indicators to the enemies, and a HUD with the score and a control to start the next wave.
 

Reference: Tower Defense in JavaFX (4) from our JCG partner Toni Epple at the Eppleton blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


2 + = eight



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close