直接看下效果图。最外层为半透明蒙版,下面就是技能图片。
实现思路:
通过Pixmap来绘制蒙版三角形,然后把Pixmap放到Texture上绘制即可。
我们假定整个蒙版为一个圆形区域,划分为100个小扇形块,单个小块的角度为3.6。共有100个点。
例:
技能冷却时长:3s
那么我们每过0.03s更新1次进度值,大于进度值的小扇形块我们进行绘制,小于的不用绘制。
使用方法:
// 传入图片路径,冷却时长(单位:秒) CHCircleProgressBar chCircleProgressBar = new CHCircleProgressBar("skill.jpg", 2); // 加入舞台 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.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 * * @author haocao * */ public class CHCircleProgressBar extends CHActor { private FileHandle fileHandle; // 圆的半径 private float radius; // 总时长 private float duration; public CHCircleProgressBar (String pngName, float duration) { fileHandle = Gdx.files.internal(pngName); this.duration = duration; Pixmap.setFilter(Filter.NearestNeighbour); onProgress(); radius = (float)Math.sqrt(Math.pow(getWidth() / 2, 2) + Math.pow(getHeight() / 2, 2)); } @Override public void draw (Batch batch, float parentAlpha) { // TODO Auto-generated method stub super.draw(batch, parentAlpha); } // 进度标识:范围【0~100】 private int proIdx = 0; private Array<CirclePoint> pointsArray = new Array<CHCircleProgressBar.CirclePoint>(); public void start () { if (pointsArray.size == 0) { // 角度 float singleDegree = 3.6f; // 计算所有的点 pointsArray.add(new CirclePoint((int)(getWidth() / 2), (int)(getHeight() / 2 - radius))); for (int i = proIdx + 1; i <= 100; 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 / 100; addAction(Actions.repeat(101, Actions.delay(singleDuration, Actions.run(new Runnable() { @Override public void run () { // 进度 onProgress(); proIdx++; proIdx = proIdx > 100 ? 100 : proIdx; } })))); } /** * 每间隔1走1次进度 */ private void onProgress () { if (proIdx == 0 && progressBarListener != null) { progressBarListener.onStart(); } boolean isEnd = proIdx == 100; if (isEnd && progressBarListener != null) { progressBarListener.onFinish(); } Pixmap pixmap = new Pixmap(fileHandle); Color bColor = Color.BLACK; bColor.a = 0.5f; if (isEnd) { // 结束 resetProgress(); bColor.a = 0; } pixmap.setColor(bColor); 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(); setBgTexture(bgTexture); } /** * 重置进度 */ private void resetProgress () { proIdx = 0; clearActions(); } private CHProgressBarListener progressBarListener; public void setProgressBarListener (CHProgressBarListener progressBarListener) { this.progressBarListener = progressBarListener; } public class CirclePoint { public int x, y; public CirclePoint (int cx, int cy) { x = cx; y = cy; } } }
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