The High Scores Screen

Next on our list is the high-scores screen. Here we'll use part of the main menu UI labels (the HIGHSCORES portion) and render the high scores stored in Settings via the Font instance we store in the Assets class. Of course, we have an arrow button so the player can get back to the main menu. Listing 9-7 shows the code.

Listing 9-7. HighscoresScreen.java: The High-Scores Screen package com.badlogic.androidgames.jumper;

import java.util.List;

import javax.microedition.khronos.opengles.GL10;

import com.badlogic.androidgames.framework.Game; import com.badlogic.androidgames.framework.Input.TouchEvent; import com.badlogic.androidgames.framework.gl.Camera2D; import com.badlogic.androidgames.framework.gl.SpriteBatcher; import com.badlogic.androidgames.framework.impl.GLScreen; import com.badlogic.androidgames.framework.math.OverlapTester; import com.badlogic.androidgames.framework.math.Rectangle; import com.badlogic.androidgames.framework.math.Vector2;

public class HighscoreScreen extends GLScreen { Camera2D guiCam; SpriteBatcher batcher; Rectangle backBounds; Vector2 touchPoint; String[] highScores; float xOffset = 0;

As always, we have a couple of members for the camera, the SpriteBatcher, bounds for the arrow button, and so on. In the highscores array we store the formatted strings for each high score we present to the player. The xOffset member is a value we compute to offset the rendering of each line so that the lines are centered horizontally.

public HighscoreScreen(Game game) { super(game);

guiCam = new Camera2D(glGraphics, 320, 480);

touchPoint = new Vector2();

batcher = new SpriteBatcher(glGraphics, 100);

highScores = new String[5];

highScores[i] = (i + 1) + ". " + Settings.highscores[i];

xOffset = Math.max(highScores[i].length() * Assets.font.glyphWidth, xOffset);

In the constructor we set up all members as usual and compute that xOffset value. We do so by evaluating the size of the longest string out of the five strings we create for the five high scores. Since our bitmap font is fixed-width, we can easily calculate the number of pixels needed for a single line of text by multiplying the number of characters with the glyph width. This will of course not account for nonprintable characters or characters outside of the ASCII character set. Since we know that we won't be using those, we can get away with this simple calculation. The last line in the constructor then subtracts half of the longest line width from 160 (the horizontal center of our target screen of 320x480 pixels) and adjusts it further by subtracting half of the glyph width. This is needed since the Font.drawText() method uses the glyph centers instead of one of the corner points.

@Override public void update(float deltaTime) {

List<TouchEvent> touchEvents = game.getInput().getTouchEvents();

game.getInput().getKeyEvents();

int len = touchEvents.size();

TouchEvent event = touchEvents.get(i); touchPoint.set(event.x, event.y); guiCam.touchToWorld(touchPoint);

if(event.type == TouchEvent.TOUCH_UP) {

if(OverlapTester.pointInRectangle(backBounds, touchPoint)) { game.setScreen(new MainMenu(game)); return;

The update() method just checks whether the arrow button was pressed, in which case it plays the click sound and transitions back to the main menu screen.

@Override public void present(float deltaTime) { GL10 gl = glGraphics.getGL(); gl.glClear(GL10. GL_COLOR_BUFFER_BIT); guiCam.setViewportAndMatrices();

gl.glEnable(GL10. GL_TEXTURE_2D);

batcher.beginBatch(Assets.background);

batcher.drawSprite(160, 240, 320, 480, Assets.backgroundRegion); batcher.endBatch();

gl.glEnable(GL10.GL_BLEND);

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

batcher.beginBatch(Assets.items);

batcher.drawSprite(160, 360, 300, 33, Assets.highScoresRegion); float y = 240;

Assets./ont.drawText(batcher, highScores[i], xOffset, y); y += Assets./ont.glyphHeight;

batcher.beginBatch(Assets.items);

batcher.drawSprite(160, 360, 300, 33, Assets.highScoresRegion); float y = 240;

Assets./ont.drawText(batcher, highScores[i], xOffset, y); y += Assets./ont.glyphHeight;

batcher.drawSprite(32, 32, 64, 64, Assets.arrow); batcher.endBatch();

gl.glDisable(GL10.GL_BLEND);

^Override public void resume() { }

^Override public void dispose() { }

The present() method is again very straightforward. We clear the screen, set the matrices, render the background, render the highscores portion of the main menu labels, and then render the five high-score lines using the xOffset we calculated in the constructor. Now we can see why the Font does not do any texture binding: we can batch the five calls to Font.drawText(). Of course, we have to make sure that the SpriteBatcher instance can batch as many sprites (or glyphs in this case) as are needed for rendering our texts. We made sure it can when creating it in the constructor with a maximum batch size of 100 sprites (glyphs).

Time to look at the classes of our simulation.

0 0

Post a comment