package loon.action.sprite; import java.util.HashMap; import loon.LSystem; import loon.core.LObject; import loon.core.geom.RectBox; import loon.core.graphics.device.LColor; import loon.core.graphics.device.LGraphics; import loon.core.graphics.device.LImage; import loon.core.graphics.opengl.GLEx; import loon.core.graphics.opengl.LTexture; import loon.utils.MathUtils; /** * Copyright 2008 - 2009 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loon * @author cping * @email:javachenpeng@yahoo.com * @version 0.1 */ public class StatusBar extends LObject implements ISprite { private static final long serialVersionUID = 1L; protected final static HashMap<Integer, LTexture> colors = new HashMap<Integer, LTexture>( 10); private final static int[] backPos = { 1, 1, 3, 3 }; private final static int[] beforePos = { 5, 1, 7, 3 }; private final static int[] afterPos = { 1, 5, 3, 7 }; private static int quoteCount = 0; protected boolean hit, visible, showValue, dead; private int width, height; private int value, valueMax, valueMin; private int current, goal; private String hpString; private LTexture texture; private static boolean useBegin; public StatusBar(int width, int height) { this(0, 0, width, height); } public StatusBar(int x, int y, int width, int height) { this(100, 100, x, y, width, height); } public StatusBar(int value, int max, int x, int y, int width, int height) { synchronized (StatusBar.class) { quoteCount++; } this.value = value; this.valueMax = max; this.valueMin = value; this.current = (width * value) / valueMax; this.goal = (width * valueMin) / valueMax; this.width = width; this.height = height; this.visible = true; this.hit = true; this.texture = loadBarColor(LColor.gray, LColor.red, LColor.orange); this.setLocation(x, y); } /** * 顺序为背景,前景,中景 * * @param c1 * @param c2 * @param c3 * @return */ public LTexture loadBarColor(LColor c1, LColor c2, LColor c3) { if (colors.size() > 10) { synchronized (colors) { for (LTexture tex2d : colors.values()) { if (tex2d != null) { tex2d.destroy(); tex2d = null; } } colors.clear(); } } int hash = 1; hash = LSystem.unite(hash, c1.getRGB()); hash = LSystem.unite(hash, c2.getRGB()); hash = LSystem.unite(hash, c3.getRGB()); LTexture texture = null; synchronized (colors) { texture = colors.get(hash); } if (texture == null) { LImage image = new LImage(8, 8, false); LGraphics g = image.getLGraphics(); g.setColor(c1); g.fillRect(0, 0, 4, 4); g.setColor(c2); g.fillRect(4, 0, 4, 4); g.setColor(c3); g.fillRect(0, 4, 4, 4); g.dispose(); texture = image.getTexture(); colors.put(hash, texture); } return (this.texture = texture); } public void set(int v) { this.value = v; this.valueMax = v; this.valueMin = v; this.current = (width * value) / valueMax; this.goal = (width * valueMin) / valueMax; } public void empty() { this.value = 0; this.valueMin = 0; this.current = (width * value) / valueMax; this.goal = (width * valueMin) / valueMax; } public static void glBegin() { synchronized (colors) { for (LTexture tex2d : colors.values()) { if (tex2d != null) { tex2d.glBegin(); } } useBegin = true; } } public static void glEnd() { synchronized (colors) { for (LTexture tex2d : colors.values()) { if (tex2d != null) { tex2d.glEnd(); } } useBegin = false; } } private void drawBar(GLEx g, float v1, float v2, float size, float x, float y) { float cv1 = (width * v1) / size; float cv2; if (v1 == v2) { cv2 = cv1; } else { cv2 = (width * v2) / size; } if (!useBegin) { texture.glBegin(); } if (cv1 < width || cv2 < height) { texture.draw(x, y, width, height, backPos[0], backPos[1], backPos[2], backPos[3]); } if (valueMin < value) { if (cv1 == width) { texture.draw(x, y, cv1, height, beforePos[0], beforePos[1], beforePos[2], beforePos[3]); } else { if (!dead) { texture.draw(x, y, cv2, height, afterPos[0], afterPos[1], afterPos[2], afterPos[3]); } texture.draw(x, y, cv1, height, beforePos[0], beforePos[1], beforePos[2], beforePos[3]); } } else { if (cv2 == width) { texture.draw(x, y, cv2, height, beforePos[0], beforePos[1], beforePos[2], beforePos[3]); } else { texture.draw(x, y, cv1, height, afterPos[0], afterPos[1], afterPos[2], afterPos[3]); texture.draw(x, y, cv2, height, beforePos[0], beforePos[1], beforePos[2], beforePos[3]); } } if (!useBegin) { texture.glEnd(); } } public void updateTo(int v1, int v2) { this.setValue(v1); this.setUpdate(v2); } public void setUpdate(int val) { valueMin = MathUtils.mid(0, val, valueMax); current = (width * value) / valueMax; goal = (width * valueMin) / valueMax; } public void setDead(boolean d) { this.dead = d; } public boolean state() { if (current == goal) { return false; } if (current > goal) { current--; value = MathUtils.mid(valueMin, ((current * valueMax) / width), value); } else { current++; value = MathUtils.mid(value, ((current * valueMax) / width), valueMin); } return true; } @Override public void createUI(GLEx g) { if (visible) { if (showValue) { hpString = "" + value; g.setColor(LColor.white); int current = g.getFont().stringWidth(hpString); int h = g.getFont().getSize(); g.drawString("" + value, (x() + width / 2 - current / 2) + 2, (y() + height / 2 + h / 2)); } drawBar(g, goal, current, width, getX(), getY()); } } @Override public RectBox getCollisionBox() { return getRect(x(), y(), width, height); } public boolean isShowHP() { return showValue; } public void setShowHP(boolean showHP) { this.showValue = showHP; } @Override public int getWidth() { return width; } @Override public int getHeight() { return height; } @Override public boolean isVisible() { return visible; } @Override public void setVisible(boolean visible) { this.visible = visible; } @Override public void update(long elapsedTime) { if (visible && hit) { state(); } } public int getMaxValue() { return valueMax; } public void setMaxValue(int valueMax) { this.valueMax = valueMax; this.current = (width * value) / valueMax; this.goal = (width * valueMin) / valueMax; this.state(); } public int getMinValue() { return valueMin; } public void setMinValue(int valueMin) { this.valueMin = valueMin; this.current = (width * value) / valueMax; this.goal = (width * valueMin) / valueMax; this.state(); } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public boolean isHit() { return hit; } public void setHit(boolean hit) { this.hit = hit; } @Override public LTexture getBitmap() { return texture; } @Override public void dispose() { synchronized (colors) { quoteCount--; if (quoteCount <= 0) { if (colors != null) { for (LTexture tex2d : colors.values()) { if (tex2d != null) { tex2d.destroy(); tex2d = null; } } colors.clear(); } } } } }