5 de jan. de 2017

Efeito Metaballs com JavaFX

Falamos sobre como escrever pixel por pixel de um Canvas e o objetivo na verdade era essa postagem aqui.

Nessa postagem vamos criar o efeito Metaballs e iremos seguir o mesmo código explicado pelo MESTRE Shiffman no vídeo abaixo, mas iremos aplicar em JavaFX. Sugiro você ver o vídeo, ler o artigo sobre escrita de pixels com JavaFX e tentar fazer por você mesmo. Se não conseguir, em seguida você pode ver o código que criamos como exemplo.



Nosso simples projeto





Como vocês viram, o Shiffman usa Processing,a linguagem de programação mais bacana para criarmos efeitos visuais. A boa notícia é que tudo que fazemos com Processing podemos fazer com JavaFX. A versão original de Processing, na verdade, é baseada em Java (com versões para JavaScript e Python). Logo, tudo que você vê ele fazendo você consegue fazer também e em Java, ou seja, você se diverte e ainda exercita o uso de uma linguagem de mercado.
O nosso programa vai ter duas pequenas classes, veja o código e a seguir um vídeo que fiz explicando. Se tiver dúvidas você pode perguntar no nosso grupo ou nos comentários


class Blob {
double posX, posY;
double velX, velY;
double raio;
public Blob(double x, double y) {
super();
this.posX = x;
this.posY = y;
this.raio = 200;
velX = Main.random.nextFloat() * 10;
velY = Main.random.nextFloat() * 10;
}
public void update() {
posX += velX;
posY += velY;
if(posX < 0 || posX > Main.WIDTH) {
velX *= -1;
}
if(posY < 0 || posY > Main.HEIGHT) {
velY *= -1;
}
}
}
view raw Blob.java hosted with ❤ by GitHub
import static java.lang.Math.pow;
import static java.lang.Math.sqrt;
import java.util.Random;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
public static final float WIDTH = 600;
public static final float HEIGHT = 400;
int COLOR_MODES = 7;
public static Random random = new Random();
Blob[] blobs = new Blob[12];
public static void main(String[] args) {
launch();
}
int selectedColorMode = 1;
boolean inverter = false;
private Canvas canvas;
@Override
public void start(Stage stage) throws Exception {
canvas = new Canvas(WIDTH, HEIGHT);
for (int i = 0; i < blobs.length; i++) {
blobs[i] = new Blob(random.nextFloat() * WIDTH, random.nextFloat() * HEIGHT);
}
canvas.setOnMouseClicked(e -> {
if (e.isControlDown())
inverter = !inverter;
else if (selectedColorMode > COLOR_MODES)
selectedColorMode = 1;
else
selectedColorMode++;
});
stage.setTitle("MetaBalls example with JavaFX");
stage.show();
stage.setScene(new Scene(new StackPane(canvas), WIDTH, HEIGHT));
KeyFrame frame = new KeyFrame(Duration.millis(100), e -> draw());
Timeline timeline = new Timeline(frame);
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.play();
}
private void draw() {
GraphicsContext ctx = canvas.getGraphicsContext2D();
ctx.clearRect(0, 0, WIDTH, HEIGHT);
for (int x = 0; x < WIDTH; x++) {
for (int y = 0; y < HEIGHT; y++) {
int total = 0;
for (Blob blob : blobs) {
double d = distance(x, y, blob.posX, blob.posY);
total += 15 * (blob.raio / d);
}
if (total > 255)
total = 255;
Color color = selectColor(total);
ctx.getPixelWriter().setColor(x, y, color);
}
}
for (int i = 0; i < blobs.length; i++) {
blobs[i].update();
}
}
private Color selectColor(int total) {
int inverso = 255;
if (inverter) {
inverso = 255 % total;
}
Color color = Color.rgb(total, total, total);
switch (selectedColorMode) {
case (1):
color = Color.rgb(total, total, total);
break;
case (2):
color = Color.rgb(total, total, inverso);
break;
case (3):
color = Color.rgb(total, inverso, total);
break;
case (4):
color = Color.rgb(total, inverso, inverso);
break;
case (5):
color = Color.rgb(inverso, total, total);
break;
case (6):
color = Color.rgb(inverso, total, inverso);
break;
case (7):
color = Color.rgb(inverso, inverso, total);
}
return color;
}
private double distance(double x, double y, double x2, double y2) {
return sqrt(pow(x2 - x, 2) + pow(y2 - y, 2));
}
}
view raw Main.java hosted with ❤ by GitHub



Conclusão


E está aberta a temporada de efeitos especiais no JavaFX! Vamos criar coisas baseadas nos vídeos do Shiffman. Em breve voltamos com mais novidades.

Nenhum comentário:

Postar um comentário