Как сделать несколько «врагов» (т.е. квадратов) видимыми одновременно в графическом интерфейсе - PullRequest
0 голосов
/ 07 июля 2019

Я пытаюсь сделать простую игру с уклонением, в которой квадраты падают с верхней части экрана, и игрок должен уклоняться от них с помощью клавиш со стрелками как можно дольше.

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

Заранее прошу прощения за любые структурные ошибки или пренебрежение соглашениями Java. Я пытался сделать код максимально читабельным и корректным, но я все еще начинающий. Я, конечно, открыт для любых предложений / исправлений относительно соглашений об именах, структуры и т. Д. Я был бы очень признателен за любые советы / рекомендации, которые могли бы помочь мне научиться или указать мне правильное направление.

Я подозреваю, что проблема в методе paintComponent класса Board или мне нужно хранить квадраты в структуре данных другого типа. Или, возможно, сочетание двух.

Доска класса:

public class Board extends JPanel implements ActionListener {

    private int WIDTH = 500;
    public static int HEIGHT = 500;
    public static int PLAYER_WIDTH = 25;

    private Image player;

    private int player_x = WIDTH/2;
    private int player_y = HEIGHT - 50;

    private boolean running;

    private Timer t;

    public static boolean direction_left = false;
    public static boolean direction_right = false;
    public static boolean direction_up = false;
    public static boolean direction_down = false;

    ArrayList<Square> enemy_array = new ArrayList<Square>();

    public Board() {

        addKeyListener(new DodgerListener());
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setFocusable(true);
        setBackground(Color.WHITE);

        ImageIcon cat = new ImageIcon("src/black_cat.png");

        player = cat.getImage();

        running = true;

        t = new Timer(50, this);
        t.start();

        manage_arraylist();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(running) {
            move_enemy();
            move_player();
            check_death();
        }
        Square.update();
        repaint();
    }

    private void move_player() {
        if (direction_left && player_x > 0)
        {
            player_x -= 5;
        }
        if (direction_right && player_x < WIDTH - PLAYER_WIDTH)
        {
            player_x += 5;
        }
        if (direction_up && player_y > 0)
        {
            player_y -= 5;
        }
        if (direction_down && player_y < HEIGHT - PLAYER_WIDTH)
        {
            player_y += 5;
        }
    }

    // makes each square fall from the top of the screen
    private void move_enemy() {
        Square.enemy_y += 10;
    }

    private void check_death() {
        if((player_x - Square.enemy_x <= Square.death_distance) && (player_x - Square.enemy_x >= -Square.death_distance) && (player_y - Square.enemy_y <= Square.death_distance) && (player_y - Square.enemy_y >= -Square.death_distance)) {
            running = false;
        }
        if(!running) {
            t.stop();
        }
    }

    // initializes the ArrayList of squares and replaces each square after it leaves the window
    private void manage_arraylist() {
        for (int i = 0; i < 20; i++) {
            enemy_array.add(i, new Square(Square.enemy_x, 0));
        }
        if(Square.enemy_y >= HEIGHT) {
            enemy_array.remove(19);
            enemy_array.add(0, new Square(Square.enemy_x, 0));
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if(running) {
            g.drawImage(player, player_x, player_y, this);
            for (int i = 19; i >= 0; i--) {
                enemy_array.get(i).paint(g);
            }
            Toolkit.getDefaultToolkit().sync();
        } else {
            Font f = new Font("Calibri", Font.BOLD, 16);
            g.setColor(Color.BLACK);
            g.setFont(f);
            g.drawString("Game Over", (WIDTH/2), HEIGHT/2);
        }
    }
}

Квадратный класс:

public class Square {

    public static int enemy_x;
    public static int enemy_y;
    private static int square_size;
    public static double death_distance;

    public Square(int x, int y) {
        setEnemyLocation();
        setSquareSize();
        setDeathDistance();
    }

    // determines how close the player can get to each square without dying
    private static double setDeathDistance() {
        return death_distance = square_size*0.75;
    }

    private static int setSquareSize() {
        return square_size = (int) (Math.random()*100);
    }

    // determines a random x coordinate at the top of the screen for the square to be painted at
    private static void setEnemyLocation() {
        int random = (int) (Math.random()*490);
        enemy_x = random;
        enemy_y = 0;
    }

    public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect(enemy_x, enemy_y, square_size, square_size);
    }

    // changes the x coordinate and size of the square once it falls through the bottom of the window
    public static void update() {
        if(enemy_y >= Board.HEIGHT) {
            setEnemyLocation();
            setSquareSize();
            setDeathDistance();
        }
    }
}
...