[Java] Flappy Bird
Сделайте FlappyBird - игру аналогичную этой.
1) Создайте пустой проект FlappyBird. Как и с прошлым заданием про единорога - пишите все с чистого листа. Подглядывать в старые материалы можно, но без копирования и прямого перепечатывания.
2) Создайте окно, добавьте на него ваш класс BirdPanel
наследованный от JPanel
с переопределенным методом protected void paintComponent(Graphics g) { ... }
.
3) В методе paintComponent
нарисуйте картинкой игрового персонажа. Можете взять произвольную маленькую картинку из интернета или одну из этих:
Замечание
Если ничего не рисуется, то проверьте что:
- вы создали объект
BirdPanel
черезnew BirdPanel()
- вы добавили этот объект в окно через
frame.add
- вы сделали
frame.add(birdPanel)
ДОframe.setVisible(true)
- вы добавили
while(true) { frame.repaint(); }
- в
BirdPanel
в методеpaintComponent
вызывается рисование картинки
4) Создайте класс Bird
описывающий птицу (ее положение в пространстве, ее скорость и угол наклона и т.п.) и реализующий метод void draw(Graphics g)
который теперь инкапсулирует (т.е. прячет детали реализации того как нарисовать птицу внутри себя) отрисовку птицы. Иначе говоря тот код который рисовал картинку в paintComponent
теперь должен быть перенесен в метод Bird.draw(Graphics g)
. Обратите внимание что поле с картинкой птицы тоже надо перенести в класс Bird
(и соответственно его инициализацию - в конструктор птицы).
5) Создайте объект этого класса, и вызовите его отрисовку (т.е. метод draw
объекта класса Bird
) из метода BirdPanel.paintComponent
. Объект например хорошо хранить как поле внутри BirdPanel
. Обратите внимание что у вас должен быть ровно один объект птицы на всю программу, в т.ч. это означает что new Bird()
должен быть написан ровно один раз во все программе.
6) Добавьте в класс Bird
метод void update(double dt)
который будет обновлять положение птицы (с учетом прошедшего времени \(dt\) и ускорения гравитацией).
7) Добавьте в main-функции
цикл, который будет вызывать frame.repaint()
и bird.update
, тем самым постоянно обновляя положение птицы (она должна падать) и отрисовывая ее.
8) Добавьте обработчик клавиатуры, который при нажатии на пробел будет подкидывать птицу вверх (спойлер: для подкидывания нужно просто выставить значение вертикальной скорости вверх)
Обратите внимание что нужно изменять скорость птицы хранящейся в панели, т.е. panel.bird
.
9) Убедитесь что птица ведет себя естественно на ваш взгляд при нажатии на пробел. Если нет - задумайтесь и подгоните константы и метод update
.
10) Сделайте так, чтобы птица поворачивалась на небольшой угол пропорционально тому, с какой скоростью она стремиться ко дну в данный момент. (быстро летит вниз - смотрит вниз, летит вверх - смотрит вверх, только что летела вверх а теперь почти начинает лететь вниз - смотрит горизонтально)
11) Добавьте класс Wall
, описывающий стену, которая движется справа налево. Метод wall.update
должен обновлять ее местоположение и соответственно так же должен быть вызван из цикла в main-функции
. Метод wall.paint
должен рисовать ее и соответственно должен быть вызван из paintComponent
12) В цикле добавьте создание стены, ее движение и создание новой случайной стены когда текущая стена ушла за пределы экрана налево.
13) Добавьте метод checkCollision
который будет проверять, не врезалась ли птица в стену, и если врезалась - печатайте сообщение в консоль “Game over”
14) Сделайте так, чтобы при врезании игра начиналась заново. (обратите внимание что состояние игры исчерпывающе описывается птицей и стеной, поэтому для “перезапуска” игры достаточно вернуть их состояние в изначальное - например пересоздав их)
15) Можете попробовать добавить промежуточное состояние - показывать на несколько секунд черный экран с надписью “Game over” при врезании с последующим перезапуском (или перезапуск только после клика на пробел).
16) ???
17) Вы восхитительны!