Android Open Source - rpg Chess Board






From Project

Back to project page rpg.

License

The source code is released under:

Apache License

If you think the Android project rpg 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

package org.aschyiel.rpg.graph;
/*w  ww  .ja  v a  2 s.  co  m*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.andengine.entity.Entity;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.sprite.TiledSprite;
import org.andengine.input.touch.TouchEvent;
import org.aschyiel.rpg.GameObject;
import org.aschyiel.rpg.IFullGameObject;
import org.aschyiel.rpg.IGameObject;
import org.aschyiel.rpg.Resorcerer;
import org.aschyiel.rpg.activities.Terrain;
import org.aschyiel.rpg.level.LandType;
import org.aschyiel.rpg.level.UnitType;

import android.util.Log;

/**
* The chess-board is mechanism for keeping tabs on unit spatial orientation.
* Just like a real chessboard, there are only squares; Nothing to do with pixels.
*
* Specific pixel-perfect placement is to be dealt with elsewhere.
*/
public class ChessBoard
{

  protected static final String TAG = "[RPG:ChessBoard]";
  /**
  * Our board dimensions in squares.
  * rows    are synonymous with height (m).
  * columns are synonymous with width  (n).
  */
  protected final int rows;
  protected final int columns;

  protected final Square[][] squares;
  
  private final LandType[][] squareTextures;

  public ChessBoard( int rows, int columns )
  {
    this.rows    = rows;
    this.columns = columns;
    squaresByUnit = new HashMap<Integer, Square>();
    squares = new Square[rows][columns];
    squareTextures = new LandType[rows][columns];

    setupVertices();
    setupEdges();
  } 
  
  
  /**
  * Provides a way of changing the land-type for an individual square.
  * To be called BEFORE we create sprites for each square... 
  */
  public void setLandType( LandType landType, int row, int col )
  {
    squareTextures[row][col] = landType;
    
  }

  public void placeUnit( final IGameObject unit, int row, int col )
  {
    placeUnit( unit, squares[row][col] );
  }
  public void placeUnit( final IGameObject unit, final Square sq )
  {
    sq.occupy( unit );
  }
  
  /** 
   * The corollary of ChessBoard#placeUnit. 
   */
  public IGameObject removeUnit( int row, int col )
  {
    return removeUnit( squares[row][col] );
  }
  public IGameObject removeUnit( final Square sq )
  {
    final IGameObject unit = sq.unoccupy();
    broadcastVacancy( sq );
    return unit;
  }

  /**
  * Let others know that a previously occupied square is now available.
  * Needed for blocked units that are trying to complete their navigation-steps.
  *
  * @see GirlFriend#guide
  */
  private void broadcastVacancy( final Square sq )
  {
    for ( VacancySubscriber sub : vacancySubscribers )
    {
      sub.onVacancy( sq );
    }
  }

  private List<VacancySubscriber> vacancySubscribers = new ArrayList<VacancySubscriber>();

  public void subscribeToVacancies( final VacancySubscriber sub )
  {
    vacancySubscribers.add( sub );
  }

  /**
  * Setup the touch event listeners accross the board;
  * (Render the squares - for development purposes only).
  */
  public void bindSquares( float w,
                           float h,
                           Resorcerer rez,
                           Scene scn,
                           final OnSquareClickHandler cb )
  {
    for ( int m = 0; m < rows;    m++ )
    for ( int n = 0; n < columns; n++ )
    {
      final Square sq = squares[m][n];
      final Sprite sprite = new Sprite( w * n,
                                        h * m,
                                        rez.getLandTypeTexture( squareTextures[m][n] ),
                                        rez.getVertexBufferObjectManager() )
          {
            @Override
            public boolean onAreaTouched( final TouchEvent vente,
                                          final float _,
                                          final float __ )
            {
              if ( !vente.isActionUp() )
              {
                return false;
              }
              cb.onSquareClicked( sq, (IFullGameObject) sq.occupant );
              return true;
            }
          };
      sprite.setSize( w, h );
      scn.registerTouchArea( sprite );
      scn.attachChild( sprite );
      sq.sprite = sprite;
    }
  }

  /**
  * A reverse lookup capability --- managed via Square#occupy et al.
  * Uses the IGameObject.id as the key.
  */
  private final Map<Integer, Square> squaresByUnit;

  protected Square findSquare( IGameObject unit )
  {
    return squaresByUnit.get( unit.getId() );
  }

  /**
  * Create each squares (8x8 will be 64, etc.).
  */
  private void setupVertices()
  {
    boolean isColoured = false;    // flip back-and-forth between white vs. black.
    for ( int row = 0; row < rows; row++ )
    {
      for ( int col = 0; col < columns; col++ )
      {
        squares[row][col] = new Square( row, col, isColoured );
        isColoured = !isColoured;
      }
      isColoured = !isColoured;    // Stagger per row (not redundant).
    }
  }

