Задание 20
Наслаждаемся игрой


Задание 19
Осталось совсем чуть-чуть

Реализовать метод checkBricksBump
В этом методе надо проверить - не столкнулся ли шарик с каким-нибудь из "кирпичей"
Для проверки столкновения используй метод isIntersec
Если шарик все-таки попал в кирпич, то
а) шарик отлетает в случайном направлении (0..360 градусов)
double angel = Math.random() * 360;
ball.setDirection(angel);
б) кирпич умирает - надо удалить его из списка всех кирпичей

Реализовать метод checkStandBump
В этом методе надо проверить - не ударился ли шарик о подставку
Для проверки столкновения используй метод isIntersec
Если шарик все-таки ударился о подставку, то:
шарик отлетает в случайным направлении строго вверх (80..100 градусов)
double angel = 80 + Math.random()*20;
ball.setDirection(angel);

Реализовать метод checkEndGame
Если координата y шарика больше чем высота поля игры (height), значит шарик улетел вниз за границу экрана
В этом случае надо переменную isGameOver установить в true


Задание 18
Теперь вернемся к классу Arcanoid
Реализуй методы:
а) move()
В этом методе нужно двигать все движимые объекты (stand, ball)
б) draw(Canvas canvas)
В этом методе надо вызвать метод draw всех существующих объектов, которые его имеют.


Задание 17
Но и это еще не все
Еще нужны методы:
а) move  - см. move в BaseObject
Движение доски осуществляется горизонтально, поэтому мы меняем только координату х.
Подумай, как координата х зависит от направления (direction) и скорости (speed). Реализуй зависимость.
б) draw  - см. draw в BaseObject
Его кодом я займусь сам.
в) moveLeft() - задает постоянное движение "подставки" влево
Просто присвой правильное значение переменной direction и все.
г) moveRight() - задает постоянное движение "подставки" вправо
Просто присвой правильное значение переменной direction и все.


Задание 16
И наконец "подставка"!
Ей понадобятся такие переменные
а) speed (скорость шарика) типа double
б) direction (направление движения по оси x: 1 - вправо, -1 - влево) типа double
в) создай для них геттеры


А еще с тебя конструктор, примерно вот такой:
public Stand(double x, double y)
{
    super(x,y,3);
    speed = 1;
    direction = 0;
}


Задание 15
Не поверишь, но и это еще не все.

Во-первых нужен метод setDirection
Который не только устанавливает значение переменной direction,
но и вычисляет новые значения переменных x & y
Код должен выглядеть примерно так:
this.direction = direction;
double angel = Math.toRadians(direction);
dx = Math.cos(angel) * speed;
dy = -Math.sin(angel) * speed;

Во-вторых шарик может удариться о стенку.
При этом он должен от нее отскочить.
Для этого нам понадобится еще один метод:
public void checkRebound(int minx, int maxx, int miny, int maxy)
Создай его, кодом я займусь сам



Задание 14
Чего-то не хватает:

Во-первых надо переопределить метод move(), который наследуется от BaseObject
а) объявить такой же метод как и в BaseObject, только без ключевого слова abstract
б) написать его реализацию
x должен увеличиваться на dx каждый ход
y должен увеличиваться на dy каждый ход
если шарик "заморожен", то x и y меняться не должны

Во-вторых надо переопределить метод draw(Canvas canvas)
а) объявить такой же метод как и в BaseObject, только без ключевого слова abstract
б) написать его реализацию. Выглядеть она должна примерно так:
canvas.setPoint(x, y, 'O');

В третьих надо реализовать метод start()
Именно его вызов "размораживает" шарик.
Что для этого надо сделать - это ты уже сам реши.


Задание 13
Класс Ball уже посложнее - шарик же двигается.
Нам понадобятся переменные
а) speed (скорость шарика) типа double
б) direction (направление движения в градусах: от 0 до 360) типа double
в) dx (расстояние по x, которое проходит шарик за один шаг. вычисляется на основе speed и direction) типа double.
г) dy (расстояние по y, которое проходит шарик за один шаг. вычисляется на основе speed и direction) типа double.
д) isFrozen ("истина" если шарик "заморожен" - не двигается) типа boolean
е) добавь геттеры для всех переменных этого класса

