Jquery Easing function - java

I was studying a jquery easing function to use in a java application and ended with this:
// t: current time, b: begInnIng value, c: change In value, d: duration
float easeInOutQuad (float x, float t, float b, float c, float d) {
if ((t/=d/2) < 1) return c/2*t*t + b;
return -c/2 * ((--t)*(t-2) - 1) + b;
}
can someone teach me how do i plug this into my animated sphere movement?
EDIT: I wont put here unnecessary code describing my sphere movement. Imagine a sphere, with X position named X and it will go from 0 to 1000, using this easing function. How do i feed the function?

This is basically psuedo-java code, but I tested it and it works. I drew a small circle instead of using a sphere:
Sphere sphere = new Sphere();
// you might want these to be in the sphere class
float begin;
float change;
float time;
long start;
float duration;
float destX = 200;
// setup, do this when you want to start the animation
void init(){
begin = sphere.x;
change = destX - begin;
time = 0;
start = System.currentTimeMillis();
duration = 1000;
}
// loop code, may also be where you render the sphere
void loop(){
if (time <= duration){
sphere.x = easeInOutQuad(time, begin, change, duration);
}else{
// animation is over, stop the loop
}
time = System.currentTimeMillis() - start;
sphere.render();
}
float easeInOutQuad (float t, float b, float c, float d) {
if ((t/=d/2) < 1) return c/2*t*t + b;
return -c/2 * ((--t)*(t-2) - 1) + b;
}
class Sphere{
float x = 0;
void render(){
ellipse(x, 100, 10, 10);
}
}
You'll probably want to move things around depending on your set up, but this is how you can use this style of easing equation.

Related

Can someone improve my collision detection code, it doesn't work properly ,as even when the mouse is not on the circle, it counts as being on it

It's basically a simple game, in that, when the mouse pointer is within the circle, it adds one to the score. I'm new to processing and tried to create this simple game.
Here's the code:
float dist;
float score;
float x;
float y;
float ran;
float a;
float b;
void setup(){
size(800,600);
background(0);
score = 0;
}
void draw(){
background(0);
text("score: "+score,600,20);
x = random(800);
y = random(600);
circle_(x,y);
if ( (abs(mouseX - x) <= 200) && (abs(mouseY - y) <= 200 )) { // algorithm for checking whether mouse inside the circle or not
score = score + 1;
}
}
void circle_(float x,float y){
delay(1000);
circle(x,y,50);
}
There are 2 problems here: first, you're checking 200 pixels where it should be 25 (as in 25 being half the diameter of the circle). But this is the easy one. The real issue is with the delay(1000); line.
That's the real pain.
It means that your program "sleeps" for about 1000/1001 seconds. While the mouse can go around the screen, this one just isn't listening. It's waiting.
You can track time in Processing with the millis() method. It gives you how many milliseconds have passed since you started running the sketch. I ninja coded you a couple lines to keep track of time and teleport the circle every 1 second. Here's the code:
float score;
float x;
float y;
int respawnCircle;
void setup() {
size(800, 600);
background(0);
score = 0;
}
void draw() {
background(0);
text("score: "+score, 600, 20);
if (millis() > respawnCircle) {
changeCircleCoordinates();
}
circle_(x, y);
if ((abs(mouseX - x) <= 25) && (abs(mouseY - y) <= 25 )) { // using 25 as it's half the circle's diameter
score = score + 1;
// if you want the circle to change place right when you get one point uncomment the next line
// changeCircleCoordinates();
}
}
void changeCircleCoordinates() {
respawnCircle = millis() + 1000;
x = random(800);
y = random(600);
}
void circle_(float x, float y) {
//delay(1000); // this is why your collision detection wasn't working: the program is sleeping for about 1000/1001 milliseconds... you have to be very lucky to be on target at just the right time
circle(x, y, 50);
}
Hope it helps. Have fun!

move across the same distance of a curve at increasing speeds

