Killer Game Programming in JavaFX - (Chapter 15)
So I was looking at Killer Game Programming in Java and decided to rewrite the first 3D chapter in JavaFX it turned out pretty well code below I don't think I am going to explain anything today...LOL.
Checkers3D.java
Checkers3D.java
package io.skidrunner.killer_javafx.ch15; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.PerspectiveCamera; import javafx.scene.PointLight; import javafx.scene.Scene; import javafx.scene.input.MouseEvent; import javafx.scene.paint.Color; import javafx.scene.paint.PhongMaterial; import javafx.scene.shape.Sphere; import javafx.scene.transform.Rotate; import javafx.scene.transform.Translate; import javafx.stage.Stage; /** * Created by U292337 on 6/6/2017. */ public class Checkers3D extends Application { private final Group root = new Group(); private PerspectiveCamera camera; private Rotate cameraRotateX, cameraRotateY, cameraRotateZ; private Translate cameraTranslate; private double mouseOldX, mouseNewX; private double mouseOldY, mouseNewY; public static void main(String[] args) { Checkers3D.launch(args); } @Override public void start(Stage stage) { // Create Camera camera = new PerspectiveCamera(true); cameraRotateX = new Rotate(0, Rotate.X_AXIS); cameraRotateY = new Rotate(0, Rotate.Y_AXIS); cameraRotateZ = new Rotate(0, Rotate.Z_AXIS); cameraTranslate = new Translate(0, 0, -25); camera.getTransforms().addAll( cameraRotateX, cameraRotateY, cameraRotateZ, cameraTranslate); root.getChildren().add(camera); // Create Scene and Handlers createScene(); Scene scene = new Scene(root, 800, 450, true); scene.setOnMousePressed((e) -> onMousePressed(e)); scene.setOnMouseDragged((e) -> onMouseDragged(e)); // Set the Stage stage.setTitle("Killer JavaFX - Checkers3D"); stage.setScene(scene); scene.setFill(Color.LIGHTSKYBLUE); scene.setCamera(camera); stage.show(); } public void onMousePressed(MouseEvent mouseEvent) { mouseOldX = mouseNewX = mouseEvent.getSceneX(); mouseOldY = mouseNewY = mouseEvent.getSceneY(); } public void onMouseDragged(MouseEvent mouseEvent) { mouseOldX = mouseNewX; mouseOldY = mouseNewY; mouseNewX = mouseEvent.getSceneX(); mouseNewY = mouseEvent.getSceneY(); double mouseDeltaX = (mouseNewX - mouseOldX); double mouseDeltaY = (mouseNewY - mouseOldY); cameraRotateX.setAngle(cameraRotateX.getAngle() - mouseDeltaY); cameraRotateY.setAngle(cameraRotateY.getAngle() + mouseDeltaX); } private void createScene() { lightScene(); floatingSphere(); root.getChildren().add(new CheckerFloor(20)); } private void lightScene() { // Set up the ambient light //AmbientLight ambientLight = new AmbientLight(Color.DARKGRAY); // Set up the point lights PointLight pointLight1 = new PointLight(Color.WHITE); pointLight1.getTransforms().add(new Translate(-20, -20, -20)); PointLight pointLight2 = new PointLight(Color.WHITE); pointLight2.getTransforms().add(new Translate(20, -20, 20)); root.getChildren().addAll(pointLight1, pointLight2); } private void floatingSphere() { PhongMaterial material = new PhongMaterial(); material.setDiffuseColor(Color.DODGERBLUE); material.setSpecularColor(Color.WHITE); Sphere sphere = new Sphere(2); sphere.getTransforms().add(new Translate(0, -4, 0)); sphere.setMaterial(material); root.getChildren().add(sphere); } }CheckerFloor.java
package io.skidrunner.killer_javafx.ch15; import javafx.geometry.Bounds; import javafx.geometry.Point3D; import javafx.geometry.VPos; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.SnapshotParameters; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.PixelReader; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; import javafx.scene.paint.PhongMaterial; import javafx.scene.shape.*; import javafx.scene.text.Font; import javafx.scene.text.FontWeight; import javafx.scene.text.Text; import javafx.scene.text.TextAlignment; import javafx.scene.transform.Translate; import java.util.ArrayList; public class CheckerFloor extends Group { public CheckerFloor(int size) { super(); if((size & 1) != 0) { throw new AssertionError("size should be multiple of 2"); } ArrayListorangePoints = new ArrayList<>(); ArrayList whitePoints = new ArrayList<>(); for(int z = -size / 2; z <= (size / 2) - 1; z++) { boolean colorOrange = (z & 1) == 0; for(int x = -size / 2; x <= (size / 2) - 1; x++) { createPoints(x, 0, z, colorOrange ? orangePoints : whitePoints); colorOrange = !colorOrange; } } getChildren().add(createMesh(orangePoints, Color.ORANGE)); getChildren().add(createMesh(whitePoints, Color.WHITESMOKE)); getChildren().add(createOriginMesh()); getChildren().add(createLabelAxesGroup(size)); } private void createPoints(int x, int y, int z, ArrayList points) { points.add(new Point3D(x, y, z + 1.0f)); points.add(new Point3D(x + 1.0f, y, z + 1.0f)); points.add(new Point3D(x + 1.0f, y, z)); points.add( new Point3D(x, y, z)); } private Shape3D createMesh(ArrayList points, Color color) { TriangleMesh mesh = new TriangleMesh(VertexFormat.POINT_NORMAL_TEXCOORD); for(int i = 0; i < points.size(); i += 4) { for(int j = 0; j < 4; j++) { Point3D point = points.get(i + j); mesh.getPoints().addAll((float)point.getX(), (float)point.getY(), (float)point.getZ()); } mesh.getNormals().addAll(0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0); mesh.getTexCoords().addAll(0,1, 1,1, 1,0, 0,0); int i0 = i; int i1 = i + 1; int i2 = i + 2; int i3 = i + 3; mesh.getFaces().addAll(i0,i0,i0, i3,i3,i3, i2,i2,i2); mesh.getFaces().addAll(i1,i1,i1, i0,i0,i0, i2,i2,i2); } PhongMaterial material = new PhongMaterial(); material.setDiffuseColor(color); material.setSpecularColor(color.brighter()); MeshView meshView = new MeshView(mesh); meshView.setMaterial(material); return meshView; } private Shape3D createOriginMesh() { PhongMaterial material = new PhongMaterial(); material.setDiffuseColor(Color.DODGERBLUE); material.setSpecularColor(Color.WHITE); Box box = new Box(0.5, 0.1, 0.5); box.setMaterial(material); return box; } private Group createLabelAxesGroup(int size) { Group group = new Group(); for (int i = -size / 2; i <= size / 2; i++) { Group marker = makeText(String.format("%02d", i)); marker.getTransforms().add(new Translate(i, -0.5, 0)); group.getChildren().add(marker); } for (int i = -size / 2; i <= size / 2; i++) { Group marker = makeText(String.format("%02d", i)); marker.getTransforms().add(new Translate(0, -0.5, i)); group.getChildren().add(marker); } return group; } private Group makeText(String string) { Font font = Font.font(null, FontWeight.BOLD, 64); Text text = new Text(string); text.setFont(font); new Scene(new Group(text)); Bounds bounds = text.getLayoutBounds(); Canvas canvas = new Canvas(bounds.getWidth() + 4, bounds.getHeight() + 4); GraphicsContext context = canvas.getGraphicsContext2D(); context.setTextAlign(TextAlignment.CENTER); context.setTextBaseline(VPos.CENTER); context.setFill(Color.BLACK); context.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); context.setFill(Color.WHITE); context.setFont(font); context.fillText(string, canvas.getWidth() * 0.5, canvas.getHeight() * 0.5); SnapshotParameters snapshotParameters = new SnapshotParameters(); WritableImage writableImage = new WritableImage((int)canvas.getWidth(), (int)canvas.getHeight()); WritableImage snapshot = canvas.snapshot(snapshotParameters, writableImage); PixelReader pixelReader = writableImage.getPixelReader(); PixelWriter pixelWriter = writableImage.getPixelWriter(); for(int y = 0; y < writableImage.getHeight(); y++) { for(int x = 0; x < writableImage.getWidth(); x++) { Color color = pixelReader.getColor(x, y).grayscale(); pixelWriter.setColor(x, y, Color.DODGERBLUE.deriveColor(0, 1, 1, color.getBrightness())); } } PhongMaterial material = new PhongMaterial(); material.setDiffuseMap(snapshot); material.setSelfIlluminationMap(snapshot); material.setSpecularMap(snapshot); float scale = (float)(0.5 / writableImage.getHeight()); float extentX = (float)(writableImage.getWidth() * 0.5) * scale; float extentY = (float)writableImage.getHeight() * scale; TriangleMesh mesh = new TriangleMesh(VertexFormat.POINT_TEXCOORD); mesh.getPoints().addAll(-extentX,-extentY,0, extentX,-extentY,0, -extentX,0,0, extentX,0,0); mesh.getNormals().addAll(0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1); mesh.getTexCoords().addAll(0,0, 1,0, 0,1, 1,1); mesh.getFaces().addAll(2,2, 1,1, 0,0, 2,2, 3,3, 1,1); MeshView meshView = new MeshView(mesh); meshView.setMaterial(material); //meshView.getTransforms().addAll(cameraRotateX, cameraRotateY, cameraRotateZ); Group group = new Group(); group.getChildren().add(meshView); return group; } }
Comments
Post a Comment