Я пытаюсь сделать простую игру с уклонением, в которой квадраты падают с верхней части экрана, и игрок должен уклоняться от них с помощью клавиш со стрелками как можно дольше.
Пока все работает более-менее нормально, но я бы хотел, чтобы на экране было несколько квадратов одновременно. В своем текущем состоянии программа рисует только один квадрат за раз, а затем рисует его снова, как только он опустился за нижнюю часть окна.
Заранее прошу прощения за любые структурные ошибки или пренебрежение соглашениями 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();
}
}
}