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.
Related Whitepaper:

Java Essential Training

Author David Gassner explores Java SE (Standard Edition), the language used to build mobile apps for Android devices, enterprise server applications, and more!

The course demonstrates how to install both Java and the Eclipse IDE and dives into the particulars of programming. The course also explains the fundamentals of Java, from creating simple variables, assigning values, and declaring methods to working with strings, arrays, and subclasses; reading and writing to text files; and implementing object oriented programming concepts. Exercise files are included with the course.

Get it Now!  

Leave a Reply


× one = 3



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
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.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books