From f60469bbdfe49f175be9d038536ab0bb86845b79 Mon Sep 17 00:00:00 2001 From: Enrico Fasoli Date: Mon, 6 Jul 2015 17:40:18 +0200 Subject: [PATCH] Fixed brain renderer and implemented creature list in GUI --- core/src/com/mygdx/game/Game.java | 8 +- core/src/com/mygdx/game/Listener.java | 17 + core/src/logic/World.java | 29 +- core/src/logic/neural/Brain.java | 14 +- core/src/logic/neural/Neuron.java | 11 +- desktop/src/gui/GUI.form | 32 ++ desktop/src/gui/GUI.java | 456 ++++++++++++++------------ 7 files changed, 334 insertions(+), 233 deletions(-) create mode 100644 core/src/com/mygdx/game/Listener.java diff --git a/core/src/com/mygdx/game/Game.java b/core/src/com/mygdx/game/Game.java index 01f442f..486dbcb 100644 --- a/core/src/com/mygdx/game/Game.java +++ b/core/src/com/mygdx/game/Game.java @@ -96,20 +96,20 @@ public class Game extends ApplicationAdapter { } } catch (ConcurrentModificationException ex) { } + renderer.setColor(0.3f, 0.3f, 0.3f, 1); + // draw borders + renderer.rect(0, 0, world.getWidth(), world.getHeight()); if (world.getSelectedCreature() != null) { // There is a selection Creature c = world.getSelectedCreature(); renderer.setColor(1, 1, 1, 1); // Draw selection rectangle - renderer.rect(c.getX() - c.getSize() / 2, c.getY() - c.getSize() / 2, c.getX() + c.getSize() / 2, c.getY() + c.getSize() / 2); + renderer.rect(c.getX() - c.getSize() / 2, c.getY() - c.getSize() / 2, c.getSize(), c.getSize()); // Draw brain overlayRenderer.begin(); c.getBrain().render(overlayRenderer); overlayRenderer.end(); } - renderer.setColor(0.3f, 0.3f, 0.3f, 1); - // draw borders - renderer.rect(0, 0, world.getWidth(), world.getHeight()); renderer.end(); } diff --git a/core/src/com/mygdx/game/Listener.java b/core/src/com/mygdx/game/Listener.java new file mode 100644 index 0000000..52a275f --- /dev/null +++ b/core/src/com/mygdx/game/Listener.java @@ -0,0 +1,17 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.mygdx.game; + +/** + * + * @author Fazo + */ +public interface Listener { + + public static int FPS_CHANGED = 0, CREATURE_LIST_CHANGED = 1; + + public void on(int event); +} diff --git a/core/src/logic/World.java b/core/src/logic/World.java index 05df2ba..2933d84 100644 --- a/core/src/logic/World.java +++ b/core/src/logic/World.java @@ -6,6 +6,7 @@ package logic; import com.mygdx.game.Game; +import com.mygdx.game.Listener; import com.mygdx.game.Log; import java.util.ArrayList; import java.util.Comparator; @@ -30,7 +31,7 @@ public class World implements Runnable { private final ArrayList graveyard; private final ArrayList plants; private final ArrayList deadPlants; - private final ArrayList fpsListeners; + private final ArrayList listeners; public World(int width, int height) { this.width = width; @@ -43,7 +44,7 @@ public class World implements Runnable { plants = new ArrayList(); deadPlants = new ArrayList(); graveyard = new ArrayList(); - fpsListeners = new ArrayList(); + listeners = new ArrayList(); selected = null; newGen(true); } @@ -62,9 +63,7 @@ public class World implements Runnable { if (now.getTime() - timekeeper.getTime() > 1000) { fps = frames; frames = 0; - for (FpsListener f : fpsListeners) { - f.fpsChanged(fps); - } + fire(Listener.FPS_CHANGED); timekeeper = new Date(); } if (fpsLimit > 0) { @@ -106,7 +105,9 @@ public class World implements Runnable { elements.removeAll(deadPlants); plants.removeAll(deadPlants); deadPlants.clear(); - creatures.removeAll(graveyard); + if (creatures.removeAll(graveyard)) { + fire(Listener.CREATURE_LIST_CHANGED); + } if (creatures.isEmpty()) { // All dead, next gen newGen(false); @@ -176,6 +177,7 @@ public class World implements Runnable { ne.getBrain().mutate(0.05f); // mutate children } graveyard.clear(); + fire(Listener.CREATURE_LIST_CHANGED); generation++; } } @@ -218,11 +220,6 @@ public class World implements Runnable { } } - public interface FpsListener { - - public abstract void fpsChanged(int newValue); - } - public void selectCreatureAt(int x, int y) { selected = null; // Clear selection try { @@ -236,6 +233,12 @@ public class World implements Runnable { } } + public void fire(int eventCode) { + for (Listener f : listeners) { + f.on(eventCode); + } + } + private void spawnVegetable() { spawn(false, null); } @@ -260,8 +263,8 @@ public class World implements Runnable { return generation; } - public void addFpsListener(FpsListener f) { - fpsListeners.add(f); + public void addListener(Listener f) { + listeners.add(f); } public void add(Element e) { diff --git a/core/src/logic/neural/Brain.java b/core/src/logic/neural/Brain.java index ec56023..6b992a0 100644 --- a/core/src/logic/neural/Brain.java +++ b/core/src/logic/neural/Brain.java @@ -88,6 +88,7 @@ public class Brain { * @param s the ShapeRenderer to use for the drawing */ public void render(ShapeRenderer s) { + int sepX = 100, sepY = 50, offset = 100; s.set(ShapeRenderer.ShapeType.Filled); int neuronHeight = 0; for (Neuron[] ns : neurons) { @@ -95,22 +96,20 @@ public class Brain { neuronHeight = ns.length; } } - s.rect(0, 0, neurons.length * 50, neuronHeight * 30); for (int i = 0; i < neurons.length; i++) { //s.set(ShapeRenderer.ShapeType.Line); for (int j = 0; j < neurons[i].length; j++) { // get neuron result first so cache system can kick in and save some calculations float nr = neurons[i][j].compute(); // Draw neuron links - float[] links = neurons[i][j].getInputs(); + float[] links = neurons[i][j].getWeights(); for (int f = 0; f < links.length; f++) { - s.setColor(links[f], links[f], links[f], 1); - s.line(i * 50, j * 30, (i - 1) * 50, f * 30); + 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); - s.set(ShapeRenderer.ShapeType.Filled); - s.circle(i * 50, j * 30, 15); + s.circle(i * sepX + offset, j * sepY + offset, 15); } } } @@ -130,7 +129,6 @@ public class Brain { for (int i = 0; i < values.length; i++) { neurons[0][i].setOutput(values[i]); } - clearCache(); } /** @@ -140,7 +138,7 @@ public class Brain { * result */ public float[] compute() { - //clearCache(); // unnecessary if already called when changing inputs + clearCache(); // unnecessary if already called when changing inputs float[] res = new float[neurons[neurons.length - 1].length]; for (int i = 0; i < neurons[neurons.length - 1].length; i++) { res[i] = neurons[neurons.length - 1][i].compute(); diff --git a/core/src/logic/neural/Neuron.java b/core/src/logic/neural/Neuron.java index cf6c5b6..cbee083 100644 --- a/core/src/logic/neural/Neuron.java +++ b/core/src/logic/neural/Neuron.java @@ -55,7 +55,9 @@ public class Neuron { if (isInputNeuron) { return output; } - if(cache.hasCachedOutput()) return cache.getCachedOutput(); + if (cache.hasCachedOutput()) { + return cache.getCachedOutput(); + } float a = bias * -1; // activation for (int i = 0; i < weights.length; i++) { if (cache.has(i)) { @@ -83,6 +85,11 @@ public class Neuron { return mutatedWeights; } + /** + * Broken, doesn't work for some reason. + * + * @return + */ public float[] getInputs() { float inputs[] = new float[weights.length]; for (int i = 0; i < inputs.length; i++) { @@ -99,7 +106,7 @@ public class Neuron { } return inputs; } - + public void setOutput(float output) { isInputNeuron = true; this.output = output; diff --git a/desktop/src/gui/GUI.form b/desktop/src/gui/GUI.form index c634f00..637bb6f 100644 --- a/desktop/src/gui/GUI.form +++ b/desktop/src/gui/GUI.form @@ -169,6 +169,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/desktop/src/gui/GUI.java b/desktop/src/gui/GUI.java index 145bb98..14dba00 100644 --- a/desktop/src/gui/GUI.java +++ b/desktop/src/gui/GUI.java @@ -1,206 +1,250 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package gui; - -import com.badlogic.gdx.backends.lwjgl.LwjglApplication; -import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; -import com.mygdx.game.Game; -import com.mygdx.game.Log; -import com.mygdx.game.Log.LogListener; -import logic.World; - -/** - * - * @author fazo - */ -public class GUI extends javax.swing.JFrame implements LogListener,World.FpsListener { - - private Game game; - private LwjglApplication app; - - /** - * Creates new form GUI - */ - public GUI() { - initComponents(); - setLocationRelativeTo(null); // Center the window - Log.addListener(this); - logTextArea.setText("Started GUI.\n"); - } - - /** - * This method is called from within the constructor to initialize the form. - * WARNING: Do NOT modify this code. The content of this method is always - * regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { - - container = new javax.swing.JPanel(); - tabs = new javax.swing.JTabbedPane(); - logPane = new javax.swing.JPanel(); - jScrollPane1 = new javax.swing.JScrollPane(); - logTextArea = new javax.swing.JTextArea(); - jLabel1 = new javax.swing.JLabel(); - logLevelBox = new javax.swing.JComboBox(); - status = new javax.swing.JLabel(); - menuBar = new javax.swing.JMenuBar(); - jMenu1 = new javax.swing.JMenu(); - startButton = new javax.swing.JMenuItem(); - exitButton = new javax.swing.JMenuItem(); - - setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); - setTitle("AIrium"); - - logTextArea.setEditable(false); - logTextArea.setColumns(20); - logTextArea.setLineWrap(true); - logTextArea.setRows(5); - logTextArea.setText("Started GUI."); - logTextArea.setWrapStyleWord(true); - jScrollPane1.setViewportView(logTextArea); - - jLabel1.setText("Log Level"); - - logLevelBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Errors Only", "Default", "Debug Mode" })); - logLevelBox.setSelectedIndex(1); - logLevelBox.setToolTipText(""); - logLevelBox.addItemListener(new java.awt.event.ItemListener() { - public void itemStateChanged(java.awt.event.ItemEvent evt) { - logLevelBoxItemStateChanged(evt); - } - }); - - javax.swing.GroupLayout logPaneLayout = new javax.swing.GroupLayout(logPane); - logPane.setLayout(logPaneLayout); - logPaneLayout.setHorizontalGroup( - logPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(logPaneLayout.createSequentialGroup() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(logLevelBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 404, Short.MAX_VALUE) - ); - logPaneLayout.setVerticalGroup( - logPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(logPaneLayout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) - .addGap(10, 10, 10) - .addGroup(logPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) - .addComponent(logLevelBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) - ); - - tabs.addTab("Log", logPane); - - status.setText("Simulation stopped"); - - javax.swing.GroupLayout containerLayout = new javax.swing.GroupLayout(container); - container.setLayout(containerLayout); - containerLayout.setHorizontalGroup( - containerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(tabs) - .addGroup(containerLayout.createSequentialGroup() - .addComponent(status) - .addGap(0, 0, Short.MAX_VALUE)) - ); - containerLayout.setVerticalGroup( - containerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(containerLayout.createSequentialGroup() - .addComponent(tabs) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(status)) - ); - - jMenu1.setText("File"); - - startButton.setText("Start"); - startButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - startButtonActionPerformed(evt); - } - }); - jMenu1.add(startButton); - - exitButton.setText("Exit"); - exitButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - exitButtonActionPerformed(evt); - } - }); - jMenu1.add(exitButton); - - menuBar.add(jMenu1); - - setJMenuBar(menuBar); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(container, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(container, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - ); - - pack(); - }// //GEN-END:initComponents - - private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitButtonActionPerformed - System.exit(0); - }//GEN-LAST:event_exitButtonActionPerformed - - private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonActionPerformed - if (game != null) { - return; - } - LwjglApplicationConfiguration.disableAudio = true; - LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); - config.height = 600; - config.width = 800; - config.resizable = false; - app = new LwjglApplication(game = new Game(), config); - game.getWorld().addFpsListener(this); - }//GEN-LAST:event_startButtonActionPerformed - @Override - public void onLog(int level, String msg) { - logTextArea.append(msg + "\n"); - setScrollBarToTheBottom(); - } - - public void setScrollBarToTheBottom() { - jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMaximum()); - } - - private void logLevelBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_logLevelBoxItemStateChanged - Log.setLogLevel(logLevelBox.getSelectedIndex()); - }//GEN-LAST:event_logLevelBoxItemStateChanged - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JPanel container; - private javax.swing.JMenuItem exitButton; - private javax.swing.JLabel jLabel1; - private javax.swing.JMenu jMenu1; - private javax.swing.JScrollPane jScrollPane1; - private javax.swing.JComboBox logLevelBox; - private javax.swing.JPanel logPane; - private javax.swing.JTextArea logTextArea; - private javax.swing.JMenuBar menuBar; - private javax.swing.JMenuItem startButton; - private javax.swing.JLabel status; - private javax.swing.JTabbedPane tabs; - // End of variables declaration//GEN-END:variables - - @Override - public void fpsChanged(int fps) { - status.setText("Generation: "+game.getWorld().getGeneration()+" FPS: "+fps); - } -} +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package gui; + +import com.badlogic.gdx.backends.lwjgl.LwjglApplication; +import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; +import com.mygdx.game.Game; +import com.mygdx.game.Listener; +import com.mygdx.game.Log; +import com.mygdx.game.Log.LogListener; +import javax.swing.JOptionPane; +import logic.World; + +/** + * + * @author fazo + */ +public class GUI extends javax.swing.JFrame implements LogListener, Listener { + + private Game game; + private LwjglApplication app; + + /** + * Creates new form GUI + */ + public GUI() { + initComponents(); + setLocationRelativeTo(null); // Center the window + Log.addListener(this); + logTextArea.setText("Started GUI.\n"); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + container = new javax.swing.JPanel(); + tabs = new javax.swing.JTabbedPane(); + logPane = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + 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(); + status = new javax.swing.JLabel(); + menuBar = new javax.swing.JMenuBar(); + jMenu1 = new javax.swing.JMenu(); + startButton = new javax.swing.JMenuItem(); + exitButton = new javax.swing.JMenuItem(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("AIrium"); + + logTextArea.setEditable(false); + logTextArea.setColumns(20); + logTextArea.setLineWrap(true); + logTextArea.setRows(5); + logTextArea.setText("Started GUI."); + logTextArea.setWrapStyleWord(true); + jScrollPane1.setViewportView(logTextArea); + + jLabel1.setText("Log Level"); + + logLevelBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Errors Only", "Default", "Debug Mode" })); + logLevelBox.setSelectedIndex(1); + logLevelBox.setToolTipText(""); + logLevelBox.addItemListener(new java.awt.event.ItemListener() { + public void itemStateChanged(java.awt.event.ItemEvent evt) { + logLevelBoxItemStateChanged(evt); + } + }); + + javax.swing.GroupLayout logPaneLayout = new javax.swing.GroupLayout(logPane); + logPane.setLayout(logPaneLayout); + logPaneLayout.setHorizontalGroup( + logPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(logPaneLayout.createSequentialGroup() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(logLevelBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 404, Short.MAX_VALUE) + ); + logPaneLayout.setVerticalGroup( + logPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(logPaneLayout.createSequentialGroup() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE) + .addGap(10, 10, 10) + .addGroup(logPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(logLevelBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + tabs.addTab("Log", logPane); + + creatureList.setModel(new javax.swing.AbstractListModel() { + String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; + public int getSize() { return strings.length; } + public Object getElementAt(int i) { return strings[i]; } + }); + creatureList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + creatureListValueChanged(evt); + } + }); + jScrollPane2.setViewportView(creatureList); + + tabs.addTab("Creatures", jScrollPane2); + + status.setText("Simulation stopped"); + + javax.swing.GroupLayout containerLayout = new javax.swing.GroupLayout(container); + container.setLayout(containerLayout); + containerLayout.setHorizontalGroup( + containerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(tabs) + .addGroup(containerLayout.createSequentialGroup() + .addComponent(status) + .addGap(0, 0, Short.MAX_VALUE)) + ); + containerLayout.setVerticalGroup( + containerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(containerLayout.createSequentialGroup() + .addComponent(tabs) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(status)) + ); + + jMenu1.setText("File"); + + startButton.setText("Start"); + startButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + startButtonActionPerformed(evt); + } + }); + jMenu1.add(startButton); + + exitButton.setText("Exit"); + exitButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + exitButtonActionPerformed(evt); + } + }); + jMenu1.add(exitButton); + + menuBar.add(jMenu1); + + setJMenuBar(menuBar); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(container, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(container, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + + pack(); + }// //GEN-END:initComponents + + private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitButtonActionPerformed + System.exit(0); + }//GEN-LAST:event_exitButtonActionPerformed + + private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonActionPerformed + if (game != null) { + return; + } + LwjglApplicationConfiguration.disableAudio = true; + LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); + config.height = 600; + config.width = 800; + config.resizable = false; + app = new LwjglApplication(game = new Game(), config); + game.getWorld().addListener(this); + setCreatureList(); + }//GEN-LAST:event_startButtonActionPerformed + @Override + public void onLog(int level, String msg) { + logTextArea.append(msg + "\n"); + setScrollBarToTheBottom(); + } + + @Override + public void on(int event) { + if (event == Listener.FPS_CHANGED) { + status.setText("Generation: " + game.getWorld().getGeneration() + " FPS: " + game.getWorld().getFps()); + } else if (event == Listener.CREATURE_LIST_CHANGED) { + setCreatureList(); + } + } + + private void setCreatureList() { + String list[] = new String[game.getWorld().getCreatures().size()]; + for (int i = 0; i < list.length; i++) { + list[i] = "Fitness: " + game.getWorld().getCreatures().get(i).getFitness(); + } + creatureList.setListData(list); + } + + public void setScrollBarToTheBottom() { + jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMaximum()); + } + + private void logLevelBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_logLevelBoxItemStateChanged + Log.setLogLevel(logLevelBox.getSelectedIndex()); + }//GEN-LAST:event_logLevelBoxItemStateChanged + + private void creatureListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_creatureListValueChanged + 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 + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel container; + private javax.swing.JList creatureList; + private javax.swing.JMenuItem exitButton; + private javax.swing.JLabel jLabel1; + private javax.swing.JMenu jMenu1; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JComboBox logLevelBox; + private javax.swing.JPanel logPane; + private javax.swing.JTextArea logTextArea; + private javax.swing.JMenuBar menuBar; + private javax.swing.JMenuItem startButton; + private javax.swing.JLabel status; + private javax.swing.JTabbedPane tabs; + // End of variables declaration//GEN-END:variables + +}