Point changing for some reason

I am creating a 2d game and want to add a feature so that the “cell” kinda floats around in the area from where it spawned. I am trying to get the original location from where it was spawned, but it keeps changing. I have nothing mentioning it or setting it other than when I set it’s spawn in the constructor. Does anyone see why it is changing?

Cell Class:


public class Cell extends Entity{
	
	private Random random;
	
	private CellType cellType;
	private Point spawn;
	
	private int angle;
	private float xVelocity, yVelocity;
	private float maxVelocity = .2f;
	
	public Cell(Point location) {
		random = new Random();
		
		cellType = MasterGame.cellTypes.get(random.nextInt(MasterGame.cellTypes.size()));
		width = MasterGame.cellSizes.get(cellType);
		height = width;
		this.spawn = location;
		super.location = location;
	}
	
	int ticks = 0;
	public void tick() {
		if(ticks == 15) {
			angle = random.nextInt(360);
			xVelocity = (float) (maxVelocity * Math.cos(angle));
			yVelocity = (float) (maxVelocity * Math.sin(angle));
			ticks = 0;
		} 
		if(ticks % 3 == 0){
			System.out.println(spawn);
			location.x += xVelocity;
			location.y += yVelocity;
		}
		ticks++;
	}
	
	public void render(Graphics g) {
		g.drawImage(Assets.cell, location.x, location.y, width, height, null);
	}
	
}

And here is the Entity Class that Cell extends


public abstract class Entity {
	
	protected int width, height;
	
	protected Point location;
	protected CellType cellType;

	abstract void tick();
	abstract void render(Graphics g);
	
	public int getWidth() {
		return width;
	}
	public int getHeight() {
		return height;
	}
	public Point getLocation() {
		return location;
	}
	public CellType getCellType() {
		return cellType;
	}
	
}

public Cell(Point location)

Java passes references, and Point is a mutable type.
Any changes (outside this class) made to the Point instance that you pass into the constructor will alter the value returned by Entity#getLocation().

A superficial way of fixing this would be to replace:

super.location = location;

with:

super.location = new Point(location)

There’s a 2nd problem with your code; your Entity class has a protected member:

protected Celltype cellType

while your Cell subclass has a private member of the same name.

So the assignment in your Cell constructor:

cellType = MasterGame.cellTypes.get(random.nextInt(MasterGame.cellTypes.size()));

…is assigning a value to the member Cell#cellType.

While the Entity method:

   public CellType getCellType() {
      return cellType;
   }

…will be returning Entity#cellType.

I doubt this is what you intend.

Java actually passes by value, it never passes by reference.

It may look like it passes by reference but it is actually by value.

This doesn’t change the answer though.

I didn’t say it passes by reference; I said it “passes references”, and yes, it passes references by value.

However, this is semantic complexity that is entirely beyond the level of understanding demonstrated by the OP, hence why I avoided the topic.

Out of curiosity, how would you ever pass a reference without passing the value of the reference? At some point, you are always going to pass a value.

If it is pass by reference, everything you do to the reference should be reflected everywhere, if you decide to set the reference to a new object, the original object will be changed to.


public static void main(String[] args) {
	MyObject ref = new MyObject();
	ref.a = "nope, not pass by reference";
	System.out.println(ref.a); //if pass by reference, this should print out "yep, pass by reference"
}

public void test(MyObject ref) {
	ref = new MyObject();
   ref.a = "yep, pass by reference";
}

True pass by reference should set the object to be be the new object created, but because its pass by value the original object is still what it was when it was created in the main.

You would pass by reference in C++ by using &.

@Phased: You never actually called the test() function. I think you meant something more like this:

public static void main(String[] args) {
   MyObject ref = new MyObject();
   ref.a = "nope, not pass by reference";
   test(ref);
   System.out.println(ref.a); //if pass by reference, this should print out "yep, pass by reference"
}

public static void test(MyObject ref) {
   ref = new MyObject();
   ref.a = "yep, pass by reference";
}

Note that the test() function also has to be made static to be called from the main() method.

oops, yep, I wrote it while talking to 2 people and trying to play a game at the same time.

I don’t know how I missed calling test(ref); I swear I typed it, maybe I deleted it when I tried to rewrite it to make it more clear.

Heh, no problem. I like a simpler example anyway:


public class ReferenceTest{
   public static void main(String... args){
      Integer i = 1;
      change(i);
      System.out.println(i);
   }

   public static void change(Integer i){
      i = 2;
   }
}

I did it as an object as in Java people are more likely to say primitives are passed by value and objects are passed by reference.

So some code failing a pass by reference for an object makes them realise their mistake.

I can’t count the number of times I’ve seen this discussion in different forums, complete with the line that’s bound to confuse any newcomer (references in Java are passed by value). It’s a confusing and roundabout way of saying that Java classes are ‘reference types’, built-in types are ‘value types’, and function arguments are ‘passed by value’. The nature of the types needs to be distinguished from the nature of how the instances are handed off in function calls.

The thing that finally made it click for me was this article on variables: http://www.javaranch.com/campfire/StoryCups.jsp

And its follow-up on passing by value: http://www.javaranch.com/campfire/StoryPassBy.jsp

I highly recommend reading these (in order) for anybody who is still confused about passing by value.