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

1

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

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

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

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

Вот классы:

Родительский класс (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;
    }
}

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

КОРАБЛЬ:

//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;
    }

}

Следующая ошибка возникает из "супер" вызова во втором конструкторе Weapon, а также в качестве этого. которые следуют за ним, т.е. все это не работает haha https://drive.google.com/file/d/0B7ye7Ul2JDG2cy0yak82eUZaclE/view?usp=sharing

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

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

//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);


    }

}

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

  • 0
    Мне кажется, я только что заметил, что мой массив WEAPONS - это двумерный массив, тогда как в перегруженном конструкторе я вызываю только одномерный массив ...
Теги:
inheritance
constructor
parameters
overloading

2 ответа

0
Лучший ответ

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

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

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

  • 0
    Кстати: вы используете какую-либо IDE? Он имеет проверку кода в режиме реального времени. Для начинающих я предлагаю вам скачать Netbeans - он сообщает вам еще до компиляции, если все в порядке, а почему нет.
  • 0
    У меня есть Netbeans да, но я стараюсь максимально упростить этот проект (:
Показать ещё 1 комментарий
1

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

public static final Weapon[][] WEAPONS

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

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

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

  • 0
    Да, я упомянул в комментариях, что только что заметил это, спасибо (: Далее я понял еще одну опечатку, которую я сделал в классе Entity

Ещё вопросы

Сообщество Overcoder
Наверх
Меню