Package com.golden.gamedev.object.collision

Source Code of com.golden.gamedev.object.collision.BasicCollisionGroup

/*
* Copyright (c) 2008 Golden T Studios.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package com.golden.gamedev.object.collision;

// GTGE
import com.golden.gamedev.object.CollisionManager;
import com.golden.gamedev.object.PlayField;
import com.golden.gamedev.object.Sprite;
import com.golden.gamedev.object.SpriteGroup;

/**
* Basic collision check, only check whether a collision occured or not.
* <p>
*
* This class does not gather any information from the collision. To get more
* information from the collision, such as collision side, use
* {@link CollisionGroup} instead.
* <p>
*
* This type of collision check is the best to use for hit and destroy
* collision.
* <p>
*
* For example: collision between projectile and enemy ships
*
* <pre>
* Playfield playfield;
* SpriteGroup PROJECTILE, ENEMY;
* playfield.addCollisionGroup(PROJECTILE, ENEMY, new BasicCollisionGroup() {
*  
*   public void collided(Sprite s1, Sprite s2) {
*     // after enemy collided with projectile,
*     // the enemy explode (set to non-active)
*     s2.setActive(false);
*   }
* });
* </pre>
*
* @see PlayField#addCollisionGroup(SpriteGroup, SpriteGroup, CollisionManager)
*/
public abstract class BasicCollisionGroup extends CollisionManager {
 
  // sprite bounding box
  /**
   * Default collision shape used as every sprites in group 1 bounding box.
   */
  protected final CollisionRect rect1 = new CollisionRect();
 
  /**
   * Default collision shape used as every sprites in group 2 bounding box.
   */
  protected final CollisionRect rect2 = new CollisionRect();
 
  /**
   * Indicates whether this collision detection should use pixel-perfect
   * precision or not.
   * <p>
   *
   * The usual way to turn on this variable is :
   *
   * <pre>
   * class ThisThatCollision extends BasicCollisionGroup {
   *  
   *   // class initialization
   *   {
   *     pixelPerfectCollision = true;
   *   }
   * }
   * </pre>
   */
  public boolean pixelPerfectCollision;
 
  /** ************************************************************************* */
  /** ***************************** CONSTRUCTOR ******************************* */
  /** ************************************************************************* */
 
  /**
   * Creates new <code>BasicCollisionGroup</code>.
   */
  public BasicCollisionGroup() {
  }
 
  /**
   * Returns collision shape (bounding box) of specified sprite from group 1.
   * <p>
   *
   * In this implementation, the sprite bounding box is set as large as
   * <code>Sprite</code> dimension:
   *
   * <pre>
   * public CollisionShape getCollisionRect1(Sprite s1) {
   *   rect1.setBounds(s1.getX(), s1.getY(), s1.getWidth(), s1.getHeight());
   *   return rect1;
   * }
   * </pre>
   *
   * @param s1 the sprite from group 1 to be check its collision
   * @return The collision shape of the sprite, or null to skip collision
   *         check.
   *
   * @see #rect1
   * @see #getCollisionShape2(Sprite)
   * @see CollisionShape#intersects(CollisionShape)
   */
  public CollisionShape getCollisionShape1(Sprite s1) {
    this.rect1.setBounds(s1.getX(), s1.getY(), s1.getWidth(), s1
            .getHeight());
   
    return this.rect1;
  }
 
  /**
   * Returns collision shape (bounding box) of specified sprite from group 2.
   * <p>
   *
   * In this implementation, the sprite bounding box is set as large as
   * <code>Sprite</code> dimension:
   *
   * <pre>
   * public CollisionShape getCollisionRect2(Sprite s2) {
   *   rect2.setBounds(s2.getX(), s2.getY(), s2.getWidth(), s2.getHeight());
   *   return rect2;
   * }
   * </pre>
   *
   * @param s2 the sprite from group 2 to be check its collision
   * @return The collision shape of the sprite, or null to skip collision
   *         check.
   *
   * @see #rect2
   * @see #getCollisionShape1(Sprite)
   * @see CollisionRect#intersects(CollisionShape)
   */
  public CollisionShape getCollisionShape2(Sprite s2) {
    this.rect2.setBounds(s2.getX(), s2.getY(), s2.getWidth(), s2
            .getHeight());
   
    return this.rect2;
  }
 
  /** ************************************************************************* */
  /** ****************** MAIN-METHOD: CHECKING COLLISION ********************** */
  /** ************************************************************************* */
 
  public void checkCollision() {
    SpriteGroup group1 = this.getGroup1(), group2 = this.getGroup2();
    if (!group1.isActive() || !group2.isActive()) {
      // one of the group is not active
      return;
    }
   
    Sprite[] member1 = group1.getSprites(), // group one members
    member2 = group2.getSprites();
    int size1 = group1.getSize(), // size of non-null members
    size2 = group2.getSize();
   
    Sprite sprite1, sprite2; // sprite reference
    CollisionShape shape1, shape2; // sprite collision rect
   
    for (int i = 0; i < size1; i++) {
      sprite1 = member1[i];
     
      if (!sprite1.isActive()
              || (shape1 = this.getCollisionShape1(sprite1)) == null) {
        // sprite do not want collision check
        continue;
      }
     
      for (int j = 0; j < size2; j++) {
        sprite2 = member2[j];
       
        if (!sprite2.isActive() || sprite1 == sprite2
                || (shape2 = this.getCollisionShape2(sprite2)) == null) {
          // sprite do not want collision check
          continue;
        }
       
        if (this.isCollide(sprite1, sprite2, shape1, shape2)) {
          // fire collision event
          this.collided(sprite1, sprite2);
         
          // size1 = group1.getSize();
          // size2 = group2.getSize();
         
          if (!sprite1.isActive()
                  || (shape1 = this.getCollisionShape1(sprite1)) == null) {
            // collided sprite has been dead
            break;
          }
        }
      }
    }
  }
 
  /**
   * Performs collision check between Sprite <code>s1</code> and Sprite
   * <code>s2</code>, and returns true if the sprites (<code>shape1</code>,
   * <code>shape2</code>) is collided.
   * <p>
   *
   * Note: this method do not check active state of the sprites.
   *
   * @param s1 sprite from group 1
   * @param s2 sprite from group 2
   * @param shape1 bounding box of sprite 1
   * @param shape2 bounding box of sprite 2
   * @return true, if the sprites is collided one another.
   */
  public boolean isCollide(Sprite s1, Sprite s2, CollisionShape shape1, CollisionShape shape2) {
    if (!this.pixelPerfectCollision) {
      return (shape1.intersects(shape2));
     
    }
    else {
      if (shape1.intersects(shape2)) {
        return CollisionManager.isPixelCollide(s1.getX(), s1.getY(), s1
                .getImage(), s2.getX(), s2.getY(), s2.getImage());
      }
     
      return false;
    }
  }
 
  /**
   * Notified when <code>sprite1</code> from group 1 collided with
   * <code>sprite2</code> from group 2.
   *
   * @param s1 sprite from group 1
   * @param s2 sprite from group 2
   */
  public abstract void collided(Sprite s1, Sprite s2);
 
}
TOP

Related Classes of com.golden.gamedev.object.collision.BasicCollisionGroup

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.