Сдача задания на уроке: не уходите пожалуйста пока я не успею отметить ваши успехи за урок. Если я вдруг не успел или забыл к вам подойти - скажите.

Сдача домашнего задания: на следующем уроке нужно будет запустить на компьютере то что вы выполнили дома и получить оценку за домашнее задание.

Цель вводного задания - сделать окно в котором единорог постепенно убегает из окна но при клик мышкой телепортирует его обратно в середину окна.

Создаем опять окно с панелью

Начнем с того чтобы сделать простое окно с нарисованным внутри эллипсом.

1) Создайте новый проект

2) Создайте новый класс MyPanel (разверните сверху слева структуру проекта, там src -> правый клик -> New -> Java Class)

3) Укажите что он наследуется от JPanel (import javax.swing.JPanel;)

4) Переопределите метод public void paintComponent(Graphics g)

5) Создайте новый класс Main и в нем main-функцию и создайте в ней примитивное окно (не забыв в него добавить вашу панель):

JFrame frame = new JFrame(); // создали объект 'окно'
frame.setSize(640, 480);     // сделали его чуть побольше
frame.setDefaultCloseOperation(EXIT_ON_CLOSE); // настроили окно так чтобы при его закрытии ваша программа завершалась
MyPanel p = new MyPanel();   // создали объект 'ваша панель' (в которой мы будем рисовать)
frame.add(p);                // не забыли ее добавить на окно (чтобы она в нем рисовалась)

frame.setVisible(true);      // теперь когда окно готово - делаем его видимым
while (true) {       // в вечном цикле
    frame.repaint(); // будем постоянно просить окно переотрисовываться (т.о. перерисовывая и вашу панель, вызывая ее метод paintComponent)
}

P.S. не забудьте импортировать JFrame и EXIT_ON_CLOSE (кликаете на них, затем Alt+Enter, затем Import class).

6) Теперь в MyPanel в вашем методе paintComponent можно начать что-то рисовать - нарисуйте эллипс, запустите программу и убедитесь что он рисуется.

Рисуем картинку

Теперь давайте сделаем так чтобы ваша MyPanel хранила картинку единорога и рисовала ее вместо эллипса.

7) Загрузите на диск из интернета эту картинку - откройте ее и затем нажмите Ctrl+S. Скопируйте эту картинку в папку src вашего проекта чтобы картинки были рядом с исходными файлами. Папку src можно легко найти в проводнике если в IDEA нажать на ней правой кнопкой и там Show in Explorer или что-то вроде Показать в проводнике. Или просто перетащите скачанную картинку из проводника в папку src в IDEA (чтобы переместить ее туда).

8) Чтобы хранить картинку в вашей панеле MyPanel - нужно в ней создать поле BufferedImage unicornImage;

9) Теперь это поле нужно инициализировать (считать в поле unicornImage с диска картинку) - сделайте это в конструкторе вашей панели:

  • Создайте конструктор у вашей панели: public MyPanel() { ... }
  • Внутри этого конструктора инициализируйте поле: this.unicornImage = ImageIO.read(new File("C:\\...\\src\\unicorn.png")); (поправьте путь, самый удобный способ: в IDEA правый клик по картинке -> Copy Path -> Absolute Path и затем Ctrl+V)
  • Обратите внимание что ImageIO и File - красные, это потому что их нужно импортировать - импортируем
  • Теперь подсвечивается ошибкой ImageIO.read( - это потому что чтение может кинуть ошибку (при неверном пути например), кликните на read -> Alt+Enter -> Add exception to method signature.

10) Наконец давайте заменим рисование эллипса на рисование картинки: g.drawImage(this.unicornImage, 100, 200, null); (т.е. рисуем по координатам x=100, y=200). Запустите программу чтобы проверить что картинка рисуется!

Двигаем картинку

Теперь давайте сделаем так чтобы единорог двигался на 1 пиксель при каждой отрисовке - для этого надо хранить его координаты в полях int x; и int y; в классе MyPanel.

11) Создайте в MyPanel поля хранящие координаты единорога. В конструкторе панели инициализируйте эти поля значениями соответствующими середине окошка.

12) Теперь при каждой отрисовке:

  • Увеличивайте обе координаты (т.е. оба поля) на единицу
  • Рисуйте единорога не по фиксированным координатам, а по этим координатам хранящимся в этих двух полях

Добавляем обработку клика мышкой

Хотим добавить пользователю возможность взаимодействовать с программой - давайте добавим обработку кликов мышки. Сначала пусть это будет телепортация единорога назад в середину экрана, затем пусть это будет телепортация единорога в место клика.

Было бы здорово если бы было достаточно переопределить метод “обработка клика мышки” подобно тому как это было с переопределением метода “отрисовываем панель”, и почти так и выйдет!

Но не любая панель умеет обрабатывать клики мышки.

13) Чтобы ваша панель явно заявила это умение - надо добавить в MyPanel к уже имеющемуся наследованию от JPanel (extends JPanel) еще и гордое заявление “я являюсь сертифицированным слушателем мышки - MouseListener” - я реализую (на английском - implements) контракт MouseListener:

public class MyPanel extends JPanel implements MouseListener {

14) Не забываем добавить импорт для MouseListener.

15) Теперь красная ошибка сообщает нам что мы заявили что мы якобы умеем обрабатывать клики мышки, но пока не рассказали как это делаем - кликаем -> Alt+Enter -> Implement methods (реализовать методы обработки событий мышки) -> OK

16) У вас появились пустые методы обработки разных событий - их названия говорящие, давайте в каждый из этих методов добавим отладочный вывод в коноль чтобы проверить что они срабатывают (в mouseClicked напишите System.out.println("mouseClicked");, в остальные четыре метода - соответствующие сообщения)

17) И теперь надо зарегистрировать себя как слушателия мышки - добавьте в конструктор панели this.addMouseListener(this);. Запустите программу, покликайте мышкой по окну. Убедитесь что в консоли появляются сообщения. Что же каждый метод означает? Исследуйте этот вопрос, если остались непонятки - спросите.

18) Сделайте так чтобы при клике мышкой значение полей хранящих координаты единорога сбрасывались на середину окна (единорог телепортировался при нажатии). Убедитесь что рабоатет.

19) Заметьте что эти методы принимают в скобочках аргумент - MouseEvent e - он описывает событие более подробно, например там есть информация о координатах клика (e.getX() и e.getY()) и том какая кнопка мышки была нажата (e.getButton()) - проверьте что эти методы возвращают правильные значения - добавьте вывод результатов их вызова в консоль.

20) Измените логику с “телепорт единорога в середину экрана” на “телепорт единорога в место где пользователь нажал мышкой”.

21) Сделайте так чтобы единорог убегал не так быстро:

  • сделайте так чтобы координаты единорога хранились в вещественных числах а не целых, и при каждой отрисовке увеличивались не на 1, а на 0.01 например
  • или сделайте так чтобы ваше окно переотрисовывалось не слишком часто - добавьте в while(true) небольшую задержку - Thread.sleep(30); - например 30 миллисекунд (т.е. окно в секунду будет перерисовано 1000/30 раз)

22) Добавьте еще одного единорога. Пусть он убегает в другую сторону. Сделайте так чтобы один телепортировался только по левой кнопке мыши, а другой - только по правой.

23) Добавьте еще 100 единорогов (массивом или динамическим списком) разбегающихся в случайных направлениях.

Домашнее задание

Если не доделали описанное выше задание - сначала доделайте его.

Затем придумайте какую-нибудь классную интерактивную анимацию (собранную из разных картинок) и реализуйте ее.

Набросы идей для вдохновения:

  • Найдите в интернете маленькую картинку-иконку зайки, нарисуйте 10 заек (в цикле), сделайте так чтобы при клике мышки зайки подпрыгивали
  • Найдите в интернете картинки планет солнечной системы, сделайте так чтобы они вращались по осям только пока кнопка мыши зажата (а как только отжата - планеты замирали)
  • Найдите картинку какого-нибудь интересного вам персонажа, найдите картинку закрытых и открытых глаз, сделайте так чтобы при клике мышки персонаж моргал (если кнопка мыши зажата - пусть поверх рисуются закрытые глаза, иначе - открытые)
  • Найдите картинки метеоритов - при клике добавляйте в динамический список (ArrayList) новую пару координат (место клика мышки) - это то где находится еще один метеорит. И при каждой отрисовке двигайте каждый метеорит из списка в случайном направлении (и отрисовывайте по текущим координатам). При клике правой кнопкой мыши - проверьте не попал ли клик в один из метеоритов, и если попал - меняйте его цвет или удаляйте его из списка (пользователь его “подстрелил”).

Если вам захочется заглянуть вперед - можете еще использовать вращение картинок.

Как переносить проект

Рекомендуемый простой и надежный способ переноса проекта с компьютера на компьютер (при выполнении домашки вам наверняка поможет принесенный домой результат работы на уроке):

1) Открыть папку с исходниками (называется src, можно легко найти в проводнике если в IDEA нажать на ней правой кнопкой и там Show in Explorer или что-то вроде Показать в проводнике)

2) В этой папке несколько ваших исходных файлов с расширением .java (картинки тоже храните в этой папке для удобства)

3) Выделите все исходные файлы (включая картинки) -> правый клик -> Отправить -> Сжатая ZIP-папка

4) Теперь у вас есть ZIP-архив со всеми исходными файлами и картинками - отправьте его себе на почту например или скиньте на флешку

5) Перенесите ZIP-архив на другой компьютер

6) Создайте новый пустой проект в IDEA, откройте в проводнике src папку (просто нажмите на нее правой кнопкой в IDEA -> Show in Explorer или что-то вроде Показать в проводнике)

7) В эту пустую папку для исходников нового проекта скопируйте все что было в ZIP-архиве

8) Вернитесь обратно в IDEA - в папке src должны были появится все исходники и картинки т.к. вы их только что сюда скопировали

9) Чтобы запустить - нужно кликнуть правой кнопкой на файл с main-функцией и там кликнуть на Run (зеленая стрелочка)