Return object in method and use its functions

Hey folks,

I am trying to get interactions done in a little fisicia-based game of mine. Goal is a method/function, that returns the nearest type of objectType X (passed as an argument) in a given interaction distance (say the player can only interact with objects in a +/- 30/30 square box around him).

This method looks currently like this:

Object fetchNearestObject(String objectType) { //return coordinates of nearest object of type 'objectType' inside action radius 
  ArrayList nearestObjects = new ArrayList();
  while (nearestObjects.get(0).getClass().getSimpleName() != objectType ) {
    for (float extentX=0; extentX<=actionRadius; extentX++) {
      for (float extentY=0; extentY<=actionRadius; extentY++) {
        ArrayList temp1 = new ArrayList();
        ArrayList temp2 = new ArrayList();
        temp1 = world.getBodies((player.xPos + extentX), (player.yPos + extentY), true);
        temp2 = world.getBodies((player.xPos - extentX), (player.yPos - extentY), true);
        if (temp1.size() != 0) {
          for (int i=0; i<temp1.size(); i++) {
            if (temp1.get(i).getClass().getSimpleName() == objectType) {
              nearestObjects.add(temp1.get(i));
              println("Found " + temp1.get(i));
            }
          }
        }
        if (temp2.size() != 0) { 
          for (int i=0; i<temp2.size(); i++) {
            if (temp2.get(i).getClass().getSimpleName() == objectType) {
              nearestObjects.add(temp2.get(i));
              println("Found " + temp2.get(i));
            }
          }
        }
      }
    }
  }
  return nearestObjects.get(0);

As you can see, it returns an object type (am I doing this right? :thinking:)

Now I’m using this method call in other interaction functions, e.g. in the player method void climb

  void climb(String direction) {
    if (fetchNearestObject("Ladder").getClass().getSimpleName() == "Ladder") {// check if ladder is in range and center player according to ladder base/top
      if (fetchNearestObject("Ladder").topAnchor.get(1) >= this.yPos-actionRadius) {
        this.xPos = fetchNearestObject("Ladder").topAnchor.get(0);
      } else if (fetchNearestObject("Ladder").bottomAnchor.get(1) >= this.yPos+actionRadius) {
        this.xPos = fetchNearestObject("Ladder").bottomAnchor.get(0);
      }

      if (direction == "up") {
        yPos = yPos++;
      } else if (direction == "down") {
        yPos = yPos--;
      }
    }
  }

But it seems like JAVA doesn’t like this way of object passing (I am far from being a skilled JAVA developer; I know just the basics). The error raised is basically global variable topAnchor does not exist, same goes for any method like the getX()-function inherited to the “Ladder” class by fisica’s FBody class.

Hope you can help me with that - how can I access the methods and local variables of an object returned by my fetchNearestObject() function?

Kind regards from Germany
Yannik

Object is a Java keyword. Did you name your class Object as well? Not a good idea.

When your class has a decent name like ObjectTypeX and you want to return ObjectTypeX, tell processing that this is so:

ObjectTypeX fetchNearestObject(String objectType) {

Remark

By the way you can declare an ArrayList like this: ArrayList<ObjectTypeX> list = new ArrayList();

Remark

This

... .getSimpleName() != objectType

won’t work, you can’t use == with String.

Use equals instead

if  (  !  ... .getSimpleName().equals ( objectType ) )

Remark

        temp1 = world.getBodies((player.xPos + extentX), (player.yPos + extentY), true);
        temp2 = world.getBodies((player.xPos - extentX), (player.yPos - extentY), true);
        

I kind of understand what you are doing here but with using + and again + in the first line and - and - in the second, you would pick the right and down section with the first line, and the left and up section with the 2nd, but not the other 2 sections.

So either say

                             // minus 
for (float extentX= -actionRadius; extentX<=actionRadius; extentX++) {

OR look at dist() for the distance between object (center) and player (center)

Chrisir

1 Like

Hey Chrisir,
thanks for your reply.


I thought using Object as the method type would be sufficient as I cannot really predict what kind of object is being returned.

I have multiple classes (e.g. class Ladder, class Door, …), which all inherit from/extend to the primary class FBody (a native fisica-class).
Using FBody as the object type won’t work - and using the distinctive class type would void the idea of returning any object of the all possible classes (e.g. you could only return a Ladder object, if the method type is Ladder).

Is there any way to return any of my class objects? If you pass the String “Ladder” to the method, it should return a Ladder type, if you pass “Door”, it should return a Door type etc. - and if possible all inside one function.

Other idea would be: return a FBody with the fisica-function getBody() and only use the coordinates gathered before that. Toss them into the getBody() function. And return an FBody.


What do you mean with your second remark? Perhaps “can’t declare like this”?


Regarding the two nested for-loops: it should work as expected, since the first loop (extentX) starts at 0 and then all extentY-values from 0 - 30 (actionRadius) are checked (temp1) and then from -30 - 0). After this, the extentX gets incremented by 1 and the second for loop checks in both directions (again up 30 and down 30).
Generally speaking: start at the center x = player.xPos, check horizontally +30 and -30 from player.yPos. After that, do the same horizontal-check one x-step left and right of the player.xPos, then do the same two x-steps left and right of the player.xPos, … , do the same 30 x-steps left and right of the player.xPos
The result should be a fully covered square of 30 pixels in each direction.

The only “not-so-great-thing” about this idea is of course that you might fetch a false-positive nearest object by doing so. E.g. one object that is 30 pixels below the player, but shares the same xPos will be returned, while another object is just 1 pixel right next to the player in x-direction, but get’s ignored. But I could live with that; objects of the same kind won’t be that tightly spaced. ^^


Thanks for some tips (especially the equals()-method for strings :slight_smile:

Kind regards and thanks for your patience
Yannik

1 Like

I understand now what you mean.

Just stick with Object for the moment.

Upon instantiating each object from the class, you could pass its type as a String (or an integer) to the object: class Ladder , class Door … as myType

And then after getting the object from the function use switch(myType) {} to distinguish between the objects.


like this: ArrayList<ObjectTypeX> list = new ArrayList();


There are 4 quadrants surounding the point

try this:


PVector pv;


void setup() {
  size(1100, 900);
}

void draw() {
  background(0);

  float actionRadius = 130; 
  float playerxPos = width /2; 
  float playeryPos=height/2;

  noStroke(); 


  for (float extentX=0; extentX<=actionRadius; extentX++) {
    for (float extentY=0; extentY<=actionRadius; extentY++) {

      PVector temp1 = new PVector (playerxPos + extentX, playeryPos + extentY);
      PVector  temp2 = new PVector (playerxPos - extentX, playeryPos - extentY);

      fill(random(255), random(255), random(255));
      ellipse(temp1.x, temp1.y, 
        4, 4);

      ellipse(temp2.x, temp2.y, 
        4, 4);
    }
  }
}

Remark

You can use

        temp1 = world.getBodies((player.xPos + extentX), (player.yPos + extentY), true);// + + 
        temp2 = world.getBodies((player.xPos - extentX), (player.yPos - extentY), true); // - -
        temp1 = world.getBodies((player.xPos + extentX), (player.yPos - extentY), true); // + - 
        temp2 = world.getBodies((player.xPos - extentX), (player.yPos + extentY), true);  // -   +
            

OR just loop over all objects and check if dist() command gives you something < actionRadius. See reference

Remark

You return only the first item from the ArrayList… so you could check for the nearest or you could return from the function once you found ONE item (the first). Use command return.

Warm regards,

Chrisir

1 Like

Hey Chrisir,

could you ellaborate a bit further on your suggestion of using switch()?

I’m now circling over everything using “dist” (looks much cleaner :slight_smile:) - thanks for the visual explanation of my error in reasoning; I was quite sure that my method should have worked, but I admit defeat ^^).

I came up with a different approach to use different objects. Simply assign them a name (fortunately, FBody has a method to do so, setName) - where name represents the variable name storing the object - and then use the method to retrieve the object name needed to access the object’s private methods. Should work…

Warm regards
Yannik

1 Like

switch() is just another way of

if(typeObject.equals("Latter") 
{.....} 
 else if(typeObject.equals("bridge")
 {.....}

Thanks, I did a little search on my own and must admit - switch() has certainly some good use cases where it outperforms if-elif-else (or rather else-if; trying not to speak Pythonic in Java ^^), mainly in terms of code readability.

Thank you once more for your help, Chrisir :slight_smile:

1 Like