GameObject.java :  » Graphics-3D-2D-OpenGL » nage-android » com » nage » engine » Android Open Source

Android Open Source » Graphics 3D 2D OpenGL » nage android 
nage android » com » nage » engine » GameObject.java
package com.nage.engine;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import android.util.Log;

import com.nage.components.Component;
import com.nage.components.display.Drawable;
import com.nage.input.Input;
import com.nage.multiplayer.MultiplayerSystem;
import com.nage.utils.ByteArrayBuilder;

public class GameObject {
  
  public float x;
  public float y;
  
  public GameGraph parent;

  public String name;
  ArrayList<Component> objectComponents;
  ArrayList<Component> removeQueue;
  private  ArrayList<Component> addQueue;

  public boolean hasMoved;
  
  public boolean remoteObject, localObject; // remote objects will use remote input. local objects use local input. can both be true too.
  public String ownerId; // the ID of the phone that owns this object. can be local or remote phone.
  public byte owner;
  
  boolean remotelyUpdated;
  
  /** Set to true when the object is modified and this will enable the
   * changes to be propagated across multiplayer system.
   */
  public boolean modified;
  
  /**
   * Unique id for this object that allows it to be identified across
   * multiplayer system.
   */
  public byte id; 
  
  /**
   * Assigned to a GameObject when it is created. Make sure this is incremented
   * so that each GameObject has a unique id.
   */
  private static byte next_id = 0x01;

  
  public GameObject(GameGraph p) {
    objectComponents = new ArrayList<Component>();
    removeQueue = new ArrayList<Component>();
    addQueue = new ArrayList<Component>();
    hasMoved = true;
    parent = p;
    localObject = true; // objects are by default local and not remote.
    remoteObject = false;
    owner = MultiplayerSystem.DEFAULT;
    id = next_id++;
  }
  
  public void addComponentWhenPossible(Component c) {
    addQueue.add(c);
  }
  public void addComponent(Component c) {
    objectComponents.add(c);
  }
  
  public Component getComponent(int id) {
    for (Component c : objectComponents) {
      if(c.type==id) {
        return c;
      }
    }
    return null;
  }
  
  public boolean hasComponent(int id) {
    for (Component c : objectComponents) {
      if(c.type==id) {
        return true;
      }
    }
    return false;
  }

  public void removeComponent(int id) {
    for (Component c : objectComponents) {
      if(c.type==id) {
        removeQueue.add(c);
      }
    }
  }
  
  public void removeComponent(Component c) {
    removeQueue.add(c);
  }
  
  public ArrayList<Drawable> update(long delta, Input local, Input remote) {
    
  //  Log.d("GameObject", "  update() start: "+name+" x = "+x+" y = "+y);
    
    if(!removeQueue.isEmpty()) {
      for(Component c : removeQueue) {
        objectComponents.remove(c);
      }
      removeQueue.clear();
    }
    if(!addQueue.isEmpty()) {
      for(Component c : addQueue) {
        objectComponents.add(c);
      }
      addQueue.clear();
    }
    
    ArrayList<Drawable> drawItems = new ArrayList<Drawable>();
     
  //  Log.d("GameObject", "Performing update. Object Name = "+name+", input - remote = "+remote+", local = "+local);
    
    // If we have recieved local input and it is owned by the same owner as this object
    if(local!=null && (local.owner==this.owner || local.owner==MultiplayerSystem.DEFAULT)) {
      // then update this object with that input.
      performUpdate(delta, local, drawItems);
      Log.d("GameObject", "Updating "+name+" with local input from "+local.owner);
    } else {
      // update this object with null input
      performUpdate(delta, null, drawItems);
    }
    
    // If we have recieved remote input and it is owned by the same owner as this object
    if(remote!=null && remote.owner==this.owner) {
      // then update this object with that input.
      performUpdate(delta, remote, drawItems);
      Log.d("GameObject", "Updating "+name+" with remote input from "+remote.owner);
    } // otherwise, we don't to update with null input, cause it has already been updated above.
    
    
    modified = true;
    
    return drawItems;
  }

//  public void calcVertices(GL10 gl) {
//    for(Component c : objectComponents) {
//      if(c instanceof Drawable) {
//        Drawable d = (Drawable) c;
//        d.calcVertices(gl);
//      }
//    }
//  }

