30 октября 2016 г

Отправлено 31 окт. 2016 г., 12:54 пользователем Dimitrijs Fedotovs   [ обновлено 31 окт. 2016 г., 13:08 ]

Пройденный материал

  • Повтороили материал с предыдущих уроков
    • Как регистрировать спрайты и рисовать уровень
    • Запуск шарика
    • Отскок шарика от стен
    • Удаление шарика с экрана, если он врезался в ловушку (огонь, лаву и прочее)
  • Новый материал
    • Цвета шариков, типы ловушек и блоков.
    • Каретка

Ход занятия

Создание нового проекта

Инструкция как создать новый проект

Добавление спрайтов в level.txt

  1. открыть level.txt
  2. добавить туда один вид блоков при помощи какого-нибудь символа, например "=". Учитываем, что один блок занимает две клетки
  3. добавить другой вид блоков при помощи другого символа, например "+"
  4. добавить шарик при помощи символа "o"
  5. внизу добавить ловушки при помощи символа "w". Учитываем, что ловушка занимает 4 клетки
  6. над ловушками добавить каретку при помощи симовла "-"

Должно получится чтото похожее на такой уровень:

##################################
# #
# = = = = = = = = = = = = = = = #
# = + = + = + = + = + = + = + = #
# = = = = = = = = = = = = = = = #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# o #
# #
# - #
#w w w w w w w w #

Регистрация спрайтов

Открываем MyGame.java. Видим, что символ решетки "#" уже зарегистрирован для стенок. Аналогично регистрируем блоки, ловушки, шарик и каретку:

@Override
public void setup() {
setBackground(new DesertBackground());

register('#', WallSprite::new)
.onInit(w -> w.setColor(WallColor.BLUE));

register('=', BlockSprite::new);

register('+', BlockSprite::new);

register('w', TrapSprite::new);

register('o', BallSprite::new);

register('-', CaretSprite::new);

load("/level.txt");
}

Промежуточный результат 1

Теперь, если запустить игру, у нас должен получиться такой вот уровень:

 Что осталось сделать?
  1. Мы зарегистрировали два разных блока символами "=" и "+". Но выводятся все блоки одинаковые.
  2. Каретка не двигается
  3. Шарик не летает

Разные блоки

Необходимо дополнить регистрацию блоков обработкой события onInit и там установить материал блоков:

register('=', BlockSprite::new)
     .onInit(b -> b.setMaterial(BlockMaterial.METAL));

Возможны следующие варианты:

  • AMBER
  • CANDY
  • METAL
  • BUBBLESTONE
  • GREENSTONE
  • CITRINE
  • BRICK
  • SAND
  • CONCRETE

Самостоятельно придумываем и изменяем код, чтобы блок под символом "=" был бы одного вида, а под символом "+" другого.

Движение каретки

В первую очередь нужно задать скорость на событие onInit:

.onInit(c -> c.setSpeed(15));

Затем, на каждый кадр нужно сдвигать каретку по горизонтали по направлению к курсору мышки:

.onLoop(ai::followMouseX);
Если оставить так, то каретка будет проезжать сквозь стены. Надо добавить обработку события столкновения:
.onCollision(ai::stopX);
Собираем все вместе. Должен получиться такой код для каретки:
register('-', CaretSprite::new)
.onInit(c -> c.setSpeed(15))
.onLoop(ai::followMouseX)
.onCollision(ai::stopX);
Запускаем игру - каретка двигается за мышкой.

Запуск шарика

В первую очередь надо задать скорость шарика:
.onInit(b -> b.setSpeed(10));
Для каждого кадра шарик должен сдвигаться в заданном направлении (по умолчанию вверх)
.onLoop(ai::followDirection);
Теперь шарик просто улетит вверх сквозь блоки и стены. Нам нужно добавить отскок при сталкновении:
.onCollision(ai::bounce);
Собрав все вместе получается следующий код для шарика:
register('o', BallSprite::new)
.onInit(b -> b.setSpeed(10))
.onLoop(ai::followDirection)
.onCollision(ai::bounce);

