Ejemplo n.º 1
0
  public void draw() {
    background(
        theme.getColor(Types.BACKGROUND)); // Draws background, basically refreshes the screen
    win.setBackground(theme.getColor(Types.BACKGROUND));
    sidePanel.setBackground(theme.getColor(Types.SIDEPANEL1));

    for (int i = 0; i < SIM_TICKS; i++) {
      env.updateAllAgents(); // 'Ticks' for the new frame, sensors sense, networks network and
      // collisions are checked.
      env.updateCollisions(); // update the environment with the new collisions
      env.updateAgentsSight(); // update all the agents to everything they can see in their field
      // of view
      handleCollisions();
      if (!env.fitnessOnly) {
        checkDeaths();
      }
      updateUI();

      autoSnapshot();
    }

    // move drawn region
    if (arrowsPressed[0] && !arrowsPressed[1]) offsetY -= moveSpeed * zoomLevel; // UP
    if (arrowsPressed[1] && !arrowsPressed[0]) offsetY += moveSpeed * zoomLevel; // DOWN
    if (arrowsPressed[2] && !arrowsPressed[3]) offsetX -= moveSpeed * zoomLevel; // LEFT
    if (arrowsPressed[3] && !arrowsPressed[2]) offsetX += moveSpeed * zoomLevel; // RIGHT

    win.draw();

    fill(255);
    text("FrameRate: " + frameRate, 10, 10); // Displays framerate in the top left hand corner
    text("Mouse X: " + mouseX + "Mouse Y: " + mouseY, 10, 30);
    text("Fish Generation: " + env.getFishGeneration(), 10, 50);
    text("Ticks to next fish generation: " + (1000 - (env.getTick() % 1000)), 10, 70);
  }
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);
          }
        });
  }
Ejemplo n.º 3
0
  private void drawSimulation(PApplet canvas) {
    pushMatrix();
    translate(offsetX, offsetY);
    scale(zoomLevel);

    ArrayList<Agent> agents = env.getAllAgents(); // Returns an arraylist of agents
    ArrayList<Food> food = env.getAllFood(); // Returns an arraylist of all the food on the map
    ArrayList<Wall> walls = env.getAllWalls(); // Returns an arraylist of all walls
    ArrayList<Seaweed> seaweed = env.getAllSeaweed();

    for (int i = 0;
        i < agents.size();
        i++) { // Runs through arraylist of agents, will draw them on the canvas
      Agent ag = agents.get(i);

      // draw the field of view for the agent
      if (selectedAgent == null || !agentFocused || (agentFocused && ag == selectedAgent))
        stroke(128);
      else stroke(128, 100); // , (float) ag.getHealth()*200+55
      noFill();
      double range = ag.getVisionRange() * 2;

      pushMatrix();
      translate(ag.getX(), ag.getY());
      rotate((float) Utilities.toRadians(ag.getViewHeading() - ag.getFOV()));
      line(0, 0, (int) (range / 2), 0);
      popMatrix();

      pushMatrix();
      translate(ag.getX(), ag.getY());
      rotate((float) Utilities.toRadians(ag.getViewHeading() + ag.getFOV()));
      line(0, 0, (int) (range / 2), 0);
      popMatrix();

      arc(
          (float) ag.getX(),
          (float) ag.getY(),
          (float) range,
          (float) range,
          (float) Utilities.toRadians(ag.getViewHeading() - ag.getFOV()),
          (float) Utilities.toRadians(ag.getViewHeading() + ag.getFOV()));

      // draw our circle representation for the agent
      noStroke();
      // if(selectedAgent == null || !agentFocused || (agentFocused && ag == selectedAgent))
      // fill(theme.getColor((ag instanceof Enemy ? Types.SHARK : Types.FISH)));
      // else fill(theme.getColor((ag instanceof Enemy ? Types.SHARK : Types.FISH)), 100); //,
      // (float) ag.getHealth()*200 +55); // Alpha was severly impacting performance of simulation
      if (ag instanceof Enemy) {
        fill(
            ((ag.getSpeciesId() + 1) * 25) % 256,
            ((ag.getSpeciesId() + 1) * 47) % 256,
            ((ag.getSpeciesId() + 1) * 69) % 256,
            (agentFocused && ag == selectedAgent ? 100 : 256));
        pushMatrix();
        translate(ag.getX(), ag.getY());
        rotate((float) Utilities.toRadians(ag.getViewHeading()));
        rect(-10, -10, 20, 20);
        popMatrix();
      } else {
        fill(
            ((ag.getSpeciesId() + 1) * 25) % 256,
            ((ag.getSpeciesId() + 1) * 47) % 256,
            ((ag.getSpeciesId() + 1) * 69) % 256,
            (agentFocused && ag == selectedAgent ? 100 : 256));
        ellipse(ag.getX(), ag.getY(), 20, 20);
      }

      if (agentFocused
          && ag == selectedAgent) { // keep agent on screen if in focused / tracking mode
        int simAgX =
            (int) ((ag.getX() * zoomLevel) + offsetX); // screen coordinates of the selected agent
        int simAgY = (int) ((ag.getY() * zoomLevel) + offsetY);

        if (simAgX < trackingBounds) offsetX += trackingBounds - simAgX;
        else if (simAgX > draw_width - trackingBounds)
          offsetX -= simAgX - draw_width + trackingBounds;

        if (simAgY < trackingBounds) offsetY += trackingBounds - simAgY;
        else if (simAgY > draw_height - trackingBounds)
          offsetY -= simAgY - draw_height + trackingBounds;
      }
    }

    noStroke();
    fill(theme.getColor(Types.FOOD));
    for (int i = 0;
        i < food.size();
        i++) { // Runs through arraylist of food, will draw them on the canvas
      Food fd = food.get(i);
      ellipse(fd.getX(), fd.getY(), 5, 5);
    }

    noStroke();
    fill(201, 23, 134);
    for (int i = 0;
        i < seaweed.size();
        i++) { // Runs through arraylist of food, will draw them on the canvas
      Seaweed fd = seaweed.get(i);
      ellipse(fd.getX(), fd.getY(), 5, 5);
    }

    stroke(theme.getColor(Types.WALL));
    noFill();
    for (Wall wl : walls) { // Runs through arraylist of walls, will draw them on the canvas
      switch (wl.getWallType()) {
        case Collision.TYPE_WALL_AGENT:
          stroke(theme.getColor(Types.FISH));
          break;
        case Collision.TYPE_WALL_ENEMY:
          stroke(theme.getColor(Types.SHARK));
          break;
        default:
          stroke(theme.getColor(Types.WALL));
      }

      line(
          (float) wl.getStart().x,
          (float) wl.getStart().y,
          (float) wl.getEnd().x,
          (float) wl.getEnd().y);
    }

    popMatrix();

    fill(0);
    // rect(draw_width - 50, 0, 250, draw_height);
  }