А еще сделай-ка конструктор:
а) в конструктор передаются x,y, speed, direction
б) радиус (для родительского класса) всегда равен 1
в) не забудь установить isFrozen в true - в начале игры шарик никуда не летит.


Задание 12
Теперь напишем класс Brick
Во-первых займемся конструктором и в нем точно зададим радиус всех "кирпичей".
Путь он выглядит так:
public Brick(double x, double y)
{
        super(x,y,3);
}

Еще нам нужно переопределить два метода move() и draw(Canvas canvas)
Метод move() не делает ничего (не содержит кода), т.к. кирпич никуда не двигается.

Напиши еще метод draw(Canvas canvas).
Его кодом я займусь сам.



Задание 11
Еще Canvas понадобится два метода, напиши их.
а) метод clear()
Этот метод будет очищать матрицу, чтобы на ней снова можно было рисовать.
Например заменить все символы матрицы на пробелы.

б) метод print()
Этот метод отрисовывает матрицу на экран.
Тут уже ты должен сам разобраться: вывести набор символов не так уж и сложно.
Не забудь добавить пару пустых строк в конце, чтобы матрицы выведенные в разное время не слипались.



Задание 10
Что мы будем делать с Canvas?
Мы будем рисовать на нем (в его матрице).
Поэтому нам понадобятся два метода
public void setPoint(double x, double y, char c)
public void drawMatrix(double x, double y, int[][] matrix, char c)

Первый метод - setPoint будет "ставить точку в координатах x,y цветом c".
В методе надо:
а) округлить x и y до целых чисел
б) занести в matrix[y][x] значение с
в) ничего не делать, если x<0 или y<0 или y>matrix.length или x>matrix[0].length

Второй метод - drawMatrix копирует переданную ему картинку (матрицу) в матрицу Canvas.
И не просто копирует, а начиная с координат x, y
В методе надо:
а) с помощью двух вложенных циклов пройтись по всем ячейкам переданной картинки
б) если значение ячейки matrix[i][j] не равно 0, то покрасить в матрице объекта Canvas точку (x+j, y+i) в цвет c:
 setPoint(x+j, y+i, c)



Задание 9
Теперь займемся классом Canvas.
Он у нас будет содержать матрицу(двумерный массив), куда мы будем "рисовать".
У матрицы есть ширина и высота.
А еще будем в ней хранить не числа (int), а символы (char).
Надо:
а) Добавить в класс две переменные width и height
б) Добавить в класс переменную matrix (char[][])
в) Добавить конструктор с width и height
г) Добавь геттеры для всех переменных класса
Я тут немного изменил класс BaseObject. Пройдись по классам наследникам.



Задание 8
Но и это еще не все.
Классу BaseObject нужны еще методы.
Пока это будут пустые методы draw() и move().
Классы-наследники должны будут переопределить их у себя и реализовать необходимую функциональность.
Объяви эти методы, но сделай их абстрактными.
Также сделай абстрактным сам класс BaseObject.

А еще нам нужно будет определять попал шарик в кирпич или в подставку.
Это будем делать так:
В этом же классе, создадим специальный метод: public boolean isIntersec(BaseObject o)
Он будет определять - "пересеклись" объекты или нет. Если пересеклись - возвращать true, если нет - false.

Т.к. объекты мы условно считаем кругами, то предлагаю такую формулу взаимодействия
Если центр круга одного объекта попал в круг другого, то будем считать, что они столкнулись.
Или еще проще:
дистанция_между_объектами < max (радиус_первого_объекта, радиус_второго_объекта)



Задание 7
Теперь перейдем к классу BaseObject.
Я хочу сделать несколько предложений.

Во-первых для простоты считать все объекты у нас будут круглыми.
Нет, отрисовывать их мы будем фигурными, как и раньше.
А вот при расчетах из взаимодействия исходить из того, что они круглые.
Так - гораздо проще.

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

Надо:
а) Добавь в класс BaseObject переменные x (double), y (double), radius (double)
б) Добавить геттеры и сеттеры
в) Добавь конструктор BaseObject(double x, double y, double radius)
г) Надо пройтись по все классам-наследникам и поправить у них конструкторы
Если вы пользуйтесь Intellij IDEA - Alt+Insert вам в помощь