  /**
  * Setup each square to have 4 neighbors max.
  */
  private void setupEdges()
  {
    for ( int row = 0; row < rows; row++ )
    {
      for ( int col = 0; col < columns; col++ )
      {
        Square sq = squares[row][col];
        sq.up    = ( row - 1 < 0           )? null : squares[ row - 1][ col     ];
        sq.left  = ( col - 1 < 0           )? null : squares[ row    ][ col - 1 ];
        sq.down  = ( row + 1 > rows    - 1 )? null : squares[ row + 1][ col     ];
        sq.right = ( col + 1 > columns - 1 )? null : squares[ row    ][ col + 1 ];
      }
    }
  }

  /**
  * An individual place within our board.
  */
  public class Square
  {
    /** ie. "A3" */
    protected final String name;

    protected final int row;
    protected final int column;

    /** Friendly neighbors. */
    protected Square up;
    protected Square down;
    protected Square left;
    protected Square right;

    /** For debugging. */
    protected Sprite sprite;

    /**
    * Think alternating white vs. black squares in a chess-board.
    */
    protected final boolean isColoured;

    /** The current occupant of the square (changes). */
    protected IGameObject occupant = null;

    Square( int row, int column, boolean isColoured )
    {
      name =  String.valueOf( Character.toChars( 65 + column ) ) +
              String.valueOf( row + 1 );
      this.row        = row;
      this.column     = column;
      this.isColoured = isColoured;
    }

    protected void occupy( IGameObject unit )
    {
      if ( isOccupado() )
      {
        throw new RuntimeException( "Don't double-book units onto the same square." );
      }
      if ( null == unit )
      {
        throw new RuntimeException( "NPE - Invalid occupant for square." );
      }
      occupant = unit;
      squaresByUnit.put( unit.getId(), this ); 
    }

    /**
    * Clear out a square and returns the current occupant, if any.
    */
    protected IGameObject unoccupy()
    {
      IGameObject unit = occupant;
      occupant = null;
      if ( null != unit && this == squaresByUnit.get( unit.getId() ) )
      {
        // GOTCHA: Be specific vs. last-one wins.
        squaresByUnit.put( unit.getId(), null );
      } 
      return unit;
    }

    /**
    * Returns true if we're NOT vacant.
    */
    protected boolean isOccupado()
    {
      return null != occupant;
    }

    @Override
    public String toString()
    {
      return name;
    }

    /**
    * Returns true if this square is unavailable to the given unit-type.
    * ie. ships can't go on land.
    */
    public boolean isInaccessible( UnitType unitType )
    {
      // Always allow empty-values free reign (for testing).
      if ( null == unitType )
      {
        return false;
      }

      // TODO: Don't hardcode -- base it off of land-types, etc.
      //   Also, we should allow units to "run-over" other unit-types,
      //   based on the occupant, etc.
      return isOccupado();
    }
  }
}




Java Source Code List

org.aschyiel.rpg.Coords.java
org.aschyiel.rpg.Focus.java
org.aschyiel.rpg.GameObjectFactory.java
org.aschyiel.rpg.GameObject.java
org.aschyiel.rpg.ICanHasFocus.java
org.aschyiel.rpg.IFullGameObject.java
org.aschyiel.rpg.IGameObject.java
org.aschyiel.rpg.PowerChords.java
org.aschyiel.rpg.Resorcerer.java
org.aschyiel.rpg.activities.Launcher.java
org.aschyiel.rpg.activities.Sandbox.java
org.aschyiel.rpg.activities.Terrain.java
org.aschyiel.rpg.activities.sandbox.BasicCombat.java
org.aschyiel.rpg.activities.sandbox.BasicMovement.java
org.aschyiel.rpg.activities.sandbox.MovementVsLandTypes.java
org.aschyiel.rpg.graph.ChessBoard.java
org.aschyiel.rpg.graph.DefaultPathFinder.java
org.aschyiel.rpg.graph.GirlFriend.java
org.aschyiel.rpg.graph.NavPath.java
org.aschyiel.rpg.graph.Navigator.java
org.aschyiel.rpg.graph.OnSquareClickHandler.java
org.aschyiel.rpg.graph.PathFinder.java
org.aschyiel.rpg.graph.Step.java
org.aschyiel.rpg.graph.VacancySubscriber.java
org.aschyiel.rpg.level.LandType.java
org.aschyiel.rpg.level.LevelDetail.java
org.aschyiel.rpg.level.Level.java
org.aschyiel.rpg.level.Player.java
org.aschyiel.rpg.level.UnitType.java