I have an object that I am trying to get to move in a smooth "arc". The x value of the object does not actually change, but the y value does.
The y value starts at -108, and needs to get to -37.5. Every iteration I want it to move the same distance in a shorter time. The issue is that it needs to decelerate and stop at -37.5 (this would be for half of the motion). When the current code runs the time stays the same, the distance increases. this does work for the first iteration.
This is what I have:
private void jump() {
int startV = 10;
float yVal;
float velocity;
int airTime = 1;
float currY = -108;
Main main = New Main();
// main.iter is the iteration
velocity = startV * (1 + (main.iter / 10));
while (airtime != 0) {
yVal = yVal + velocity;
velocity = velocity - (1 + (main.iter / 10));
if (currY < yVal) {
airtime++;
}
else {
airtime--;
}
}
yVal = -108;
}
EDIT:
main.iter is an int that increments by one

Hexagonal Grid (Flat Top) Distance Calculation

I have been working on creating a hexagonal (flat top) grid for a simulation I am working on. I have attempted to work out the distance between the hexagons, from a specified target hexagon.
The solution I have works for most of the time, apart from every odd column from the target hexagon north of the target is shifted up by 1. I know that sounds confusing but I have attached an image to explain what I mean:
As you guys can see, the bottom half of the grid below the target hexagon and every other column above the target Hexagon is correct. I cannot understand why :S
Here is an explanation of the Axial & Cube Co-ords.
http://www.redblobgames.com/grids/hexagons/#coordinates
Here is the code responsible for converting the Axial Co-ords to Cube Co-ords.
public void setQR(int theQ, int theR){
this.q = theQ;
this.r = theR;
this.x = this.q;
this.z = this.r - (this.q - (this.q&1)) /2;
this.y = -(this.x + this.z);
}
And heres the code for working out distance.
FYI, the Hexagons are created from a CentrePoint (CPx, CPy).
private double distance = 0;
public double workOutDistance(Hexagon hexagon, HexagonFood target){
double targetX = target.getCPX();
double targetY = target.getCPY();
double hexagonX = hexagon.getCPX();
double hexagonY = hexagon.getCPY();
double deltaX = (targetX-hexagonX)*-1;
double deltaY = (targetY-hexagonY)*-1;
double deltaXRadius = (deltaX/(SimField.hexSize)/1.5);
double deltaYApothem = (deltaY/(SimField.hexSize/1.155)/2);
hexagon.setQR((int)deltaXRadius, (int)deltaYApothem);
ArrayList<Integer> coords = new ArrayList<>();
coords.add(
Math.abs(hexagon.getX() - target.getX())
);
coords.add(
Math.abs(hexagon.getZ() - target.getZ())
);
coords.add(
Math.abs(hexagon.getY() - target.getY())
);
System.out.println(coords);
distance = Collections.max(coords);
return distance;
}
Can anyone please tell me why this is happening ? Would be greatly appreciated.
EDIT:
After changing Int to Double as suggested by Tim, I get this.
http://i.stack.imgur.com/javZb.png
**
SOLUTION
**
after experimenting with the answers given, This small tweak solves the problem.
changing this..
public void setQR(int theQ, int theR){
this.q = theQ;
this.r = theR;
this.x = this.q;
this.z = this.r - (this.q - (this.q&1)) /2;
this.y = -(this.x + this.z);
}
to this..
public void setQR(int theQ, int theR){
this.q = theQ;
this.r = theR;
this.x = this.q;
if (this.r>0){
this.z = this.r - (this.q - (this.q&1))/2;
}
else {
this.z = this.r - (this.q + (this.q&1))/2;
}
this.y = -(this.x + this.z);
}
You're casting a double to an int when calling setQR(); are you sure that's doing what you expect? Doubles use floating point math, so the number you'd expect to be 2.0 might actually be 1.999999989, which would then be rounded down to 1 when cast to an int.
I'm also skeptical of the line that reads this.z = this.r - (this.q - (this.q&1)) /2;. You're adding 1 when the number is odd, which seems to be the failure case you're experiencing; I'd make sure that line is doing what you're expecting, too.
If you're not stepping through this with a debugger and examining the values, you're doing it wrong.
You could also take an entirely different approach to this problem. You know the X/Y (cartesian) coordinates of your two hexagons, which means you can get each hexagon's cubic coordinates relative to the origin of your hexagonal space. The distance between the two hexagons is simply the sum of the absolute values of the differences between the two hexagons' X, Y and Z cubic coordinates. (That is, dist = |h2.X - h1.X| + |h2.Y - h1.Y| + |h2.Z - h1.Z|) So rather than trying to compute the vector between the two centerpoints and then convert that into cubic coordinates, you could just compute the distance directly in cubic coordinates (just like you would if these were squares in cartesian coordinates)...
Even if you take this approach, though, I'd strongly recommend that you debug what's going on with your original approach. Even if you end up throwing away the code, the exercise of debugging will probably teach you valuable lessons that you'll be able to apply in the future.
Note to readers: "cubic" coordinates aren't 3-dimensional cartesian coordinates, they're a hexagon-specific coordinate system for which a link was provided by the OP.
The fact that the computation (that is, the conversion from offset- to cube coordinates, and the computation of the distance in cube coordinates) seems to be correct suggests that Tim was right with his assumption about the floating point errors.
You should try to change the line
hexagon.setQR((int)deltaXRadius, (int)deltaYApothem);
from your original code to something like
hexagon.setQR((int)Math.round(deltaXRadius), (int)Math.round(deltaYApothem));
Which could solve the issue in this case.
If not ... or... in any case, here's a small example, basically doing the same as you did, but as a MVCE...
import java.awt.Point;
public class HexagonsTest
{
public static void main(String[] args)
{
// Above and below
test(8,6, 8,5, 1);
test(8,6, 8,7, 1);
// Left
test(8,6, 7,5, 1);
test(8,6, 7,6, 1);
// Right
test(8,6, 9,5, 1);
test(8,6, 9,6, 1);
// The first one that was wrong:
test(8,6, 7,4, 2);
}
private static void test(int x0, int y0, int x1, int y1, int expected)
{
int distance = computeStepsDistance(x0, y0, x1, y1);
System.out.println(
"Distance of (" + x0 + "," + y0 + ") to " +
"(" + x1 + "," + y1 + ") is " + distance +
", expected " + expected);
}
private static int computeStepsDistance(int x0, int y0, int x1, int y1)
{
Point cp0 = convertOffsetToCubeCoordinates(x0, y0, null);
Point cp1 = convertOffsetToCubeCoordinates(x1, y1, null);
int cx0 = cp0.x;
int cy0 = cp0.y;
int cz0 = -cx0-cy0;
int cx1 = cp1.x;
int cy1 = cp1.y;
int cz1 = -cx1-cy1;
int dx = Math.abs(cx0 - cx1);
int dy = Math.abs(cy0 - cy1);
int dz = Math.abs(cz0 - cz1);
return Math.max(dx, Math.max(dy, dz));
}
private static Point convertOffsetToCubeCoordinates(
int ox, int oy, Point p)
{
int cx = ox;
int cz = oy - (ox - (ox&1)) / 2;
int cy = -cx-cz;
if (p == null)
{
p = new Point();
}
p.x = cx;
p.y = cy;
return p;
}
}

