I actually wanted to build a 2x2 rubiks cube. As the Box class in javafx doesn't provide the feature of building a cube with different colours on different faces, I chose to build the cubes using RectangleBuilder to build rectangles with different colours and then applied transformations to build the cubes. But while testing the code I saw that the entire display was coming in a broken manner with the edges overlapping as shown in the picture. Here is my source code:
package helloworld;
import javafx.scene.transform.Rotate;
import javafx.scene.PerspectiveCamera;
import javafx.scene.transform.Translate;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.SceneAntialiasing;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.RectangleBuilder;
import javafx.scene.transform.Rotate;
import javafx.util.Duration;
public class NewFXMain1 extends Application {
public class Cube extends Group {
final Rotate rx = new Rotate(0,Rotate.X_AXIS);
final Rotate ry = new Rotate(0,Rotate.Y_AXIS);
final Rotate rz = new Rotate(0,Rotate.Z_AXIS);
public Cube(double size, Color back,Color bottom,Color right,Color left,Color top,Color front, double shade) {
getTransforms().addAll(rz, ry, rx);
getChildren().addAll(
RectangleBuilder.create() // back face
.width(size).height(size)
.fill(back.deriveColor(0.0, 1.0, (1 - 0.5*shade), 1.0))
.translateX(-0.5*size)
.translateY(-0.5*size)
.translateZ(0.5*size)
.smooth(true)
.stroke(Color.BLACK)
.build(),
RectangleBuilder.create() // bottom face
.width(size).height(size)
.fill(bottom.deriveColor(0.0, 1.0, (1 - 0.4*shade), 1.0))
.translateX(-0.5*size)
.translateY(0)
.rotationAxis(Rotate.X_AXIS)
.rotate(90)
.smooth(true)
.stroke(Color.BLACK)
.build(),
RectangleBuilder.create() // right face
.width(size).height(size)
.fill(right.deriveColor(0.0, 1.0, (1 - 0.3*shade), 1.0))
.translateX(-1*size)
.translateY(-0.5*size)
.rotationAxis(Rotate.Y_AXIS)
.rotate(90)
.smooth(true)
.stroke(Color.BLACK)
.build(),
RectangleBuilder.create() // left face
.width(size).height(size)
.fill(left.deriveColor(0.0, 1.0, (1 - 0.2*shade), 1.0))
.translateX(0)
.translateY(-0.5*size)
.rotationAxis(Rotate.Y_AXIS)
.rotate(90)
.smooth(true)
.stroke(Color.BLACK)
.build(),
RectangleBuilder.create() // top face
.width(size).height(size)
.fill(top.deriveColor(0.0, 1.0, (1 - 0.1*shade), 1.0))
.translateX(-0.5*size)
.translateY(-1*size)
.rotationAxis(Rotate.X_AXIS)
.rotate(90)
.smooth(true)
.stroke(Color.BLACK)
.build(),
RectangleBuilder.create() // front face
.width(size).height(size)
.fill(front)
.translateX(-0.5*size)
.translateY(-0.5*size)
.translateZ(-0.5*size)
.smooth(true)
.stroke(Color.BLACK)
.build()
);
}
}
PerspectiveCamera camera = new PerspectiveCamera(true);
@Override public void start(Stage primaryStage) throws Exception {
Group root = new Group();
Scene scene=new Scene(root,600,600,true);
camera.setNearClip(0.00001);
camera.setFarClip(10000000.0);
camera.getTransforms().addAll (
new Rotate(0, Rotate.Y_AXIS),
new Rotate(0, Rotate.X_AXIS),
new Translate(0, 0, -1000));
scene.setCamera(camera);
Cube c1 = new Cube(50,Color.BLUE.darker(),Color.BLUE.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c1.setTranslateX(100);
Cube c2 = new Cube(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c2.setTranslateX(50);
Cube c3 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c3.setTranslateX(50);
c3.setTranslateZ(50);
Cube c4 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c4.setTranslateX(100);
c4.setTranslateZ(50);
Cube c5 = new Cube(50,Color.BLUE.darker(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c5.setTranslateX(100);
c5.setTranslateY(50);
Cube c6 = new Cube(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c6.setTranslateX(50);
c6.setTranslateY(50);
Cube c7 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c7.setTranslateX(50);
c7.setTranslateZ(50);
c7.setTranslateY(50);
Cube c8 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
c8.setTranslateX(100);
c8.setTranslateZ(50);
c8.setTranslateY(50);
handleMouse(scene,root);
Group k=new Group(c1,c2,c3,c4,c5,c6,c7,c8);
root.getChildren().addAll(k);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) { launch(args); }
private static final double CONTROL_MULTIPLIER = 0.1;
private static final double SHIFT_MULTIPLIER = 10.0;
private static final double MOUSE_SPEED = 0.1;
private static final double ROTATION_SPEED = 2.0;
double mousePosX,mousePosY,mouseOldX,mouseOldY,mouseDeltaX,mouseDeltaY;
private void handleMouse(Scene scene, final Node root) {
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent me) {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
mouseOldX = me.getSceneX();
mouseOldY = me.getSceneY();
}
});
scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent me) {
mouseOldX = mousePosX;
mouseOldY = mousePosY;
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
mouseDeltaX = (mousePosX - mouseOldX);
mouseDeltaY = (mousePosY - mouseOldY);
double modifier = 1.0;
if (me.isControlDown()) {
modifier = CONTROL_MULTIPLIER;
}
if (me.isShiftDown()) {
modifier = SHIFT_MULTIPLIER;
}
if (me.isPrimaryButtonDown()) {
camera.setRotationAxis(Rotate.Y_AXIS);camera.setRotate(camera.getRotate() -
mouseDeltaX*modifier*ROTATION_SPEED); //
camera.setRotationAxis(Rotate.X_AXIS);camera.setRotate(camera.getRotate() +
mouseDeltaY*modifier*ROTATION_SPEED); // -
}
else if (me.isSecondaryButtonDown()) {
double z = camera.getTranslateZ();
double newZ = z + mouseDeltaX*MOUSE_SPEED*modifier;
camera.setTranslateZ(newZ);
}
}
}); // setOnMouseDragged
} //handleMouse
}