если скорость равна 9 и я хочу уменьшить ее на 10%, я не могу сделать это "9 * 0,1", потому что она должна быть целым числом
- увеличить скорость и координаты (умножить, например, на 256 или сдвинуть влево, например, на 8)
- рассчитать уменьшение для увеличенной скорости "9 * 256/10"
- рассчитать новую (увеличенную) позицию и скорость
- уменьшить
Примерно так, как показано ниже ...
Ball move(Ball ball, Border border, Tracer tracer) {
tracer.trace("scale stuff up to handle acceleration = velocity / 8");
Scale scale = new Scale(256);
Int2D position = scale.up(ball.position);
Velocity velocity = new Velocity(scale.up(ball.velocity));
tracer.trace("calculate acceleration as scaled up velocity / 8";
Int2D acceleration = new Scale(8).down(velocity);
tracer.trace("Move the ball at the given velocity");
position = position.plus(velocity);
tracer.trace("slow down velocity");
velocity = velocity.slowDown(acceleration);
tracer.trace("scale back down to original");
ball = new Ball(scale.down(position), new Velocity(scale.down(velocity)));
tracer.trace("adjust if ball hits the borders and change the way");
return border.reflectIfNeeded(ball);
}
interface Tracer { void trace(String msg); }
class Scale {
final int scale; // better be power of 2
Scale(int scale) { this.scale = scale; }
Int2D up(Int2D src) { return new Int2D(src.x * scale, src.y * scale); }
Int2D down(Int2D src) { return new Int2D(src.x / scale, src.y / scale); }
} // Scale
class Border {
final Int2D topLeft, bottomRight;
Border(Int2D topLeft, Int2D bottomRight) {
this.topLeft = topLeft;
this.bottomRight = bottomRight;
}
Ball reflectIfNeeded(Ball ball) {
if (within(ball)) { return ball; }
throw new UnsupportedOperationException("not yet implemented");
}
private boolean within(Ball ball) {
return within(ball.position.x, topLeft.x, bottomRight.x)
&& within(ball.position.y, topLeft.y, bottomRight.y);
}
private boolean within(int value, int min, int max) {
return value > min && value < max;
}
} // Border
class Ball {
final Int2D position;
final Velocity velocity;
Ball(Int2D position, Velocity velocity) {
this.position = position;
this.velocity = velocity;
}
} // Ball
class Velocity extends Int2D {
Velocity(Int2D src) { super(src.x, src.y); }
Velocity slowDown(Int2D acceleration) {
return new Velocity(this.minus(acceleration));
}
Velocity reflectX() { return new Velocity(new Int2D(-x, y)); }
Velocity reflectY() { return new Velocity(new Int2D(x, -y)); }
} // Velocity
class Int2D {
final int x, y;
Int2D(int x, int y) { this.x = x; this.y = y; }
Int2D plus(Int2D other) { return new Int2D(x + other.x, y + other.y); }
Int2D minus(Int2D other) { return new Int2D(x - other.x, y - other.y); }
} // Int2D