#java #object
#java #объект
Вопрос:
Я пишу игру, которая содержит лифты в качестве препятствия. Лифт появляется слева или справа от экрана и имеет случайный шанс быть восходящим лифтом или нисходящим лифтом. Это выглядит так:
public class Elevator extends WorldObject {
public static boolean ascending;
public Elevator(int screenHeight, int xPos) {
super(xPos, screenHeight, 0, 0);
ascending = new Random().nextBoolean();
}
static public boolean isAscending(){
return ascending;
}
}
WorldObject, из которого он расширяется, выглядит следующим образом:
public class WorldObject {
protected float posX;
protected float posY;
protected float velX, velY;
public float getPosX() {
return posX;
}
public void setPosX(float posX) {
this.posX = posX;
}
public float getPosY() {
return posY;
}
public void setPosY(float posY) {
this.posY = posY;
}
public float getVelX() {
return velX;
}
public void setVelX(float velX) {
this.velX = velX;
}
public float getVelY() {
return velY;
}
public void setVelY(float velY) {
this.velY = velY;
}
public WorldObject(float posX, float posY, float velX, float velY) {
this.posX = posX;
this.posY = posY;
this.velX = velX;
this.velY = velY;
}
}
Каждые 5 секунд будет создаваться лифт и добавляться в ArrayList из Elevator
s примерно так:
if (timeToElevator > 5.0f) {
timeToElevator = 0;
Elevator elevator = new Elevator((int) screenHeight, (int) generateElevatorXPos());
Sprite eSprite = new Sprite(elevatorTexture);
eSprite.setOrigin(0, 0);
elevators.add(elevator);
elevatorSprites.add(eSprite);
}
Затем я проверяю наличие столкновений в каждом лифте с плеером, удаляю его, если он выходит за пределы, и если ни одно из них не происходит, я обновляю положение объекта лифта:
public static void calculateElevatorCollisions() {
int counter = 0;
for (Iterator<Elevator> i = elevators.iterator(); i.hasNext(); ) {
Elevator item = i.next();
if (item.getPosY() < -100) {
//remove elevator
} else if (..collision..) {
//collision
} else {
item.setVelY(item.isAscending() ? -5 : 5);
item.setPosY(item.getVelY() item.getPosY());
elevatorSprites.get(counter).setPosition(item.getPosX(),
item.getPosY());
counter ;
}
Моя проблема заключается в том, что всякий раз, когда создается новый Elevator
, все текущие Elevator
s меняют свое направление на направление нового Elevator
. Итак, предположим, что у меня нарисованы два восходящих лифта, всякий раз, когда мой третий лифт создается для спуска, два других ранее восходящих лифта теперь поднимаются!
Что является причиной этого?
Комментарии:
1.
static
Поле является общим для всех объектов.
Ответ №1:
Это ваша проблема:
public static boolean ascending;
^^^^^^
static
означает «Это поле класса, которое является общим для всех объектов». Поэтому, если вы изменили поле из одного объекта, это будет замечено во всех объектах этого типа.
Удаление его для создания ascending
поля экземпляра означает, что каждый экземпляр Elevator
будет иметь свою собственную копию, которую он может изменять сам по себе, не изменяя копии других экземпляров.
Ответ №2:
Изменить
public static boolean ascending;
Для
public boolean ascending;
Когда вы устанавливаете переменную как статическую, это class
переменная, а не instance
переменная. Переменные класса — это переменные, которые являются общими для всего instances
объекта, тогда instance
как переменные специфичны для instance
объекта.
Ответ №3:
Поскольку я пока не могу комментировать (rep), я хочу сделать еще одно замечание:
Вы практикуете инкапсуляцию с использованием метода получения для возрастания, isAscending() ; однако поле, которое вы инкапсулируете public
, делает его доступным из всех областей.
Рекомендуется сохранять инкапсулированные поля private
.
Кроме того, кажется, что все только заявляют, что поле должно быть изменено на нестатическую переменную; однако метод по-прежнему статичен, хотя на самом деле это также метод экземпляра!
В результате необходимы изменения:
public static boolean ascending;
становится
private boolean ascending;
…и…
static public boolean isAscending()
становится
public boolean isAscending()