Ashley ECS IteratingSystem not processing entity family - java

Somehow I cannot get the IteratingSystem to work. In the update I double check if there are entities, it returns more then 0. But that should mean that processEntity gets called on those but it never runs.
//...
import net.madmenyo.teststuff.AshleyTest.components.MovementComponent;
import net.madmenyo.teststuff.AshleyTest.components.PositionComponent;
//...
public class MovementSystem extends IteratingSystem {
private ComponentMapper<PositionComponent> pm;
private ComponentMapper<MovementComponent> mm;
public MovementSystem () {
super(Family.all(PositionComponent.class, MovementComponent.class).get());
pm = ComponentMapper.getFor(PositionComponent.class);
mm = ComponentMapper.getFor(MovementComponent.class);
}
#Override
public void processEntity (Entity entity, float deltaTime) {
System.out.println("Process moveSystem");
PositionComponent position = pm.get(entity);
MovementComponent movement = mm.get(entity);
position.x += movement.velocityX * deltaTime;
position.y += movement.velocityY * deltaTime;
}
#Override
public void update(float deltaTime) {
Engine engine = getEngine();
int count = engine.getEntitiesFor(Family.all(PositionComponent.class, MovementComponent.class).get()).size();
}
}
Afaik, for each count in the update method it should run ProcessEntity each time the engine is updated. Since update is called the engine is updated and since count > 0 it should be processing entities, yet it is never called. By inspecting the engine during runtime it also contains multiple entities for the family I define.

processEntity(...) is called by the parent update method which I wasn't calling. Easy fix once I looked at it again, I just leave it here in case.
#Override
public void update(float deltaTime) {
super.update(deltaTime); // <-- call parent update
}

Related

Command based Java: Accessing a method from a subsystem in a command (Java)

