Trying to make a circle of different colours in javafx - java

I'm awfully new to Javafx and want to try and make a very simple game. I'm trying to plot colors in a circle. The circle has different colors and must be hollow on the inside. I'll show a picture here:
I know I could just print out the image but I want to find out when the player collides with the incorrect color(exactly like how it is done in color switch) so that they lose in that case which I'm assuming wont be possible if i used the picture. How do i go about this?

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Arc;
import javafx.stage.Stage;
public class FourArcs extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Arc arc = new Arc();
arc.setCenterX(100.0f);
arc.setCenterY(100.0f);
arc.setRadiusX(80.0f);
arc.setRadiusY(80.0f);
arc.setStartAngle(0.0f);
arc.setLength(90.0f);
arc.setStroke(Color.BLUE);
arc.setStrokeWidth(10);
arc.setFill(Color.TRANSPARENT);
Arc arc2 = new Arc(100, 100, 80, 80, 90, 90);
arc2.setStroke(Color.PURPLE);
arc2.setStrokeWidth(10);
arc2.setFill(Color.TRANSPARENT);
Arc arc3 = new Arc(100, 100, 80, 80, 180, 90);
arc3.setStroke(Color.YELLOW);
arc3.setStrokeWidth(10);
arc3.setFill(Color.TRANSPARENT);
Arc arc4 = new Arc(100, 100, 80, 80, 270, 90);
arc4.setStroke(Color.RED);
arc4.setStrokeWidth(10);
arc4.setFill(Color.TRANSPARENT);
Group root = new Group(arc, arc2, arc3, arc4);
Scene scene = new Scene(root);
scene.setFill(Color.BLACK);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The above code is based on this question and answer.
Screen capture:

Related

JavaFx Equivalent to Graphics context.rotate() for nodes

If I am drawing in a canvas, I can rotate the coordinate system of the graphicscontext without rotating anything that is already drawn in the corresponding canvas, same with translations.
Is there anything similar possible in a group? If I just rotate and translate it's children I don't get the right effect because translations orient themselves on the unrotated system of the group.
If not, is there anything like a 3d canvas with that functionality?
As Slaw pointed out, what i was looking for were the classes in the package javafx.scene.transform.
Here is an example: Let's say I want a Line starting from (200, 200) with a length of 200 in direction 60 degrees from the x-axis. This would be not so hard to do without the transform package aswell but it shall only serve as an easy example.
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.shape.Line;
import javafx.scene.transform.Affine;
import javafx.stage.Stage;
public class Example extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage stage) throws Exception {
Group group = new Group();
Scene scene = new Scene(group, 400, 400);
stage.setScene(scene);
// Does not work as intended
Line line1 = new Line(0,0, 200, 0);
line1.setTranslateX(200);
line1.setTranslateY(200);
line1.setRotate(60);
// Does work as intended.
Line line2 = new Line(0, 0, 200, 0);
Affine affine = new Affine();
affine.appendTranslation(200, 200);
affine.appendRotation(60);
line2.getTransforms().add(affine);
group.getChildren().addAll(line1, line2);
stage.show();
}
}

Generate 10 random circles and points them in the path

