Использование перегрузки конструктора и уже существующих статических объектов с наследованием

Это мой второй вопрос относительно проекта, который я делаю на Space Invaders.

Я реорганизовал свой код для работы с Inheritance и ArrayLists. В моем проекте классы Ship, Weapon и Bullet расширяют класс Entity (где Entity - это любая "вещь", которая может возникнуть на экране игры, имеющая координаты, ориентацию и набор спрайтов, представленных массивом). имен файлов)

В классе, который обрабатывает игровой экран, у меня есть уже существующие наборы оружия, которые можно использовать непосредственно для их статистики для удобства. Они были созданы с использованием стандартного конструктора оружия, который содержит вызов супер-конструктора к Entity.

Моя проблема связана с перегруженным конструктором для оружия: я хочу связать этот конструктор оружия с кораблем, к которому прикреплено оружие (обратите внимание, что это два отдельных оружия, которые стреляют параллельно, на расстоянии от центра корабля), так что оружие автоматически создается со свойствами, соответствующими текущему игровому сценарию (корабль отслеживает, какое оружие загрузить, а затем рисует на экране для каждого кадра).

Вот классы:

Родительский класс (Entity)

//IMMUTABLE
public class Entity extends Object
{

    //FIELDS
    private final double x;
    private final double y;
    private final double orientation;
    private final String[] sprites;

    //CONSTRUCTOR
    public Entity(double x, double y, double orientation, String[] sprites)
    {
        this.x = x;
        this.y = y;
        this.orientation = orientation;
        this.sprites = sprites;
    }

    //ACCESSORS
    public double getX()
    {
        return this.x;
    }

    public double getY()
    {
        return this.y;
    }

    public double getOrientation()
    {
        return this.orientation;
    }

    private String[] getSprites()
    {
        return this.sprites;
    }
}

Подклассы, Корабль и Оружие (у меня также есть Пуля, но если я решу проблему с Оружием, то это также исправит Пуля)

КОРАБЛЬ:

//IMMUTABLE
public class Ship extends Entity
{

    //GLOBAL VARIABLES
    public static final double SHIP_MOVE_INT = 1;
    //100 hp, weapon 0, not moving, no thrusters
    public static final State defState = new State(100, 0, false, false, 0);

    //FIELDS
    private final State state;

    //CONSTRUCTOR
    public Ship(double x, double y, double orientation, String[] sprites, State state)
    {
        super(x, y, orientation, sprites);
        this.state = state;
    }

    //ACCESSORS
    public State getState()
    {
        return this.state;
    }

    //METHODS
    public void moveLeft()
    {
        if (this.x > 15*SHIP_MOVE_INT)
        {
            this.x -= SHIP_MOVE_INT;
        }
    }

    public void moveRight()
    {
        if (this.x < Graphics.X_SCALE - 15*SHIP_MOVE_INT)
        {
            this.x += SHIP_MOVE_INT;
        }
    }

    //Works, but revise
    public void invaderPattern(double gameClock)
    {
        double stage1Bound = 0.3*Graphics.X_SCALE;
        double stage2Bound = stage1Bound + 0.05*Graphics.Y_SCALE;
        double stage3Bound = stage2Bound + stage1Bound;
        double stage4Bound = stage3Bound + 0.05*Graphics.Y_SCALE;

        if (gameClock < stage1Bound)
        {
            //Move right
            this.state.setMovingRight(true);
            this.state.setMovingLeft(false);
            this.x += SHIP_MOVE_INT;
        }
        else if (gameClock >= stage1Bound && gameClock < stage2Bound)
        {
            //Move down
            this.state.setMovingRight(false);
            this.state.setMovingLeft(false);
            this.y -= SHIP_MOVE_INT;
        }
        else if (gameClock >= stage2Bound && gameClock < stage3Bound)
        {
            //Move left
            this.state.setMovingLeft(true);
            this.state.setMovingRight(false);
            this.x -= SHIP_MOVE_INT;
        }
        else
        {
            //Move down
            this.state.setMovingRight(false);
            this.state.setMovingLeft(false);
            this.y -= SHIP_MOVE_INT;
        }
    }
}