Задание 6
У нас будут "кирпичи", "шарик" и "подставка" и у них будет много общего.
Они будут перемещаться по полю и отрисовываться.
Значит у них у всех будут координаты и размер.
А еще методы move() - для перемещения и draw() для отрисовки.

Есть интересное предложение: давай введем один базовый класс для все объектов.
Пусть это будет класс BaseObject.
А классы Ball, Stand, Brick от него наследуются.
Создай класс BaseObject и добавь его родителем к классам  Ball, Stand, Brick

Еще нам понадобится класс Canvas
Он будет ответственным за "отрисовку" объектов.
С помощью его они будут отрисовывать себя.
Вернее даже на нем, но детали я сообщу позднее.
Создай и этот класс.



Задание 5
Чего еще не хватает классу Arcanoid?
Ну во-первых ему нужен метод run(), в котором будет описана основная логика программы
Еще нужен метод move() - который будет двигать на один шаг все объекты требующие движения.
Создай методы run() и move().

Еще нам понадобится статическая переменная game типа Arcanoid, которая будет хранить ссылку
на созданный экземпляр класса Arcanoid.
Выглядеть это должно примерно так:
public static Arcanoid game;



Задание 4
Также классу Arcanoid нужно будет хранить ссылку на шарик (Ball) и "подставку" Stand.
И список "кирпичей"
Надо:
а) создать в классе Arcanoid две переменных ball типа Ball и stand типа Stand
б) добавить переменную bricks типа ArrayList<Brick>
в) добавь для них геттеры и сеттеры



Задание 3
Главному классу (Arcanoid) нужно будет хранить информацию о размерах поля, где будут происходить все действия.
Поэтому:
а) добавь ему две переменных width (ширина) типа int и height(высота) типа int
б) добавь их в конструктор класса
г) сделай для них геттеры и сеттеры



Задание 2
Добавь в класс Arcanoid метод main.



Задание 1
Давай сегодня напишем игру Арканоид.
В оригинале это выглядит примерно так http://www.youtube.com/watch?v=Th-Z6QQ5AOQ
Для начала мы напишем упрощенную версию этой игры.
У нас будут кубики, шарик и летающая "подставка", которая не дает шарику упасть.

Поэтому нам понадобятся классы:
а) Arcanoid - класс в котором происходят основные действия
б) Ball - шарик
в) Brick - "кирпичи", которые мы сбиваем шариком
г) Stand - летающая подставка

Создай их.

 

package com.javarush.test.level24.lesson14.big01;

import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Главный класс игры
 */
public class Arcanoid {
    public static Arcanoid game;
    //ширина и высота
    private int width;
    private int height;
    //список кирпичей
    private ArrayList<Brick> bricks = new ArrayList<Brick>();
    //шарик
    private Ball ball;
    //подставка
    private Stand stand;
    //игра закончена?
    private boolean isGameOver = false;

