Sunday, January 25, 2015

Anansi: Scoring


I guess the FX in JavaFX stands for Effects. So let's see which ones it provides and use them.

When we hit an enemy ship, it's an achievement. We score some points. We could simply increment the high score. That would usually do it, but we'd like to pimp up our game.

JavaFX has a FadeTransition class, we should use it. Let's show the score of every enemy we shoot down on screen. We overlay the explosion with the points we score and let that text fade out slowly.

The Oracle website has a nice article about Using Text and Text Effects in JavaFX.

Looks like it can be done very easy. Let's get coding.

public class ScoreTransition {
 
 Text text;

 FadeTransition transition;
 
 public ScoreTransition( Pane layer, SpriteBase sprite, double durationMs, int score) {
  
  // create view
  text = new Text( NumberFormat.getInstance().format( score));
  
  // set visual properties
  // TODO: uses css, eg text.setStyle("-fx-font: 120px Tahoma; -fx-text-fill: white; -fx-stroke: black; -fx-stroke-width: 2;");
        text.setStroke(Color.BLACK);
        text.setStrokeWidth(0.2);
        text.setFill(Color.WHITE);
        
        // item gets visible at the center of the given sprite
  relocateToCenterOf( sprite);
  
        // make item visible on screen
  layer.getChildren().add( getView());
  
  // create fade transition
        transition = new FadeTransition( Duration.millis( durationMs));
        
        transition.setNode( getView());
        transition.setFromValue(1.0);
        transition.setToValue(0.0);
        transition.setCycleCount(1);
        transition.setAutoReverse(false);
        
        // remove object from screen
        transition.setOnFinished(new EventHandler() {

   @Override
   public void handle(ActionEvent event) {
    
    // remove from screen
    layer.getChildren().remove( getView());
    
   }
         
        });

        
 }
 
 public void play() {
  transition.play();
 }
 
 private Text getView() {
  return text;
 }
 
 /**
  * Move the view to the center of the given sprite.
  * @param sprite
  */
 private void relocateToCenterOf( SpriteBase sprite) {
  getView().relocate( sprite.getCenterX() - getView().getBoundsInParent().getWidth() / 2.0, sprite.getCenterY() - getView().getBoundsInParent().getHeight() / 2.0);
 }

}

It turned out that we can't subclass from FadeTransition. So we implement a play() method in analogy to the sprite animation class.

Each sprite we hit will give us a different score, so let's define them in the Settings class.
public static int SCORE_ENEMY = 100;

We show the score in the game with these few lines of code.
private void spawnScoreTransition( SpriteBase sprite, int score) {
 
 ScoreTransition transition = new ScoreTransition(playfieldLayer, sprite, 1000.0, score);
 transition.play();
 
}

private void checkProjectileCollisions( List projectileList) {
  ...
  if( projectile.collidesWith(enemy)) {
   ...
   // show score
   spawnScoreTransition( enemy, Settings.SCORE_ENEMY);
   ...
  }
  ...
}   
Nice and easy. You can see how it looks like in the following screenshot:


Now we have all the information we need to create a high score for the game. But let's first toy around a bit more with sprites.

No comments:

Post a Comment