Basic 2D path finding (no graph needed)

I am working on a game (just for my own fun) in Processing (a variant of Java), and have run into a problem. I have a projectile class that is created and managed by a Castle class, and it goes towards an Enemy class (which is a moving target). What I am trying to do (conceptually) is make this projectile find its intended target (Euclidian distance), say its 20 units away, and move 5 units along that line (i.e. 1/4 of the way there). My problem is that I don't know how to extract the x and y components of that vector to update this projectile's position. Here is my projectile class currently:
class Projectile{
private PImage sprite;
private Enemy target;
private int x;
private int y;
private int speed;
public Projectile(PImage s, Enemy t, int startx, int starty, int sp) throws NullPointerException{
if(t == null){
if(debug){
println("Null target given to Projectile(), throwing exception");
}
throw new java.lang.NullPointerException("The target of the projectile is null");
}
sprite = s;
target = t;
x = startx;
y = starty;
speed = sp;
if(debug){
println("Projectile created: " + t + " starting at position: " + startx + " " + starty);
}
}
public void update(){
if(target != null){
int goingToX = target.getCenterX() ;
int goingToY = target.getCenterY();
//find the total distance to the target
float d = dist(this.x, this.y, target.getCenterX(), target.getCenterY());
//divide it by the velocity vector
d /= speed;
//get the dx and dy components of the vector
}else{//target is null, i.e. already destroyed by something else
//destroy this projectile
//if the higher functions were correct, then nothing needs to go here
//this should be deleted as long as it checks for this.hitTarget()
return;
}
}
public void render(){
image(sprite, x, y, 10, 10);
}
//checks if it hit the target, but does a little bit of rounding because the sprite is big
//done this way in the interest of realism
public boolean hitTarget(){
if(target != null){
if(abs(x - target.getCenterX()) <= 5 && abs(y - target.getCenterY()) <= 5 ){
return true;
}else{
return false;
}
}
//this activates if the target is null, which marks this for deletion
return true;
}
}
I've been researching this for hours and realized my approach was unnecessarily complicated when I was looking into converting floats into strings, formatting them to some number of decimal places, then trying to convert that into a fraction which I would then reduce. I feel like this is far easier than I realize, but I am lacking the math background to do it. All necessary changes should only need to be done in Projectile.update(). Thanks!
Assuming that you want your projectile to 'track' the target, then you can use a simple bit of trig to work out the relative speeds in x and y:
//Calculate the differences in position
float diffX = target.getCenterX() - this.x;
float diffY = target.getCenterY() - this.y;
//Calculate the angle
double angle = Math.atan2(diffY, diffX);
//Update the positions
x += Math.cos(angle) * speed;
y += Math.sin(angle) * speed;
This essentially calculates the angle between the projectile and the target, then moves the projectile in that direction, based on the speed given.