    public Arcanoid(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public static void main(String[] args) throws Exception {
        game = new Arcanoid(20, 30);

        Ball ball = new Ball(10, 29, 2, 95);
        game.setBall(ball);

        Stand stand = new Stand(10, 30);
        game.setStand(stand);

        game.getBricks().add(new Brick(3, 3));
        game.getBricks().add(new Brick(7, 5));
        game.getBricks().add(new Brick(12, 5));
        game.getBricks().add(new Brick(16, 3));

        game.run();
    }

    public ArrayList<Brick> getBricks() {
        return bricks;
    }

    public Ball getBall() {
        return ball;
    }

    public void setBall(Ball ball) {
        this.ball = ball;
    }

    public Stand getStand() {
        return stand;
    }

    public void setStand(Stand stand) {
        this.stand = stand;
    }

    /**
     * Рисуем на холсте границы и все объекты.
     */
    public void draw(Canvas canvas) {
        //отрисуй границы
        //отрисуй кирпичи
        //отрисуй шарик
        //отрисуй подставку
        this.drawBoders(canvas);
        this.ball.draw(canvas);
        this.stand.draw(canvas);
        for (Brick brick : bricks) {
            brick.draw(canvas);
        }
    }

    /**
     * Рисуем на холсте границы
     */
    private void drawBoders(Canvas canvas) {
        //draw game
        for (int i = 0; i < width + 2; i++) {
            for (int j = 0; j < height + 2; j++) {
                canvas.setPoint(i, j, '.');
            }
        }

        for (int i = 0; i < width + 2; i++) {
            canvas.setPoint(i, 0, '-');
            canvas.setPoint(i, height + 1, '-');
        }

        for (int i = 0; i < height + 2; i++) {
            canvas.setPoint(0, i, '|');
            canvas.setPoint(width + 1, i, '|');
        }
    }

    /**
     * Основной цикл программы.
     * Тут происходят все важные действия
     */
    public void run() throws Exception {
        //Создаем холст для отрисовки.
        Canvas canvas = new Canvas(width, height);

        //Создаем объект "наблюдатель за клавиатурой" и стартуем его.
        KeyboardObserver keyboardObserver = new KeyboardObserver();
        keyboardObserver.start();

        //Исполняем цикл, пока игра не окончека
        while (!isGameOver) {
            //"наблюдатель" содержит события о нажатии клавиш?
            if (keyboardObserver.hasKeyEvents()) {
                KeyEvent event = keyboardObserver.getEventFromTop();

                //Если "стрелка влево" - сдвинуть фигурку влево
                if (event.getKeyCode() == KeyEvent.VK_LEFT)
                    stand.moveLeft();
                    //Если "стрелка вправо" - сдвинуть фигурку вправо
                else if (event.getKeyCode() == KeyEvent.VK_RIGHT)
                    stand.moveRight();
                    //Если "пробел" - запускаем шарик
                else if (event.getKeyCode() == KeyEvent.VK_SPACE)
                    ball.start();
            }

            //двигаем все объекты
            move();

            //проверяем столкновения
            checkBricksBump();
            checkStandBump();

            //проверяем, что шарик мог улететь через дно.
            checkEndGame();

            //отрисовываем все объекты
            canvas.clear();
            draw(canvas);
            canvas.print();

            //пауза
            Thread.sleep(300);
        }

        //Выводим сообщение "Game Over"
        System.out.println("Game Over!");
    }

    /**
     * Двигаем шарик и подставку.
     */
    public void move() {
        //двигай шарик
        //двигай подставку
        ball.move();
        stand.move();
    }

    /**
     * Проверяем столкновение с кирпичами.
     * Если столкновение было - шарик отлетает в случайном направлении 0..360 градусов
     */
    public void checkBricksBump() {
        //Тут проверь - столкнулся ли шарик с кирпичом.
        //Если да - кирпичь удалить, а шарик запустить в случайно направлении.
        Iterator<Brick> iterator = bricks.iterator();
        while (iterator.hasNext()) {
            if (iterator.next().isIntersec(ball)) {
                iterator.remove();
                double angel = Math.random() * 360;
                ball.setDirection(angel);
            }
        }
    }

    /**
     * Проверяем столкновение с подставкой.
     * Если столкновение было - шарик отлетает в случайном направлении  вверх 80..100 градусов.
     */
    public void checkStandBump() {
        //Тут проверь - столкнулся ли шарик с подставкой.
        //Если да - запустить шарик  вверх на 80..100 градусов.
        if (ball.isIntersec(stand)) {
            double angel = 80 + Math.random()*20;
            ball.setDirection(angel);
        }
    }

    /**
     * Проверяем - не улетел ли шарик через дно.
     * Если да - игра окончена (isGameOver = true)
     */
    public void checkEndGame() {
        //Если шарик улетел за нижнюю границы - игра окончена.
        if (ball.y > height) isGameOver = true;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }
}

 

package com.javarush.test.level24.lesson14.big01;

/**
 * Класс для шарика в игре
 */
public class Ball extends BaseObject {
    //скорость
    private double speed;
    //направление  (в градусах от 0 до 360)
    private double direction;

    //текущее значение вектора движения (dx,dy)
    private double dx;
    private double dy;

    //заморожен ли объект или может двигаться
    private boolean isFrozen;

    public Ball(double x, double y, double speed, double direction) {
        super(x, y, 1);

        this.direction = direction;
        this.speed = speed;

        this.isFrozen = true;
    }

    public double getSpeed() {
        return speed;
    }

    public void setSpeed(double speed) {
        this.speed = speed;
    }

    public double getDirection() {
        return direction;
    }

    /**
     * Устанавливаем новое направление движения.
     * Тут же вычисляем и новый вектор.
     * Тако подход удобно использовать при отскоках от стен.
     */
    public void setDirection(double direction) {
        this.direction = direction;

        double angel = Math.toRadians(direction);
        dx = Math.cos(angel) * speed;
        dy = -Math.sin(angel) * speed;
    }

    public double getDx() {
        return dx;
    }

    public double getDy() {
        return dy;
    }

    /**
     * Рисуем себя на "канвасе".
     */
    @Override
    public void draw(Canvas canvas) {
        canvas.setPoint(x, y, 'O');
    }

    /**
     * Двигаем себя на один шаг.
     */
    public void move() {
        if (isFrozen) return;

        x += dx;
        y += dy;

        checkRebound(1, Arcanoid.game.getWidth(), 1, Arcanoid.game.getHeight() + 5);
    }

    /**
     * Проверяем не улетел ли шарик за стенку.
     * Если да - отражаем его.
     */
    public void checkRebound(int minx, int maxx, int miny, int maxy) {
        if (x < minx) {
            x = minx + (minx - x);
            dx = -dx;
        }

        if (x > maxx) {
            x = maxx - (x - maxx);
            dx = -dx;
        }

        if (y < miny) {
            y = miny + (miny - y);
            dy = -dy;
        }

        if (y > maxy) {
            y = maxy - (y - maxy);
            dy = -dy;
        }
    }

    /**
     * Запускам шарик.
     * isFrozen = false.
     * Пересчитываем вектор движения (dx,dy).
     */
    public void start() {
        this.setDirection(direction);
        this.isFrozen = false;
    }
}

 

package com.javarush.test.level24.lesson14.big01;

/**
 * Класс-холст для отрисовки.
 */
public class Canvas
{
    //ширина и высота
    private int width;
    private int height;
    //матрица, где рисуем. символ - это цвет.
    private char[][] matrix;

    public Canvas(int width, int height)
    {
        this.width = width;
        this.height = height;
        this.matrix = new char[height + 2][width + 2];
    }

    /**
     * Очищаем холст
     */
    public void clear()
    {
        this.matrix = new char[height + 2][width + 2];
    }

    /**
     * Печатаем переданную фигуру в указанных координатах уветом c.
     * Если переданный массив содержит единицы, то на холсте им будут соответствовать символы - с.
     */
    public void drawMatrix(double x, double y, int[][] matrix, char c)
    {
        int height = matrix.length;
        int width = matrix[0].length;

        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                if (matrix[i][j] == 1)
                    setPoint(x + j, y + i, c);
            }
        }
    }

    /**
     * Ставим одну точку на холсте с координатами (x,y) и цветом - c.
     */
    public void setPoint(double x, double y, char c)
    {
        int x0 = (int) Math.round(x);
        int y0 = (int) Math.round(y);
        if (y0 < 0 || y0 >= matrix.length) return;
        if (x0 < 0 || x0 >= matrix[y0].length) return;

        matrix[y0][x0] = c;
    }

    /**
     * Печатаем содержимое холста на экран.
     */
    public void print()
    {
        System.out.println();

        for (int i = 0; i < height + 2; i++)
        {
            for (int j = 0; j < width + 2; j++)
            {
                System.out.print(" ");
                System.out.print(matrix[i][j]);
                System.out.print(" ");
            }

            System.out.println();
        }

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

    public int getWidth()
    {
        return width;
    }

    public int getHeight()
    {
        return height;
    }

    public char[][] getMatrix()
    {
        return matrix;
    }
}

 

package com.javarush.test.level24.lesson14.big01;

import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

public class KeyboardObserver extends Thread {
    private Queue<KeyEvent> keyEvents = new ArrayBlockingQueue<KeyEvent>(100);

    private JFrame frame;

    @Override
    public void run() {
        frame = new JFrame("KeyPress Tester");
        frame.setTitle("Transparent JFrame Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setUndecorated(true);
        frame.setSize(400, 400);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setLayout(new GridBagLayout());

        frame.setOpacity(0.0f);
        frame.setVisible(true);

        frame.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {
                //do nothing
            }

            @Override
            public void focusLost(FocusEvent e) {
                System.exit(0);
            }
        });


        frame.addKeyListener(new KeyListener() {

            public void keyTyped(KeyEvent e) {
                //do nothing
            }

            public void keyReleased(KeyEvent e) {
                //do nothing
            }

            public void keyPressed(KeyEvent e) {
                keyEvents.add(e);
            }
        });
    }


    public boolean hasKeyEvents() {
        return !keyEvents.isEmpty();
    }

    public KeyEvent getEventFromTop() {
        return keyEvents.poll();
    }
}

 

package com.javarush.test.level24.lesson14.big01;

/**
 * Базовый класс для всех объектов игры.
 */
public abstract class BaseObject {
    //координаты
    protected double x;
    protected double y;
    //радиус объекта
    protected double radius;

    protected BaseObject(double x, double y, double radius) {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    /**
     * Метод рисует свой объект на "канвасе".
     */
    public abstract void draw(Canvas canvas);

    /**
     * Двигаем себя на один ход.
     */
    public abstract void move();

    /**
     * Проверяем - не выходит ли (x,y) за границы.
     */
    public void checkBorders(double minx, double maxx, double miny, double maxy) {
        if (x < minx) x = minx;
        if (x > maxx) x = maxx;
        if (y < miny) y = miny;
        if (y > maxy) y = maxy;
    }

    /**
     * Проверяем - пересекаются ли переданный(o) и наш(this) объекты.
     */
    public boolean isIntersec(BaseObject o) {
        double dx = x - o.x;
        double dy = y - o.y;
        double destination = Math.sqrt(dx * dx + dy * dy);
        double destination2 = Math.max(radius, o.radius);
        return destination <= destination2;
    }
}

 

package com.javarush.test.level24.lesson14.big01;

/**
 * Класс для объекта "кирпич".
 */
public class Brick extends BaseObject
{
    //картинка для отрисовки
    private static int[][] matrix = {
            {0, 0, 0, 0, 0},
            {0, 1, 1, 1, 0},
            {0, 1, 1, 1, 0},
            {0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0},
    };

    public Brick(double x, double y)
    {
        super(x,y,3);
    }

    /**
     * Рисуем себя на холсте
     */
    @Override
    public void draw(Canvas canvas)
    {
        canvas.drawMatrix(x - radius + 1, y, matrix, 'H');
    }

    /**
     * Ничего не делаем - кирпич неподвижен
     */
    @Override
    public void move()
    {
        //do nothing
    }
}

 

package com.javarush.test.level24.lesson14.big01;

/**
 *  Подставка, с помощью которой отражаем мячик.
 */
public class Stand extends BaseObject
{
    //картинка для отрисовки
    private static int[][] matrix = {
            {1, 1, 1, 1, 1},
            {1, 0, 0, 0, 1},
            {0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0},
    };

    //скорость
    private double speed = 1;
    //направление (-1 влево, +1 вправо)
    private double direction = 0;

    public Stand(double x, double y)
    {
        super(x,y,3);
    }

    /**
     * Метод передвигает подставку в соответствии с текущим значением direction.
     */
    public void move()
    {
        double dx = speed * direction;
        x = x + dx;

        checkBorders(radius, Arcanoid.game.getWidth() - radius + 1, 1, Arcanoid.game.getHeight() + 1);
    }

    /**
     * direction устанавливается равным -1
     */
    public void moveLeft()
    {
        direction = -1;
    }

    /**
     * direction устанавливается равным +1
     */
    public void moveRight()
    {
        direction = 1;
    }

    public double getSpeed()
    {
        return speed;
    }

    public double getDirection()
    {
        return direction;
    }

    /**
     * Отрисовываем себя на холсте
     */
    @Override
    public void draw(Canvas canvas)
    {
        canvas.drawMatrix(x - radius + 1, y, matrix, 'M');
    }
}