ОРУЖИЕ:

//IMMUTABLE
public class Weapon extends Entity
{

    //FIELDS
    private final String type;
    private final int damage;
    private final int rof; //Rate of fire
    private final int firingStage;

    //CONSTRUCTORS
    public Weapon(double x, double y, double orientation, String[] sprites, String type, int damage, int rof, int firingStage)
    {
        super(x, y, orientation, sprites);
        this.type = type;
        this.damage = damage;
        this.rof = rof;
        this.firingStage = firingStage;
    }

    public Weapon(double x, Ship defender, double orientation)
    {
        super(x, defender.getY(), orientation, GameScreen.WEAPONS[defender.getState().getWeapon()].getSprites());
        this.type =         GameScreen.WEAPONS[defender.getState().getWeapon()].getType();
        this.damage =       GameScreen.WEAPONS[defender.getState().getWeapon()].getDamage();
        this.rof =          GameScreen.WEAPONS[defender.getState().getWeapon()].getRof();
        this.firingStage =  GameScreen.WEAPONS[defender.getState().getWeapon()].getFiringStage();
    }
    //END OF CONSTRUCTORS

    //ACCESSORS
    public String getType()
    {
        return this.type;
    }

    public int getDamage()
    {
        return this.damage;
    }

    public int getRof()
    {
        return this.rof;
    }

    public int getFiringStage()
    {
        return this.firingStage;
    }

}

Ошибка, которая следует, происходит от вызова "super" во втором конструкторе оружия, а также от this. вызовы назначения, которые следуют за ним, то есть все это не работает, ха-ха https://drive.google.com/file/d/0B7ye7Ul2JDG2cy0yak82eUZaclE/view?usp=sharing

Ссылкой на класс GameScreen (который сам будет ссылаться на Graphics) являются следующие классы:

GameScreen (мне еще нужно добавить мутаторы)

//MUTABLE - NB
public class GameScreen
{
    //GLOBAL VARIABLES
    public static final String HIGH_SCORE_FILE = "highScore.txt";

    //FIELDS
    private Ship defender;
    private Weapon[] weapons;
    private ArrayList invaders;
    private ArrayList bullets;
    private int score;
    private int lives;
    private int highscore;
    private double gameClock;

    //AVAILABLE WEAPONS
    public static final Weapon[][] WEAPONS = new Weapon[][]
    {
        {
            new Weapon(0, 0, 0, Graphics.WEAPON_SPRITES[0], "Machinegun L", 10, 20, 0),
            new Weapon(0, 0, 0, Graphics.WEAPON_SPRITES[0], "Machinegun R", 10, 20, 0)
        },
        {
            new Weapon(0, 0, 0, Graphics.WEAPON_SPRITES[1], "Plasma MG L", 20, 20, 0),
            new Weapon(0, 0, 0, Graphics.WEAPON_SPRITES[1], "Plasma MG L", 20, 20, 0)
        },
        {
            new Weapon(0, 0, 0, Graphics.WEAPON_SPRITES[2], "Photon Cannon L", 40, 5, 0),
            new Weapon(0, 0, 0, Graphics.WEAPON_SPRITES[2], "Photon Cannon R", 40, 5, 0)
        },
        {
            new Weapon(0, 0, 0, Graphics.WEAPON_SPRITES[3], "Alien Destabilizer L", 60, 10, 0),
            new Weapon(0, 0, 0, Graphics.WEAPON_SPRITES[3], "Alien Destabilizer L", 60, 10, 0)
        }
    };

    //AVAILABLE BULLETS
    public static final Bullet[] BULLETS = new Bullet[] //Correspond to WEAPONS above
    {
        new Bullet(0, 0, 0, Graphics.BULLET_SPRITES[0], WEAPONS[0][0].getDamage()),
        new Bullet(0, 0, 0, Graphics.BULLET_SPRITES[1], WEAPONS[1][0].getDamage()),
        new Bullet(0, 0, 0, Graphics.BULLET_SPRITES[2], WEAPONS[2][0].getDamage()),
        new Bullet(0, 0, 0, Graphics.BULLET_SPRITES[3], WEAPONS[3][0].getDamage())
    };

