2016-09-02 2 views
1

У меня есть игра с некоторыми астероидными объектами в arraylist. Чтобы мой код был аккуратным и жестким, я хочу передать этот arraylist различным классам/методам. Я думал, что понял, но, видимо, нет. Здесь: Класс Level1 начинается с метода инициализации (init), который вызывает метод populateAsteroid в классе астероидов. Кроме того, класс Level1 содержит функцию обновления, которая пересекает астероидный арифалист и обновляет его. Все это прекрасно работает:Получение arraylist возвращает null

public class Level1 { 
    private Asteroid populateAsteroid 
    private Collision collision; 

    public void init() { 

    populateAsteroid = new Asteroid(); 
    // create and populate an arraylist with asteroid objects 
    populateAsteroid.populateAsteroid(1); 
    collision = new Collision(); 
    } 

    public void update() { 
    // get the arraylist 
    ArrayList<Asteroid> asteroidList = populateAsteroid.getAsteroidList(); 

    for(int i = 0; i < asteroidList.size(); i++) {   
     Asteroid a = asteroidList.get(i); 
     a.update(i); 
    } 
    collision.checkCollision(); 
    } 
} 


public class Asteroid {  
    public ArrayList<Asteroid> asteroidList; 

    public void populateAsteroid(int level) { 
    // if the arraylist is null, as when the function is called by init, create the array 
    if (asteroidList == null){ 
     asteroidList = new ArrayList<Asteroid>(); 
    } 

    for (int i = 1 + asteroidList.size(); i <= (asteroidsAtEachLevel[level]); i++){ 
     Asteroid a = new Asteroid(); 
     asteroidList.add(a); 
    } 
    } 

    public ArrayList<Asteroid> getAsteroidList() { 
     return asteroidList; 
    } 
} 

Однако, беда приходит в моем классе столкновения, вызванном с помощью функции обновления в классе Level1, который содержит метод checkCollision

public class Collision { 

    private Asteroid a; 

    public void checkCollision(){ 

    a = new Asteroid(); 
    // get the arraylist     
    ArrayList<Asteroid> asteroidList = a.getAsteroidList(); 

    if (asteroidList == null){ 
     System.out.println("null");} 
    } 
    ..."more code".... 

Список имеет нулевое значение, хотя я считаю, что я возвращаю arraylist идентично тому, как я это делаю в функции Level1.update. Это потому, что какой-то аррайалист не отображается, поскольку он создается из вызова класса Level1? Какие-либо предложения?

+1

Вы никогда не называете 'populateAsteroid'' '', поэтому список никогда не создается. – resueman

+1

Вы никогда не заполняете астероид, поэтому его список по-прежнему «null». Возможно, вы хотели использовать тот, который вы создали, в свой метод 'init()', вместо этого создавая новый (пустой) в 'checkCollision()'? – azurefrog

+0

Вы говорите 'a = новый Asteroid();' и затем вызываете 'a.getAsteroidList();', это не инициализирует список астероидов – Orin

ответ

1

Вы создаете новый Asteroid в своем классе Collision, который не инициализируется. Вместо этого вы должны передать экземпляр вашего ранее инициализированного астероида в класс.

Например:

public class Level1 { 

    private Asteroid populateAsteroid 
    private Collision collision; 

    public void init() { 

     populateAsteroid = new Asteroid(); 
     // create and populate an arraylist with asteroid objects 
     populateAsteroid.populateAsteroid(1); 
     collision = new Collision(populateAsteroid); //Pass in the reference to the asteroid. 

} 

и

public class Collision { 

private Asteroid a; 

public void checkCollision(Asteroid rock){ 

    a = rock; 
    // get the arraylist     
    ArrayList<Asteroid> asteroidList = a.getAsteroidList(); 

    if (asteroidList == null){ 
     System.out.println("null");} 
    } 
    ..."more code".... 
3

В checkCollision() вы создаете новый объект Asteroid. Когда будет создан новый экземпляр класса Asteroid, ничто не создаст Список в его конструкторе. Вот почему вы видите нуль.

Чтобы корректно работать, необходимо проверить тот же объект Asteroid, который вы заполняете ранее.

Вы можете добиться этого, передавая Asteroid объект, который вы сделали ранее к нему, как

public void checkCollision(Asteroid a){    
    ArrayList<Asteroid> asteroidList = a.getAsteroidList(); 

    if (asteroidList == null){ 
     System.out.println("null");} 
    } 
    ..."more code".... 
} 

Затем измените init() метод

public void init() { 
    populateAsteroid = new Asteroid(); 
    populateAsteroid.populateAsteroid(1); 
    collision = new Collision(); 
    collision.checkCollision(populateAsteroid) 
} 
+0

Это имеет смысл, спасибо. Одна из причин, по которой мне нужен класс столкновений, состоит в том, что у меня есть несколько списков массивов с разными объектами (комета, астероид, враги и т. Д.). Как передать произвольный объект функции проверки коллизии? Раньше у меня был метод проверки чека в классе комет, классе астероидов и т. Д., Но я хотел бы иметь один метод, чтобы покрыть все это. Вот почему я думал, что могу получить метод для получения необходимых списков вместо передачи его методу при его вызове. – user2913053

+1

Думаю, что я могу просто передать все различные списки массивов методу checkCollision одновременно и проверить их все сразу, а не называть метод checkCollision индивидуально для каждого списка массивов. – user2913053

2

Вы не заселять список астероидов. Вы инстанцирование нового класса, но не делаете необходимые методы для заполнения списка:

a = new Asteroid(); 
a.populateAsteroid(someInteger)    
ArrayList<Asteroid> asteroidList = a.getAsteroidList(); 

При создании объекта Астероида класса, вы только объявить список. Вы не присваивая ему значение:

public ArrayList<Asteroid> asteroidList; 

Это не является до populateAsteroid метод, который создается новый экземпляр ArrayList. Если вы оставите его в объявлении, он вернет null. Вот почему следующее if-условие всегда будет возвращать true:

if (asteroidList == null){ 
    asteroidList = new ArrayList<Asteroid>(); 
} 
Смежные вопросы