Java, как две переменные указывают на один и тот же примитивный объект - PullRequest
0 голосов
/ 02 сентября 2018

Я пишу платформенную игру на Java, в которой есть различные игровые объекты, такие как платформы, игрок и (в конце концов) враги. Я описываю положение этих игровых объектов с помощью прямоугольников: x position, y position, width и height. Тем не менее, я также хотел бы добавить другие переменные для описания позиции: слева, сверху, справа и снизу. Для последних двух я знаю, что мне нужно будет менять их всякий раз, когда x, y, width или height изменяются, но так как левый и верхний такие же, как x и y, мне было интересно, как я могу заставить их указывать на одно и то же значение как х и у. Я думаю, что это можно сделать в C с помощью функции #define, но, к сожалению, это Java, а не C.

Как я могу получить два разных имени переменных, чтобы они указывали на одно и то же значение в Java, чтобы при изменении одного изменялось и другое?

Редактировать: вот основы моего класса GameObject:

 public abstract class GameObject {
    protected float x;
    protected float y;

    protected float right;
    protected float bottom;
    protected float width;
    protected float height;

    public float getX() {
        return x;
    }

    public float getY() {
        return y;
    }

    public void setX(float x) {
        this.x = x;
        right=this.x+width;
    }

    public void setY(float y) {
        this.y = y;
        bottom=this.y+height;
    }
    //A bunch of other getters/setters

    //Subclasses must have render (for displaying graphics) and tick (mainly for updating position) functions.
    public abstract void render(Graphics g);

    public abstract void tick();
}

Я хотел бы добавить еще две переменные:

protected float left = x;
protected float top = y;

и они относятся к тому же примитиву, что и x и y (не копировать примитивы). Это, по-видимому, не представляется возможным. Спасибо за ваши ответы!

Ответы [ 5 ]

0 голосов
/ 02 сентября 2018

Если вам действительно нужно что-то, что ведет себя как ссылка на примитив, вам нужно создать объект, содержащий это примитивное значение, а затем разделить объект "holder".

Однако я не думаю, что это лучший способ решить вашу проблему.

Насколько я понимаю, ваши игровые объекты могут быть полностью описаны с помощью переменных x, y, height и width. left, top, right и bottom, с другой стороны, являются значениями, которые могут быть получены из четырех основных.

На самом деле можно было бы иметь игровой объект, содержащий только x, y, height и width, и вычислять другие четыре значения вне объекта всякий раз, когда они необходимы. Такой объект может выглядеть так:

public class GameObject {
  private int x, y, height, width;

  public int getX() { return x; }
  public int getY() { return y; }
  public int getHeight() { return height; }
  public int getWidth() { return width; }

  public void setX(int x) { this.x = x; }
  public void setY(int y) { this.y = y; }
  public void setHeight(int height) { this.height = height; }
  public void setwidth(int width) { this.width = width; }
}

Обратите внимание, что фактические переменные private и доступны для чтения только через геттеры. Это помогает избежать использования ссылки на переменную в дальнейшем.

Теперь, чтобы иметь простой и уникальный способ доступа к left, top, right и bottom, в то время как вы могли бы добавить четыре переменные и синхронизировать их с четыре другие переменные уже присутствуют, я думаю, что это не лучший способ сделать это.

Я предлагаю вам просто вычислять их на лету внутри немного умнее, чем в среднем, геттеров. Это будет выглядеть так:

public class GameObject {
  // getters and setters omitted for brevity
  private int x, y, height, width;

  public int getLeft() {
    return x;
  }

  public int getRight() {
    // assuming x increase toward the right
    return x + width;
  }

  public int getTop() {
    return y
  }

  public int getBottom() {
    // assuming y increas toward the bottom
    return y + height;
  }
}

Это также поможет, если вам нужно создать некоторые специальные методы обновления, такие как moveRight(int delta), scale(double factor), поскольку вам нужно будет применять изменения только к базовым переменным, а не к значениям, производным от них.

0 голосов
/ 02 сентября 2018

Этого нельзя сделать на Java в том смысле, в каком вы это имеете в виду. У вас может быть две ссылки на объекты, которые указывают на один и тот же объект, но если у вас есть обычная примитивная переменная, они всегда различны и не ссылаются друг на друга. Вы можете сделать объектом для хранения примитива, иметь две разные ссылки на один и тот же объект, и изменение содержимого этого объекта через одну ссылку будет отражено в другой, но вы не сможете имеет int x и int y, где запись x = 10 составит y == 10.

0 голосов
/ 02 сентября 2018

Это легко сделать, создав новый класс. Java является объектно-ориентированным, поэтому, в основном, все о классах и их экземплярах. Взгляните на пример ниже:

class GameObject
{
     //Instance variables
     //(all objects of this class will have their own)
     int x;
     int y;
     int width;
     int height;

     //Constructor
     //(you call a constructor when creating a new object)
     GameObject(int x, int y, int width, int height)
     {
          //Here you are assigning the values received to the instance variables (marked with "this", that represents the current object)
          this.x = x;
          this.y = y;
          this.width = width;
          this.height = height;
     }

    //This method will return the ordinate ("y") of the object's top position (assuming the "y axis" points down)
    int getTop() {
        return (y - height/2);
    }
}

После создания класса GameObject вы можете создавать его экземпляры (объекты). Смотрите ниже:

GameObject player = new GameObject(0, 0, 50, 50); //creates a new object with coordinates (0,0), width = 50 and height = 50
GameObject enemy1 = new GameObject(30, 50, 100, 100);

//Getting the "x" position of the player and the monster
System.out.println("Player X = " + player.x);
System.out.println("Enemy1 X = " + enemy1.x);

//Get the top position "y" 
System.out.println("Player top = " + player.getTop());

//Change player's "y"
player.y = 10;

//Get player's top position again
System.out.println("Player top = " + player.getTop()); //it will have changed, since "y" was changed.

У Oracle действительно хороший урок о объектно-ориентированном программировании , вы должны проверить его здесь . Язык C структурирован, в то время как Java является объектно-ориентированной, это две разные парадигмы. Я надеюсь, что это помогло. Ура! * * 1013

0 голосов
/ 02 сентября 2018

В Java есть два типа переменных. 1. Примитивные типы 2. Типы ссылок

Вам необходимо использовать переменную ссылочного типа, если вы хотите ссылаться на один и тот же объект через разные переменные.

В вашем случае для игрового приложения эти параметры могут часто меняться. Таким образом, , если все значения времени , слева и сверху равны , совпадают с x и y, вы можете использовать одну переменную для представления обоих параметров, которые экономят память. например: для левой и х используйте одну переменную.

Или с использованием концепций Java OOP, Вы можете сделать эти параметры x, y, left, top приватными и назначить для них методы получения и установки.

public int setX(int x){
    this.x =x;
}

public setLeft(int left){
    this.left = left;
}

public int setY(int y){
    this.y =y;
}

public setTop(int top){
    this.top= top;
}

public setXnLeft(int xnleft){
    setX(xnleft);
    setleft(xnleft);
}

public setYnTop(int yntop){
    setY(yntop);
    setTop(yntop);
}
0 голосов
/ 02 сентября 2018

int / integer передается по значению, а не по ссылке в Java.

Вы можете определить новый класс, например,

public class Position {
     int x;
     int y;
}

Пусть две переменные указывают на один и тот же экземпляр Position.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...