  private void performUpdate(long delta, Input i, ArrayList<Drawable> drawItems ) {
    for (Component c : objectComponents) {
      Drawable toAdd = c.update(delta, i);
      if (toAdd != null) {
        drawItems.add(toAdd);
      } 
    }    
  }

  public void setX(float x) {
    this.x = x;
    hasMoved = true;
  }

  public float getX() {
    return x;
  }

  public void setY(float y) {
    this.y = y;
    hasMoved = true;
  }

  public float getY() {
    return y;
  }

  public void setX(String x) {
    if(x!=null) {
      this.x = (float)Integer.parseInt(x);
      hasMoved = true;
    }
  }
  
  public void setY(String y) {
    if(y!=null) {
      this.y = (float)Integer.parseInt(y);
      hasMoved = true;
    }
  }

  /**
   * Visit each component in this object and tells it to perform its
   * flatten routine using the stream_builder. Adds the overall count
   * of components, and a header for each component.
   * 
   * @param stream_builder
   * @return
   * @throws IOException
   */
  public boolean flatten(ByteArrayOutputStream stream_builder) throws IOException {
    
    stream_builder.write(id); // first send obj identification.
    stream_builder.write(name.getBytes()); // write name to byte array
    stream_builder.write(0); // null terminate the string
    stream_builder.write(ByteArrayBuilder.floatToByteArray(x)); // write member variable x
    stream_builder.write(ByteArrayBuilder.floatToByteArray(y)); // write member variable y
    
    
    stream_builder.write(getModifiedCount()); // number of components this object has
    int comp_number = 1;
    for(Component comp : objectComponents) {
      if(comp.modified) {
        Log.d("GameObject", "COMP "+comp.id+" ("+comp.getType()+") MODIFIED");
        stream_builder.write(comp_number++); // component number
        comp.flatten(stream_builder); // component contents
        comp.modified = false; // reset modified.
      }
    }
    return comp_number==objectComponents.size();
  }

   /** Counts the number of objects within graph that have their modified
   * flag set to true. 
   * @return Number of modified objects in graph
   */
  private int getModifiedCount() {
    int i = 0;
    for(Component comp : objectComponents) {
      if(comp.modified)
        i++;
    }
    return i;
  }

  /**
   * Expands the byte array b starting at index i. It will check the count of
   * components contained in the array, and create that many blank components. Each
   * blank component is then asked to expand itself, being given the buffer and an
   * index to start expanding from.
   * 
   * @param b Byte array containing a flattened game graph
   * @param i Index in array that has been already expanded
   * @return  
   * @throws GameGraphException 
   */
  public int expand(byte[] b, int i) throws GameGraphException {
    
    id = b[i++]; // read id
    
    StringBuffer str = new StringBuffer();
    while(b[i]!=0) { // null terminated, so read till 0 is found.
      str.append((char)b[i++]);
    }
    i++;
    name = str.toString(); // read name.
    x = ByteArrayBuilder.byteArrayToFloat(b[i++], b[i++], b[i++], b[i++]); // set x from bytestream
    y = ByteArrayBuilder.byteArrayToFloat(b[i++], b[i++], b[i++], b[i++]); // set y from bytestream
    
    int expected_size = b[i++]; // the is the size of the objectComponents graph
                  // of the flattened game object. (number of components
                  // this object has.
    Log.d("GameObject", "          Expanding "+expected_size+" Components");

    for(int j = 1; j <= expected_size; j++) {
      if(b[i++]!=j) { throw new GameGraphException("Component numbers do not match"); }
      Component comp = Component.createComponent(b[i++], this);
      Log.d("GameObject", "         Created a blank "+comp.toString());
      i = comp.expand(b, i);
      addComponent(comp);
      
    }
    remotelyUpdated = true;
    return i;
  }



}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.