One of the things everyone struggles with, is using the GL project() function. Part of the problem is the matrices required may not be part of the application's state, especially when not using shaders, which require them anyway to compute proper coordinates.
Why do we even care about these functions? Because a common task is figuring out the screen coordinates of an "interesting" point in model space, or figuring out where in model space a user input (tap) occurred. A specific example: display the points scored at the location where a collision occurs.
As you might hope, AGE handles all of the messy work for you; it natively uses the matrices needed by project() and unproject(), and exposes these to you via RenderService.
The boilerplate is pretty simple. There is only one catch: because of our old friend inverted Y-axis, we must invert the Y axis of the result of project(). We may roll this into the computation, but for now, it is your task.
final ScorePoints sp = (ScorePoints)go; final int score = state.scorePoints(sp.points + sp.bonus); host.setText(R.id.score, nfpoints.format(score)); sb.setLength(0); sb.append(nfpoints.format(sp.points)); rr.project(sp.position.x, sp.position.y, 0f, win); rr.getViewportSize(vpsize); // invert y host.fadeInOutText((int)win[0], vpsize.y - (int)win[1], R.layout.score_text, sp.points > 0 ? Color.YELLOW : Color.rgb(255,200,200), sb.toString());
The above example uses a RelativeLayout overlay and the GameHost interface to display the text.
Another detail involved in accurate text placement, is where the text origin is located relative to the computed project(). Without any adjustment, the text upper-left is where the origin is. This will be okay until you get too far to the right or bottom edge of the display, where the text starts clipping.