Android Open Source - DolphinOES Game Object






From Project

Back to project page DolphinOES.

License

The source code is released under:

Apache License

If you think the Android project DolphinOES listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*******************************************************************************
 * Copyright 2014 See AUTHORS file.//from   w ww. j  a v a2 s .c  o m
 * 
 * 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.
 ******************************************************************************/

package com.sidereal.dolphinoes.architecture;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.ObjectMap;
import com.sidereal.dolphinoes.architecture.pos.Position;
import com.sidereal.dolphinoes.util.DolphinOESException;

/** An entity in the framework. It is added in the framework by passing the scene
 * we want to add it to in the constructor
 * {@link #GameObject(GameScene, Object...)}.
 * <p>
 * To add functionality in the form of a {@link GameBehavior}, the
 * {@link GameBehavior#GameBehavior(GameObject)} constructor has to be called
 * which will add the behavior to the passed object's {@link #behaviors}.
 * <p>
 * Additional custom functionality can be added using methods that can be
 * overriden such as {@link #createObject(Object...)}, {@link #update()},
 * {@link #handleSceneChange()}, {@link #onResize(float, float, float, float)}
 * and {@link #onPositionChange()}.
 * <p>
 * To make the object exist throughout all scenes until deleted, use
 * {@link #isPersistent}, and to pass the object to the next scene only, use
 * {@link GameScene#passObjToNextScene(GameObject)} or
 * {@link GameScene#passListToNextScene(ArrayList)}.
 * <p>
 * The {@link GameBatch} can be set using {@link #setGameBatch(String)}, being
 * able to afterwards get gameBatch data from {@link #gameBatch}.
 * <p>
 * Removing the object is done using {@link GameScene#remove(GameObject)}.
 * 
 * @author Claudiu Bele */
public abstract class GameObject
{

  // region fields
  /** Whether or not the object is persistent through scenes, automatically
   * being added to the new scene.
   * <p>
   * Objects with this value equal to {@link Boolean#TRUE} will be passed to
   * the next scene regardless of whether or not it is found in the previous
   * scene's {@link GameScene#toKeepForNextScene}.
   * <p>
   * Used in {@link GameScene#GameScene()} when
   * processing the previous screen to retrieve the objects found inside of
   * it. */
  protected boolean isPersistent;
  /** Set to false,after being added to the scene and in the scene, set to true */
  protected boolean inScene;

  /** The variable is true from after adding to the scene until we planned on
   * removing it */
  protected boolean enabled;

  /** The object's target gamebatch */
  public GameBatch gameBatch;


  // region parent/children

  /** The local position of the object. It is used if the object is a child.
   * <p>
   * This acts as an offset to the parent's position, the child's position
   * being made by adding it's own {@link #localPosition} and the parent's
   * {@link #position}. */
  Vector3 localPosition = new Vector3();

  /** List of children. When adding a new Children, we add them to the list */
  public ArrayList<GameObject> children;

  /** The parent of a child, assigned when adding a child to a parent. */
  public GameObject parent;
  // endregion

  /** The name of the object, will be used when finding an object by name or
   * type. Changing this value without a setter ( using
   * {@link #setName(String)} ) is only useful if set in
   * {@link #createObject(Object...)}. */
  private String name;

  /** The type of the object,will be used when finding an object by name or
   * type. Changing this value without a setter ( using
   * {@link #setType(String)} ) is only useful if set in
   * {@link #createObject(Object...)} */
  private String type;

  /** The scene that the object is currently in */
  public GameScene scene;

  /** The list of behaviors. Will be added by passing the object to the
   * constructor of a behavior */
  public final List<GameBehavior> behaviors;

  /** Comparator used for sorting the behaviors, set based on priority by
   * default; */
  public Comparator<GameBehavior> behaviorsComparator;

  /** Map of behaviors, used for retrieving behaviors by name */
  public final ObjectMap<Class<? extends GameBehavior>, GameBehavior> behaviorTable;

  /** Object that represents the object's position. Assigned in
   * {@link GameObject#GameObject(GameScene, Object...)}. */
  public final Position pos;

  /** A reference to the object. Is to be used in annonymous inner types */
  public final GameObject instance;


  // endregion fields