this is my first time using Java and I seem to be stuck. I'm trying to access a method (getHeading) from a subsystem (DriveTrain) in a command (DriveStraight), but I keep getting the error that "the type getHeading(double) is undefined for the type Subsystem" when I try heading = Robot.DriveTrain.getHeading();. This is the command:
public class DriveStraight extends Command {
private double speed;
private double duration;
private double heading;
public DriveStraight(float driveSpeed, float duration) {
requires(Robot.DriveTrain);
**heading = Robot.DriveTrain.getHeading();**
}
// Called just before this Command runs the first time
protected void initialize() {
setTimeout(duration);
}
// Called repeatedly when this Command is scheduled to run
protected void execute() {
**float currentheading = Robot.DriveTrain.getHeading();**
Robot.DriveTrain.arcadeDrive(speed, (heading - currentheading) * 0.08);
}
And this is the subsystem:
public class DriveTrain extends Subsystem {
AnalogGyro gyro;
RobotDrive drive;
VictorSP frontLeftMotor, rearLeftMotor, frontRightMotor, rearRightMotor;
public DriveTrain() {
frontLeftMotor = new VictorSP(RobotMap.frontLeftMotor);
rearLeftMotor = new VictorSP(RobotMap.rearLeftMotor);
frontRightMotor = new VictorSP(RobotMap.frontRightMotor);
rearRightMotor = new VictorSP(RobotMap.rearRightMotor);
gyro = new AnalogGyro(RobotMap.analogGyro);
gyro.setSensitivity(0.00666);
gyro.calibrate();
}
public void arcadeDrive(float speed, float turn) {
drive.arcadeDrive(OI.joy.getRawAxis(OI.LEFT_Y_AXIS),
OI.joy.getRawAxis(OI.RIGHT_X_AXIS), true);
}
public void tankDrive(float leftValue, float rightValue) {
drive.tankDrive(OI.joy.getRawAxis(OI.LEFT_Y_AXIS),
OI.joy.getRawAxis(OI.RIGHT_Y_AXIS), true);
}
public double getHeading() {
return gyro.getAngle();
}
protected void initDefaultCommand() {
arcadeDrive(0, 0);
}
}
I just came from using C++ so I think I might be trying to use pointers, but I'm not sure. So what's the right way to call a method from a subsystem?
Thanks,
Sethra53
You're not managing an instance of Robot.DriveTrain anywhere - all your method calls on the DriveTrain class are being seen by the compiler as calls to static methods (which don't relate to an object, only to the class). The nearest matching method you have defined anywhere is public double getHeading() {, which is an instance method and so should be called on an instance. There are 4 places in your code which are referring to Robot.DriveTrain and I'm not sure what your requires method is doing so it's tricky to know what you should be passing to it. The other three places, however, should be referring to instances of Robot.DriveTrain.
e.g.
public class DriveStraight extends Command {
private double speed;
private double duration;
private double heading;
private Robot.DriveTrain driveTrain;
public DriveStraight(float driveSpeed, float duration) {
requires(Robot.DriveTrain);
driveTrain = new Robot.DriveTrain() // create new shared instance
heading = driveTrain.getHeading(); // use instance.
}
// Called just before this Command runs the first time
protected void initialize() {
setTimeout(duration);
}
// Called repeatedly when this Command is scheduled to run
protected void execute() {
float currentheading = driveTrain.getHeading(); // use instance created in constructor.
driveTrain.arcadeDrive(speed, (heading - currentheading) * 0.08);
}
...
I can't guarantee any of that will 'work' however, without understanding how the requires method call works.
A better approach would be to pass the instance in to the DriveStraight constructor...
public class DriveStraight extends Command {
private Robot.DriveTrain driveTrain;
public DriveStraight(float driveSpeed, float duration, DriveTrain driveTrain) {
this.driveTrain = driveTrain; // use instance created elsewhere
...

calling a helper method for parent's constructor with fields defined in child

I am having a problem instantiating a child object using its parent constructor. The constructor calls its helper method but I want the variables used in that method to be child's fields.
I'm not sure this makes sense, so I put simplified version of the classes below. Basically it's a simple Java program that simulates air traffic. As the program handles several types of plane, a parent class (Plane) was created along with some children classes that correspond to each type. At the moment a Factory class (PlaneFactory) is used to generate a one of the types of plane depending on a probability.
When a plane is created, an id and timestamp are assigned. Another thing which needs to be done is to set its remaining fuel time. This is done in the helper method, generateInitialFuelTime() which is called in the Plane constructor. The method returns a random number between min and max values. Each type of planes has different min and max values, so when generateProbability() is called, I wanted it to make it use minFuelTime and maxFuelTime values defined as fields in children class but it seems to be looking at its parent's at the moment (which is null).
I thought about making generateInitialFuelTime() or setting minFuelTime & maxFuelTime values as parameters of the constructor, but not quite sure if it's the best way.
PlaneFactory class:
public class PlaneFactory {
public Plane getPlane(int id, Time time){
Plane plane = null;
double probability = generateProbability();
if (0.5 > probability) {
plane = new Type1Plane();
} else if (0.2 > probability) {
plane = new Type2Plane();
}
return plane;
}
private double generateProbability() {
// This method returns a probability between 0 and 1
}
}
Plane class (Parent class):
public class Plane{
protected int id;
protected Time initialRemainingFuelTime;
protected Time initializedTime;
protected int minFuelTime;
protected int maxFuelTime;
public Parent(int id, Time currentTime) {
this.id = id;
initializedTime = currentTime;
initialFuelTime = generateInitialFuelTime();
}
protected Time generateInitialFuelTime() {
Random r = new Random();
int min = getMinFuelTime().getMinute() + 1;
int range = getMaxFuelTime().getMinute() - getMinFuelTime().getMinute();
int initialFuelTime = r.nextInt(min) + range;
return new Time (0, randomMinute , 0);
}
protected Time getMinFuelTime() {
return minFuelTime;
}
protected Time getMaxFuelTime() {
return maxFuelTime;
}
Type1Plane class (Child class):
public class Type1Plane extends Plane{
private int minFuelTime = new Time(0, 20, 0) // 20 minute
private int maxFuelTime = new Time(0, 40, 0) // 40 minute
public Type2Plane (int id, Time currentTime) {
super(id, currentTime);
}
}
Type2Plane class (Child class):
public class Type2Plane extends Plane{
private int minFuelTime = new Time(0, 10, 0) // 10 minute
private int maxFuelTime = new Time(0, 20,0) // 20 minute
public Type2Plane (int id, Time currentTime) {
super(id, currentTime);
}
}
Let me know if you have a good solution for this problem. Thank you for your time.
Simply override getMinFuelTime and getMaxFuelTime in your child classes, as such:
public class Type1Plane extends Plane{
private Time minFuelTime = new Time(0, 20, 0) // 20 minute
private Time maxFuelTime = new Time(0, 40, 0) // 40 minute
public Type2Plane (int id, Time currentTime) {
super(id, currentTime);
}
protected Time getMinFuelTime() {
return minFuelTime;
}
protected Time getMaxFuelTime() {
return maxFuelTime;
}
}
And the same goes for Type2Plane.
Now, if Plane class should never be instantiated on its own, then make it abstract and the get methods as well (and remove the variables):
public abstract class Plane{
protected int id;
protected Time initialRemainingFuelTime;
protected Time initializedTime;
public Parent(int id, Time currentTime) {
this.id = id;
initializedTime = currentTime;
initialFuelTime = generateInitialFuelTime();
}
protected Time generateInitialFuelTime() {
Random r = new Random();
int min = getMinFuelTime().getMinute() + 1;
int range = getMaxFuelTime().getMinute() - getMinFuelTime().getMinute();
int initialFuelTime = r.nextInt(min) + range;
return new Time (0, randomMinute , 0);
}
protected abstract Time getMinFuelTime();
protected abstract Time getMaxFuelTime();
}
By the way, please note that there seems to be some inconsistency with your variables, you treat Time variables as int or vise-versa.
You need to override getMinFuelTime and getMaxFuelTime methods in the child classes.
Since subclasses are initialized after parent class you can't rely on fields of a subclass in a superclass constructor.
What you can do is provide a custom behavior through an abstract method, so basically
private int minFuelTime = new Time(0,20,0);
protected Time getMinFuelTime() { return minFuelTime; }
becomes:
class Planet {
protected abstract Time getMinFuelTime();
}
class Type1Plane extends Planet {
#Override
protected Time getMinFuelTime() { return new Time(0,20,0); }
}
This is allowed since at this point there is no "missing hole" that need to be initialized by the subclass since the implementation will be present in any case when initializing the parent.

Should I use an anonymous inner class to simulate 'out' parameters in Java?

I'm still a relative newbie when it comes to Java, coming mainly from a C# background.
I was discussing the lack of 'out' parameters in Java methods with a colleague and how to work around this. He suggested creating a structure/class to hold the various parameters and passing it back.
Sometimes this feels 'wrong' to me - especially if I have a special method that I want to use to return a subset of parameters from a larger class.
So I wondered about using anonymous inline classes instead to achieve this. Code sample below.
Is this a sensible approach? Just wondering what the perceived wisdom is on this.
public class MyClass {
Patient myPatient = null;
// An interface to enable us to return these variables in a single call
public interface VitalStatsResponse { public void returnStats(int bloodPressure, int heartRate); }
public class Patient {
int bloodPressure = 100;
int heartRate = 280;
// Lots of other variables here
public void calculateVitalStats(VitalStatsResponse response)
{
response.returnStats((bloodPressure * 2), (heartRate / 10) ;
}
}
public void doWork()
{
// We want the patient's blood pressure and heart rate returned by a single method call, so use an anonymous inline class
myPatient.calculateVitalStats(new VitalStatsResponse() {
#Override
public void returnStats(int bloodPressure, int heartRate) {
// Handle returned variables here
}
});
}
}
I would go for the simple solution of creating a VitalStats object. If you need the VitalStatus of a patient, then VitalStats is a concept in your application that can be represented as an Object.
public class VitalStatus {
final int bloodPressure;
final int heartRate;
public VitalStats(int bloodPressure, int heartRate) {
this.bloodPressure = bloodPressure;
this.heartRate = heartRate;
}
}
public class Patient {
int bloodPressure = 100;
int heartRate = 280;
// Other variables
public VitalStatus getVitalStatus() {
return new VitalStats(bloodPressured * 2, heartRate / 2);
}
}
Out params is a procedural solution for return times. Java primarily fits the Object Oriented paradigm of programming and as such don't be afraid to make objects. This fits with the S in SOLID if your class is doing a lot of complex things see if you can break it down into smaller more manageable pieces.
I would also use "class to hold the parameters" over "inline anonymous inner class"
public class MyClass implements VitalStatsResponse{
Patient myPatient = null;
private ArrayList<VitalStatsResponse> response;
void MyClass(ArrayList<VitalStatsResponse> response) {
this.response = response;
}
public class Patient {
int bloodPressure = 100;
int heartRate = 280;
// Lots of other variables here
public void calculateVitalStats()
{
for(int i = 0; i < response.length; i++) {
// call returnStats method of every registered callback
response.get(i).returnStats((bloodPressure * 2), (heartRate / 10) ;
}
}
}
// any client can register/unregister callback via these methods
void registerResponse(VitalStatsResponse response) {
this.response.add(response);
}
void unRegisterResponse(VitalStatsResponse response) {
this.response.remove(response);
}
public void doWork()
{
// We want the patient's blood pressure and heart rate returned by a single method call, so use an anonymous inline class
myPatient.calculateVitalStats();
}
public void returnStats(int bloodPressure, int heartRate) {
// implement the body according to this class requirement
}
}

How can I access a class other than though passing in a method?

Let us say we have a class called World. Which contains a class called Data. We also have a third class called Input. If Input.clicked(Event event, int x, int y) were to be called I would not be able to access World which means I can't access Data. How do you go about resolving this?
Another way to ask this might be: How can you access something in a method from another class that can't be changed when what you need to access is not final?
Sorry, I am having a hard time explaining this.
Update bit: The world class already exists, can't create a new one. It would be inside the Game class.
Here is a code example, not working code. More pseudo.
public class World {
Data data = new Data();
Input input = new Input();
public void update(float delta) {
input.getInput();
input.makeChangesBasedOnInput();
}
public void render(float delta) {
}
}
public class Data {
public int importantNumber; // Static is not an option
// For me I have to get a user name... but same idea here
public Data() {
Random ran = new Random();
importantNumber = ran.nextInt(1000);
}
}
public class Input {
Button button = new Button();
public Input() { // passing the World class does not work, ex. public Input(World world) {
button.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) { // I can't add world here...
// HERE IS ISSUE
System.out.println(World.Data.importantNumber);
}
}
}
public void getInput() {
// MAGIC
}
public void makeChangesBasedOnInput() {
// MAGIC
}
}
Update 2: Here is another example of what I am trying to do with TextButton & ClickListener from libgdx.
statsButton is a TextButton() from libgdx.
You say passing the World class does not work, well that is probably because you tried to acces a local variable from anonymous function, example:
public Input(World world) {
button.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
// error: world is not final
System.out.println(world.data.importantNumber);
}
}
}
this is what probably happened (if not, please let me know). In Java 8, world would be effectivly final, but in Java 7 or earlier, you would have to declare it final explicitly, like
public Input(final World world) { ... }
Also a common approach is to store your world inside a field:
private World world;
public Input(World world) {
this.world = world;
...
}

JBox2D Body Was There, Now it's null?

A strange bug I can't track down. I've implemented a ContactListener class for handling collisions in my Android game. In the beginContact(Contact arg0) method I can see that the two bodies in arg0 is there, and pushed onto a stack. Right after calling world.step() I run my own handleCollisions() method, where I pop off the Contact objects and do some game logic. However, occasionally when I pop off a Contact, one or both of its bodies are null.
The Contact goes in the stack with its bodies there, but it comes out with null bodies. I don't know why this is occurring, and more importantly, I can't find when this is occurring. To my knowledge, none of my code elsewhere is removing the bodies, but then again there could be side effects I'm unaware of. It doesn't help that this doesn't always happen. Typically it occurs when there's several collisions occurring.
Anyone have any ideas on what might remove the bodies? Or, does anyone know of a way to track the bodies to determine when they become null?
Below is some code which may or may not be helpful:
public class ConcreteContactListener implements ContactListener
{
private Stack<Contact> contacts;
public ConcreteContactListener()
{
contacts = new Stack<Contact>();
}
#Override
public void beginContact(Contact arg0)
{
contacts.push(arg0);
System.out.println("push: " + arg0.m_fixtureA.m_body);
}
public int handleCollisions(ArrayList<Ball> balls, World world, ArrayList<Ball> smears, SoundEffects sfx, Combos combos)
{
int score = 0;
while (!contacts.isEmpty())
{
Contact contact = contacts.pop();
System.out.println("Contact: " + contact.m_fixtureA.m_body);
int a = -1;
int b = -1;
for (int i = 0; i < balls.size(); i++)
{
System.out.println("Ball: " + balls.get(i).getBody());
if (contact.m_fixtureA.m_body.equals(balls.get(i).getBody()))
a = i;
else if (contact.m_fixtureB.m_body.equals(balls.get(i).getBody()))
b = i;
}
...
}
}
Contacts are pooled and re-used, so I would not recommend using this approach. Instead I would buffer only the information you need (which is probably the two bodies). The jbox2d testbed handles it this way:
First we have a contact point:
public class ContactPoint {
public Fixture fixtureA;
public Fixture fixtureB;
public final Vec2 normal = new Vec2();
public final Vec2 position = new Vec2();
public PointState state;
}
And then we listen like so:
public void beginContact(Contact contact) {
}
public void endContact(Contact contact) {
}
public void postSolve(Contact contact, ContactImpulse impulse) {
}
private final PointState[] state1 = new PointState[Settings.maxManifoldPoints];
private final PointState[] state2 = new PointState[Settings.maxManifoldPoints];
private final WorldManifold worldManifold = new WorldManifold();
public void preSolve(Contact contact, Manifold oldManifold) {
Manifold manifold = contact.getManifold();
if (manifold.pointCount == 0) {
return;
}
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
Collision.getPointStates(state1, state2, oldManifold, manifold);
contact.getWorldManifold(worldManifold);
for (int i = 0; i < manifold.pointCount
&& pointCount < MAX_CONTACT_POINTS; i++) {
ContactPoint cp = points[pointCount];
cp.fixtureA = fixtureA;
cp.fixtureB = fixtureB;
cp.position.set(worldManifold.points[i]);
cp.normal.set(worldManifold.normal);
cp.state = state2[i];
++pointCount;
}
}
This would probably be a bit overkill for your purposes, as it executes this logic for every single contact. Instead you can use the beginContact() and endContact() methods and buffer something a little more optimized with your game, like just storing the colliding bodies or something.

Categories