1
0
mirror of https://github.com/fazo96/AIrium.git synced 2025-04-20 01:38:38 +02:00

added frame limiter

This commit is contained in:
Enrico Fasoli 2015-07-03 22:47:19 +02:00
parent 03b3eeb442
commit 8e17b5a4c1
5 changed files with 120 additions and 32 deletions

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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<Action> 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<Action>();
}
@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<Action> getActions() {
return actions;
}
}

View File

@ -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

View File

@ -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<Creature> creatureComp;
private final int width, height, nPlants, creatPerGen;
private int generation = 1;
private float fpsLimit = 60;
private boolean busy = true;
public ArrayList<Element> elements;
public ArrayList<Element> 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<Element> getElements() {
return elements;
}