直接看下效果图。最外层为半透明蒙版,下面就是技能图片。
实现思路:
通过Pixmap来绘制蒙版三角形,然后把Pixmap放到Texture上绘制即可。
我们假定整个蒙版为一个圆形区域,划分为100个小扇形块,单个小块的角度为3.6。共有100个点。
例:
技能冷却时长:3s
那么我们每过0.03s更新1次进度值,大于进度值的小扇形块我们进行绘制,小于的不用绘制。
使用方法:
// 传入图片路径,冷却时长(单位:秒),类型:圆形或矩形
CHCircleProgressBar chCircleProgressBar = new CHCircleProgressBar("skill.jpg", 2,PType.CIRCLE);
// 加入舞台
addActor(chCircleProgressBar);
// 调用开始方法
chCircleProgressBar.start();
// 你也可设置进度监听器,监听开始和结束状态。在下面代码中可以参考。
代码展示:
package com.oahcfly.chgame.core.ui;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Filter;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.utils.Array;
import com.oahcfly.chgame.core.listener.CHProgressBarListener;
import com.oahcfly.chgame.core.mvc.CHActor;
/**
*
*
* 圆形Loading冷却:
* 先采用Pixmap生成黑色纹理,然后绘制时使用半透明处理,达到蒙版的效果。
*
* @author haocao
*
*/
public class CHCircleProgressBar extends CHActor {
private FileHandle fileHandle;
// 圆的半径
private float radius;
// 总时长
private float duration;
// 三角形数量
private final int MAX = 100;
public enum PType {
/**圆形冷却**/
CIRCLE,
/**矩形冷却**/
RECANGLE
}
private Texture pngTexture;
public CHCircleProgressBar (String pngName, float duration, PType type) {
fileHandle = Gdx.files.internal(pngName);
pngTexture = new Texture(fileHandle);
this.duration = duration;
Pixmap.setFilter(Filter.NearestNeighbour);
onProgress();
if (type == PType.CIRCLE) {
// 内切圆
radius = Math.max(getWidth() / 2, getHeight() / 2);
} else if (type == PType.RECANGLE) {
// 外切圆
radius = (float)Math.sqrt(Math.pow(getWidth() / 2, 2) + Math.pow(getHeight() / 2, 2));
}
}
// 进度标识:范围【0~MAX】
private int proIdx = 0;
private Array<CirclePoint> pointsArray = new Array<CHCircleProgressBar.CirclePoint>();
/**
* 开始进度
*/
public void startProgress () {
if (pointsArray.size == 0) {
// 角度
float singleDegree = 360f / MAX;
// 计算所有的点
pointsArray.add(new CirclePoint((int)(getWidth() / 2), (int)(getHeight() / 2 - radius)));
for (int i = proIdx + 1; i <= MAX; i++) {
int x = (int)(getWidth() / 2 + radius * MathUtils.sinDeg(i * singleDegree));
int y = (int)(getWidth() / 2 - radius * MathUtils.sinDeg(90 - i * singleDegree));
pointsArray.add(new CirclePoint(x, y));
}
}
// 单步时长
float singleDuration = duration / MAX;
addAction(Actions.repeat(MAX + 1, Actions.delay(singleDuration, Actions.run(new Runnable() {
@Override
public void run () {
// 进度
onProgress();
proIdx++;
proIdx = proIdx > MAX ? MAX : proIdx;
}
}))));
}
/**
* 每间隔1走1次进度
*/
private void onProgress () {
if (proIdx == 0 && progressBarListener != null) {
progressBarListener.onStart();
}
boolean isEnd = proIdx == MAX;
if (isEnd && progressBarListener != null) {
progressBarListener.onFinish();
}
Pixmap pixmap = new Pixmap(pngTexture.getWidth(), pngTexture.getHeight(), Format.RGBA4444);
if (isEnd) {
// 结束
resetProgress();
}
pixmap.setColor(Color.BLACK);
for (int i = proIdx, size = pointsArray.size; i < size; i++) {
CirclePoint curPoint = pointsArray.get(i);
if (i < size - 1) {
CirclePoint nextPoint = pointsArray.get(i + 1);
// 圆心
int x1 = pixmap.getWidth() / 2;
int y1 = pixmap.getHeight() / 2;
int x2 = curPoint.x;
int y2 = curPoint.y;
int x3 = nextPoint.x;
int y3 = nextPoint.y;
y2 = y2 < 0 ? 0 : y2;
y3 = y3 < 0 ? 0 : y3;
pixmap.fillTriangle(x1, y1, x2, y2, x3, y3);
}
}
Texture bgTexture = new Texture(pixmap);
pixmap.dispose();
Color bColor = new Color(Color.BLACK);
bColor.a = isEnd ? 0 : 0.6f;
setColor(bColor);
setBgTexture(bgTexture);
}
@Override
public void draw (Batch batch, float parentAlpha) {
if (pngTexture != null) {
batch.draw(pngTexture, getX(), getY(), getOriginX(), getOriginY(), getWidth(), getHeight(), getScaleX(), getScaleY(),
getRotation(), 0, 0, (int)getWidth(), (int)getHeight(), false, false);
}
super.draw(batch, parentAlpha);
}
/**
* 重置进度
*/
private void resetProgress () {
clearActions();
proIdx = 0;
stoped = false;
}
/**
* 正在执行进度中
* @return
*/
public boolean isProgressing () {
return proIdx > 2;
}
private boolean stoped;
public void stopProgress () {
if (isProgressing()) stoped = true;
}
public void resumeProgress () {
stoped = false;
}
/**
* 暂停与否
* @return
*/
public boolean isStoped () {
return stoped;
}
@Override
public void act (float delta) {
if (stoped) return;
super.act(delta);
}
private CHProgressBarListener progressBarListener;
public void setProgressBarListener (CHProgressBarListener progressBarListener) {
this.progressBarListener = progressBarListener;
}
@Override
public boolean remove () {
if (getBgTexture() != null) {
getBgTexture().dispose();
}
return super.remove();
}
public class CirclePoint {
public int x, y;
public CirclePoint (int cx, int cy) {
x = cx;
y = cy;
}
}
@Override
public void drawAfterBg (Batch batch) {
// TODO Auto-generated method stub
}
}
package com.oahcfly.chgame.core.listener;
public interface CHProgressBarListener {
public void onStart ();
public void onFinish ();
}
package com.oahcfly.chgame.core.mvc;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.utils.Pool.Poolable;
import com.badlogic.gdx.utils.Pools;
import com.oahcfly.chgame.core.Chao;
/** <pre>
* 二次封装的actor
*
* date: 2014-12-11
* </pre>
*
* @author caohao */
public class CHActor extends Actor implements Poolable {
private int tag;
private Texture bgTexture;
private TextureRegion bgTextureRegion;
public CHActor () {
}
@Override
public void draw (Batch batch, float parentAlpha) {
Color color = getColor();
batch.setColor(color.r, color.g, color.b, color.a);
float x = getX();
float y = getY();
float scaleX = getScaleX();
float scaleY = getScaleY();
float width = getWidth();
float height = getHeight();
if (bgTexture != null) {
batch.draw(bgTexture, x, y, getOriginX(), getOriginY(), getWidth(), getHeight(), scaleX, scaleY, getRotation(), 0, 0,
(int)width, (int)height, false, false);
}
if (bgTextureRegion != null) {
if (bgTextureRegion instanceof Sprite) {
Sprite sprite = (Sprite)bgTextureRegion;
sprite.setColor(batch.getColor());
sprite.setOrigin(getOriginX(), getOriginY());
sprite.setPosition(x, y);
sprite.setScale(scaleX, scaleY);
sprite.setSize(width, height);
sprite.setRotation(getRotation());
sprite.draw(batch);
} else {
batch.draw(bgTextureRegion, x, y, getOriginX(), getOriginY(), width, height, scaleX, scaleY, getRotation());
}
}
}
public void setBgTexture (Texture bgTexture) {
this.bgTexture = bgTexture;
if (bgTexture != null) {
setSize(bgTexture.getWidth(), bgTexture.getHeight());
}
setOrigin(Align.center);
}
/** <pre>
* 使用缓存池
*
* date: 2015-1-3
* </pre>
*
* @author caohao
* @return */
@SuppressWarnings("unchecked")
public static <T extends CHActor> T obtain (Class<T> type) {
Pool<CHActor> pool = (Pool<CHActor>)Pools.get(type);
CHActor actor = pool.obtain();
actor.setBgTexture(null);
return (T)actor;
}
public static CHActor obtain () {
return obtain(CHActor.class);
}
@Override
public void reset () {
this.bgTexture = null;
this.bgTextureRegion = null;
setScale(1);
setRotation(0);
clear();
setUserObject(null);
this.setColor(new Color(1, 1, 1, 1));
setStage(null);
setParent(null);
setVisible(true);
setName(null);
setOrigin(Align.center);
setPosition(0, 0);
}
public Texture getBgTexture () {
return bgTexture;
}
public TextureRegion getBgTextureRegion () {
return bgTextureRegion;
}
public void setBgTextureRegion (TextureRegion textureRegion) {
this.bgTextureRegion = textureRegion;
if (bgTextureRegion != null) {
if (bgTextureRegion instanceof Sprite) {
Sprite sprite = (Sprite)bgTextureRegion;
setSize(sprite.getWidth(), sprite.getHeight());
} else if (bgTextureRegion instanceof AtlasRegion) {
AtlasRegion atlasRegion = (AtlasRegion)bgTextureRegion;
bgTextureRegion = Chao.plistCenter.createSprite(atlasRegion);
Sprite sprite = (Sprite)bgTextureRegion;
setSize(sprite.getWidth(), sprite.getHeight());
} else {
setSize(bgTextureRegion.getRegionWidth(), bgTextureRegion.getRegionHeight());
}
}
setOrigin(Align.center);
}
@Override
public boolean remove () {
boolean remove = super.remove();
if (remove) {
Pools.free(this);
}
return remove;
}
public int getTag () {
return tag;
}
public void setTag (int tag) {
this.tag = tag;
}
}
欢迎关注CHGame框架(基于Libgdx二次封装快速开发框架):
https://git.oschina.net/oahcfly/CHGame.git