Fix your timesteps in Java

I've read the article from here.
But it seems i can't translate that to Java, and by that I mean this:
double t = 0.0;
const double dt = 0.01;
double currentTime = hires_time_in_seconds();
double accumulator = 0.0;
State previous;
State current;
while ( !quit )
{
double newTime = time();
double frameTime = newTime - currentTime;
if ( frameTime > 0.25 )
frameTime = 0.25; // note: max frame time to avoid spiral of death
currentTime = newTime;
accumulator += frameTime;
while ( accumulator >= dt )
{
previousState = currentState;
integrate( currentState, t, dt );
t += dt;
accumulator -= dt;
}
const double alpha = accumulator / dt;
State state = currentState*alpha + previousState * ( 1.0 - alpha );
render( state );
}
What is the State class he is using? I've downloaded the code and i couldn't find it's declaration? How would the code look like in Java?
State is more an abstract idea. He's just interpolating a number. For example, state could be the x position of an entity.
An example for you:
float x = x*alpha+oldX*(1-alpha);
In my physics game, I passed the alpha value to all my entities during each render. They would use this during the render to calculate the best approximation of their position. I would suggest you do the same. Just have your render routines accept alpha, and have each object track its old state.
So every entity guesses where it really is at the time of rendering using its last position and its current position.
EDIT:
public class Entity{
double oldX;
double oldY;
double x;
double y;
public void render(Graphics g, float alpha){
float estimatedX = x*alpha+oldX*(1-alpha);
float estimatedY = y*alpha+oldY*(1-alpha);
g.drawRect((int)estimatedX,(int)estimatedY,1,1);
}
}
It's a simple structure containing the current position and velocity before each integration step. It's defined in the previous tutorial, and also near the beginning of Timestep.cpp in the code you can download from that page:
struct State
{
float x; // position
float v; // velocity
};

Categories

Resources