What I want: I need to generate random 10 circles, with random coordinates and points them in path. Then create a square that needs to move along that path using animation.
What is my problem: I cant create 10 random circles with random coordinates, but I created code for animation.
Here is my code, I created random curved line and square that goes along it. That curved line is just for example, because I don't know how to make circles with random coordinates and points them in path.
Example of my code
final Rectangle rectPath = new Rectangle(0, 0, 40, 40);
rectPath.setArcHeight(10);
rectPath.setArcWidth(10);
rectPath.setFill(Color.ORANGE);
Path path = new Path();
path.getElements().add(new MoveTo(20, 20));
path.getElements().add(new CubicCurveTo(380, 0, 380, 120, 200, 120));
path.getElements().add(new CubicCurveTo(0, 120, 0, 240, 380, 240));
path.getElements().add(new CubicCurveTo(420, 350, 420, 440, 10, 450));
PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(Duration.millis(4000));
pathTransition.setPath(path);
pathTransition.setNode(rectPath);
pathTransition.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pathTransition.setCycleCount(5);
pathTransition.setAutoReverse(true);
pathTransition.play();
Group root = new Group();
root.getChildren().add(rectPath);
root.getChildren().add(path);
Scene scene = new Scene(root, 600, 450);
primaryStage.setTitle("Path transition demo");
primaryStage.setScene(scene);
primaryStage.show();
Firstly check my comment regarding the question. It is not something very complex. It is all about learning the concepts and putting them together. Assuming that you might be a beginner, please find the below example for your requirement.
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
public class RandomPathTransistionDemo extends Application {
PathTransition pathTransition;
Path path;
SecureRandom random = new SecureRandom();
#Override
public void start(Stage stage) {
VBox root = new VBox();
root.setSpacing(10);
root.setPadding(new Insets(10));
Scene scene = new Scene(root, 600, 600);
stage.setScene(scene);
stage.setTitle("Random Path Transistion");
stage.show();
Pane pane = new Pane();
pane.setPadding(new Insets(10));
pane.setStyle("-fx-border-width:1px;-fx-border-color:black;-fx-background-color:white;");
VBox.setVgrow(pane, Priority.ALWAYS);
Button generateBtn = new Button("Generate circles");
Button animationBtn = new Button("Start Animation");
animationBtn.setDisable(true);
HBox buttons = new HBox(generateBtn, animationBtn);
buttons.setSpacing(15);
root.getChildren().addAll(buttons, new Label("Click generate button as many times as you want !!"),pane);
final Rectangle rectPath = new Rectangle(0, 0, 20, 20);
rectPath.setArcHeight(10);
rectPath.setArcWidth(10);
rectPath.setFill(Color.ORANGE);
path = new Path();
path.setStroke(Color.LIGHTGREEN);
path.setStrokeWidth(2);
generateBtn.setOnAction(e -> {
animationBtn.setDisable(false);
if (pathTransition != null) {
pathTransition.stop();
}
pane.getChildren().clear();
path.getElements().clear();
int width = (int) pane.getWidth() - 20;
int height = (int) pane.getHeight() - 20;
List<Circle> dots = new ArrayList<>();
for (int i = 0; i < 10; i++) {
double x = random.nextInt(width); // Get a random value of x within the pane width
double y = random.nextInt(height);// Get a random value of y within the pane height
// If required include your logic to see if this point is not within the range of other points.
// Create a circle with this random point
Circle dot = new Circle(x, y, 5, Color.RED);
dots.add(dot);
// Also inlcude a path element for this random point.
path.getElements().add(i == 0 ? new MoveTo(x, y) : new LineTo(x, y));
}
// Add all nodes in the pane one after another to have a nice visual.
pane.getChildren().add(path);
pane.getChildren().addAll(dots);
pane.getChildren().add(rectPath);
// Move the rectangle to the start point of the path.
rectPath.setTranslateX(dots.get(0).getCenterX() - 10); // 10 :: half of rectangle width
rectPath.setTranslateY(dots.get(0).getCenterY() - 10); // 10 :: half of rectangle height
});
animationBtn.setOnAction(e -> {
pathTransition = new PathTransition();
pathTransition.setDuration(Duration.millis(4000));
pathTransition.setPath(path);
pathTransition.setNode(rectPath);
pathTransition.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pathTransition.setAutoReverse(false);
pathTransition.play();
});
}
public static void main(String[] args) {
launch(args);
}
}

JavaFX: Drawing a infinite symbol and moving along

