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); }
public void mousePressed() { ArrayList<Agent> agents = env.getAllAgents(); Agent agent_clicked = null; if (win.mousePressed()) return; if (!Utilities.isPointInBox(mouseX, mouseY, 0, 0, draw_width, draw_height)) return; /* * Mouse Modes are as follows: * 0 = Click tool - Select agents to see information on them in the top left hand corner * 1 = Food tool - Place food where you click * 2 = Agent tool - Place agent where you click * 3 = Thrust tool - Thrusts the agent clicked on by 2 * 4 = Wall tool - Place a new wall in the environment */ // coordinates of the mouse within the simulation environment int simMouseX = (int) ((float) (mouseX - offsetX) / zoomLevel); int simMouseY = (int) ((float) (mouseY - offsetY) / zoomLevel); if (!Utilities.isPointInBox(simMouseX, simMouseY, 0, 0, Environment.width, Environment.height)) return; // A wall has been placed -> add to the world if (PLACE_MODE) { PLACE_MODE = false; ArrayList<Wall> walls = env.getAllWalls(); Wall wl = walls.get(walls.size() - 1); wl.addToWorld(); return; } switch (mouseMode) { case 0: agent_clicked = getClickedAgent(agents, simMouseX, simMouseY); if (agent_clicked != null) { // agent was clicked so update selected selectedAgent = agent_clicked; } break; case 1: env.addSeaweed(new Point2D.Double(simMouseX, simMouseY)); break; case 2: int heading = (int) Math.floor(Math.random() * 360); env.addFish(new Point2D.Double(simMouseX, simMouseY), heading); break; case 3: agent_clicked = getClickedAgent(agents, simMouseX, simMouseY); if (agent_clicked != null) { // agent was clicked so update selected agent_clicked.thrust(2); } break; case 4: env.addWall( new Point2D.Double(simMouseX, simMouseY), new Point2D.Double(simMouseX, simMouseY)); PLACE_MODE = true; } }
public void mouseWheel(MouseWheelEvent event) { if (win.mouseWheel(event)) return; if (!Utilities.isPointInBox(mouseX, mouseY, 0, 0, draw_width, draw_height)) return; if (zoomLevel > minZoom || event.getWheelRotation() > 0) { zoomLevel = Math.max(minZoom, (zoomLevel + 0.1f * event.getWheelRotation())); offsetX -= (int) (((mouseX - offsetX) * (0.1f * event.getWheelRotation()))) / zoomLevel; offsetY -= (int) (((mouseY - offsetY) * (0.1f * event.getWheelRotation()))) / zoomLevel; } } // SIM_TICKS = (int) (slider.getValue() * SIM_TPS_MAX);
private void addNEATParamInput(String name, int offset) { UILabel label = new UILabel(this, 0, offset * 50, name); UITextField input = new UITextField(this, 0, offset * 50 + 20, 250, getNEATParam(name)); input.setEventHandler( new UIAction() { public void change(UITextField input) { setNEATParam(input.getName(), input.getText()); } }); input.setName(name); neatParams.addObject(label); neatParams.addObject(input); neatParamInputs.add(input); }
// lblSimTPS.setText("Ticks: " + SIM_TICKS); public void keyReleased() { // Hotkeys for buttons if (win.keyReleased()) return; if (!Utilities.isPointInBox(mouseX, mouseY, 0, 0, draw_width, draw_height)) return; switch (key) { case ('e'): mouseMode = 2; btnGroupModes.selectButton(btnAddAgent); break; case ('q'): mouseMode = 0; btnGroupModes.selectButton(btnSelectAgent); break; case ('r'): mouseMode = 3; btnGroupModes.selectButton(btnThrust); break; case ('w'): mouseMode = 1; btnGroupModes.selectButton(btnAddFood); break; case ('t'): mouseMode = 4; btnGroupModes.selectButton(btnAddWall); break; case ('s'): saveEnvironment(); break; case ('o'): restoreEnvironment(); break; case (' '): SIM_TICKS = (SIM_TICKS > 0 ? 0 : 1); sliderTPS.setValue(SIM_TICKS / SIM_TPS_MAX); lblSimTPS.setText("Ticks: " + SIM_TICKS); break; case ('a'): changeNeuralLayout(); break; } switch (keyCode) { case (UP): arrowsPressed[0] = false; break; case (DOWN): arrowsPressed[1] = false; break; case (LEFT): arrowsPressed[2] = false; break; case (RIGHT): arrowsPressed[3] = false; break; } }
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; }
// We are unsure whether the God will be a NeatGod or a HyperNeatGod. @SuppressWarnings("rawtypes") private void setupNEATParams() { neatParamInputs = new ArrayList<UITextField>(); godDrop = new UIDropdown<God>(this, 10, 10, 230, env.getAllGods()); godDrop.setEventHandler( new UIAction() { public void change(UIDropdown drop) { setAllNEATParams(); } }); for (int i = 0; i < neatParameters.length; i++) { addNEATParamInput(neatParameters[i], i + 1); } neatParams.addObject(godDrop); }
public void keyPressed() { // Hotkeys for buttons if (win.keyPressed()) return; if (!Utilities.isPointInBox(mouseX, mouseY, 0, 0, draw_width, draw_height)) return; switch (keyCode) { case (UP): arrowsPressed[0] = true; break; case (DOWN): arrowsPressed[1] = true; break; case (LEFT): arrowsPressed[2] = true; break; case (RIGHT): arrowsPressed[3] = true; break; } }
private void updateUI() { agentHeading.setVisible(selectedAgent != null); winStats.setVisible(selectedAgent != null); if (selectedAgent != null) { // agentHeading.setAngle(selectedAgent.getViewHeading()); agentHeading.setAgent(selectedAgent); if (env.fitnessOnly) { progHealth.setValue(selectedAgent.getFitness() / 10); progHealth.setColor( (int) (255 - 255 * selectedAgent.getFitness()), (int) (255 * selectedAgent.getFitness()), 0); } else { progHealth.setValue(selectedAgent.getHealth()); progHealth.setColor( (int) (255 - 255 * selectedAgent.getHealth()), (int) (255 * selectedAgent.getHealth()), 0); } sliderX.setValue((double) selectedAgent.getX() / Environment.width); sliderY.setValue((double) selectedAgent.getY() / Environment.height); lblX.setText("x = " + selectedAgent.getX()); lblY.setText("y = " + selectedAgent.getY()); lblHeading.setText( "heading = " + Math.round(selectedAgent.getViewHeading() * 100.0) / 100.0 + "°"); lblAngle.setText( "moving angle = " + Math.round(selectedAgent.getMovingAngle() * 100.0) / 100.0 + "°"); lblHealth.setText("fitness = " + Math.round(selectedAgent.getFitness() * 1000.0) / 1000.0); lblSpeed.setText("speed = " + Math.round((selectedAgent.getMovingSpeed() / 1000)) + " m/s"); // lblX.setText("Selected agent see = "+selectedAgent.getCanSee().size()+ " "+tmp, 10, 70); // lblX.setText("Selected agent see food (seg 0)= // "+selectedAgent.viewingObjectOfTypeInSegment(0, SightInformation.TYPE_FOOD), 10, 85); } }
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); } }); }
public void mouseDragged() { if (win.mouseDragged()) return; }
public void mouseReleased() { if (win.mouseReleased()) return; }
private UILabel addStatLabel(String value, int pos) { UILabel lbl = new UILabel(this, 10, pos, value); winStats.addObject(lbl); return lbl; }