Промежуточный результат 2

Запускаем игру, проверяем, исправляем ошибки.
На этот раз шарик должен летать, отскакивать от стен, блоков и от каретки. Но так же он отскакивает и от лавы! Еще есть другая проблема - блоки не исчезают от удара шарика.

Исчезновение шарика при попадании в лаву

Чтобы шарик исчезал от попадания в лаву, нужно добавить еще одну обработку события onCollision на шарике, но только для конкретного класса спрайтов - ловушки:

.onCollision(ai::halt, TrapSprite.class);

Теперь шарик исчезнект (ai::halt) как только коснеться лавы (TrapSprite). Все вместе код выглядит так:

register('o', BallSprite::new)
.onInit(b -> b.setSpeed(10))
.onLoop(ai::followDirection)
.onCollision(ai::bounce)
.onCollision(ai::halt, TrapSprite.class);

Исчезновение блоков от удара шарика

Аналогично исчезновению шарика, нужно добавить обработку onCollision для блоков:

.onCollision(ai::halt, BallSprite.class);

или если совместить с кодом блока:

register('=', BlockSprite::new)
.onInit(b -> b.setMaterial(BlockMaterial.CITRINE))
.onCollision(ai::halt, BallSprite.class);

Внимание! У нас так же есть блок, обозначенный символом "+". Самостоятельно добавьте обработку onCollision и для него, иначе эти блоки будет невозможно выбить.

Дополнительные примеры

Вид ловушки (огонь, лава, вода)

register('w', TrapSprite::new)
    .onInit(t -> t.setMaterial(TrapMaterial.FIRE));

Так же можно использовать другие материалы ловушки:

  • ACID
  • LAVA
  • WATER
  • PLASMA
  • FIRE

Цвет шарика

register('o', BallSprite::new)
     .onInit(b -> b.setColor(BallColor.YELLOW));

Возможны следующие цвета:

  • BLUE
  • YELLOW
  • VIOLET
  • GREEN

Материал блока

register('=', BlockSprite::new)
     .onInit(b -> b.setMaterial(BlockMaterial.METAL));

Возможны следующие варианты:

  • AMBER
  • CANDY
  • METAL
  • BUBBLESTONE
  • GREENSTONE
  • CITRINE
  • BRICK
  • SAND
  • CONCRETE

Цвет стены

register('#', WallSprite::new)
     .onInit(b -> b.setColor(WallColor.BLUE));

Возможны следующие цвета:

  • ORANGE
  • GREEN
  • BLUE
  • GRAY
  • BLACK

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

  1. Повторить дома все шаги, опсанные здесь.
  2. Добавить еще один, третий тип блоков.
  3. Добавить еще один, второй шарик, другого цвета.
  4. Второй шарик не должен бояться лавы - просто отскакивать от нее.

Код целиком

@Override
public void setup() {
setBackground(new DesertBackground());

register('#', WallSprite::new)
.onInit(w -> w.setColor(WallColor.BLUE));

register('=', BlockSprite::new)
.onInit(b -> b.setMaterial(BlockMaterial.CITRINE))
.onCollision(ai::halt, BallSprite.class);

register('+', BlockSprite::new)
.onInit(b -> b.setMaterial(BlockMaterial.METAL));

register('w', TrapSprite::new)
.onInit(t -> t.setMaterial(TrapMaterial.WATER));

register('o', BallSprite::new)
.onInit(b -> b.setSpeed(10))
.onLoop(ai::followDirection)
.onCollision(ai::bounce)
.onCollision(ai::halt, TrapSprite.class);

register('-', CaretSprite::new)
.onInit(c -> c.setSpeed(15))
.onLoop(ai::followMouseX)
.onCollision(ai::stopX);

load("/level.txt");
}
Comments