package org.opengl.game;
import java.util.Arrays;
import java.util.Comparator;
import javax.microedition.khronos.opengles.GL10;
/**
* 图层管理器
* 可以动态设置图片,来显示遮挡效果
* 可以动态调用procShelter(Layer the,Layer other)方法实现遮挡
* 可以动态调用collidesImpl(Layer the,Layer other)方法来实现碰撞检测
* @author 张世洋
* @date 2011-10-14
* @QQ 381715271
*/
public class LayerManager implements Comparator<Layer>{
private Layer[] layers=new Layer[4];
private int nlayers;
public LayerManager(){
}
public void draw(GL10 gl){
for (int i =0;i<nlayers;i++){
Layer layer=layers[i];
layer.draw(gl);
}
}
/**
* Appends a Layer to this LayerManager. The Layer is appended to the
* list of existing Layers such that it has the highest index (i.e. it
* is furthest away from the user). The Layer is first removed
* from this LayerManager if it has already been added.
*
* @see #insert(Layer, int)
* @see #remove(Layer)
* @param l the <code>Layer</code> to be added
* @throws NullPointerException if the <code>Layer</code> is
* <code>null</code>
*/
public void append(Layer layer) {
// remove the Layer if it is already present
// will throw NullPointerException if the Layer is null
removeImpl(layer);
addImpl(layer, nlayers);
}
/**
* Inserts a new Layer in this LayerManager at the specified index.
* The Layer is first removed from this LayerManager if it has already
* been added.
* @see #append(Layer)
* @see #remove(Layer)
* @param l the <code>Layer</code> to be inserted
* @param index the index at which the new <code>Layer</code> is
* to be inserted
* @throws NullPointerException if the <code>Layer</code> is
* <code>null</code>
* @throws IndexOutOfBoundsException if the index is less than
* <code>0</code> or
* greater than the number of Layers already added to the this
* <code>LayerManager</code>
*/
public void insert(Layer layer, int index) {
/* Check for correct arguments: index in bounds */
if ((index < 0) || (index > nlayers)) {
throw new IndexOutOfBoundsException();
}
// if the Layer is already present
// remove it
// will throw NullPointerException if the Layer is null
removeImpl(layer);
// insert it at the specified index
addImpl(layer, index);
}
/**
* Removes the specified Layer from this LayerManager. This method does
* nothing if the specified Layer is not added to the this LayerManager.
* @see #append(Layer)
* @see #insert(Layer, int)
* @param l the <code>Layer</code> to be removed
* @throws NullPointerException if the specified <code>Layer</code> is
* <code>null</code>
*/
public void remove(Layer l) {
removeImpl(l);
}
/**
* add or insert a layer
* @param layer The Layer to be inserted
* @param index the position at which to insert the layer
*/
private void addImpl(Layer layer, int index) {
// Add component to list;
// allocate new array if necessary.
if (nlayers == layers.length) {
Layer newlayers[] = new Layer[nlayers + 4];
System.arraycopy(layers, 0, newlayers, 0, nlayers);
System.arraycopy(layers, index, newlayers,
index + 1, nlayers - index);
layers = newlayers;
} else {
System.arraycopy(layers, index, layers,
index + 1, nlayers - index);
}
layers[index] = layer;
nlayers++;
}
/**
* Removes the specified Layer from this LayerManager.
* @param l The Layer to be removed
* @throws NullPointerException if the specified Layer is null
**/
private void removeImpl(Layer layer) {
if (layer== null) {
throw new NullPointerException();
}
/**
* Search backwards, expect that more recent additions
* are more likely to be removed.
*/
for (int i = nlayers; --i >= 0; ) {
if (layers[i] == layer) {
remove(i);
}
}
}
/**
* remove a layer at the specified index.
* @param index the position at which to insert the layer,
*/
private void remove(int index) {
System.arraycopy(layers, index + 1,
layers, index,
nlayers - index - 1);
layers[--nlayers] = null;
}
public void removeAll(){
for(int i=nlayers-1;i>0;i--){
remove(i);
}
}
/*
* 对图层数组进行排序,来实现遮挡效果
*/
private void sortLayer(){
Arrays.sort(layers, this);
}
/*
* 处理遮挡
* 通过比较图层深度和当前的模型y坐标,动态交互图层来实现
*/
public void procShelter(Layer the,Layer other){
// float y1=the.getY();
// float y2=other.getY();
// int id1=the.getLayerNum();
// int id2=other.getLayerNum();
if(this.collidesImpl(the, other)){//发送了碰撞,进行排序
this.sortLayer();
// float x1=the.getX();
// float x2=other.getX();
// if((x1<x2)&&(id1<id2)){
// the.setLayerNum(id2);
// other.setLayerNum(id1);
// this.insert(the,id2);
// this.insert(other, id1);
// return ;
// }else if((x1>x2)&&(id1>id2)){
// the.setLayerNum(id2);
// other.setLayerNum(id1);
// this.insert(the,id2);
// this.insert(other, id1);
// return;
// }
}
// if((y1<y2)&&(id1<id2)){
// the.setLayerNum(id2);
// other.setLayerNum(id1);
// this.insert(the,id2);
// this.insert(other, id1);
// return ;
// }
// if((y1>y2)&&(id2>id2)){
// the.setLayerNum(id2);
// other.setLayerNum(id1);
// this.insert(the, id2);
// this.insert(other, id1);
// return;
// }
}
/*
* 碰撞检测
* param other 要检测的对象
* return 发送碰撞是返回true
*/
public boolean collidesImpl(Layer the,Layer other){
float otherX=other.getX();
float otherY=other.getY();
float theX=the.getX();
float theY=the.getY();
float otherW=other.getWidth();
float otherH=other.getHeight();
float theW=the.getWidth();
float theH=the.getHeight();
if(theX<otherX+otherW&&theX+theW>otherX&&
theY<otherY+otherH&&theY+theH>otherY){
return true;
}
return false;
}
/*
* 碰撞检测
* param other 要检测的对象
* return 发送碰撞是返回true
*/
public boolean collidesWith(Layer the,Layer other){
float otherX=other.getCollidesX();
float otherY=other.getCollidesY();
float theX=the.getCollidesX();
float theY=the.getCollidesY();
float otherW=other.getCollidesW();
float otherH=other.getCollidesH();
float theW=the.getCollidesW();
float theH=the.getCollidesH();
if(theX<otherX+otherW&&theX+theW>otherX&&
theY<otherY+otherH&&theY+theH>otherY){
return true;
}
return false;
}
/*
* Comparator接口的比较方法
* 对两个图层实例进行比较
* 比较的具体实现是根据Y坐标
* 实现这个接口是为了实现遮挡效果
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public int compare(Layer lhs, Layer rhs) {
float l=lhs.getY();
float r=rhs.getY();
if(l<r){
return 1;
}else if(l>r){
return -1;
}else{
return 0;
}
}
}