Ejemplo n.º 1
0
 private UIButton addModeButton(final int mode, String txt, int r, int g, int b) {
   UIButton btn =
       new UIButton(
           this, 10 + 60 * (mode % 4), 10 + (35 * (int) Math.floor(mode / 4)), 50, 30, txt);
   btn.setEventHandler(
       new UIAction() {
         public void click(UIButton btn) {
           btnGroupModes.selectButton(btn);
           mouseMode = mode;
         }
       });
   btn.setColor(r, g, b);
   btnGroupModes.addObject(btn);
   return btn;
 }
Ejemplo n.º 2
0
  private void setupUI() {
    // Set colors of each element of simulation
    theme = new UITheme();
    theme.setColor(Types.BACKGROUND, color(0));
    theme.setColor(Types.SIDEPANEL1, color(50));
    theme.setColor(Types.FOOD, color(0, 255, 0));
    theme.setColor(Types.FISH, color(255, 127, 0));
    theme.setColor(Types.SHARK, color(255, 0, 0));
    theme.setColor(Types.WALL, color(255, 255, 0));
    theme.setColor(Types.NEURON, color(200));
    theme.setColor(Types.NEURON_FIRED, color(0, 255, 0));

    // setup main window for UI elements
    win = new UIWindow(this, 0, 0, screen.width, screen.height);
    sideTabs = new UITab(this, 250, 0, 250, screen.height);
    sideTabs.setIsLeft(false);
    sideTabs.setBackground(50);
    sideTabs.setFixedBackground(true);

    sidePanel = sideTabs.addTab("Information"); // new UIWindow(this, 250, 0, 250, screen.height);
    neatParams = sideTabs.addTab("NEAT Params");
    neatParams.setBackground(30);
    setupNEATParams();

    // Simulation draw region
    UIDrawable sim = new UIDrawable(this, 0, 0, draw_width, draw_height);
    sim.setBackground(color(255));
    sim.setFixedBackground(true);
    sim.setEventHandler(
        new UIAction() {
          public void draw(PApplet canvas) {
            drawSimulation(canvas);
          }
        });
    win.addObject(sim);
    win.addObject(sideTabs);

    // Buttons to change the current mode
    btnGroupModes = new UIWindow(this, 0, 0, 250, 150);
    btnGroupModes.setBackground(30);
    btnGroupModes.setFixedBackground(true);
    sidePanel.addObject(btnGroupModes);

    btnSelectAgent = addModeButton(0, "Select", 2, 118, 255);
    btnAddFood = addModeButton(1, "Seaweed", 84, 255, 159);
    btnAddAgent = addModeButton(2, "Agent", 255, 127, 0);
    btnThrust = addModeButton(3, "Thrust", 0, 231, 125);
    btnAddWall = addModeButton(4, "Wall", 255, 255, 0);

    btnGroupModes.selectButton(btnSelectAgent);

    // Change number of ticks updated each frame
    sliderTPS = new UISlider(this, 10, 90, 170, 30);
    sliderTPS.setEventHandler(
        new UIAction() {
          public void change(UISlider slider) {
            SIM_TICKS = (int) (slider.getValue() * SIM_TPS_MAX);
            lblSimTPS.setText("Ticks: " + SIM_TICKS);
          }
        });
    sliderTPS.setValue(1.0 / SIM_TPS_MAX);
    btnGroupModes.addObject(sliderTPS);

    lblSimTPS = new UILabel(this, 190, 92, "Ticks: " + SIM_TICKS);
    btnGroupModes.addObject(lblSimTPS);

    // Statistics window for the currently selected agent
    winStats = new UIWindow(this, 0, 165, 300, 500);
    winStats.setBackground(30);
    winStats.setFixedBackground(true);
    sidePanel.addObject(winStats);

    // control to change the selected agents heading
    agentHeading = new UIVision(this, 25, 270, 200);
    agentHeading.setTheme(theme);
    agentHeading.setEventHandler(
        new UIAction() {
          public void change(UIAngle ang) {
            if (selectedAgent != null) {
              selectedAgent.changeViewHeading(ang.getAngle() - selectedAgent.getViewHeading());
            }
          }
        });
    winStats.addObject(agentHeading);

    // progress bar of the selected agents current health
    progHealth = new UIProgress(this, 10, 93, 230, 10);
    winStats.addObject(progHealth);

    // sliders to move agents position
    sliderX = new UISlider(this, 10, 35, 230, 15);
    sliderX.setEventHandler(
        new UIAction() {
          public void change(UISlider slider) {
            if (selectedAgent != null) {
              selectedAgent.setX((int) (slider.getValue() * Environment.width));
            }
          }
        });
    winStats.addObject(sliderX);

    sliderY = new UISlider(this, 10, 60, 230, 15);
    sliderY.setEventHandler(
        new UIAction() {
          public void change(UISlider slider) {
            if (selectedAgent != null) {
              selectedAgent.setY((int) (slider.getValue() * Environment.height));
            }
          }
        });
    winStats.addObject(sliderY);

    // boost agent health back to 100%
    btnSelectHealth = new UIButton(this, 10, 115, 65, 20, "100%");
    btnSelectHealth.setColor(84, 255, 159);
    btnSelectHealth.setEventHandler(
        new UIAction() {
          public void click(UIButton btn) {
            if (selectedAgent != null) {
              selectedAgent.updateHealth(1);
            }
          }
        });
    winStats.addObject(btnSelectHealth);

    // thrust selected agent
    btnSelectThrust = new UIButton(this, 93, 115, 65, 20, "Thrust");
    btnSelectThrust.setColor(251, 150, 20);
    btnSelectThrust.setEventHandler(
        new UIAction() {
          public void click(UIButton btn) {
            if (selectedAgent != null) {
              selectedAgent.thrust(5);
            }
          }
        });
    winStats.addObject(btnSelectThrust);

    // kill poor agent
    btnSelectKill = new UIButton(this, 175, 115, 65, 20, "KILL");
    btnSelectKill.setColor(210, 50, 50);
    btnSelectKill.setEventHandler(
        new UIAction() {
          public void click(UIButton btn) {
            if (selectedAgent != null) {
              // env.removeAgent(selectedAgent);
              env.scheduledRemove.add(selectedAgent);
              selectedAgent = null;
            }
          }
        });
    winStats.addObject(btnSelectKill);

    // Toggle focused / tracking mode for selected agent
    btnToggleFocused = new UIButton(this, 120, 5, 65, 15, (agentFocused ? "Unfocus" : "Focus"));
    btnToggleFocused.setIsLeft(false);
    btnToggleFocused.setColor(50, 100, 255);
    btnToggleFocused.setEventHandler(
        new UIAction() {
          public void click(UIButton btn) {
            agentFocused = !agentFocused;
            btn.setText(agentFocused ? "Unfocus" : "Focus");
          }
        });
    winStats.addObject(btnToggleFocused);

    // 3D neural network visual

    UITab bottomWindow = new UITab(this, 0, 300, 250, 300);
    bottomWindow.setIsTop(false);
    sidePanel.addObject(bottomWindow);

    UIWindow tabNeural = bottomWindow.addTab("Network");
    UIWindow tabTheme = bottomWindow.addTab("Theme");
    tabTheme.setBackground(30);

    neuralVisual = new UIDrawable3D(this, 0, 0, 250, 250);
    neuralVisual.setBackground(30);
    neuralVisual.setFixedBackground(true);
    tabNeural.addObject(neuralVisual);

    neuralVisual.setEventHandler(
        new UIAction() {
          private float zoom = 0.5f;
          private int offX = 0;
          private int offY = 0;
          boolean arrows[] = new boolean[4];
          private boolean rotating = true;

          public void draw(PApplet canvas) {
            if (selectedAgent == null) return;

            if (arrows[0] && !arrows[1]) offY -= moveSpeed / 3; // UP
            if (arrows[1] && !arrows[0]) offY += moveSpeed / 3; // DOWN

            MNetwork net = selectedAgent.getNetwork();

            noStroke();
            pushMatrix();

            rotateY(neuralRotation);
            scale(zoom, zoom, zoom);
            translate(offX, offY);
            for (MNeuron n : net.getNeurons()) { // draw the neurons
              int isFired = (n.isFiring() ? 255 : 60);
              if (n.getID() >= 3 && n.getID() < 3 + Agent.configNumSegments)
                fill(theme.getColor(Types.FOOD), isFired);
              else if (n.getID() >= 3 + Agent.configNumSegments
                  && n.getID() < 3 + Agent.configNumSegments * 2)
                fill(theme.getColor(Types.WALL), isFired);
              else if (n.getID() >= 3 + Agent.configNumSegments * 2
                  && n.getID() < 3 + Agent.configNumSegments * 3)
                fill(theme.getColor(Types.SHARK), isFired);
              else if (n.getID() < 3) fill(0, 255, 255, isFired);
              else fill(theme.getColor(Types.NEURON), isFired);

              MVec3f vec = n.getCoords();
              // clip node if off the display
              if ((vec.y + offY) * zoom < -135) continue;

              translate(vec.x, vec.y, vec.z);
              sphere(3);
              translate(-vec.x, -vec.y, -vec.z);
            }

            for (MSynapse s : net.getSynapses()) { // draw the links between the neurons
              MNeuron pre = s.getPreNeuron();
              MNeuron post = s.getPostNeuron();
              MVec3f n1 = pre.getCoords();
              MVec3f n2 = post.getCoords();

              // clip edge if both nodes above clipping
              if ((n1.y + offY) * zoom < -135 && (n2.y + offY) * zoom < -135) continue;

              int isFired = (pre.isFiring() ? 100 : 10);
              if (pre.getID() >= 3 && pre.getID() < 3 + Agent.configNumSegments)
                stroke(theme.getColor(Types.FOOD), isFired);
              else if (pre.getID() >= 3 + Agent.configNumSegments
                  && pre.getID() < 3 + Agent.configNumSegments * 2)
                stroke(theme.getColor(Types.WALL), isFired);
              else if (pre.getID() >= 3 + Agent.configNumSegments * 2
                  && pre.getID() < 3 + Agent.configNumSegments * 3)
                stroke(theme.getColor(Types.SHARK), isFired);
              else if (pre.getID() < 3) stroke(0, 255, 255, isFired);
              else stroke(255, isFired);

              // partial clipping when one node if above line
              if ((n1.y + offY) * zoom < -135) {
                double t = (((-135 / zoom) - offY) - n2.y) / (n1.y - n2.y);
                int x = (int) ((int) (n2.x + t * (n1.x - n2.x)) / zoom);
                line(
                    (int) (x),
                    (int) (-135 / zoom) - offY,
                    0,
                    (int) (n2.x),
                    (int) (n2.y),
                    (int) n2.z);
              } else if ((n2.y + offY) * zoom < -135) {
                double t = (((-135.0 / zoom) - offY) - (n1.y)) / (double) ((n2.y - n1.y));
                int x = (int) (n1.x + t * (n2.x - n1.x));
                line(
                    (int) (n1.x),
                    (int) (n1.y),
                    (int) n1.z,
                    (int) (x),
                    (int) (-135 / zoom) - offY,
                    0);
              } else {
                line((int) n1.x, (int) n1.y, (int) n1.z, (int) n2.x, (int) n2.y, (int) n2.z);
              }
            }

            popMatrix();
            if (rotating) neuralRotation -= 0.02;
          }

          public boolean mouseWheel(MouseWheelEvent event) {
            if (!Utilities.isPointInBox(
                mouseX, mouseY, screen.width - 250, screen.height - 250, 250, 250)) return false;

            if (zoom > minZoom || event.getWheelRotation() > 0) {
              zoom = Math.max(minZoom, (zoom + 0.1f * event.getWheelRotation()));
            }

            return true;
          }

          public boolean mousePressed() {
            if (!Utilities.isPointInBox(
                mouseX, mouseY, screen.width - 250, screen.height - 250, 250, 250)) return false;
            rotating = !rotating;
            return true;
          }

          public boolean keyReleased() { // Hotkeys for buttons
            if (!Utilities.isPointInBox(
                mouseX, mouseY, screen.width - 250, screen.height - 250, 250, 250)) return false;

            switch (keyCode) {
              case (UP):
                arrows[0] = false;
                return true;
              case (DOWN):
                arrows[1] = false;
                return true;
              case (LEFT):
                arrows[2] = false;
                return true;
              case (RIGHT):
                arrows[3] = false;
                return true;
            }
            return false;
          }

          public boolean keyPressed() { // Hotkeys for buttons
            if (!Utilities.isPointInBox(
                mouseX, mouseY, screen.width - 250, screen.height - 250, 250, 250)) return false;

            switch (keyCode) {
              case (UP):
                arrows[0] = true;
                return true;
              case (DOWN):
                arrows[1] = true;
                return true;
              case (LEFT):
                arrows[2] = true;
                return true;
              case (RIGHT):
                arrows[3] = true;
                return true;
            }
            return false;
          }
        });

    // printout of selected agents stats
    lblStatTitle = addStatLabel("Selected Agent", 5);
    lblX = addStatLabel("X", 155);
    lblY = addStatLabel("X", 170);
    lblHeading = addStatLabel("X", 185);
    lblHealth = addStatLabel("X", 200);
    lblAngle = addStatLabel("X", 215);
    lblSpeed = addStatLabel("X", 230);

    // Themes window
    themeColorWheel = new UIColorWheel(this, 45, 40);
    themeColorWheel.setEventHandler(
        new UIAction() {
          public void change(UIColorWheel wheel) {
            theme.setColor((Types) themeDrop.getSelected(), wheel.getColor());
          }
        });
    tabTheme.addObject(themeColorWheel);

    themeDrop = new UIDropdown<Types>(this, 25, 10, 200, theme.getKeys());
    themeDrop.setEventHandler(
        new UIAction() {
          public void change(@SuppressWarnings("rawtypes") UIDropdown drop) {
            themeColorWheel.setColor(theme.getColor((Types) drop.getSelected()));
          }
        });
    tabTheme.addObject(themeDrop);

    // adds mouse scrolling listener to the applet
    addMouseWheelListener(
        new MouseWheelListener() {
          public void mouseWheelMoved(MouseWheelEvent event) {
            mouseWheel(event);
          }
        });
  }