Drawing a Circular Timer (AndEngine)

I'm using AndEngine, and within that framework, I'd like to make a circular timer graphic. Specifically, I'd like to display the wait period for reuse of an ability. The idea is to dynamically fill the arc as the timer progresses. Something like this:

The java.awt.Graphics object has a fillArc() method that seems perfect for me. In fact, the above graphic was drawn using fillArc(50,5,100,100,75,-40). Great! Now here's the problem:

AndEngine doesn't use Graphics() objects, it uses its own Shape implementation (for OpenGL) and there's no defined "Circle" shape, much less a circle shape with a fillArc() method.

Possible Solutions and Their Respective Problems

Looking around for a solution I ran into "Drawing a circle using Andengine". That Q&A is not of much use to me as the only answer "Indeed, you can't directly draw a circle" offers two alternatives: (1) "Rendering a quad with a circle texture" - this won't work for me as I need to dynamically modify the circle to produce the arcfill; and (2) "Rendering a circle that's actually a circle of connected triangles." Maybe option two would work, but there's no guidance there as to how to do that.

I also ran into "Creating circle in android andengine by box2d?". I suspect someone may be tempted to say, you can simply create a circle like this:

Body circleBody = PhysicsFactory.createCircleBody(pWorld, pSprite, BodyType.StaticBody, FixtureDef);

That really doesn't help me. I'm not looking to create a 2D physics body of a circle. I'm looking to display one.

Finally, I found this discussion, which is promising. In particular, there's a suggestion:

Use Canvas to draw [it] into a Bitmap, and load that Bitmap as a TextureSource.

Sounds reasonable, although I'm still unclear how to do that.


Update: My Cheating "Solution"

Rather than dwell on this, I decided to cheat (for the moment at least). I made a spritesheet that looks like this:

作弊计时器图像

Rather than actually have the timer display the perfect fillArc(), I just pull the appropriate index of the sprite from the spritesheet based on rounding the proportion done (from 0 to 1) to the appropriate index on the spritesheet. Like this:

public void setTimer(float amount) {
    this.setCurrentTileIndex(Math.round(amount * 20));
}

For my purposes, this actually works just fine--I'm using the timers over about 2 seconds, so you really don't see the lack of detail. But maybe I'll get around to replacing this with the "proper" solution if someone posts it. Also, maybe this spritesheet will be useful for someone doing the same thing. Here's the version using transparency instead of a green background. (So it's white on the white background of stackoverflow, but it's there):

白色在白色定时器上


There is a third solution that requires a single texture and a custom object. So it's a trade off between your solutions, where one requires a lot of triangles and the other one a texture memory.

  • You need only one image, ie the full circle in your "cheat sequence" above.
  • Create a custom object consisting of 8 triangles (one 'fully drawn' triangle will represent 45° each).
  • The progress determines:
  • How many of the triangles to draw. Ie:
  • 100% ==> 360° ==> 8 full triangles
  • 50% ==> 180° ==> 4 full triangles
  • 37.5% ==> 135° ==> 3 full triangles
  • 25% ==> 90° ==> 2 full triangles
  • 20% ==> 72° ==> 1 full triangle and one triangle with one vertex moved so that it represents the remaining 27° (== 72° - 45°).
  • If you ask me this is the coolest solution, since it can be applied to any texture. =)

    链接地址: http://www.djcxy.com/p/11822.html

    上一篇: 完成另一班的活动

    下一篇: 绘制循环定时器(AndEngine)