иллюстрировать
Редактор также является новичком. Чтобы понять использование и влияние трепетания анимации, я решил написать небольшую игру с трепетом. И записывать пропущенные ямы в процессе.
подготовка к разработке
Конкретная ссылка на создание среды флаттера, информация об авторской среде
- Android Studio 3.2
- macOS 10.14
- flutter v1.1.10-pre.136
- dart 2.0
New Flutter Project
Наш приблизительный каталог:
- assets
- images
- lib
- main.dart
- src
- enter.dart
main.dart — это главный вход нашего кода, lib.src используется для хранения файлов логического кода всей нашей игры, активы используются для хранения файлов ресурсов изображений.
Вход в проект main.dart
В этом файле мы можем сделать меню и оставить его пока.Оставляем только кнопку, после нажатия на кнопку.Вставляем наш игровой интерфейс в роутер и запускаем нашу игру.Часть кода выглядит следующим образом:
RaisedButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return GameEnter();
}));
},
child: Text("开始游戏")
)
Вход в игру enter.dart
Enter.dart — это главный вход всей нашей игры, в этом входе мы загружаем ресурсы и выполняем общие операции по отрисовке. Определяем наши основные чайки в Enter.dart, примерноCustomPaintИнструкции для справки:Официальный документ, MainPainterунаследовано отCustomPainter, согласно официальной инструкции, наследуем и реализуем два его методаpaintа такжеshouldRepaint, в текущем состоянии. Весь интерфейс пустой и ничего. Далее мы определяем фон нашей игры.
// CustomPaint.painter
class MainPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return oldDelegate != this;
}
}
// GameEnter.build
Widget build(BuildContext context) {
return CustomPaint(
painter: MainPainter(),
);
}
фон игры
мы вsrcЗатем создайте новый с именемbg.dartфайл и создайте новыйBackgroundКласс, функция инициализации, используется вEnterчтобы загрузить файлы ресурсов, необходимые нашей игре,paintфункция используется вMainPainterНарисуйте нашу фоновую анимацию в формате .
class Background {
// 初始背景的偏移量
double offsetY = -100.0;
// 屏幕的宽度
double screenWidth;
// 屏幕的高度
double screenHeight;
// 画布滚动的速度
double speed = 10;
// 加载的背景图片
ui.Image image;
// 二张背景图的纵坐标点
double y1 = 100.0;
double y2 = 0.0;
// 构造函数
Background();
// 初始化, 各种资源
Future<VoidCallback> init() async {
return null;
}
// 绘图函数
paint(Canvas canvas, Size size) async {
Rect screenWrap = Offset(0.0, 0.0) & Size(screenWidth, screenHeight);
Paint screenWrapPainter = new Paint();
screenWrapPainter.color = Colors.red;
screenWrapPainter.style = PaintingStyle.fill;
canvas.drawRect(screenWrap, screenWrapPainter);
}
}
Введите запись, чтобы нарисовать фон
Далее мы нарисуем фон нашей игры на телефоне.Enterфункция инициализацииiniteStateв инициализацииBackgroundэкземпляр и инициализировать ресурсы. Затем вMainPainterВ интерфейсе рисования добавьте нашу логику рисования
void paint(Canvas canvas, Size size) {
background.paint(canvas, size);
}
Эффект операции следующий
Далее нам нужно отрисовать фоновое изображение игры на задний план, здесь мы вызываем
Canvas.drawImage(Image image, Offset offset, Painter paint) API
существуетBackground.paintВ функцию добавляем следующий код, а затем выполняем
Paint paint = new Paint();
canvas.drawImage(image, Offset(0, 0), paint);
Эффект следующий:
заставить фон двигаться
В этом исследовании анимации я используюAnimationControllerа такжеCurvedAnimationЗавершить наш эффект. Обратитесь к конкретной документации для этих двух классовAnimationControllerа такжеCurvedAnimation. мы первыеEnterизiniteStateобъявляет два экземпляра в
animation = CurvedAnimation(
parent: controller,
curve: Curves.linear,
);
animation.addListener(() {
setState(() {});
});
animation.addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller.repeat();
}
});
Контроллер имеет несколько методов управления анимацией.
- forward() движется вперед
- стоп() стоп
- reverse() перемещается назад (я тоже не понимаю эту концепцию. Оставьте это пока в стороне)
давайте следитьanimationКаждый раз, когда значение анимации изменяется, добавляйте функцию прослушивания черезsetStateдля запуска обновления текущего представления.
давайте следитьanimationСтатус анимации, чтобы определить, закончилась ли анимация, поэтому вызовитеrepeatметод, чтобы сделать цикл анимации непрерывным. С помощью приведенного выше кода.После запуска обнаруживается, что каждый кадр будет запускатьBackgroundRedRaw, на этот момент каждый раз, когда мы изменяем координаты фоновой карты из точек сюжета, вы можете добиться эффекта анимации.
paint(Canvas canvas, Size size) async {
...
y1 += 10;
}
Из-за записи экрана дисплей немного тормозит.зациклить фон
В обычной 2D-игре про самолеты фон игры циклически прокручивается.Общим методом обработки является отрисовка двух фоновых изображений в цикле и отрисовка их лицом к хвосту.Когда одно из фоновых изображений выкатывается за пределы экрана и перемещает его Перейти к верхней части предыдущего фонового изображения и совершать возвратно-поступательные движения вперед и назад, чтобы добиться эффекта круговой прокрутки фона.Здесь мы добавляем следующую логику для координат двух изображений и начальной точки,
y1 = y1 + 1 * speed;
y2 = y2 + 1 * speed;
if (y2 > image.height) {
y2 = y1 - image.height;
}
if (y1 > image.height) {
y1 = y2 - image.height;
}
В этом проекте, поскольку фоновое изображение, которое я нашел, было относительно небольшим, не было возможности заполнить весь экран, поэтому, когда я рисовал, я масштабировал Canvas.
canvas.scale(1, screenHeight / image.height);
Наконец, давайте посмотрим на эффект:
Суммировать
Первая часть, большая работа будет успешной, в ближайшие дни я добавлю соответствующую логику других элементов.git-портал