    //CONSTRUCTOR
    public GameScreen(Ship defender, Weapon[] weapons, ArrayList invaders, ArrayList bullets, int score, int lives)
    {
        this.defender = defender;
        this.weapons = weapons;
        this.invaders = invaders;
        this.bullets = bullets;
        this.score = score;
        this.lives = lives;
        this.loadHighscore();
        this.gameClock = 0;
    }

    //METHODS
    public void clk()
    {
        this.gameClock++;
        //Should only be called when the game itself is being played, not menus
    }

    public void loadHighscore()
    {
        try
        {
            Scanner sc = new Scanner(new File(HIGH_SCORE_FILE));
            this.highscore = Integer.parseInt(sc.next());
            sc.close();
        }
        catch(FileNotFoundException fnf)
        {
            System.out.println(fnf);
            this.highscore = 0;
        }
    }

    public void saveHighScore(int highscore)
    {
        try
        {
            FileWriter write = new FileWriter(HIGH_SCORE_FILE);
            PrintWriter pw = new PrintWriter(write);
            pw.print(this.highscore);

            pw.close();
        }
        catch(IOException e)
        {
            System.out.println(e);
        }
    }

    //ACCESSORS
    public Ship getDefender()
    {
        return this.defender;
    }

    public Weapon[] getWeapons()
    {
        return this.weapons;
    }

    public ArrayList getInvaders()
    {
        return this.invaders;
    }

    public ArrayList getBullets()
    {
        return this.bullets;
    }

    public int getScore()
    {
        return this.score;
    }

    public int getHighscore()
    {
        return this.highscore;
    }

    public int getLives()
    {
        return this.lives;
    }

    public double getGameClock()
    {
        return this.gameClock;
    }

}

ГРАФИКА:

//LIBRARY
public class Graphics
{

    //GLOBAL VARIABLES
    public static final int REFRESH_RATE = 20; //delay in milliseconds
    public static final double X_SCALE = 100;
    public static final double Y_SCALE = 100;
    public static final int X_SIZE = 512;
    public static final int Y_SIZE = 624;
    //Cycles of 4 stage motions
    public static final double gameClockMax = X_SCALE*(0.6) + Y_SCALE*(0.1);

    //SPRITES
    public static final String[][] SHIP_SPRITES =
    {
        {"BasicShip_TRANS.png"},    //Defender  [0][...]
        {"BasicInvader_TRANS.png"}  //Invader   [1][...]
    };

    public static final String[][] WEAPON_SPRITES =
    {
        {"MG_L_TRANS.png", "MG_R_TRANS.png"},   //Machine Gun           [0][...]
        {"PMG_L_TRANS.png", "PMG_R_TRANS.png"}, //Plasma Machine Gun    [1][...]
        {"PC_L_TRANS.png", "PC_R_TRANS.png"},   //Photon Cannon         [2][...]
        {"AD_L_TRANS.png", "AD_R_TRANS.png"}    //Alien Destabilizer    [3][...]
    };

    public static final String[][] BULLET_SPRITES =
    {
        {"MG_PROJ_TRANS.png"},
        {"PMG_PROJ_TRANS.png"},
        {"PC_PROJ_TRANS.png"},
        {"AD_PROJ.png"}
    };
    //END OF SPRITES

    //FUNCTIONS
    public static void drawMenu()
    {
        StdDraw.clear(StdDraw.GRAY);
        StdDraw.text(50, 80, "THE SWARM");
        StdDraw.text(50, 50, "P - Play");
        StdDraw.text(50, 40, "Q - Quit");
    }

    public static void init()
    {
        StdDraw.setCanvasSize(X_SIZE, Y_SIZE);
        StdDraw.setXscale(0.0, X_SCALE);
        StdDraw.setYscale(0.0, Y_SCALE);
        drawMenu();
    }

