private Point2D makeControlPoint(final double endX, final double endY, final Circle circle, final int numSegments, int direction) { final double controlPointDistance = (4.0 / 3.0) * Math.tan(Math.PI / (2 * numSegments)) * circle.getRadius(); final Point2D center = new Point2D(circle.getCenterX(), circle.getCenterY()); final Point2D end = new Point2D(endX, endY); Point2D perp = rotate(center, end, direction * Math.PI / 2.); Point2D diff = perp.subtract(end); diff = diff.normalize(); diff = scale(diff, controlPointDistance); return end.add(diff); }
/** * @param x position x of entity * @param y position y of entity * @return center point of this hit box in world coordinates */ public Point2D centerWorld(double x, double y) { return centerLocal().add(x, y); }
/** * @param x position x of entity * @param y position y of entity * @return center point of this hit box in world coordinates */ public Point2D centerWorld(double x, double y) { return centerLocal().add(x, y); }
/** * Returns the center position of a square, * if the user wants to create such a square, * with respect to this square and its side length.<br/> * @param direction The direction the new square should be placed with respect to this square. * @return Point2D The new square's center. */ public Point2D getNextSquareCenter(Direction direction) { if(UP == direction) return getCenter().add(0d, -getSideLength()); else if(LEFT == direction) return getCenter().add(-getSideLength(), 0d); else if(RIGHT == direction) return getCenter().add(getSideLength(), 0d); else if(DOWN == direction) return getCenter().add(0d, getSideLength()); else return null; } // END getNextSquareCenter
/** * Returns the center position of a hexagon, * if the user wants to create such a hexagon, * with respect to this hexagon and its side length.<br/> * @param direction The direction the new hexagon should be placed with respect to this hexagon. * @return Point2D The new hexagon's center. */ public Point2D getNextHexCenter(Direction direction) { final double twiceRadiusToSide = 2d * getRadiusToSide(); final double halfSideLength = getSideLength() / 2d; final double halfSideLengthOffCorner = getRadiusToCorner() + halfSideLength; if(NORTH == direction) return getCenter().add(0d, -twiceRadiusToSide); else if(NORTH_WEST == direction) return getCenter().add(-halfSideLengthOffCorner, -getRadiusToSide()); else if(NORTH_EAST == direction) return getCenter().add(halfSideLengthOffCorner, -getRadiusToSide()); else if(SOUTH_WEST == direction) return getCenter().add(-halfSideLengthOffCorner, getRadiusToSide()); else if(SOUTH_EAST == direction) return getCenter().add(halfSideLengthOffCorner, getRadiusToSide()); else if(SOUTH == direction) return getCenter().add(0d, twiceRadiusToSide); else return null; } // END getNextHexCenter
private Point2D makeControlPoint(final double endX, final double endY, final Circle circle, final int numSegments, int direction) { final double controlPointDistance = (4.0 / 3.0) * Math.tan(Math.PI / (2 * numSegments)) * circle.getRadius(); final Point2D center = new Point2D(circle.getCenterX(), circle.getCenterY()); final Point2D end = new Point2D(endX, endY); Point2D perp = rotate(center, end, direction * Math.PI / 2.); Point2D diff = perp.subtract(end); diff = diff.normalize(); diff = scale(diff, controlPointDistance); return end.add(diff); }
/** * Calculate the point on the path that is at <code>frac</code>tion of the total length. * @param frac fraction of the total path in the range of [0,1] * @return new postition on the path, when moving to <code>frac</code> */ public Point2D interpolate(double frac) { Preconditions.checkArgument(frac >= 0 && frac <= 1, "Fraction must be between [0,1] inclusive. frac="+frac); double pathLengthToFrac = totalLength * frac; Preconditions.checkArgument(pathLengthToFrac >= currentSegment.getData().getLengthToStart() , "The path to the new position must be larger than the previous one"); moveCurrentSegment(frac); // the destination point is somewhere in currentSegment final LinearPathSegment data = currentSegment.getData(); double lengthIntoSegment = pathLengthToFrac - data.getLengthToStart(); double frationIntoSegment = lengthIntoSegment / data.getLength(); Point2D direction = data.getEnd().subtract(data.getStart()); // Vector from start to End Point2D newLocation = data.getStart().add(direction.multiply(frationIntoSegment)); traveldFraction = frac; if (traveldFraction > 1) { traveldFraction = 1; } LOGGER.trace("Interpolate path by {} to {}", frac, newLocation); return newLocation; }
/** * @return new emitter with implosion configuration */ public static ParticleEmitter newImplosionEmitter() { ParticleEmitter emitter = new ParticleEmitter(); emitter.setNumParticles(100); emitter.setEmissionRate(0.0166); emitter.setSize(5, 20); emitter.setSpawnPointFunction(i -> { Point2D vector = new Point2D(Math.cos(i), Math.sin(i)); return new Point2D(0, 0).add(vector.multiply(25)); }); emitter.setVelocityFunction(i -> { Point2D vector = new Point2D(Math.cos(i), Math.sin(i)); Point2D newPos = new Point2D(0, 0).add(vector.multiply(25)); return newPos.subtract(Point2D.ZERO).multiply(-0.05 * 60); }); emitter.setScaleFunction(i -> new Point2D(random() * -0.1, random() * -0.1)); emitter.setExpireFunction(i -> Duration.seconds(0.5)); emitter.setColor(Color.rgb((int) random(200, 255), 30, 20)); emitter.setBlendMode(BlendMode.ADD); return emitter; }
/** * @return new emitter with implosion configuration */ public static ParticleEmitter newImplosionEmitter() { ParticleEmitter emitter = new ParticleEmitter(); emitter.setNumParticles(100); emitter.setEmissionRate(0.0166); emitter.setSize(5, 20); emitter.setSpawnPointFunction(i -> { Point2D vector = new Point2D(Math.cos(i), Math.sin(i)); return new Point2D(0, 0).add(vector.multiply(25)); }); emitter.setVelocityFunction(i -> { Point2D vector = new Point2D(Math.cos(i), Math.sin(i)); Point2D newPos = new Point2D(0, 0).add(vector.multiply(25)); return newPos.subtract(Point2D.ZERO).multiply(-0.05 * 60); }); emitter.setScaleFunction(i -> new Point2D(random() * -0.1, random() * -0.1)); emitter.setExpireFunction(i -> Duration.seconds(0.5)); emitter.setColor(Color.rgb((int) random(200, 255), 30, 20)); emitter.setBlendMode(BlendMode.ADD); return emitter; }
private void createGroundSensor(Entity e) { // 3 is a good ratio of entity width, since we don't want to occupy the full width // if we want to ban "ledge" jumps double sensorWidth = e.getWidth() / 3; double sensorHeight = 5; // assumes that origin of entity's main hit box is at 0,0 e.getComponent(PhysicsComponent.class).addGroundSensor(new HitBox("GROUND_SENSOR", new Point2D(e.getWidth() / 2, e.getHeight()).add(-sensorWidth / 2, -sensorHeight / 2), BoundingShape.box(sensorWidth, sensorHeight))); }
/** * Moves the polygon in the direction specified.<br/> * Using this method is preferred over using the Node's setTranslate methods directory,<br/> * Because this method will also update the polygon's center position reference.<br/> * @param direction The direction of movement. * @param value The distance to move the polygon. */ public void move(Direction direction, double value) { if(UP == direction) { this.setTranslateY(this.getTranslateY() - value); this.getCenter().subtract(0d, value); } // END if if(DOWN == direction) { this.setTranslateY(this.getTranslateY() + value); this.getCenter().add(0d, value); } // END if if(LEFT == direction) { this.setTranslateX(this.getTranslateX() - value); this.getCenter().subtract(value, 0d); } // END if if(RIGHT == direction) { this.setTranslateX(this.getTranslateX() + value); this.getCenter().add(value, 0d); } // END if } // END move
/** * Moves the circle in the direction specified.<br/> * Using this method is preferred over using the Node's setTranslate methods directory,<br/> * Because this method will also update the circle's center position reference.<br/> * @param direction The direction of movement. * @param value The distance to move the circle. */ public void move(Direction direction, double value) { if(UP == direction) { this.setCenterY(this.getCenterY() - value); this.getCenter().subtract(0d, value); } // END if if(DOWN == direction) { this.setCenterY(this.getCenterY() + value); this.getCenter().add(0d, value); } // END if if(LEFT == direction) { this.setCenterX(this.getCenterX() - value); this.getCenter().subtract(value, 0d); } // END if if(RIGHT == direction) { this.setCenterX(this.getCenterX() + value); this.getCenter().add(value, 0d); } // END if } // END move } // END class Circle
/** * Computes a point with the same relative position in the specified new bounds as the specified old selection's * center point in the specified old bounds. (See * {@link #transformSelectionToNewBounds(Rectangle2D, Rectangle2D, Rectangle2D) transformSelectionToNewBounds} * for a definition of "relative position"). * * @param oldSelection * the selection whose center point is the base for the returned center point as a * {@link Rectangle2D} * @param oldBounds * the bounds of the old selection as a {@link Rectangle2D} * @param newBounds * the bounds for the new selection as a {@link Rectangle2D} * @return a {@link Point2D} with the same relative position in the new bounds as the old selection's center * point in the old bounds */ private Point2D computeNewSelectionCenter(Rectangle2D oldSelection, Rectangle2D oldBounds, Rectangle2D newBounds) { Point2D oldSelectionCenter = Rectangles2D.getCenterPoint(oldSelection); Point2D oldBoundsCenter = Rectangles2D.getCenterPoint(oldBounds); Point2D oldSelectionCenterOffset = oldSelectionCenter.subtract(oldBoundsCenter); double widthRatio = newBounds.getWidth() / oldBounds.getWidth(); double heightRatio = newBounds.getHeight() / oldBounds.getHeight(); Point2D newSelectionCenterOffset = new Point2D( oldSelectionCenterOffset.getX() * widthRatio, oldSelectionCenterOffset.getY() * heightRatio); Point2D newBoundsCenter = Rectangles2D.getCenterPoint(newBounds); Point2D newSelectionCenter = newBoundsCenter.add(newSelectionCenterOffset); return newSelectionCenter; }
protected Node createMenuBodyGameMenu() { double midY = app.getHeight() / 2; double distance = midY - 50; Button btnContinue = createActionButton("RESUME", this::fireResume); Button btn1 = createActionButton("SAVE", this::fireSave); Button btn2 = createContentButton("LOAD", this::createContentLoad); Button btn3 = createContentButton("OPTIONS", () -> new MenuContent(makeOptionsMenu())); Button btn4 = createContentButton("EXTRA", () -> new MenuContent(makeExtraMenu())); Button btn5 = createActionButton("MAIN MENU", this::fireExitToMainMenu); Group group = new Group(btnContinue, btn1, btn2, btn3, btn4, btn5); double dtheta = Math.PI / (group.getChildren().size() - 1); double angle = Math.PI / 2; int i = 0; for (Node n : group.getChildren()) { Point2D vector = new Point2D(Math.cos(angle), -Math.sin(angle)) .normalize() .multiply(distance) .add(0, midY); n.setTranslateX(vector.getX() - (i == 0 || i == 5 ? 0 : 100)); n.setTranslateY(vector.getY()); angle -= dtheta; i++; } return group; }
/** * Emits a single particle with index i. * X and Y are coordinates of the particle entity this emitter is attached to. * * @param i particle index from 0 to {@link #numParticles} * @param x top left X of the particle entity * @param y top left Y of the particle entity * @return particle */ private Particle emit(int i, double x, double y) { Particle particle = Pools.obtain(Particle.class); particle.init(getControl(), sourceImage, spawnPointFunction.apply(i).add(x, y), velocityFunction.apply(i), accelerationFunction.get(), getRandomSize(), scaleFunction.apply(i), expireFunction.apply(i), getStartColor(), getEndColor(), getBlendMode(), getInterpolator(), isAllowParticleRotation(), getParametricEquation()); return particle; } }
/** * Emits a single particle with index i. * X and Y are coordinates of the particle entity this emitter is attached to. * * @param i particle index from 0 to {@link #numParticles} * @param x top left X of the particle entity * @param y top left Y of the particle entity * @return particle */ private Particle emit(int i, double x, double y) { Particle particle = Pools.obtain(Particle.class); particle.init(getControl(), sourceImage, spawnPointFunction.apply(i).add(x, y), velocityFunction.apply(i), accelerationFunction.get(), getRandomSize(), scaleFunction.apply(i), expireFunction.apply(i), getStartColor(), getEndColor(), getBlendMode(), getInterpolator(), isAllowParticleRotation(), getParametricEquation()); return particle; } }
/** * @return new emitter with smoke configuration */ public static ParticleEmitter newSmokeEmitter() { ParticleEmitter emitter = new ParticleEmitter(); emitter.setNumParticles(5); emitter.setEmissionRate(1); emitter.setSize(9, 10); emitter.setSpawnPointFunction(i -> Point2D.ZERO.add(random(-1, 1), 0)); emitter.setVelocityFunction(i -> new Point2D((random() * 0.1 * 60), 0)); emitter.setAccelerationFunction(() -> new Point2D(0, random() * -0.03)); emitter.setExpireFunction(i -> Duration.seconds(random(1, 3))); emitter.setColor(Color.rgb(230, 230, 230)); emitter.setScaleFunction(i -> new Point2D(-0.01, -0.05)); return emitter; }
/** * @return new emitter with smoke configuration */ public static ParticleEmitter newSmokeEmitter() { ParticleEmitter emitter = new ParticleEmitter(); emitter.setNumParticles(5); emitter.setEmissionRate(1); emitter.setSize(9, 10); emitter.setSpawnPointFunction(i -> Point2D.ZERO.add(random(-1, 1), 0)); emitter.setVelocityFunction(i -> new Point2D((random() * 0.1 * 60), 0)); emitter.setAccelerationFunction(() -> new Point2D(0, random() * -0.03)); emitter.setExpireFunction(i -> Duration.seconds(random(1, 3))); emitter.setColor(Color.rgb(230, 230, 230)); emitter.setScaleFunction(i -> new Point2D(-0.01, -0.05)); return emitter; }
/** * @return new emitter with fire configuration */ public static ParticleEmitter newFireEmitter() { ParticleEmitter emitter = new ParticleEmitter(); emitter.setNumParticles(15); emitter.setEmissionRate(0.5); emitter.setStartColor(Color.rgb(255, 255, 90)); emitter.setEndColor(Color.rgb(230, 75, 40)); emitter.setSize(9, 12); emitter.setVelocityFunction(i -> new Point2D(random(-0.5, 0.5) * 0.25 * 60, random() * -1 * 60)); emitter.setSpawnPointFunction(i -> new Point2D(0, 0).add(new Point2D(i * (random() - 0.5), (random() - 1)))); emitter.setScaleFunction(i -> new Point2D(random(-0.01, 0.01) * 10, random() * -0.1)); emitter.setExpireFunction(i -> Duration.seconds(1)); emitter.setBlendMode(BlendMode.ADD); return emitter; }
/** * @return new emitter with fire configuration */ public static ParticleEmitter newFireEmitter() { ParticleEmitter emitter = new ParticleEmitter(); emitter.setNumParticles(15); emitter.setEmissionRate(0.5); emitter.setStartColor(Color.rgb(255, 255, 90)); emitter.setEndColor(Color.rgb(230, 75, 40)); emitter.setSize(9, 12); emitter.setVelocityFunction(i -> new Point2D(random(-0.5, 0.5) * 0.25 * 60, random() * -1 * 60)); emitter.setSpawnPointFunction(i -> new Point2D(0, 0).add(new Point2D(i * (random() - 0.5), (random() - 1)))); emitter.setScaleFunction(i -> new Point2D(random(-0.01, 0.01) * 10, random() * -0.1)); emitter.setExpireFunction(i -> Duration.seconds(1)); emitter.setBlendMode(BlendMode.ADD); return emitter; }