  // region constructors
  /** Default GameObject constructor.
   * 
   * @param scene
   * @param params
   *            parameters passed to {@link #createObject(Object...)} */
  public GameObject(GameScene scene, Object... params)
  {

    setEnabled(true);
    this.isPersistent = false;
    this.instance = this;
    this.behaviorTable = new ObjectMap<Class<? extends GameBehavior>, GameBehavior>();
    this.behaviors = new ArrayList<GameBehavior>();
    this.children = new ArrayList<GameObject>();
    this.scene = scene;
    this.pos = new Position(this);
    this.type = (getClass().getSimpleName());
    this.name = (this.getType() + " " + System.nanoTime());
    
    this.behaviorsComparator = new Comparator<GameBehavior>()
    {

      @Override
      public int compare(GameBehavior o1, GameBehavior o2)
      {

        return (o1.priorityLevel - o2.priorityLevel);
      }

    };

    setGameBatch("Default");

    createObject(params);
    scene.add(this);
  }

  // endregion

  // region methods
  /** Disposes all of the assets of a {@link GameObject}, including behaviors
   * and all descendants.
   * 
   * Method to be called when we want an object to be removed from the scene.
   * It will update the parent's list of children by removing the object from
   * the parents' list.
   * <p>
   * The method also disposes the resources of the children recursively, by
   * calling {@link #disposeInternal()} on all of gameobjects found in
   * {@link #children}.
   * <p>
   * The list of behaviors found in {@link #behaviors} is iterated over,
   * calling {@link GameBehavior#dispose()} in each of them.
   * <p>
   * After clearing all the data, it also calls {@link #dispose()}, which is a
   * method that can be customised from implementation to implementation */
  final void disposeInternal()
  {

    // removes itself from the parent's list of children if the object has
    // parents
    if (parent != null)
    {
      if (parent.children != null)
      {
        synchronized (parent.children)
        {
          parent.children.remove(this);
        }
      }
    }

    // calls the same method in all of the chilldren
    if (children != null)
    {
      for (int i = 0; i < children.size(); i++)
      {
        children.get(i).disposeInternal();
      }
    }

    // disposes all of the data that each individual gamebehavior wants to
    // dispose
    if (behaviors != null)
    {
      for (int i = 0; i < behaviors.size(); i++)
      {
        behaviors.get(i).dispose();
      }
      behaviors.clear();
    }
    dispose();
  }

  /** Updates the debugging methods in each behavior attached to the GameObject
   * 
   * @param info */
  public final void updateDebug()
  {
    if (!enabled())
      return;
    for (GameBehavior behavior : behaviors)
    {
      if(DolphinOES.debug.isEnabled() && DolphinOES.debug.get(behavior).enabled)
      {
        behavior.updateDebug();
      }
        
    }
  }

  /** Updates the Game Object, being called every frame
   * <p>
   * If the object has a parent, it has it's position set the parent's
   * position to which we append the object's own {@link #localPosition}
   * variable of type {@link Vector2}.
   * <p>
   * The method calls the extendable method {@link #update()}, sorts the
   * behaviors in order of their priority value, as well as updating each of
   * the behaviors found in {@link #behaviors} by calling
   * {@link GameBehavior#update()}. */
  public final void updateInternal()
  {
    if (!enabled())
      return;

    instance.update();

    Collections.sort(behaviors, behaviorsComparator);

    for (int i = 0; i < behaviors.size(); i++)
    {
      behaviors.get(i).updateInternal();
    }
  }

  // region override-able methods

  /** Can add a unique event/behavior to run in the object's update thread, so
   * we don't have to make a new custom behavior for each class */
  protected void update()
  {

  }

  /** Method called in {@link #GameObject(GameScene, Object...)} which can be
   * extended to initialize logic in individual Game Object implementations
   * 
   * @param params
   *            parameters passed from
   *            {@link #GameObject(GameScene, Object...)} */
  protected void createObject(Object... params)
  {

  }

  /** Called in {@link DolphinOES#handleSceneTransition()}, on the
   * objects that were passed from a scene to another one. */
  public void handleSceneChange()
  {

  }

  /** Called when removing an object, in {@link #disposeInternal()}. The method
   * can be customized in the implementations of individual Game Objects. */
  protected void dispose()
  {

  }

