简体   繁体   中英

How to dynamically create Objects to add into ArrayList in Java

I am currently building a 2D Asteroid game using Java and Codename One with a heavy focus on OOP patterns. I'm having trouble, however, trying to dynamically create new objects (in my case the Object I want to add is a superclass GameObject) to add to an ArrayList. As you can see in void init() method of GameWorld.java, I created a list that holds types of GameObject which include subclasses of Asteroids, Ships, Spacestations.

The program asks for a command keyboard input in the class such as 'a', which is then supposed to add a new Asteroid (subclass of GameObject) object into the ArrayList. The user should be able to add as many Asteroids as they want to allocate to the ArrayList.

My question is : How do I do this without already declaring a variable called AsteroidTest of type Asteroid like I have currently been doing in my addAsteroid() function of the class GameWorld? Thanks!

GameWorld.java

package com.mycompany.a1;

import java.util.ArrayList; //For ArrayList Usage

public class GameWorld {

public void init() {
    ArrayList<GameObject> list = new ArrayList<GameObject>();
}
//other methods here to manipulate Game objects and data
public void addShip() {
    Ship ShipTest = new Ship();  

    list.add(ShipTest);

    System.out.println(ShipTest.getLocation());
}

public void addAsteroid(){
    Asteroid AsteroidTest = new Asteroid();

    list.add(AsteroidTest);


    System.out.println(AsteroidTest.getLocation());
}


public void addSpaceStation(){

}
}

Game.java

package com.mycompany.a1;

import com.codename1.ui.events.ActionListener;
import com.codename1.ui.Label;
import com.codename1.ui.TextField;
import com.codename1.ui.events.ActionEvent;
import java.lang.String;
import com.codename1.ui.Form;

public class Game extends Form{
private GameWorld gw;

public Game (){
    gw  = new GameWorld();
    gw.init();
    play();

}

private void play(){

    Label myLabel=new Label("Enter a Command:"); this.addComponent(myLabel);
    final TextField myTextField=new TextField();
    this.addComponent(myTextField);
    this.show();
    myTextField.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent evt) {
            String sCommand=myTextField.getText().toString();
            myTextField.clear();
            switch (sCommand.charAt(0)){
            case 's':
                gw.addShip();
                break;
            case 'a':
                gw.addAsteroid();
                break;
            case 'b':
                gw.addSpaceStation();
                break;
            //add code to handle rest of the commands
            } //switch
        } //actionPerformed
    } //new ActionListener()
            ); //addActionListener
    } //play
  //code to enter text field and receive keyboard input 
}

GameObject.java Superclass. Subclasses include Asteroids, Ships, Missles, SpaceStation

package com.mycompany.a1;

public abstract class GameObject {
private double x;
private double y;

public GameObject(){
    x = 0;
    y = 0;
}

public double getX(){
    return x;
}

public void setX(double newX){
    x = newX;
}

public double getY(){
    return y;
}

public void setY(double newY){
    y = newY;
}

public String getLocation(){
    return "(" + x + ", " + y + ")";

 }
}

Asteroid.java

 package com.mycompany.a1;

 import java.util.Random;

 public class Asteroid extends MovableObject {

 private Random rand = new Random();


 public Asteroid() {
    setX(rand.nextInt(1023) + rand.nextDouble());

    setY(rand.nextInt(767) + rand.nextDouble());// TODO Auto-generated 
  constructor stub
  }

 }

It is quite simple:

public void addAsteroid(){
  this.list.add(new Asteroid());
}

but if you want to print location, you must do it while the new asteroid is created, so in the constructor:

public GameObject(){
  x = 0;
  y = 0;
  System.out.println("(" + x + ", " + y + ")");
}

Moreover:

  • declare ArrayList<GameObject> list as List<GameObject> to use abstraction NOT specific implementation
  • declare List<GameObject> list as private field in GameWorld class
  • consider to work with constructor rather then with public void init()
  • in case of concurency problems, use java.util.concurrent.CopyOnWriteArrayList<E> instead of traditional List
  • consider to use second constructor in GameObject that handles creation of an object with initaial cordinates + remove setX and setY methods + introduce moveTo(double x, double y) method to be more clear with intentions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM