Merge pull request #17 from PizzaLovers007/master

Reworked Spinner
This commit is contained in:
Jeffrey Han 2015-02-14 00:37:55 -05:00
commit 2c59b345b5

View File

@ -37,6 +37,7 @@ import org.newdawn.slick.Image;
* Data type representing a spinner object. * Data type representing a spinner object.
*/ */
public class Spinner implements HitObject { public class Spinner implements HitObject {
/** Container dimensions. */ /** Container dimensions. */
private static int width, height; private static int width, height;
@ -47,13 +48,25 @@ public class Spinner implements HitObject {
private GameData data; private GameData data;
/** The last rotation angle. */ /** The last rotation angle. */
private float lastAngle = -1f; private float lastAngle = 0f;
/** The current number of rotations. */ /** The current number of rotations. */
private float rotations = 0f; private float rotations = 0f;
/** The total number of rotations needed to clear the spinner. */ /** The total number of rotations needed to clear the spinner. */
private float rotationsNeeded; private float rotationsNeeded;
/** The sum of all the velocities in storedVelocities. */
private float sumVelocity = 0f;
/** Array of the last 50 rotation velocities. */
private float[] storedVelocities = new float[50];
/** True if the mouse cursor is pressed. */
private boolean isSpinning;
/** Current index of the stored velocities in rotations/second. */
private int velocityIndex = 0;
/** /**
* Initializes the Spinner data type with images and dimensions. * Initializes the Spinner data type with images and dimensions.
@ -120,6 +133,9 @@ public class Spinner implements HitObject {
if (extraRotations > 0) if (extraRotations > 0)
data.drawSymbolNumber(extraRotations * 1000, width / 2, height * 2 / 3, 1.0f); data.drawSymbolNumber(extraRotations * 1000, width / 2, height * 2 / 3, 1.0f);
} }
int rpm = Math.abs(Math.round(sumVelocity/storedVelocities.length*60));
//TODO: add rpm meter at bottom of spinner
} }
/** /**
@ -173,35 +189,54 @@ public class Spinner implements HitObject {
return false; return false;
} }
// not spinning: nothing to do // game button is released
if (!Utils.isGameKeyPressed()) { if (isSpinning && !Utils.isGameKeyPressed()) {
lastAngle = -1f; isSpinning = false;
}
float angle = (float) Math.atan2(mouseY - (height / 2), mouseX - (width / 2));
// set initial angle to current mouse position to skip first click
if (!isSpinning && Utils.isGameKeyPressed()) {
lastAngle = angle;
isSpinning = true;
return false; return false;
} }
// scale angle from [-pi, +pi] to [0, +pi] float angleDiff = angle - lastAngle;
float angle = (float) Math.atan2(mouseY - (height / 2), mouseX - (width / 2));
if (angle < 0f) // make angleDiff the smallest angle change possible
angle += Math.PI; // (i.e. 1/4 rotation instead of 3/4 rotation)
if (angleDiff < -Math.PI) {
if (lastAngle >= 0f) { // skip initial clicks angleDiff = (float) (angleDiff + Math.PI*2);
float angleDiff = Math.abs(lastAngle - angle); } else if (angleDiff > Math.PI) {
if (angleDiff < Math.PI / 2) { // skip huge angle changes... angleDiff = (float) (angleDiff - Math.PI*2);
data.changeHealth(delta * GameData.HP_DRAIN_MULTIPLIER);
rotate(angleDiff);
}
} }
// spin caused by the cursor
float cursorVelocity = 0;
if (isSpinning)
cursorVelocity = Math.min((float)(angleDiff / (Math.PI*2) / delta * 1000), 8f);
sumVelocity -= storedVelocities[velocityIndex];
sumVelocity += cursorVelocity;
storedVelocities[velocityIndex++] = cursorVelocity;
velocityIndex %= storedVelocities.length;
data.changeHealth(delta * GameData.HP_DRAIN_MULTIPLIER);
rotate(sumVelocity / storedVelocities.length * (float)Math.PI*2 * delta / 1000);
lastAngle = angle; lastAngle = angle;
return false; return false;
} }
/** /**
* Rotates the spinner by a number of degrees. * Rotates the spinner by a number of radians.
* @param degrees the angle to rotate (in radians) * @param angle the angle to rotate (in radians)
*/ */
private void rotate(float degrees) { private void rotate(float angle) {
float newRotations = rotations + (degrees / (float) (2 * Math.PI)); angle = Math.abs(angle);
float newRotations = rotations + (angle / (float) (2 * Math.PI));
// added one whole rotation... // added one whole rotation...
if (Math.floor(newRotations) > rotations) { if (Math.floor(newRotations) > rotations) {
@ -216,4 +251,4 @@ public class Spinner implements HitObject {
rotations = newRotations; rotations = newRotations;
} }
} }