  /** Method that gets called when the screen is being resized
   * 
   * @param x
   *            the new window width
   * @param y
   *            the new window height
   * @param oldX
   *            old window width
   * @param oldY
   *            old window height */
  protected void onResize(float x, float y, float oldX, float oldY)
  {

  }

  /** Method that gets called whenever the position of the object is changed.
   * <p>
   * Method is called from {@link #setLocalPosition(float, float)} and
   * {@link #MISSING()} */
  protected void onPositionChange()
  {

  }

  // endregion

  // region getters/setters

  public final void setGameBatch(String newTag)
  {

    if (scene == null)
      throw new NullPointerException("Gamescene attached to GameObject is null in setGameBatch");

    for (int i = 0; i < scene.gameBatches.size(); i++)
    {
      
      if (scene.gameBatches.get(i).name.equals(newTag))
      {
        if (gameBatch != null)
        {
          if (gameBatch.objects.contains(this))
            gameBatch.objects.remove(this);
        }
        gameBatch = scene.gameBatches.get(i);
        if (!gameBatch.objects.contains(this))
        {
          gameBatch.objects.add(this);
        }
        return;

      }
    }
    
    throw new DolphinOESException("Didn't find a GameBatch with the name equal to "+newTag);
  }

  /** Set's a Game Object's parent, updating all the object's position and
   * level based on parent data.
   * <p>
   * If the {@link #parent} variable is null when calling this method, the
   * {@link #localPosition} variable is set to {@link #position}, in order to
   * have the real object's position saved when updating {@link #position} to
   * meet the hierarchy's perspective on it.
   * <p>
   * 
   * @param obj */
  public final void setParent(GameObject obj)
  {

    // if GameObject passed is self, exit method
    if (obj == this)
      return;

    if (obj == null)
    {
      // if object previously had a parent and we pass a null, update the
      // local position of the object
      // to own hierarchial position.
      if (parent == null)
        return;
      else
      {
        // local position is hierarchial position
        parent = null;
        pos.setLocal(pos.get());
        return;
      }
    }

    // setting the parent as an own child leads to removing the passed
    // parammeter
    // from the list of children as well as changing the child's parent to
    // null
    if (children.contains(obj))
    {
      obj.setParent(null);
      children.remove(obj);
    }

    parent = obj;

    synchronized (obj.children)
    {
      if (obj.children == null)
        obj.children = new ArrayList<GameObject>();
      obj.children.add(this);
    }

    // updating child position based on parent position
    pos.ensureHierarchialMatch();

    // update child level based on parent level
    this.setGameBatch(obj.gameBatch.name);

  }


  // endregion misc

  // endregion

  // region name
  /** Default name getter
   * 
   * @return */
  public final String getName()
  {

    return name;
  }

  /** Changes the name of the GameObject and updates the map in which the
   * GameObject can be found.
   * <p>
   * If the name passed is the same as before or the scene is null, we will
   * not handle the change of the variable.
   * <p>
   * This method can be used in {@link #createObject(Object...)} as well as
   * outside of it, being an alternative to explicitly changing {@link #name},
   * removing the object from its' previous place in
   * {@link GameScene#objectsMap } if necessary.
   * 
   * @param name
   *            The new name of the GameObject. If value passed is the same as
   *            the old one, the method will not be handled */
  public final void setName(String name)
  {

    if (this.name.equals(name))
      return;
    if (scene == null)
      return;

    if (!scene.objectsMap.containsKey(this.getType()))
    {
      scene.objectsMap.put(this.getType(),
          new HashMap<String, GameObject>());
    } else
    {
      if (scene.objectsMap.get(this.getType()).containsValue(this))
        scene.objectsMap.get(this.getType()).remove(this.name);
    }

    scene.objectsMap.get(this.getType()).put(name, this);

    this.name = name;
  }

  // endregion

  // region type
  /** Default type getter
   * 
   * @return */
  public final String getType()
  {

    return type;
  }

