From 8e17b5a4c156a5e5902b0f2c2e64d52bacae9280 Mon Sep 17 00:00:00 2001 From: Enrico Fasoli Date: Fri, 3 Jul 2015 22:47:19 +0200 Subject: [PATCH] added frame limiter --- core/src/com/mygdx/game/Game.java | 9 ++++ core/src/logic/Action.java | 44 ++++++++++++++++++++ core/src/logic/Creature.java | 69 ++++++++++++++++++------------- core/src/logic/Vegetable.java | 4 +- core/src/logic/World.java | 26 +++++++++++- 5 files changed, 120 insertions(+), 32 deletions(-) create mode 100644 core/src/logic/Action.java diff --git a/core/src/com/mygdx/game/Game.java b/core/src/com/mygdx/game/Game.java index d5ed2d6..1a79d45 100644 --- a/core/src/com/mygdx/game/Game.java +++ b/core/src/com/mygdx/game/Game.java @@ -60,6 +60,15 @@ public class Game extends ApplicationAdapter { if (Gdx.input.isKeyJustPressed(Input.Keys.P)) { paused = !paused; } + if (Gdx.input.isKeyJustPressed(Input.Keys.L)) { + if (world.getFpsLimit() > 0) { + Log.log(Log.INFO, "Disabling FPS Limit"); + world.setFpsLimit(0); + } else { + Log.log(Log.INFO, "Setting FPS Limit to 60"); + world.setFpsLimit(60); + } + } // Draw Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); diff --git a/core/src/logic/Action.java b/core/src/logic/Action.java new file mode 100644 index 0000000..c5dcbf1 --- /dev/null +++ b/core/src/logic/Action.java @@ -0,0 +1,44 @@ +/* + * 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 logic; + +/** + * Represents a Action performed by an agent + * @author fazo + */ +public class Action { + private final Creature agent; + private final Element victim; + private final float damage; + + public Action(Creature agent, Element victim, float damage) { + this.agent = agent; + this.victim = victim; + this.damage = damage; + } + + public void apply(){ + if(victim instanceof Creature){ + Creature c = (Creature) victim; + c.setHp(c.getHp()-damage); + } else { + victim.setSize(victim.getSize()-damage); + } + } + + public Creature getAgent() { + return agent; + } + + public Element getVictim() { + return victim; + } + + public float getDamage() { + return damage; + } + +} diff --git a/core/src/logic/Creature.java b/core/src/logic/Creature.java index a495818..d2d8a8e 100644 --- a/core/src/logic/Creature.java +++ b/core/src/logic/Creature.java @@ -3,6 +3,7 @@ package logic; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.mygdx.game.Game; import com.mygdx.game.Log; +import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; import logic.neural.Brain; @@ -15,19 +16,19 @@ import logic.neural.Brain; public class Creature extends Element implements Runnable { public static final int default_radius = 20; - public static final float max_speed = 3, max_rot_speed = 0.05f; + public static final float max_speed = 3, max_rot_speed = 0.05f, max_beak = default_radius / 2; private Brain brain; - private float dir, hp, prevHp, speed, sightRange, fov, fitness, rotSpeed, beak; + private float dir, hp, speed, sightRange, fov, fitness, rotSpeed, beak, hpDiff; private boolean eating = false, killing = false, done = true; private Sight[] sights; private Thread thread; + private ArrayList actions; public Creature(float x, float y) { super(x, y, default_radius); dir = (float) (Math.random() * 2 * Math.PI); hp = 100; - prevHp = 100; speed = 0; rotSpeed = 0; sightRange = 350; @@ -35,6 +36,7 @@ public class Creature extends Element implements Runnable { fitness = 0; brain = new Brain(10, 5, 2, 10); sights = new Sight[2]; + actions = new ArrayList(); } @Override @@ -64,16 +66,16 @@ public class Creature extends Element implements Runnable { @Override public boolean update() { + actions.clear(); // apply hunger hp -= 0.3f; - prevHp = hp; if (hp < 0) { // Dead /* - Vegetable carcass = new Vegetable(getX(), getY()); - carcass.setSize(getSize()); - carcass.setDecayRate(0.01f); - Game.get().getWorld().add(carcass); - */ + Vegetable carcass = new Vegetable(getX(), getY()); + carcass.setSize(getSize()); + carcass.setDecayRate(0.01f); + Game.get().getWorld().add(carcass); + */ return false; } // take a look @@ -115,27 +117,27 @@ public class Creature extends Element implements Runnable { } } values[8] = eating || killing ? 1 : 0; - values[9] = prevHp > hp ? 1 : 0; + values[9] = hpDiff < 0 ? 1 : 0; // Compute brain - float[] actions = null; + float[] outputs = null; try { - actions = brain.compute(values); + outputs = brain.compute(values); } catch (Exception ex) { // Should not happen Logger.getLogger(Creature.class.getName()).log(Level.SEVERE, null, ex); } - Log.log(Log.DEBUG, "Accel: " + actions[0] + " RotClock: " + actions[1] + " RotAntiClock: " + actions[2] + " Beak: " + actions[3]); - speed = (actions[0] * 2 - actions[4] / 2) * max_speed; - rotSpeed = (actions[1] - actions[2]) / 3; + Log.log(Log.DEBUG, "Accel: " + outputs[0] + " RotClock: " + outputs[1] + " RotAntiClock: " + outputs[2] + " Beak: " + outputs[3]); + speed = (outputs[0] * 2 - outputs[4] / 2) * max_speed; + rotSpeed = (outputs[1] - outputs[2]) / 3; /*if (rotSpeed > max_rot_speed) { rotSpeed = max_rot_speed; } if (rotSpeed < -max_rot_speed) { rotSpeed = -max_rot_speed; }*/ - beak = actions[3]; - if (beak > default_radius * 3) { - beak = default_radius * 3; + beak = outputs[3] * max_beak; + if (beak > max_beak) { + beak = max_beak; } else if (beak < 0) { beak = 0; } @@ -146,6 +148,9 @@ public class Creature extends Element implements Runnable { * Applies the creature's desired movements to the world */ public void applyToWorld() { + for (Action a : actions) { + a.apply(); + } if (speed > max_speed) { speed = max_speed; } @@ -178,10 +183,10 @@ public class Creature extends Element implements Runnable { @Override public void render(ShapeRenderer s) { - if (prevHp > hp || killing) { + if (hpDiff < 0 || killing) { // Kill/BeKilled mark s.set(ShapeRenderer.ShapeType.Filled); - s.setColor(prevHp > hp ? 1 : 0, killing ? 1 : 0, 0, 1); + s.setColor(hpDiff < 0 ? 1 : 0, killing ? 1 : 0, 0, 1); s.circle(getX(), getY(), default_radius); s.set(ShapeRenderer.ShapeType.Line); } @@ -195,8 +200,8 @@ public class Creature extends Element implements Runnable { s.setColor(c0, c1, sights[0] == null && sights[1] == null ? 1 : 0, 1); s.circle((float) relX * getSize() * 0.6f + getX(), (float) relY * getSize() * 0.6f + getY(), 3); // Beak - s.setColor(beak / default_radius * 3, 1 - beak / default_radius * 3, 0, 1); - s.line((float) (relX * getSize() * 0.8f + getX()), (float) (relY * getSize() * 0.8f + getY()), (float) (relX * getSize() * (1.5f + beak / default_radius * 3) + getX()), (float) (relY * getSize() * (1.5f + beak / default_radius * 3) + getY())); + s.setColor(beak / max_beak, 1 - beak / max_beak, 0, 1); + s.line((float) (relX * getSize() * 0.8f + getX()), (float) (relY * getSize() * 0.8f + getY()), (float) (relX * getSize() * (1.5f + beak / max_beak) + getX()), (float) (relY * getSize() * (1.5f + beak / max_beak) + getY())); //FOV float degrees = fov * 180f / (float) Math.PI; float orient = dir * 180f / (float) Math.PI - degrees / 2; @@ -236,11 +241,12 @@ public class Creature extends Element implements Runnable { if (overlaps(e)) { eating = true; if (hp < 100) { - e.setSize(e.getSize() - 0.5f); - } - if (e.getSize() <= 0) { - e.setSize(0); + actions.add(new Action(this, e, 0.5f)); + //e.setSize(e.getSize() - 0.5f); } + /*if (e.getSize() <= 0) { + e.setSize(0); + }*/ hp++; fitness++; if (hp > 100) { @@ -282,13 +288,14 @@ public class Creature extends Element implements Runnable { // Check if attackable if (tempDist < beak && Math.abs(relAngle - ndir) < fov / 4) { // Attacking! - hp += beak / default_radius * 3; - fitness += 10; + hp += beak / max_beak; + fitness++; if (hp > 100) { hp = 100; } killing = true; - e.setHp(e.getHp() - beak / default_radius * 3); + actions.add(new Action(this, e, beak / max_beak)); + //e.setHp(e.getHp() - beak / max_beak); } } @@ -346,4 +353,8 @@ public class Creature extends Element implements Runnable { public Thread getThread() { return thread; } + + public ArrayList getActions() { + return actions; + } } diff --git a/core/src/logic/Vegetable.java b/core/src/logic/Vegetable.java index b20784d..71a7b8f 100644 --- a/core/src/logic/Vegetable.java +++ b/core/src/logic/Vegetable.java @@ -14,11 +14,11 @@ import com.mygdx.game.Game; */ public class Vegetable extends Element { - public static final int default_radius = 5; + public static final int default_radius = 10; private float decayRate = 0; public Vegetable(float x, float y) { - super(x, y, default_radius); + super(x, y, (float) (default_radius+(Math.random()*default_radius/2)-default_radius/2)); } @Override diff --git a/core/src/logic/World.java b/core/src/logic/World.java index 43a5575..961a2fe 100644 --- a/core/src/logic/World.java +++ b/core/src/logic/World.java @@ -9,6 +9,7 @@ import com.mygdx.game.Game; import com.mygdx.game.Log; import java.util.ArrayList; import java.util.Comparator; +import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; @@ -21,6 +22,7 @@ public class World implements Runnable { private final Comparator creatureComp; private final int width, height, nPlants, creatPerGen; private int generation = 1; + private float fpsLimit = 60; private boolean busy = true; public ArrayList elements; public ArrayList toAdd; @@ -51,10 +53,24 @@ public class World implements Runnable { @Override public void run() { + Date d; + long time; + float target; for (;;) { - // Add speed limiter here if (!Game.get().isPaused()) { + d = new Date(); update(); + if (fpsLimit > 0) { + time = new Date().getTime() - d.getTime(); + target = 1000 / fpsLimit; + if (time < target) { + try { + Thread.sleep((long) (target - time)); + } catch (InterruptedException ex) { + Logger.getLogger(World.class.getName()).log(Level.SEVERE, null, ex); + } + } + } } else { try { Thread.sleep(100); @@ -230,6 +246,14 @@ public class World implements Runnable { toAdd.add(e); } + public float getFpsLimit() { + return fpsLimit; + } + + public void setFpsLimit(float fpsLimit) { + this.fpsLimit = fpsLimit; + } + public ArrayList getElements() { return elements; }