I need to create a JavaFX application that generates a path in the form of an infinite symbol, and then create a rectangle that will move across that path.
So far I know to create a circle and square and with transitionPath to move that rectangle , but how to create an infinity shape? I'm very fresh in JavaFx (and in development as well) so please don't be harsh :)
Here is my code with Circle shape:
import javafx.animation.PathTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class PathTransitionDemo extends Application {
#Override
public void start(Stage primaryStage) {
Pane pane = new Pane();
Rectangle rectangle = new Rectangle (0, 0, 25, 50);
rectangle.setFill(Color.ORANGE);
Circle circle = new Circle(125, 100, 50);
circle.setFill(Color.WHITE);
circle.setStroke(Color.BLACK);
pane.getChildren().add(circle);
pane.getChildren().add(rectangle);
PathTransition pt = new PathTransition();
pt.setDuration(Duration.millis(4000));
pt.setPath(circle);
pt.setNode(rectangle);
pt.setOrientation(
PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pt.setCycleCount(Timeline.INDEFINITE);
pt.setAutoReverse(true);
pt.play();
circle.setOnMousePressed(e -> pt.pause());
circle.setOnMouseReleased(e -> pt.play());
Scene scene = new Scene(pane, 250, 200);
primaryStage.setTitle("PathTransitionDemo"); // Unos nayiva pozornice e
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I looked everywhere for some hint, but without luck :(
I found on the web an SVG path to draw an "infinity" shape, so replace your circle with:
SVGPath svg = new SVGPath();
svg.setFill(Color.TRANSPARENT);
svg.setStrokeWidth(1.0);
svg.setStroke(Color.BLACK);
svg.setContent("M 787.49,150 C 787.49,203.36 755.56,247.27 712.27,269.5 S 622.17,290.34 582.67,279.16 508.78,246.56 480,223.91 424.93,174.93 400,150 348.85,98.79 320,76.09 256.91,32.03 217.33,20.84 130.62,8.48 87.73,30.5 12.51,96.64 12.51,150 44.44,247.27 87.73,269.5 177.83,290.34 217.33,279.16 291.22,246.56 320,223.91 375.07,174.93 400,150 451.15,98.79 480,76.09 543.09,32.03 582.67,20.84 669.38,8.48 712.27,30.5 787.49,96.64 787.49,150 z");
and use it for drawing, transition and event catching.
You may need to adapt it to your need.
If you are looking for better "infinity" shapes, then search for "lemniscate".

Making More Than One Circle in Java

I have a project in class where I need to display a traffic light with simply three cirlces. I started with the yellow one, and then attempted to add a red one in some random other place just to see if I could do it, however the yellow one is the only one showing. I can't tell if the red one is somehow underneath the yellow one, but in any case it doesn't make much sense to me as to why the red circle isn't showing.
package tryingGraphicsStuff;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Circle;
import javafx.scene.paint.*;
import javafx.scene.text.*;
import javafx.scene.control.*;
public class TryingGraphicsStuff extends Application{
#Override
public void start(Stage stage) throws Exception {
// create circle
Circle circle = new Circle();
circle.setCenterX(150);
circle.setCenterY(150);
circle.setRadius(50);
circle.setFill(Color.RED);
// place on pane
StackPane p = new StackPane();
p.getChildren().add(circle);
// ensure it stays centered if window resized
//circle.centerXProperty().bind(p.widthProperty().divide(2));
//circle.centerYProperty().bind(p.heightProperty().divide(2));
Circle circleTwo = new Circle();
circleTwo.setCenterX(400);
circleTwo.setCenterY(400);
circleTwo.setRadius(50);
circleTwo.setFill(Color.YELLOW);
// place on pane
p.getChildren().add(circleTwo);
// create scene from pane
Scene scene = new Scene(p, 300, 1000);
// place scene on stage
stage.setTitle("Circle");
stage.setScene(scene);
stage.show();
}
public static void main (String [] args)
{
Application.launch(args);
}
}
A StackPane "lays out its children in a back-to-front stack". (The stack here is in z-coordinates). It is a "layout pane" which actually manages the placement of the child nodes for you. Consequently, the centerX and centerY properties of the circles are ignored, and they appear one on top of the other in the order they are added (so the red one is underneath the yellow one, and the only one you see is the yellow one). By default, the stack pane centers them.
All "layout panes" position the nodes for you. For example, a VBox will position nodes in a vertical stack, with the first one at the top, the second below, and so on. So if you used a VBox instead of a StackPane, the circles would appear one below the other (in the y-direction), but note they would still not respect the centerX and centerY properties.
The Pane class itself does not manage the layout of its child nodes; so if you want to use the coordinates for shape objects, Pane is probably your best option. Group behaves similarly, but takes on the bounds of the union of its child bounds, so it acts like Pane but its local coordinate system is different.
The following demo shows all these options. Again, Pane will be the one that behaves in an intuitive way.
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class CircleLayoutExample extends Application {
#Override
public void start(Stage primaryStage) {
TabPane tabs = new TabPane();
tabs.getTabs().add(createTab(new StackPane()));
tabs.getTabs().add(createTab(new VBox()));
tabs.getTabs().add(createTab(new Pane()));
tabs.getTabs().add(createTab(new Group()));
Scene scene = new Scene(tabs, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private Tab createTab(Pane pane) {
Circle c1 = new Circle(150, 150, 50, Color.RED);
Circle c2 = new Circle(400, 400, 50, Color.YELLOW);
pane.getChildren().addAll(c1, c2);
Tab tab = new Tab(pane.getClass().getSimpleName());
tab.setContent(pane);
return tab ;
}
// annoyingly, Pane and Group do not have a common superclass with a getChildren()
// method, so just reproduce the code...
private Tab createTab(Group pane) {
Circle c1 = new Circle(150, 150, 50, Color.RED);
Circle c2 = new Circle(400, 400, 50, Color.YELLOW);
pane.getChildren().addAll(c1, c2);
Tab tab = new Tab(pane.getClass().getSimpleName());
tab.setContent(pane);
return tab ;
}
public static void main(String[] args) {
launch(args);
}
}
Yeah your both the circles are overlapping.
You can simply use a VBox instead of StackPane. It will solve your issue.
VBox p = new VBox();
As other answers have suggested, using a VBox would help you out the most here, since it will automatically put its children into a vertical row. Here is a brief snippet using an array (so you can make as many circles as you want)
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Circle;
import javafx.scene.paint.*;
public class TryingGraphicsStuff extends Application{
#Override
public void start(Stage stage) throws Exception {
Circle[] circle = new Circle[3]; // create 3 circles
VBox vBox = new VBox(); // vbox will put circles in vertical row
vBox.setAlignment(Pos.CENTER); // center circles
for(int i = 0; i < circle.length; i++){
circle[i] = new Circle(50); // initialize circles with radius of 50
vBox.getChildren().add(circle[i]);
}
circle[0].setFill(Color.RED);
circle[1].setFill(Color.YELLOW);
circle[2].setFill(Color.GREEN);
// add vbox to scene
Scene scene = new Scene(vBox, 300, 800);
stage.setTitle("Circle");
stage.setScene(scene);
stage.show();
}
public static void main (String [] args){
Application.launch(args);
}
}
As always, please understand the code and don't just mindlessly copy and paste. Cheers!
I'm actually a bit confused by the code above. According to your numbers the red one should be the one showing and not the yellow one. Your scene is only 300px wide and you center the yellow circle at 400 which will put it out of view (having a radius of only 50).
Either increase your scene size or move your circle inside your view.

Rectangle is not displaying on stage?

I have written a program where a lightblue rectangle gets added in a pane. The pane is then added in the scene. The stage is then shown with the rectangle in the scene. When I run this program, the opposite happens. Nothing shows up. Even when I add, let's say text, nothing shows up either. Could someone point out what I am doing wrong? I am using JavaFX as the GUI. Here's my code:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class RectangleBound extends Application {
#Override
public void start(Stage primaryStage) {
Pane p = new Pane();
Rectangle rect = new Rectangle();
rect.setFill(Color.LIGHTSKYBLUE);
rect.setStroke(Color.DEEPSKYBLUE);
rect.setArcWidth(5);
// *C* set the width of the outline of rect to 5
p.getChildren().add(rect);
Scene sc = new Scene(p, 300, 300);
primaryStage.setScene(sc);
primaryStage.setTitle("Bound Rectangle");
primaryStage.show();
}
}
You haven't specified a width and height to the Rectangle. Just try the following and it should work.
Rectangle rect = new Rectangle(50, 50);

Categories

Resources