  /** Changes the type of the GameObject and updates the map in which the
   * GameObject can be found.
   * <p>
   * If the type passed is the same as before or the scene is null, we will
   * not handle the change of the variable.
   * <p>
   * This method can be used in {@link #createObject(Object...)} as well as
   * outside of it, being an alternative to explicitly changing {@link #type},
   * removing the object from its' previous place in
   * {@link GameScene#objectsMap } if necessary. A new Map will be created if
   * there isn't one already for the new GameObject type.
   * 
   * @param type
   *            The new type of the GameObject. If value passed is the same as
   *            the old one, the method will not be handled */
  public final void setType(String type)
  {

    if (this.type.equals(type))
      return;
    if (scene == null)
      return;

    if (scene.objectsMap.containsKey(this.type)
        && scene.objectsMap.get(this.type).containsValue(this))
    {
      scene.objectsMap.get(this.type).remove(this.getName());

    }
    if (!scene.objectsMap.containsKey(type))
    {
      scene.objectsMap.put(type, new HashMap<String, GameObject>());
    }
    scene.objectsMap.get(type).put(this.getName(), this);

    this.type = type;

  }

  // endregion

  // region behaviors
  @SuppressWarnings("unchecked")
  public final <T extends GameBehavior> T getBehavior(Class<T> behaviorClass)
  {

    return (T) behaviorTable.get(behaviorClass);
  }

  public final boolean removeBehavior(
      Class<? extends GameBehavior> behaviorClass)
  {

    GameBehavior targetBehavior = getBehavior(behaviorClass);
    if (targetBehavior == null)
      return false;

    targetBehavior.dispose();
    behaviors.remove(behaviorTable.get(behaviorClass));
    behaviorTable.remove(behaviorClass);
    return true;

  }

  // endregion

  /** Returns the status of activity of a gameobject in the hierarchy. If any
   * of the ancestors of the gameobject is inactive, this gameobject will also
   * be inactive. If all of the ancestors are self-active, then it will return
   * the gameobject's {@link #enabled} variable.
   * 
   * This return value decides whether or not to update a gameobject every
   * frame in {@link #updateInternal()} or not.
   * 
   * @return the availability of a gameobject in a hierarchy . Us */
  public final boolean enabled()
  {

    if (!isInScene())
      return false;

    if (parent != null)
    {
      if (!parent.enabled())
        return false;
    }

    return enabled;
  }

  /** Sets the availability of the gameobject. This does not set the value in
   * the hierarchy, and the gameobject will not update if {@link #parent} 
   * isn't active in the hierarchy as well.
   * 
   * Is set to false in {@link #GameObject(GameScene, Object...)} and when
   * adding the object to {@link GameScene#toRemove}.
   * <p>
   * Is set to true in {@link GameScene#addObjects}, when we add objects from
   * last frame to their respective {@link GameBatch} counterparts.
   * 
   * @param avaiable */
  public final void setEnabled(boolean avaiable)
  {

    this.enabled = avaiable;
  }

  /** Returns whether or not the user is to be removed or is in scene.
   * <p>
   * Called in {@link GameBatch#resize()}
   * 
   * @return */
  public final boolean isInScene()
  {

    return inScene;
  }

  public final boolean isPersistent()
  {

    if (isPersistent)
      return true;
    else if (parent != null)
    {
      return parent.isPersistent();
    }

    return false;
  }

  // endregion

  // endregion
}




Java Source Code List

