I am trying to create a continuous animation, eventually the goal would be a bouncing ball that bounces off the edges of the screen, however, one step at a time.
I started with the sample code from Oracle that has an animation of circles that move for 40 seconds.
public void start(Stage primaryStage)
{
Group root = new Group();
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
Group circles = new Group();
for (int i = 0; i < 1; i++)
{
MovingCircle circle = new MovingCircle(150, Color.web("white", 0.05));
circle.setStrokeType(StrokeType.OUTSIDE);
circle.setStroke(Color.web("black", 0.16));
circle.setStrokeWidth(4);
circles.getChildren().add(circle);
}
root.getChildren().add(circles);
Timeline timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
for (Node circle: circles.getChildren())
{
if(circle instanceof MovingCircle)
{
MovingCircle c = (MovingCircle)circle;
timeline.getKeyFrames().addAll(
/* new KeyFrame(Duration.ZERO, // set start position at 0
new KeyValue(circle.translateXProperty(), random() * 800),
new KeyValue(circle.translateYProperty(), random() * 600)
),*/
new KeyFrame(new Duration(10), // set end position at 40s
c.getXMovement(), c.getYMovement())
);
c.updateCenter();
}
}
// play 40s of animation
timeline.play();
primaryStage.show();
}
I created a new MovingCircle that extends Circle to try and add other stuff to it later. The two new class methods return exactly what was commented out from the default code given.
I changed the cycle to indefinite so that it would go forever. All the circle does though is bounce between its original starting point and the translated point. I have tried updating its center location in hopes that the next bounce would move it to a different location, however, that doesn't work.
I am at quite a loss as to what to try next to get this working more the way I was hoping.
Related
wondering if anyone can help with this. I have to write some ode using processing 3.0 for college, basically creating a series of circles that appear randomly and change colours etc. Ive got the circles to appear, and they change location on mouse click.
What Im struggling with is, its asked me to have the circles change colour when the mouse button is pressed, where circles to the right are blue and circles to the left of the mouse pointer are yellow? I have no idea how to implement that at all.
Here's what I have so far, any help would be hugely appreciated:
//declaring the variables
float[] circleXs = new float[10];
float[] circleYs = new float[10];
float[] circleSizes = new float[10];
color[] circleColors = new color[10];
void setup() {
size(600, 600);
createCircles();
}
//creation of showCricles function
void draw() {
background(0);
showCircles();
}
//creation of circles of random size greater than 10 but less than 50 - also of white background colour
void createCircles() {
for (int i = 0; i < circleXs.length; i++) {
circleXs[i] = random(width);
circleYs[i] = random(height);
circleSizes[i] = random(10, 50);
circleColors[i] = color(255,255,255);
}
}
void showCircles() {
for (int i = 0; i < circleXs.length; i++) {
fill(circleColors[i]);
circle(circleXs[i], circleYs[i], circleSizes[i]);
}
}
//creating new circles on mouse click
void mouseClicked() {
createCircles();
}
It's not very complicated, you just miss some of the basics. Here are 2 things you have to know to do what you want to do:
You can use mouseX or mouseY to compare coordinates with the current mouse pointer's position.
This would be way cleaner using class, but I am guessing that you are not quite there as you're using a couple arrays to store coordinates instead. But here's the thing with that method: the array's index always refer to the same object. Here your objects are circles, so every array's index n refers to the same circle. If you find a circle which x coordinate is leftward compared to the mouse pointer, you can change that circle's color by modifying the item at the same index but in the circleColors array.
So I added a couple lines to your mouseClicked() method which demonstrate what I just said. Here they are:
void mouseClicked() {
createCircles();
// here is the part that I added
// for each circle's X coordinate:
for( int i = 0; i < circleXs.length; i++) {
// if the X coordinate of the mouse is lower than the circle's...
if( mouseX > circleXs[i]) {
// then set it's color to yellow
circleColors[i] = color(255, 255, 0);
} else {
// else set it's color to blue
circleColors[i] = color(0, 0, 255);
}
}
}
It should show what you described, or close enough for you to clear the gap.
Hope it helps. Have fun!
I'm attempting to create something like a minimap with JavaFX, i.e. a (darkened) background image with some circles layered on top of it. Some of these circles need to be able to shed light on the background, revealing a small part of it. The following figure shows what I am aiming at.
I have worked my way forward using this SO solution, but at the moment, I am stuck because it seems that you can only set one instance of javafx.scene.effect.Lighting on the underlying StackPane.
I would really like to keep this as simple as possible and ideally only employ JavaFX. Any help is greatly appreciated :)
I recommend adding together Circles filled with a RadialGradient on a Pane with black background using BlendMode.LIGHTEN and combining this with a ImageView containing the "map" using BlendMode.MULTIPLY:
private Circle circle;
// gradient with yellow in the center and black on the border
private final static RadialGradient GRADIENT = new RadialGradient(0, 0, 0.5, 0.5, 0.5, true, CycleMethod.NO_CYCLE, new Stop(0, Color.YELLOW), new Stop(1, Color.BLACK));
private void newCircle(Pane container) {
circle = new Circle(50, GRADIENT);
circle.setBlendMode(BlendMode.LIGHTEN);
circle.setManaged(false);
container.getChildren().add(circle);
}
private void setCirclePosition(MouseEvent event) {
circle.setCenterX(event.getX());
circle.setCenterY(event.getY());
}
#Override
public void start(Stage primaryStage) {
Image image = new Image(imageURL);
ImageView imageView = new ImageView(image);
Pane mask = new Pane();
mask.setBlendMode(BlendMode.MULTIPLY);
mask.setStyle("-fx-background-color: black;");
mask.setOnMouseMoved(this::setCirclePosition); // move cricle with mouse
newCircle(mask);
// create new circle on mouse click
mask.setOnMouseClicked(evt -> {
newCircle(mask);
setCirclePosition(evt);
});
StackPane root = new StackPane(imageView, mask);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
Im trying to make a isometric videogame in Libgdx and when Im programming the animations I have a strange error.
I have two 3 tiles in the scene: static body without animation, tile floor and body with animation.
All have the same coordinates and the static body wihout animation and tile floor are in the same position but the body with animation are in wrong position.
Here a image, all in the image are in the same scene at the same time:
Image from scene
Static body is a frame from Spritesheet of the animation.
Here is my relevant code:
TextureAtlas texureAtlasHair;
Animation<TextureRegion> animationHairHeroRunning;
SpriteBatch batch;
texureAtlasHair = new TextureAtlas("hero/ClothesBueno/ClothesB.atlas");
animationHairHeroRunning = new Animation<TextureRegion>(1f/4f,texureAtlasHair.findRegions("Stance"));
heroLoad = new Texture("map/Stance_1.png");
heroLoadSprite = new Sprite(heroLoad);
heroLoadSprite.flip(false,true);
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(dungeonCam.combined);
dungeonCam.update();
batch.begin();
elapsedTime += Gdx.graphics.getDeltaTime();
//FloorTile
Vector2 pointFloor = twoDToIso(new Vector2(25,30));
batch.draw(floor,pointFloor.x,pointFloor.y);
//Hero without animation
Vector2 pointHero = twoDToIso(new Vector2(25,30));
batch.draw(heroLoadSprite,pointHero.x,pointHero.y);
//Hero with animation
TextureRegion currentFrameHair =
animationHairHeroRunning.getKeyFrame(elapsedTime,true);
batch.draw(currentFrameHair,pointHero.x,pointHero.y,128,-128);
batch.end();
}
public Vector2 twoDToIso(Vector2 punto) {
Vector2 tempP = new Vector2(0, 0);
tempP.x = (punto.x - punto.y) * 32;
tempP.y = (punto.x + punto.y) * 16;
return tempP;
}
Edit
AtlasImage
And my .atlas is like this.
.atlas
And my actual code to AtlasRegions:
Array<TextureAtlas.AtlasRegion> arrayRegions;
texureAtlasHair = new TextureAtlas("hero/ClothesBueno/ClothesB.atlas");
arrayRegions = texureAtlasHair.findRegions("Stance");
animationHairHeroRunning = new Animation(1f/4f,arrayRegions);
Hey I am trying to make a simple 2d scroller but I simply cannot seem to get the picture to scroll. I am using an ImagveView for the picture, and I have tried both a translatetransition and a pathtransition, but I can't get any good results? Here is my code:
public void aboutSceneAnimation() {
Rectangle2D psb = Screen.getPrimary().getVisualBounds();
Path path = new Path();
MoveTo moveTo = new MoveTo();
moveTo.setX(0.0);
path.getElements().add(moveTo);
PathTransition pt = new PathTransition();
pt.setDuration(Duration.INDEFINITE);
pt.setNode(map);
pt.setPath(path);
pt.setCycleCount(4);
pt.setAutoReverse(true);
pt.play();
}
public Scene aboutScene() {
Rectangle2D psb = Screen.getPrimary().getVisualBounds();
//Create the map
BorderPane border = new BorderPane();
border.getChildren().addAll(map2);
//Size the map
map2.setFitWidth(psb.getWidth());
map2.setFitHeight(psb.getHeight());
Scene scene = new Scene(border, 500, 500);
aboutSceneAnimation();
return scene;
}
The way it works is that when the program starts there is a start scene loaded into my stage, and then I just show the stage. When a button is pressed I simply change to the aboutScene which also calls the aboutSceneAnimation, which is where I want the map to scroll. Any ideas would be greatly appreciated!
-Cheers
You need to use a Pane instead of a BorderPane, because in a BorderPane the center node will be resized to fill the available space in the middle.
In your PathTransition you only add from where to start, i. e. the MoveTo, but you don't add where it should go, e. g. a LineTo.
Additional note:
Since your example in the question contains only bits and pieces that don't work together, please read about How to create a Minimal, Complete, and Verifiable example.
sample code
//node
Rectangle rect = new Rectangle (0, 0, 20, 20);
//path
Text text = TextBuilder.create()
.text("J a v a F X R o c k s")
.font(new Font(50))
.x(65)
.y(100)
.build();
// path transition
pathTransition = PathTransitionBuilder.create()
.duration(Duration.seconds(15))
.path(text)
.node(rect)
.orientation(OrientationType.ORTHOGONAL_TO_TANGENT)
.cycleCount(Timeline.INDEFINITE)
.autoReverse(true)
.build();
I want to display part of the the text(path) that traveled by rect node. Meaning in the above figure as rect node traveled until java, i want to be display that part only at that point of time ..
You can try to assign a clipping area to the Text and update it during animation:
public void start(Stage primaryStage) {
final Rectangle pen = new Rectangle(0, 0, 20, 20);
// this pane this contain clipping
final Pane clip = new Pane();
// listener to update clipping area
ChangeListener changeListener = new ChangeListener() {
#Override
public void changed(ObservableValue ov, Object t, Object t1) {
Rectangle newrect = new Rectangle(pen.getTranslateX(), pen.getTranslateY(), pen.getWidth(), pen.getHeight());
newrect.setRotate(pen.getRotate());
clip.getChildren().add(newrect);
}
};
// rect coordinates will be changed during animation, so we will listen to them
pen.translateXProperty().addListener(changeListener);
pen.translateYProperty().addListener(changeListener);
pen.rotateProperty().addListener(changeListener);
final Text text = TextBuilder.create()
.text("J a v a F X R o c k s")
.font(new Font(50))
.clip(clip)
.x(65)
.y(100)
.build();
PathTransition pathTransition = PathTransitionBuilder.create()
.duration(Duration.seconds(15))
.path(text)
.node(pen)
.orientation(OrientationType.ORTHOGONAL_TO_TANGENT)
.build();
// once we done we don't want to store thousands of rectangles used to clip
pathTransition.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
text.setClip(null);
clip.getChildren().clear();
}
});
Pane root = new Pane();
root.getChildren().addAll(text, pen);
primaryStage.setScene(new Scene(root, 600, 200));
primaryStage.show();
pathTransition.play();
}
A bit more efficient way to store clipping area can be Canvas object, but it will require a bit of math to draw rectangles with rotation on canvas, so it's your call.