package loon.action.sprite.effect; import loon.BaseIO; import loon.LSystem; import loon.LTexture; import loon.action.sprite.Entity; import loon.canvas.Image; import loon.canvas.LColor; import loon.canvas.Pixmap; import loon.utils.timer.LTimer; /** * 类似于吉里吉里的图片(黑白)渐变特效,按从0-255像素的趋势逐渐把一张图片透明化,从而实现各种渐变效果. */ public class PShadowEffect extends Entity { private Pixmap _pixmap; private LTimer timer = new LTimer(10); private int indexD, indexW, block; private boolean flag = true, isCompleted = false; private static int[] deasilTrans, widdershinTrans; public PShadowEffect(String fileName) { this(BaseIO.loadImage(fileName)); } public PShadowEffect(Image img) { this(img, 0, 0, LSystem.viewSize.getWidth(), LSystem.viewSize.getHeight()); } public PShadowEffect(Image img, int w, int h) { this(img, 0, 0, w, h); } public PShadowEffect(Image img, int x, int y, int w, int h) { if (deasilTrans == null) { deasilTrans = new int[256]; for (int i = 0; i < 256; i++) { deasilTrans[i] = LColor.getRGB(i, i, i); } } if (widdershinTrans == null) { widdershinTrans = new int[256]; int idx = 0; for (int i = 0; i < 256; i++) { widdershinTrans[idx++] = deasilTrans[i]; } } this.setLocation(x, y); this.setSize(w, h); this.setEffect(img); } public PShadowEffect setEffect(String path){ return setEffect(BaseIO.loadImage(path)); } public PShadowEffect setEffect(Image img) { if (_pixmap != null) { _pixmap.close(); _pixmap = null; } if (img.getWidth() > 160 || img.getHeight() > 160) { float scale = 0.5f; this._pixmap = Image.getResize(img, (int) (img.getWidth() * scale), (int) (img.getHeight() * scale)) .getPixmap(); } else { this._pixmap = img.getPixmap(); } this.setTexture(_pixmap.toTexture()); this.indexD = 255; this.indexW = 0; this.block = 8; this.isCompleted = false; img.close(); img = null; return this; } public void resetEffect() { this.indexD = 255; this.indexW = 0; this.block = 8; } @Override public void onUpdate(long elapsedTime) { if (_pixmap == null) { return; } if (isVisible() && timer.action(elapsedTime) && !isComplete()) { int[] pixels = _pixmap.getData(); if (flag) { int[] colors = new int[block]; for (int i = 0; i < block; i++) { colors[i] = widdershinTrans[indexW++]; } LSystem.base().support().toColorKeys(pixels, colors); } else { int[] colors = new int[block]; for (int i = 0; i < block; i++) { colors[i] = deasilTrans[indexD--]; } for (int i = 0; i < block; i++) { LSystem.base().support().toColorKeys(pixels, colors); } } LTexture tex = super.getBitmap(); if (tex != null && tex.pixelWidth() == _pixmap.getWidth() && tex.pixelHeight() == _pixmap.getHeight()) { tex.update(_pixmap.getImage(), false); } else { setTexture(_pixmap.getImage().texture()); } } } public boolean isComplete() { return isCompleted || (flag ? (indexW >= 255) : (indexD <= 0)); } public void setDelay(long delay) { timer.setDelay(delay); } public boolean isBlackToWhite() { return flag; } public void setBlackToWhite(boolean flag) { this.flag = flag; } public int getBlockSize() { return block; } public void setBlockSize(int block) { this.block = block; } @Override public void close() { super.close(); if (_pixmap != null) { _pixmap.close(); _pixmap = null; } isCompleted = true; } }