Package fr.cyann.reactdemo

Source Code of fr.cyann.reactdemo.Particules

/*
* Copyright (C) 2013 Yann Caron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Less General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Less General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>
*/
package fr.cyann.reactdemo;

import fr.cyann.functional.Function1;
import fr.cyann.functional.Function2;
import fr.cyann.functional.Predicate1;
import fr.cyann.functional.Procedure1;
import fr.cyann.react.MouseReact;
import fr.cyann.react.ReactManager;
import fr.cyann.react.Signal;
import fr.cyann.react.TimeReact;
import fr.cyann.react.Var;
import fr.cyann.reactdemo.ui.swing.RLabel;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import fr.cyann.reactdemo.ui.Circle;
import fr.cyann.reactdemo.ui.StagePanel;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
* The ReactDemo1 main class. Creation date: 18 oct. 2013.
*
* @author CyaNn
* @version v0.1
*/
public class Particules {

  private static final RLabel label1 = new RLabel();
  private static final RLabel label2 = new RLabel();
  private static final StagePanel particule = new StagePanel();
  private static final Circle cursor = new Circle(25);
  private static final Var<Integer> mouseX = MouseReact.onMoveX().map(new Function1<Integer, Integer>() {

    @Override
    public Integer invoke(Integer arg1) {
      return arg1 - (cursor.getSize() / 2 - 2);
    }
  }).toVar(0);
  private static final Var<Integer> mouseY = MouseReact.onMoveY().map(new Function1<Integer, Integer>() {

    @Override
    public Integer invoke(Integer arg1) {
      return arg1 - (cursor.getSize() / 2 + 30);
    }
  }).toVar(0);
  private static Signal<Integer> tab1React;

  public static void launch() {

    JFrame frame = new JFrame();
    Container pane = frame.getContentPane();
    pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));

    label1.setAlignmentX(Component.CENTER_ALIGNMENT);
    label2.setAlignmentX(Component.CENTER_ALIGNMENT);

    frame.add(particule);
    frame.add(Box.createRigidArea(new Dimension(0, 10)));
    frame.add(label1);
    frame.add(Box.createRigidArea(new Dimension(0, 10)));
    frame.add(label2);
    frame.add(Box.createRigidArea(new Dimension(0, 10)));

    frame.setPreferredSize(new Dimension(1024, 800));
    frame.pack();
    frame.setVisible(true);

    initLabelsReact();
    initCursor();
    initAnim();

  }

  public static void initLabelsReact() {
    // when mouse is pressed say "pressed" otherwise say "released"
    // concatenate message with mouse position and update each time it is necessary

    // declare the mouse reactor
    Var<String> mouseAndTime = MouseReact.onButton1().map(new Function1<Boolean, String>() {

      @Override
      public String invoke(Boolean arg1) {
        if (arg1) {
          return "button pressed";
        }
        return "button released";
      }
    }).toVar("no button yet !").merge(mouseX, new Function2<String, Integer, String>() {

      @Override
      public String invoke(String arg1, Integer arg2) {
        // add mouse x position
        return arg1 + " ( x=" + arg2;
      }
    }).merge(mouseY, new Function2<String, Integer, String>() {

      @Override
      public String invoke(String arg1, Integer arg2) {
        // add mouse y position
        return arg1 + ", y=" + arg2 + ")";
      }
    });

    label1.setText(mouseAndTime);

    Var<String> counters = particule.getShapeCounter().merge(ReactManager.getInstance().getReactCounter(), new Function2<Integer, Integer, String>() {

      @Override
      public String invoke(Integer arg1, Integer arg2) {
        return "Number of circles: " + arg1 + ", Number of react: " + arg2;
      }
    });
    label2.setText(counters);
  }

  public static void initCursor() {
    particule.addShape(cursor);
    cursor.setX(mouseX);
    cursor.setY(mouseY);
  }

  public static void initAnim() {

    // when mouse button is old, then create a new circle every 50 ms
    tab1React = TimeReact.every(10).edge(MouseReact.onButton1()).subscribe(new Procedure1<Integer>() {

      @Override
      public void invoke(Integer value) {
        // create circle
        final Circle circle = new Circle(5);
        particule.addShape(circle);

        // determine random velocity and angle constant in time
        double velAngle = Math.random() * Math.PI * 2;
        double velSpeed = Math.random() * 10;
        final double velX = Math.cos(velAngle) * velSpeed;
        final double velY = Math.sin(velAngle) * velSpeed;

        final int mx = mouseX.getValue();
        final int my = mouseY.getValue();

        // create reactive counter every 25 fps
        final Var<Integer> counter = TimeReact.framePerSecond(25).fold(0, new Function2<Integer, Integer, Integer>() {

          @Override
          public Integer invoke(Integer arg1, Integer arg2) {
            return arg1 + 1;
          }
        }).map(new Function1<Integer, Integer>() {

          @Override
          public Integer invoke(Integer arg1) {
            return arg1.intValue();
          }
        }).toVar(0);

        // creation reactive operation between counter and constants to calculate x coordonate
        final Var<Integer> x = counter.map(new Function1<Integer, Integer>() {

          @Override
          public Integer invoke(Integer value) {
            return mx + (int) (velX * value);
          }
        });

        // creation reactive operation between counter and constants to calculate y coordonate
        final Var<Integer> y = counter.map(new Function1<Integer, Integer>() {

          @Override
          public Integer invoke(Integer value) {
            return my + (int) (velY * value);
          }
        });

        // creation reactive operation between counter and constants to calculate circle size
        Signal<Integer> size = counter.map(new Function1<Integer, Integer>() {

          @Override
          public Integer invoke(Integer value) {
            double factor = Math.sin((double) value / 10 - Math.PI / 4);
            return 50 + (int) (50 * factor);
          }
        });

        size.disposeWhen(new Predicate1<Integer>() {

          @Override
          public boolean invoke(Integer value) {
            if (value == 1) {
              particule.removeShape(circle);
              x.dispose();
              y.dispose();
              return true;
            }
            return false;
          }
        });

        // set reacts to component
        circle.setX(x);
        circle.setY(y);
        circle.setSize(size);
      }
    });

  }

}
TOP

Related Classes of fr.cyann.reactdemo.Particules

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.