diff --git a/README.md b/README.md
index 12200b5..86bdaed 100644
--- a/README.md
+++ b/README.md
@@ -22,9 +22,8 @@ Visis the [releases page](https://github.com/fazo96/AIrium/releases) to download
### Controls
-- __+__ and __-__ control the zoom of the camera
-- __arrow keys__ allow you to move the camera
-- The __Configuration__ page in the GUI will let you tweak more!
+- The __Configuration__ page in the GUI will let you tweak many parameters and pause the simulation
+- You can drag with the mouse to move the camera and zoom with the mouse wheel
## Development
diff --git a/core/src/com/mygdx/game/Game.java b/core/src/com/mygdx/game/Game.java
index 35462dd..047dc84 100644
--- a/core/src/com/mygdx/game/Game.java
+++ b/core/src/com/mygdx/game/Game.java
@@ -3,6 +3,7 @@ package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
+import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
@@ -20,10 +21,60 @@ public class Game extends ApplicationAdapter {
private float cameraSpeed = 15;
private BitmapFont font;
private boolean paused = false;
+ private InputProcessor input;
@Override
public void create() {
game = this;
+ input = new InputProcessor() {
+
+ @Override
+ public boolean keyDown(int i) {
+ return true;
+ }
+
+ @Override
+ public boolean keyUp(int i) {
+ return true;
+ }
+
+ @Override
+ public boolean keyTyped(char c) {
+ return true;
+ }
+
+ @Override
+ public boolean touchDown(int i, int i1, int i2, int i3) {
+ return true;
+ }
+
+ @Override
+ public boolean touchUp(int i, int i1, int i2, int i3) {
+ return true;
+ }
+
+ @Override
+ public boolean touchDragged(int i, int i1, int i2) {
+ renderer.translate(Gdx.input.getDeltaX(), -Gdx.input.getDeltaY(), 0);
+ return true;
+ }
+
+ @Override
+ public boolean mouseMoved(int i, int i1) {
+ return true;
+ }
+
+ @Override
+ public boolean scrolled(int i) {
+ if (i>0) {
+ renderer.scale(0.5f, 0.5f, 1);
+ } else {
+ renderer.scale(1.5f, 1.5f, 1);
+ }
+ return true;
+ }
+ };
+ Gdx.input.setInputProcessor(input);
renderer = new ShapeRenderer();
renderer.setAutoShapeType(true);
overlayRenderer = new ShapeRenderer();
@@ -45,47 +96,6 @@ public class Game extends ApplicationAdapter {
@Override
public void render() {
- // Controls
- if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
- world.launchNewGen();
- }
- if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
- renderer.translate(-cameraSpeed, 0, 0);
- }
- if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
- renderer.translate(cameraSpeed, 0, 0);
- }
- if (Gdx.input.isKeyPressed(Input.Keys.UP)) {
- renderer.translate(0, -cameraSpeed, 0);
- }
- if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
- renderer.translate(0, cameraSpeed, 0);
- }
- if (Gdx.input.isKeyJustPressed(Input.Keys.PLUS)) {
- renderer.scale(0.5f, 0.5f, 1);
- }
- if (Gdx.input.isKeyJustPressed(Input.Keys.MINUS)) {
- renderer.scale(1.5f, 1.5f, 1);
- }
- if (Gdx.input.isKeyJustPressed(Input.Keys.P)) {
- paused = !paused;
- }
- if (Gdx.input.isKeyJustPressed(Input.Keys.L)) {
- if (world.getFpsLimit() == 60) {
- world.setFpsLimit(0);
- } else {
- world.setFpsLimit(60);
- }
- }
- if (Gdx.input.isButtonPressed(Input.Buttons.RIGHT)) {
- renderer.translate(Gdx.input.getDeltaX(), Gdx.input.getDeltaY() * -1, 0);
- }
- /*
- // Broken for now
- if(Gdx.input.isButtonPressed(Input.Buttons.LEFT)){
- // TODO: project coordinates to world
- world.selectCreatureAt(Gdx.input.getX(), Gdx.input.getY());
- }*/
// Draw
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
diff --git a/core/src/com/mygdx/game/Log.java b/core/src/com/mygdx/game/Log.java
index c3222b1..3bbab07 100644
--- a/core/src/com/mygdx/game/Log.java
+++ b/core/src/com/mygdx/game/Log.java
@@ -28,6 +28,7 @@ public class Log {
for (LogListener l : logListeners) {
l.onLog(level, msg);
}
+ System.out.println(msg);
}
}
diff --git a/core/src/com/mygdx/game/Serializer.java b/core/src/com/mygdx/game/Serializer.java
new file mode 100644
index 0000000..22ea4f2
--- /dev/null
+++ b/core/src/com/mygdx/game/Serializer.java
@@ -0,0 +1,111 @@
+package com.mygdx.game;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Hangles File I/O for AIrium components.
+ *
+ * @author fazo
+ */
+public class Serializer {
+
+ public static void saveToFile(File f, String content) {
+ PrintWriter fw = null;
+ try {
+ fw = new PrintWriter(f);
+ } catch (IOException ex) {
+ Log.log(Log.ERROR, ex.getMessage());
+ }
+ fw.print(content);
+ fw.flush();
+ fw.close();
+ }
+
+ public static String loadFromFile(File f) {
+ String s, a = "";
+ try {
+ BufferedReader bf = new BufferedReader(new FileReader(f));
+ while ((s = bf.readLine()) != null) {
+ a += s+"\n";
+ }
+ } catch (Exception e) {
+ Log.log(Log.ERROR, e.getMessage());
+ System.out.println(e+"");
+ }
+ return a;
+ }
+
+ public static String serializeBrain(float brainMap[][][]) {
+ String s = "# Neural Map for use with AIrium.\n"
+ + "# More information at http://github.com/fazo96/AIrium\n"
+ + "Layers: " + (brainMap.length+1);
+ s += "\nInput Neurons: " + brainMap[0][0].length;
+ s += "\n# Layer 1 Skipped because it's the input layer.";
+ // layers (input layer not included in brain map)
+ for (int i = 0; i < brainMap.length; i++) {
+ s += "\nLayer " + (i + 2) + " has " + brainMap[i].length + " neurons";
+ for (int j = 0; j < brainMap[i].length; j++) { // neurons
+ s += "\nWeights for Layer " + (i + 2) + " Neuron " + (j + 1) + " = ";
+ for (int z = 0; z < brainMap[i][j].length; z++) { // connections
+ s += brainMap[i][j][z] + " ";
+ }
+ }
+ }
+ return s;
+ }
+
+ public static float[][][] loadBrain(String s) {
+ float brainMap[][][] = null;
+ Log.log(Log.INFO,"Loading brain from String with "+s.split("\n").length+" lines:\n"+s);
+ for (String l : s.split("\n")) {
+ l = l.trim();
+ if (l.isEmpty() || l.startsWith("#")) {
+ // Skip comment
+ } else if (l.startsWith("Layers: ")) {
+ // Set Layer number
+ int layers = Integer.parseInt(l.split(" ")[1]) - 1;
+ brainMap = new float[layers][][];
+ Log.log(Log.INFO, "Loaded NLayers: " + layers);
+ } else if (l.startsWith("Input Neurons")) {
+ int in = Integer.parseInt(l.split(" ")[2]);
+ brainMap[0] = new float[in][0];
+ Log.log(Log.INFO, "Loaded NInputNeurons: " + in);
+ } else if (l.startsWith("Layer ")) {
+ // Set neuron number for given layer
+ String ll[] = l.split(" ");
+ int layer = Integer.parseInt(ll[1]) - 2;
+ int n = Integer.parseInt(ll[3]);
+ brainMap[layer] = new float[n][];//[layer>0?brainMap[layer-1].length:0];
+ } else if (l.startsWith("Weights ")) {
+ // Set weights
+ String ll[] = l.split(" ");
+ int layer = Integer.parseInt(ll[3]) - 2;
+ int neuron = Integer.parseInt(ll[5]) - 1;
+ int nWeights = ll.length - 7;
+ brainMap[layer][neuron] = new float[nWeights];
+ if(layer == 0){
+ Log.log(Log.INFO, "This weightmap is for brains with "+(nWeights)+" input neurons.");
+ } else if (nWeights != brainMap[layer - 1].length) {
+ Log.log(Log.ERROR, "WRONG WEIGHT NUMBER: prev layer has "
+ + brainMap[layer - 1].length + " neurons, but only "
+ + (nWeights)
+ + " weights are supplied to this neuron");
+ }
+ for (int i = 7; i < ll.length; i++) {
+ brainMap[layer][neuron][i - 7] = Float.parseFloat(ll[i]);
+ Log.log(Log.INFO,"Loading L"+layer+"N"+neuron+"W"+(i-7)+" = "+brainMap[layer][neuron][i-7]);
+ }
+ Log.log(Log.INFO, "Loaded " + (nWeights) + " Weights for Layer " + layer + " Neuron " + neuron);
+ }
+ }
+ return brainMap;
+ }
+}
diff --git a/core/src/logic/World.java b/core/src/logic/World.java
index 6fe3dbe..e42866a 100644
--- a/core/src/logic/World.java
+++ b/core/src/logic/World.java
@@ -348,15 +348,15 @@ public class World implements Runnable {
}
}
- private void spawnVegetable() {
+ public void spawnVegetable() {
spawn(false, null);
}
- private Creature spawnCreature() {
+ public Creature spawnCreature() {
return (Creature) spawn(true, null);
}
- private Creature spawnCreature(float[][][] b) {
+ public Creature spawnCreature(float[][][] b) {
return (Creature) spawn(true, b);
}
diff --git a/core/src/logic/neural/Brain.java b/core/src/logic/neural/Brain.java
index d7b12b9..0df0a4d 100644
--- a/core/src/logic/neural/Brain.java
+++ b/core/src/logic/neural/Brain.java
@@ -34,28 +34,13 @@ public class Brain {
initialize();
}
- /**
- * Create a new brain using given brain map (mind)
- *
- * @param brainMap the brain map (mind) to use
- */
- public Brain(float[][][] brainMap) {
- neurons = new Neuron[brainMap.length][];
- for (int i = 0; i < brainMap.length; i++) { // for each layer
- neurons[i] = new Neuron[brainMap[i].length];
- for (int j = 0; j < brainMap[i].length; j++) { // for each neuron
- neurons[i][j] = new Neuron(i, bias, this, brainMap[i][j]);
- }
- }
- }
-
/**
* Apply a new brain map (mind) to this brain
*
* @param brainMap the new brain map to apply
*/
public void remap(float[][][] brainMap) {
- for (int i = 0; i < brainMap.length; i++) { // for each layer
+ for (int i = 0; i < brainMap.length; i++) { // for each layer (skip input)
for (int j = 0; j < brainMap[i].length; j++) { // for each neuron
// skip input layer
if (neurons[i + 1][j] == null) {
@@ -103,9 +88,11 @@ public class Brain {
float nr = neurons[i][j].compute();
// Draw neuron links
float[] links = neurons[i][j].getWeights();
- for (int f = 0; f < links.length; f++) {
- s.setColor(links[f] < 0 ? links[f] / 2 * -1 : 0, links[f] > 0 ? links[f] / 2 : 0, 0, 1);
- s.line(i * sepX + offset, j * sepY + offset, (i - 1) * sepX + offset, f * sepY + offset);
+ if (links != null) {
+ for (int f = 0; f < links.length; f++) {
+ s.setColor(links[f] < 0 ? links[f] / 2 * -1 : 0, links[f] > 0 ? links[f] / 2 : 0, 0, 1);
+ s.line(i * sepX + offset, j * sepY + offset, (i - 1) * sepX + offset, f * sepY + offset);
+ }
}
// Draw neuron
s.setColor(1 - nr, nr, 0, 1);
diff --git a/core/src/logic/neural/Neuron.java b/core/src/logic/neural/Neuron.java
index ce390da..e56c204 100644
--- a/core/src/logic/neural/Neuron.java
+++ b/core/src/logic/neural/Neuron.java
@@ -76,6 +76,7 @@ public class Neuron {
* @return the output of this neuron.
*/
public float compute() {
+ if(weights == null || weights.length == 0) isInputNeuron = true;
if (isInputNeuron) {
return output;
}
diff --git a/desktop/src/gui/GUI.form b/desktop/src/gui/GUI.form
index eadfe07..a02b405 100644
--- a/desktop/src/gui/GUI.form
+++ b/desktop/src/gui/GUI.form
@@ -89,9 +89,6 @@
-
-
-
@@ -174,7 +171,7 @@
-
+
@@ -228,35 +225,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -496,7 +464,7 @@
-
+
@@ -810,6 +778,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/desktop/src/gui/GUI.java b/desktop/src/gui/GUI.java
index a621da3..f9df7d2 100644
--- a/desktop/src/gui/GUI.java
+++ b/desktop/src/gui/GUI.java
@@ -11,7 +11,9 @@ import com.mygdx.game.Game;
import com.mygdx.game.Listener;
import com.mygdx.game.Log;
import com.mygdx.game.Log.LogListener;
+import com.mygdx.game.Serializer;
import java.awt.Desktop;
+import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
@@ -19,7 +21,10 @@ import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javafx.stage.FileChooser;
+import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
+import logic.Creature;
/**
*
@@ -80,8 +85,6 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
logTextArea = new javax.swing.JTextArea();
jLabel1 = new javax.swing.JLabel();
logLevelBox = new javax.swing.JComboBox();
- jScrollPane2 = new javax.swing.JScrollPane();
- creatureList = new javax.swing.JList();
jPanel1 = new javax.swing.JPanel();
fpsLimitSlider = new javax.swing.JSlider();
jLabel3 = new javax.swing.JLabel();
@@ -129,6 +132,11 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
jLabel12 = new javax.swing.JLabel();
nMutatedConnectionsSlider = new javax.swing.JSlider();
currentNMutatedConnections = new javax.swing.JLabel();
+ jPanel3 = new javax.swing.JPanel();
+ jScrollPane2 = new javax.swing.JScrollPane();
+ creatureList = new javax.swing.JList();
+ saveBrainBtn = new javax.swing.JButton();
+ loadBrainBtn = new javax.swing.JButton();
status = new javax.swing.JLabel();
menuBar = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
@@ -143,7 +151,6 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("AIrium");
setMinimumSize(new java.awt.Dimension(700, 700));
- setPreferredSize(new java.awt.Dimension(700, 700));
logTextArea.setEditable(false);
logTextArea.setColumns(20);
@@ -178,7 +185,7 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
logPaneLayout.setVerticalGroup(
logPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(logPaneLayout.createSequentialGroup()
- .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 490, Short.MAX_VALUE)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 567, Short.MAX_VALUE)
.addGap(10, 10, 10)
.addGroup(logPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
@@ -188,21 +195,6 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
tabs.addTab("Log", logPane);
- creatureList.setModel(new javax.swing.AbstractListModel() {
- String[] strings = { "No creatures" };
- public int getSize() { return strings.length; }
- public Object getElementAt(int i) { return strings[i]; }
- });
- creatureList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
- creatureList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
- public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
- creatureListValueChanged(evt);
- }
- });
- jScrollPane2.setViewportView(creatureList);
-
- tabs.addTab("Creatures", jScrollPane2);
-
fpsLimitSlider.setMinimum(1);
fpsLimitSlider.setSnapToTicks(true);
fpsLimitSlider.setToolTipText("The maximum amount of ticks per second the simulation is allowed to compute");
@@ -598,7 +590,7 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(drawViewCones)
.addComponent(drawSightLines))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 41, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 71, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(pauseButton)
.addComponent(jButton1))
@@ -607,6 +599,58 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
tabs.addTab("Settings", jPanel1);
+ creatureList.setModel(new javax.swing.AbstractListModel() {
+ String[] strings = { "No creatures" };
+ public int getSize() { return strings.length; }
+ public Object getElementAt(int i) { return strings[i]; }
+ });
+ creatureList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
+ creatureList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
+ public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
+ creatureListValueChanged(evt);
+ }
+ });
+ jScrollPane2.setViewportView(creatureList);
+
+ saveBrainBtn.setText("Save");
+ saveBrainBtn.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ saveBrainBtnActionPerformed(evt);
+ }
+ });
+
+ loadBrainBtn.setText("Load");
+ loadBrainBtn.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ loadBrainBtnActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
+ jPanel3.setLayout(jPanel3Layout);
+ jPanel3Layout.setHorizontalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jScrollPane2)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(saveBrainBtn)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(loadBrainBtn)
+ .addContainerGap(587, Short.MAX_VALUE))
+ );
+ jPanel3Layout.setVerticalGroup(
+ jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel3Layout.createSequentialGroup()
+ .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 569, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(saveBrainBtn)
+ .addComponent(loadBrainBtn))
+ .addContainerGap())
+ );
+
+ tabs.addTab("Creatures", jPanel3);
+
status.setText("Simulation stopped");
javax.swing.GroupLayout containerLayout = new javax.swing.GroupLayout(container);
@@ -816,14 +860,14 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
currentMaxTicks.setText(maxTicksSlider.getValue() + "");
currentHpDecay.setText(hpDecaySlider.getValue() / 1000f + "");
currentSightRange.setText(sightRangeSlider.getValue() + "");
- options.put("nMutatedBrains", (float) nMutatedBrainsSlider.getValue()/100);
- currentNMutatedBrains.setText(String.format("%.2f", (float) nMutatedBrainsSlider.getValue()/100)+"%");
- options.put("nMutatedNeurons", (float) nMutatedNeuronsSlider.getValue()/100);
- currentNMutatedNeurons.setText(String.format("%.2f", (float) nMutatedNeuronsSlider.getValue()/100)+"%");
- options.put("nMutatedConnections", (float) nMutatedConnectionsSlider.getValue()/100);
- currentNMutatedConnections.setText(String.format("%.2f", (float) nMutatedConnectionsSlider.getValue()/100)+"%");
- options.put("mutationFactor", (float) mutationFactorSlider.getValue()/100);
- currentMutationFactor.setText(String.format("%.2f", (float) mutationFactorSlider.getValue()/100));
+ options.put("nMutatedBrains", (float) nMutatedBrainsSlider.getValue() / 100);
+ currentNMutatedBrains.setText(String.format("%.2f", (float) nMutatedBrainsSlider.getValue() / 100) + "%");
+ options.put("nMutatedNeurons", (float) nMutatedNeuronsSlider.getValue() / 100);
+ currentNMutatedNeurons.setText(String.format("%.2f", (float) nMutatedNeuronsSlider.getValue() / 100) + "%");
+ options.put("nMutatedConnections", (float) nMutatedConnectionsSlider.getValue() / 100);
+ currentNMutatedConnections.setText(String.format("%.2f", (float) nMutatedConnectionsSlider.getValue() / 100) + "%");
+ options.put("mutationFactor", (float) mutationFactorSlider.getValue() / 100);
+ currentMutationFactor.setText(String.format("%.2f", (float) mutationFactorSlider.getValue() / 100));
if (game != null) {
game.getWorld().reloadOptions();
}
@@ -837,20 +881,6 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
Log.setLogLevel(logLevelBox.getSelectedIndex());
}//GEN-LAST:event_logLevelBoxItemStateChanged
- private void creatureListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_creatureListValueChanged
- if (game == null) {
- creatureList.setSelectedIndex(-1);
- } else {
- try {
- if (creatureList.getSelectedIndex() >= 0) {
- Game.get().getWorld().selectCreature(Game.get().getWorld().getCreatures().get(creatureList.getSelectedIndex()));
- }
- } catch (IndexOutOfBoundsException ex) {
- JOptionPane.showMessageDialog(this, "This creature is not available");
- }
- }
- }//GEN-LAST:event_creatureListValueChanged
-
private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
if (desktop != null) {
@@ -957,6 +987,49 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
updateSettings();
}//GEN-LAST:event_nMutatedConnectionsSliderStateChanged
+ private void creatureListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_creatureListValueChanged
+ if (game == null) {
+ creatureList.setSelectedIndex(-1);
+ } else {
+ try {
+ if (creatureList.getSelectedIndex() >= 0) {
+ Game.get().getWorld().selectCreature(Game.get().getWorld().getCreatures().get(creatureList.getSelectedIndex()));
+ }
+ } catch (IndexOutOfBoundsException ex) {
+ JOptionPane.showMessageDialog(this, "This creature is not available");
+ }
+ }
+ }//GEN-LAST:event_creatureListValueChanged
+
+ private void saveBrainBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveBrainBtnActionPerformed
+ game.setPaused(true);
+ updateGUI();
+ if (game.getWorld().getSelectedCreature() == null) {
+ JOptionPane.showMessageDialog(this, "Please select a creature first");
+ return;
+ }
+ JFileChooser fc = new JFileChooser();
+ File f = null;
+ if (fc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
+ f = fc.getSelectedFile();
+ } else return;
+ Serializer.saveToFile(f, Serializer.serializeBrain(game.getWorld().getSelectedCreature().getBrain().getMap()));
+ }//GEN-LAST:event_saveBrainBtnActionPerformed
+
+ private void loadBrainBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadBrainBtnActionPerformed
+ game.setPaused(true);
+ updateGUI();
+ JFileChooser fc = new JFileChooser();
+ File f = null;
+ if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
+ f = fc.getSelectedFile();
+ } else return;
+ float map[][][] = Serializer.loadBrain(Serializer.loadFromFile(f));
+ Creature c = (Creature) game.getWorld().spawnCreature(map);
+ game.getWorld().selectCreature(c);
+ updateGUI();
+ }//GEN-LAST:event_loadBrainBtnActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel container;
private javax.swing.JSlider corpseDecaySlider;
@@ -1001,8 +1074,10 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
private javax.swing.JMenuItem jMenuItem1;
private javax.swing.JMenuItem jMenuItem2;
private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel3;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
+ private javax.swing.JButton loadBrainBtn;
private javax.swing.JComboBox logLevelBox;
private javax.swing.JPanel logPane;
private javax.swing.JTextArea logTextArea;
@@ -1017,6 +1092,7 @@ public class GUI extends javax.swing.JFrame implements LogListener, Listener {
private javax.swing.JSlider nPlantsSlider;
private javax.swing.JToggleButton pauseButton;
private javax.swing.JMenuItem pauseMenuButton;
+ private javax.swing.JButton saveBrainBtn;
private javax.swing.JSlider sightRangeSlider;
private javax.swing.JMenuItem startButton;
private javax.swing.JLabel status;