com.sidereal.dolphinoes.architecture.AbstractEvent.java
com.sidereal.dolphinoes.architecture.DebugHandler.java
com.sidereal.dolphinoes.architecture.DolphinOES.java
com.sidereal.dolphinoes.architecture.GameBatch.java
com.sidereal.dolphinoes.architecture.GameBehavior.java
com.sidereal.dolphinoes.architecture.GameObject.java
com.sidereal.dolphinoes.architecture.GameScene.java
com.sidereal.dolphinoes.architecture.Module.java
com.sidereal.dolphinoes.architecture.core.Assets.java
com.sidereal.dolphinoes.architecture.core.Configurable.java
com.sidereal.dolphinoes.architecture.core.Debug.java
com.sidereal.dolphinoes.architecture.core.DolphinOESConfiguration.java
com.sidereal.dolphinoes.architecture.core.GameData.java
com.sidereal.dolphinoes.architecture.core.MouseMovedEvent.java
com.sidereal.dolphinoes.architecture.core.Time.java
com.sidereal.dolphinoes.architecture.core.assetload.AssetLoadHandler.java
com.sidereal.dolphinoes.architecture.core.assetload.AssetLoader.java
com.sidereal.dolphinoes.architecture.core.assetload.ClassFileHandleResolver.java
com.sidereal.dolphinoes.architecture.core.assetload.LoadingPercentage.java
com.sidereal.dolphinoes.architecture.core.input.ActionData.java
com.sidereal.dolphinoes.architecture.core.input.ActionEventWrapper.java
com.sidereal.dolphinoes.architecture.core.input.ActionEvent.java
com.sidereal.dolphinoes.architecture.core.input.Input.java
com.sidereal.dolphinoes.architecture.core.input.KeyTypedEvent.java
com.sidereal.dolphinoes.architecture.core.input.ScrollEvent.java
com.sidereal.dolphinoes.architecture.core.input.TouchData.java
com.sidereal.dolphinoes.architecture.core.input.TouchEventWrapper.java
com.sidereal.dolphinoes.architecture.core.input.TouchEvent.java
com.sidereal.dolphinoes.architecture.pos.Position.java
com.sidereal.dolphinoes.architecture.pos.Positions.java
com.sidereal.dolphinoes.backend.ConcreteGametester.java
com.sidereal.dolphinoes.backend.GameTester.java
com.sidereal.dolphinoes.backend.SceneGameTester.java
com.sidereal.dolphinoes.behaviors.audio.AudioListener.java
com.sidereal.dolphinoes.behaviors.audio.AudioPlayer.java
com.sidereal.dolphinoes.behaviors.events.EventTimer.java
com.sidereal.dolphinoes.behaviors.events.RecurringEvent.java
com.sidereal.dolphinoes.behaviors.input.Clickable.java
com.sidereal.dolphinoes.behaviors.particlesystem.ParticleEmitter.java
com.sidereal.dolphinoes.behaviors.particlesystem.ParticleHandler.java
com.sidereal.dolphinoes.behaviors.particlesystem.ParticleSpriteLayout.java
com.sidereal.dolphinoes.behaviors.particlesystem.ParticleSpriteObject.java
com.sidereal.dolphinoes.behaviors.pathfinding.PathfindingHandler.java
com.sidereal.dolphinoes.behaviors.pathfinding.PathfindingMap.java
com.sidereal.dolphinoes.behaviors.pathfinding.PathfindingNode.java
com.sidereal.dolphinoes.behaviors.pathfinding.PathfindingRoute.java
com.sidereal.dolphinoes.behaviors.renderer.DrawerBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.Drawer.java
com.sidereal.dolphinoes.behaviors.renderer.Renderer.java
com.sidereal.dolphinoes.behaviors.renderer.ninepatch.NinepatchBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.ninepatch.NinepatchDrawer.java
com.sidereal.dolphinoes.behaviors.renderer.scml.SCMLBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.scml.SCMLDrawer.java
com.sidereal.dolphinoes.behaviors.renderer.sprite.SpriteBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.sprite.SpriteDrawer.java
com.sidereal.dolphinoes.behaviors.renderer.spritesequence.SpriteSequenceBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.spritesequence.SpriteSequenceDrawer.java
com.sidereal.dolphinoes.behaviors.renderer.spritesequence.SpriteSequencePreference.java
com.sidereal.dolphinoes.behaviors.renderer.texture.TextureBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.texture.TextureDrawer.java
com.sidereal.dolphinoes.behaviors.renderer.tilemap.TileMapBuilder.java
com.sidereal.dolphinoes.behaviors.renderer.tilemap.TileMapDrawer.java
com.sidereal.dolphinoes.behaviors.triggers.Activatable.java
com.sidereal.dolphinoes.behaviors.triggers.Collider.java
com.sidereal.dolphinoes.behaviors.triggers.Hoverable.java
com.sidereal.dolphinoes.ui.MessageBubble.java
com.sidereal.dolphinoes.ui.TextBuilder.java
com.sidereal.dolphinoes.util.BooleanWrapper.java
com.sidereal.dolphinoes.util.DolphinOESException.java
com.sidereal.dolphinoes.util.FloatWrapper.java
com.sidereal.dolphinoes.util.IntWrapper.java
com.sidereal.dolphinoes.util.Utility.java