    public static void drawShip(int type, Ship ship) // type: 0 Defender , 1 Invader
    {
        if (type > 1 || type < 0)
        {
            System.out.println("Invalid ship type");
            return;
        }
        int hp = ship.getState().getHealth();
        if (hp > 80) StdDraw.picture(ship.getX(), ship.getY(), SHIP_SPRITES[type][0]);
        //TODO
    }

    public static double orientation(Ship defender) //Determine weapon orientation to mouse pointer direction
    {
        //Clockwise rotation thus 270 + theta

        if (defender.getX() < StdDraw.mouseX())
        {
            if (defender.getY() < StdDraw.mouseY())
            {
                return 270 + Math.toDegrees(Math.atan((StdDraw.mouseY() - defender.getY())/(StdDraw.mouseX() - defender.getX())));
            }
            else
            {
                return 270;
            }
        }
        else if (defender.getX() > StdDraw.mouseX())
        {
            if (defender.getY() < StdDraw.mouseY())
            {
                return (180) + (270 + Math.toDegrees(Math.atan((StdDraw.mouseY() - defender.getY())/(StdDraw.mouseX() - defender.getX()))));
            }
            else
            {
                return 90;
            }

        }
        else
        {
            return 0;
        }

    }

    public static void drawWeapons(Weapon[] weapons)
    {
        //Left
        StdDraw.picture
        (
            weapons[0].getX(),
            weapons[0].getY(),
            weapons[0].getSprites()[0],
            weapons[0].getOrientation()
        );
        //Right
        StdDraw.picture
        (
            weapons[1].getX(),
            weapons[1].getY(),
            weapons[1].getSprites()[1],
            weapons[1].getOrientation()
        );
    }

    public static void drawBullet(Bullet bullet)
    {
        StdDraw.picture
        (
            bullet.getX(),
            bullet.getY(),
            bullet.getSprites()[0],
            bullet.getOrientation()
        );
    }

    //Primary function
    public void animate(GameScreen gs)
    {
        //TODO
        //accept display of stats (hp, lives, score, etc)

        /* Order of drawing:
         * 1 - Background
         * 2 - Borders
         * 3 - Stats
         * 4 - Thrusters
         * 5 - Weapons
         * 6 - Ships
         * 7 - Bullets
         * 8 - Effects
         * 9 - Notifications (Combo indicators etc)
         */

        //1
        StdDraw.clear(StdDraw.GRAY);

        //5
        drawWeapons(gs.getWeapons());

        //6
        drawShip(gs.getDefender());

        for (int i = 0; i < gs.getInvaders().size(); i++)
        {
            gs.getInvaders().get(i).invaderPattern(gs.getGameClock());
            drawShip(gs.getInvaders().get(i));
        }

        //REFRESH RATE DELAY
        StdDraw.show(REFRESH_RATE);


    }

}

Подводя итог, я пытаюсь перегрузить конструктор оружия, чтобы он настраивался с использованием существующих конфигураций оружия (перечисленных в GameScreen, созданных с использованием первого конструктора оружия), одна из которых будет выбрана в зависимости от состояния типа корабля. Компилятор довольно жалуется на это, и я пытаюсь определить, почему>.<

2 ответа

Решение

Моя проблема была двоякой:

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

Во-вторых, по какой-то глупой причине я сделал метод getSprites в Entity закрытым, а не общедоступным, поэтому он был недоступен для перегруженного конструктора.

GameScreen.Weapons это двумерный массив, определенный следующим образом:

public static final Weapon[][] WEAPONS

Это означает, что у вас есть двумерный массив оружия типа.

Если вы используете, например, это GameScreen.Weapons[0] возвращает первую строку в массиве, то есть одномерный массив оружия. И массив не имеет метод, как .getDamage()

PS: я думаю, что вы неправильно поняли, что такое многомерный массив, я предлагаю поискать некоторые учебные пособия (может быть, достаточно картинок, это довольно просто, двумерный массив - это матрица)

Другие вопросы по тегам