/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package marioRhythm;
import factories.Points;
import factories.Sizes;
import graphics.common.Box;
import graphics.common.GraphicsObject;
import graphics.java.JavaSprite;
import graphics.java.Oval;
import graphics.common.Point;
import graphics.common.Size;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Freezerburn
*/
public class RhythmBall implements GraphicsObject {
private static final int HIDDEN_LOC = -9999999;
private static final int DEFAULT_BALL_SIZE = 32;
// the amount of time (in millis) that you have to "hit" the ball.
// this is actually double the amount of time, as it will check both before
// and after the hit time
private static final int DEFAULT_TIME_FRAME = 125;
// the time frame that indicates a "perfect" hit (highest score)
private static final int DEFAULT_PERF_TIME_FRAME = 25;
// the amount of time that it will be on screen before reaching the end
// location
private static final int DEFAULT_MOVE_TIME = 5000;
private static final double SNAP_DIST_MULT = 15.0;
private JavaSprite mSprite;
private long mHitTime; // the time that it needs to be hit at
private int mTimeFrame;
private int mPerfTimeFrame;
private int mMoveTime;
// this will be the calculated amount of distance that should be traveled
// every millisecond
private double mSingleStep;
// the amount of distance that once the rhythmball is within, it will be
// considered as having "ended"
private double mSnapDist;
private Point mStartLoc, mEndLoc;
private List< Point > mIntermediaryLocs;
private int mCurIntermediary;
private boolean mStarted;
private Oval startPoint, endPoint;
public RhythmBall( String name ) {
mSprite = new JavaSprite( name,
Points.get( HIDDEN_LOC, HIDDEN_LOC, 0 ),
Sizes.get( DEFAULT_BALL_SIZE, DEFAULT_BALL_SIZE, 0 ) );
mIntermediaryLocs = new ArrayList< Point >();
mStarted = false;
mMoveTime = DEFAULT_MOVE_TIME;
mStartLoc = Points.get( 0, 0, 0 );
mEndLoc = Points.get( 0, 0, 0 );
}
public RhythmBall( JavaSprite sprite ) {
mSprite = sprite;
}
public void setStartLoc( double x, double y ) {
mStartLoc.set( x, y, 0 );
startPoint = new Oval( mStartLoc, Sizes.get( 30, 30, 0 ) );
}
public void setStartLoc( Point p ) {
mStartLoc = p;
}
public void setEndLoc( double x, double y ) {
mEndLoc.set( x, y, 0 );
endPoint = new Oval( mEndLoc, Sizes.get( 30, 30, 0 ) );
}
public void setEndLoc( Point p ) {
mEndLoc = p;
}
public void addIntermediaryLoc( double x, double y ) {
mIntermediaryLocs.add( Points.get( x, y, 0 ) );
}
public void addIntermediaryLoc( Point p ) {
mIntermediaryLocs.add( p );
}
public void start() {
mStarted = true;
mSprite.setLoc( mStartLoc );
calcSingleStep();
mCurIntermediary = 0;
}
public boolean finished() {
return !mStarted;
}
private void calcSingleStep() {
mSingleStep = 0;
if( !mIntermediaryLocs.isEmpty() ) {
mSingleStep += Math.sqrt(
Math.pow( mStartLoc.getRealX() - mIntermediaryLocs.get( 0 ).getRealX(), 2) +
Math.pow( mStartLoc.getRealY() - mIntermediaryLocs.get( 0 ).getRealY(), 2 ) );
for( int i = 1; i < mIntermediaryLocs.size() - 1; i++ ) {
mSingleStep += Math.sqrt(
Math.pow( mIntermediaryLocs.get( i ).getRealX() - mIntermediaryLocs.get( i + 1 ).getRealX(), 2) +
Math.pow( mIntermediaryLocs.get( i ).getRealY() - mIntermediaryLocs.get( i + 1 ).getRealY(), 2 ) );
}
mSingleStep += Math.sqrt(
Math.pow( mEndLoc.getRealX() - mIntermediaryLocs.get( mIntermediaryLocs.size() - 1 ).getRealX(), 2) +
Math.pow( mEndLoc.getRealY() - mIntermediaryLocs.get( mIntermediaryLocs.size() - 1 ).getRealY(), 2 ) );
}
else {
mSingleStep += Math.sqrt(
Math.pow( mStartLoc.getRealX() - mEndLoc.getRealX(), 2) +
Math.pow( mStartLoc.getRealY() - mEndLoc.getRealY(), 2 ) );
}
mSingleStep /= mMoveTime;
mSnapDist = mSingleStep * SNAP_DIST_MULT;
}
private Point calcMoveDist( double delta ) {
double move;
double slope = 0;
Point curLoc = mSprite.getPoints()[ 0 ];
if( mCurIntermediary < mIntermediaryLocs.size() ) {
if( Math.abs( curLoc.getRealX() - mIntermediaryLocs.get( mCurIntermediary ).getRealX() ) <= mSnapDist &&
Math.abs( curLoc.getRealY() - mIntermediaryLocs.get( mCurIntermediary ).getRealY() ) <= mSnapDist ) {
mCurIntermediary++;
if( curLoc.getRealX() > mEndLoc.getRealX() )
mSingleStep = -mSingleStep;
else
mSingleStep = Math.abs( mSingleStep );
}
}
if( !mIntermediaryLocs.isEmpty() && mCurIntermediary < mIntermediaryLocs.size() ) {
Point inter = mIntermediaryLocs.get( mCurIntermediary );
slope = ( inter.getRealY() - curLoc.getRealY() ) /
( inter.getRealX() - curLoc.getRealX() );
}
else {
slope = ( mEndLoc.getRealY() - curLoc.getRealY() ) /
( mEndLoc.getRealX() - curLoc.getRealX() );
}
double xmove = mSingleStep * delta;
xmove /= Math.abs( slope );
//System.out.println( "slope: " + slope );
return Points.get( xmove, xmove * slope, 0 );
}
@Override
public void draw( Graphics2D g, double delta ) {
if( mStarted ) {
mSprite.draw( g, delta );
startPoint.draw( g, delta );
endPoint.draw( g, delta );
Point p = calcMoveDist( delta );
mSprite.modLoc( p );
p = mSprite.getPoints()[ 0 ];
if( Math.abs( mEndLoc.getRealX() - p.getRealX() ) <= mSnapDist &&
Math.abs( mEndLoc.getRealY() - p.getRealY() ) <= mSnapDist ) {
mStarted = false;
mSprite.setLoc( HIDDEN_LOC, HIDDEN_LOC, 0 );
}
}
}
@Override
public String getName() {
return mSprite.getName();
}
@Override
public Point[] getPoints() {
return mSprite.getPoints();
}
@Override
public Size[] getSize() {
return mSprite.getSize();
}
@Override
public Box[] getBox() {
return mSprite.getBox();
}
@Override
public void dispose() {
mSprite.dispose();
}
}