/** * Copyright 2008 - 2012 * * 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.3.3 */ package loon.action.movie; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import loon.action.ActionBind; import loon.action.map.Field2D; import loon.action.sprite.ISprite; import loon.core.LObject; import loon.core.geom.RectBox; import loon.core.graphics.device.LColor; import loon.core.graphics.opengl.GLEx; import loon.core.graphics.opengl.LTexture; import loon.core.graphics.opengl.LTextures; /** * 0.3.3新增类,用以实现多节点的叠加效果 */ public class Node extends LObject implements ISprite, ActionBind { /** * */ private static final long serialVersionUID = 3211228930455651878L; private Comparator<Node> zIndexComparator = new Comparator<Node>() { @Override public int compare(Node one, Node two) { return one.zIndex - two.zIndex; } }; protected int width, height; protected LTexture texture; private LColor color = new LColor(LColor.white); protected ArrayList<Node> children = new ArrayList<Node>(); private ArrayList<Node> requireRemove = new ArrayList<Node>(); private int zIndex = 0; protected Node parent = null; private boolean visible = true; public Node(final String fileName) { this(LTextures.loadTexture(fileName), 0, 0); } public Node(final String fileName, final float x, final float y) { this(LTextures.loadTexture(fileName), x, y); } public Node(final LTexture tex2d, final float x, final float y) { this.texture = tex2d; this.setLocation(x, y); this.width = tex2d.getWidth(); this.height = tex2d.getHeight(); } public Node(final String fileName, final float x, final float y, final float w, final float h) { this(LTextures.loadTexture(fileName), x, y, w, h); } public Node(final LTexture tex2d, final float x, final float y, final float w, final float h) { this.texture = tex2d; this.setLocation(x, y); this.width = (int) w; this.height = (int) h; } public Node getParent() { return parent; } public void setSize(final float w, final float h) { this.width = (int) w; this.height = (int) h; } @Override public void update(long elapsedTime) { final int remove = requireRemove.size(); if (remove > 0) { for (int index = 0; index < remove; index++) { final Node removedChild = requireRemove.get(index); children.remove(removedChild); } requireRemove.clear(); } Collections.sort(children, zIndexComparator); final int size = children.size(); for (int index = 0; index < size; index++) { final Node child = children.get(index); child.update(elapsedTime); } } @Override public int getWidth() { return width; } @Override public int getHeight() { return height; } public void setColor(LColor c) { color.setColor(c); } public LColor getColor() { return color; } @Override public float getAlpha() { return color.a; } @Override public void setAlpha(float a) { color.a = a; } @Override public void setVisible(boolean v) { this.visible = v; } @Override public boolean isVisible() { return visible; } @Override public void createUI(GLEx g) { if (!visible) { return; } if (texture != null) { g.drawTexture(texture, location.x, location.y, width * scaleX, height * scaleY, rotation, color); } paint(g, location.x, location.y); final int size = children.size(); if (size == 0) { return; } for (int index = 0; index < size; index++) { final Node child = children.get(index); if (child.visible) { final float pX = location.x + child.location.x; final float pY = location.y + child.location.y; g.drawTexture(child.texture, pX, pY, child.width * scaleX, child.height * scaleY, child.rotation, child.color); paint(g, pX, pY); } } } public void paint(GLEx g, float x, float y) { } public void addChild(final Node child, final int zIndex) { child.zIndex = zIndex; child.parent = this; int index = Collections.binarySearch(children, child, zIndexComparator); if (index >= 0) { final int size = children.size(); Node prevChild; do { prevChild = children.get(index); index++; } while (index < size && children.get(index).zIndex == prevChild.zIndex); } else { index = -(index + 1); } children.add(index, child); } public void addChild(final Node pChild) { addChild(pChild, pChild.zIndex); } public void reorderZIndex(final Node pChild, final int pZIndex) { children.remove(pChild); addChild(pChild, pZIndex); } public void removeChild(final Node pChild) { pChild.parent = null; requireRemove.add(pChild); } public List<Node> getChildren() { return this.children; } public int getZIndex() { return this.zIndex; } @Override public RectBox getCollisionBox() { return getRect(x(), y(), width * scaleX, height * scaleY); } @Override public LTexture getBitmap() { return texture; } @Override public void dispose() { this.visible = false; if (texture != null) { texture.destroy(); texture = null; } } @Override public Field2D getField2D() { return null; } @Override public boolean isBounded() { return false; } @Override public boolean isContainer() { return false; } @Override public boolean inContains(int x, int y, int w, int h) { return false; } @Override public RectBox getRectBox() { return getCollisionBox(); } @Override public int getContainerWidth() { return 0; } @Override public int getContainerHeight() { return 0; } float scaleX = 1, scaleY = 1; public void setScale(final float s) { this.setScale(s, s); } @Override public void setScale(final float sx, final float sy) { if (this.scaleX == sx && this.scaleY == sy) { return; } this.scaleX = sx; this.scaleY = sy; } @Override public float getScaleX() { return this.scaleX; } @Override public float getScaleY() { return this.scaleY; } }