Младшая группа

15 января 2017г

Отправлено 19 янв. 2017 г., 13:37 пользователем Dimitrijs Fedotovs   [ обновлено 20 янв. 2017 г., 09:27 ]


На уроке мы сделали игру "Перейди дорогу". Задача игрока пройти снизу вверх поля избегая монстров. У нас будут два вида монстров - одни будут двигаться быстро, другие чуть-чуть медленнее.

level.txt

Уже ни для кого не секрет, как создать такой уровень: добавляем нужные символы в level.txt и регистрируем спрайты.
##################################
# * #
# #
# #
# 2 #
# #
# #
# 1 #
# #
# #
# 2 #
# #
# #
# 1 #
# #
# #
# 2 #
# #
# #
# 1 #
# #
# #
# m #
##################################

Звездочк - * - это портал
Цифры 1 и 2 - это монстры
Буква m - человечек, которым управляет игрок.

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

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

register('*', PortalSprite::new);

register('m', ManSprite::new);

register('1', ChickenSprite::new);

register('2', GhostSprite::new);

load("/level.txt");

Движение монстра

Монстр должен двигаться от стенки до стенки. Алгоритм его движения выглядит примерно так:

Следуя этому алгоритму монстр с самого начала летит в одну сторону и на каждом кадре проверяет, а не врезался ли он в стенку. Если врезался, то направление должно поменятся на противоположное. С проверкой врезался ли монстр в стенку все просто - используем событие onCollision. Осталось придумать как поменять направление. Для этого у меня есть еще один алгоритм:

В коде это выглядит очень просто:

.onCollision(c -> {
if (c.getDirection() == Direction.E) {
c.setDirection(Direction.W);
} else {
c.setDirection(Direction.E);
}
}, '#');

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

Оператор if проверяет что написано у него в скобках. В нашем случае там написано c.getDirection() == Direction.E. getDirection - "спросить" у спрайта в какую сторону он двигается. "==" - это проверить на равенство с направлениеа E. И если направление является E, тогда выполнить следующий лок кода - c.setDirection(Direction.W), а если какое-нибудь другое направление, то сработает блок кода в else - c.setDirection(Direction.E);

Таким образом врезаясь в стенку монстр будет "отпрыгивать" и лететь в другую сторону и так до следующей стенки.

Вот код одного монстра:

register('2', GhostSprite::new)
.onInit(c -> {
c.setDirection(Direction.E);
c.setSpeed(8);
c.setRotation(Direction.E);
})
.onLoop(ai::followDirection)
.onCollision(c -> {
if (c.getDirection() == Direction.E) {
c.setDirection(Direction.W);
c.setRotation(Direction.W);
} else {
c.setDirection(Direction.E);
c.setRotation(Direction.E);
}
}, '#');

Код второго монстра надо написать аналогичным этому.

Движение человечка

На предыдущих уроках (например 18 декабря 2016 г) мы рассматривали как управлять человечком при помощи клавиш. Код выглядит примерно так:

register('m', ManSprite::new)
.onKeyHold(m -> move(m, Direction.N), KeyCode.UP)
.onKeyHold(m -> move(m, Direction.S), KeyCode.DOWN)
.onKeyHold(m -> move(m, Direction.W), KeyCode.LEFT)
.onKeyHold(m -> move(m, Direction.E), KeyCode.RIGHT)
.onKeyReleased(m -> m.setSpeed(0), KeyCode.UP)
.onKeyReleased(m -> m.setSpeed(0), KeyCode.DOWN)
.onKeyReleased(m -> m.setSpeed(0), KeyCode.LEFT)
.onKeyReleased(m -> m.setSpeed(0), KeyCode.RIGHT);

Чтобы человечек не смог проходить через стенки:

.onCollision(ai::stopXY, '#')

И чтобы человечек "боялся" монстров:

.onCollision(ai::halt, '1', '2')

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

Дома доделать игру так, чтобы загружался следующий уровень, когда человечек "берет" портал. Как это делать читай на страничке урока 13 ноября 2016 г

Код целиком

public class MyGame extends Game {

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

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

register('*', PortalSprite::new);

register('m', ManSprite::new)
.onCollision(ai::stopXY, '#')
.onCollision(ai::halt, '1', '2')
.onKeyHold(m -> move(m, Direction.N), KeyCode.UP)
.onKeyHold(m -> move(m, Direction.S), KeyCode.DOWN)
.onKeyHold(m -> move(m, Direction.W), KeyCode.LEFT)
.onKeyHold(m -> move(m, Direction.E), KeyCode.RIGHT)
.onKeyReleased(m -> m.setSpeed(0), KeyCode.UP)
.onKeyReleased(m -> m.setSpeed(0), KeyCode.DOWN)
.onKeyReleased(m -> m.setSpeed(0), KeyCode.LEFT)
.onKeyReleased(m -> m.setSpeed(0), KeyCode.RIGHT);

register('1', ChickenSprite::new)
.onInit(c -> {
c.setDirection(Direction.E);
c.setSpeed(4);
c.setRotation(Direction.E);
})
.onLoop(ai::followDirection)
.onCollision(c -> {
if (c.getDirection() == Direction.E) {
c.setDirection(Direction.W);
c.setRotation(Direction.W);
c.setReverse(true);
} else {
c.setDirection(Direction.E);
c.setRotation(Direction.E);
c.setReverse(false);
}
}, '#');

register('2', GhostSprite::new)
.onInit(c -> {
c.setDirection(Direction.E);
c.setSpeed(8);
c.setRotation(Direction.E);
})
.onLoop(ai::followDirection)
.onCollision(c -> {
if (c.getDirection() == Direction.E) {
c.setDirection(Direction.W);
c.setRotation(Direction.W);
} else {
c.setDirection(Direction.E);
c.setRotation(Direction.E);
}
}, '#');


load("/level.txt");
}

private void move(ManSprite sprite, Direction dir) {
sprite.setSpeed(5);
sprite.setDirection(dir);
ai.followDirection(sprite);
}


@Override
public void loop() {

}
}

18 декабря 2016 г

Отправлено 9 янв. 2017 г., 13:35 пользователем Dimitrijs Fedotovs   [ обновлено 9 янв. 2017 г., 13:36 ]

Мы проходили то же самое, что и со старшей группой 11 декабря 2016 г

28 ноября 2016 г

Отправлено 28 нояб. 2016 г., 12:28 пользователем Dimitrijs Fedotovs   [ обновлено 28 нояб. 2016 г., 12:55 ]



Игра-стрелялка

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

Игровое поле и каретка

В первую очередь нам надо разместить на поле и зарегистрировать каретку.

Мы обозначим каретку знаком равно '=' и разместим ее в самом низу игрового поля:

##################################
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# #
# = #
##################################
и затем зарегистрируем:
register('=', CaretSprite::new)
установим скорость движения:
.onInit(c -> c.setSpeed(10))
направление:
.onInit(c -> c.setDirection(Direction.E))

Больше о направлениях можно почитать на страничке одного из прошлых уроков (старшей группы)

За тем на каждый кадр будем смещать каретку по указанному выше направлению:
.onLoop(ai::followDirection)
И напоследок - остановка каретки, если она врезалась в стенку:
.onCollision(ai::stopX)

Управление кареткой

Управлять кареткой мы будем при помощи клавиш вправо и влево. Для этого будем использовать специальное событие - onKeyPressed. Когда игрок нажмет клавишку влево, нам надо изменить направление движения кареткой на Direction.W - (West - запад). 
.onKeyPressed(c -> c.setDirection(Direction.W), KeyCode.LEFT)
Когда игрок нажимает клавишу вправо - Direction.E - (East - восток).
.onKeyPressed(c -> c.setDirection(Direction.E), KeyCode.RIGHT)

Результат

Код каретки должен получиться примерно такой:
register('=', CaretSprite::new)
.onInit(c -> c.setSpeed(10))
.onInit(c -> c.setDirection(Direction.E))
.onLoop(ai::followDirection)
.onCollision(ai::stopX)
.onKeyPressed(c -> c.setDirection(Direction.W), KeyCode.LEFT)
.onKeyPressed(c -> c.setDirection(Direction.E), KeyCode.RIGHT);
В результате каретка сразу начинает двигаться вправо (Direction.E). Но можно поменять направление движения при помощи клавиш вправо (KeyCode.RIGHT) и влево (KeyCode.LEFT).

Выстрел

К коду каретки надо добавить реакцию на клавишу пробел - KeyCode.SPACE.
.onKeyPressed(this::fire, KeyCode.SPACE)

Слово fire отмечено красным цветом - ошибка! Это потому, что наша программа пока еще не знает что такое fire. this - данном случае подсказка, что fire будет "объяснено" в этом же файле MyGame.

Чтобы продолжить, нужно поставить курсор (кликнуть мышкой) на слово fire. Слева появится красная лампочка. Кликнуть по этой лампочке и выбрать create method fire:

Если сделать все правильно, то появятся такие вот строчки:

Сейчас мы будем писать код в методе fire. То есть между открывающей фигурной скобкой и закрывающей { }

Этот код будет выполняться, когда игрок нажмет клавишу пробел. Значит написанное нами this::fire как раз и будет вызывать этот блок кода.

Создание спрайта шарика на экране

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

sprite(BallSprite::new, caretSprite.getX(), caretSprite.getY() - 1);

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

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

Установить скорость:

.onInit(b -> b.setSpeed(10))
Установить направление:
.onInit(b -> b.setDirection(Direction.N))
Двигаться в заданном направление:
.onLoop(ai::followDirection)

Все готово?

Если теперь запустить игру, то шарики будут улетать вверх. Выглядит, как будто все готово. Но на самом деле у нас закралась одна ошибка: 

При каждом выстреле мы создаем новый шарик на экране. И он улетает вверх. Но исчезнув и экрана - это не значит, что шарик исчез из игры. Он продолжает лететь вверх даже в "космосе", даже если мы его не видим.

Если выстрелить очень много шариков, то рано или поздно игра начнет "тормозить".

Как же быть? Нужно удалять шарик из игры (halt) когда он коснется стены сверху. То есть написать обработку события onCollision:
.onCollision(ai::halt, WallSprite.class)

Итог

Код шарика должен получится следующий:
private void fire(CaretSprite caretSprite) {
sprite(BallSprite::new, caretSprite.getX(), caretSprite.getY() - 1)
.onInit(b -> b.setSpeed(10))
.onInit(b -> b.setDirection(Direction.N))
.onLoop(ai::followDirection)
.onCollision(ai::halt, WallSprite.class);
}
Все готово!

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

Нужно сделать так, чтобы кареткой можно было управлять не только вправо и влево, но так же вверх и вниз!
Подсказки:
  • коды клавиш
    • KeyCode.UP - клавиша "вверх"
    • KeyCode.DOWN - клавиша "вниз"
  • чтобы каретка не улетала вверх или вниз за экран нужно воспользоваться ai::stopXY.

Код

Полный код, написанный во время занятия:
import guru.bug.game.*;
import guru.bug.game.sprite.*;
import guru.bug.game.background.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseButton;


public class MyGame extends Game {

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

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

register('=', CaretSprite::new)
.onInit(c -> c.setSpeed(10))
.onInit(c -> c.setDirection(Direction.E))
.onLoop(ai::followDirection)
.onCollision(ai::stopX)
.onKeyPressed(c -> c.setDirection(Direction.W), KeyCode.LEFT)
.onKeyPressed(c -> c.setDirection(Direction.E), KeyCode.RIGHT)
.onKeyPressed(this::fire, KeyCode.SPACE);

load("/level.txt");
}

private void fire(CaretSprite caretSprite) {
sprite(BallSprite::new, caretSprite.getX(), caretSprite.getY() - 1)
.onInit(b -> b.setSpeed(10))
.onInit(b -> b.setDirection(Direction.N))
.onLoop(ai::followDirection)
.onCollision(ai::halt, WallSprite.class);
}

@Override
public void loop() {

}
}

13 ноября 2016 г

Отправлено 16 нояб. 2016 г., 08:39 пользователем Dimitrijs Fedotovs   [ обновлено 16 нояб. 2016 г., 11:16 ]

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

На этом уроке мы нарисовали лабиринт, и проходили его управляя шариком, который следовал за курсором мышки.

В конце лабиринта мы поставим спрайт GemSprite и если шарик в него врежется мы загрузим еще один уровень

Рисование стен

Создав новый проект у нас сразу есть стены, очерчивающие прямоугольник игрового поля. В файле level.txt они обозначены при помощи символа-решетки - '#'.

В коде игры символ решетки зарегистрирован для рисования спрайтов стен:

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

Так что все, что нам нужно сделать - это нарисовать лабиринт. Например, такой:

#################################
# # # # # #
# x # # # # #
# # # # # #
# # # # # # ##### #
# # # # # #
# # # # # #
# # # # # #
# # ##### ######### # #
# # # # # #
# # # # # #
# # # # # #
# ##### # ##### # #####
# # # # # #
# # # # # #
# # # # # #
##### # ##### ##### # #
# # # # #
# # # # #
# # # # #
# ##### ##### # ##### #
# # # # # # #
# # # # # # #
# # # # # # #
##### # # ##### #########
# # # # #
# # # # #
# # # # #
# # ######### ##### # #
# # # #
# # # o #
# # # #
#################################

Чтобы не терять времени сразу поставим в лабиринт шарик 'o' и выход 'x'. Так же нам надо зарегистрировать эти символы. Для символа 'x' мы будем использовать новый спрайт - GemSprite.

Получился следующий код:

public void setup() {
setBackground(new SpaceBackground());

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

register('x', GemSprite::new);

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

load("/level.txt");
}

Перемещение шарика при помощи мышки

Если сейчас запустить проект - мы увидим лабиринт, шарик и кристалл. Но пока шариком управлять нельзя. Для того чтобы шарик полетел за мышкой нужно установить ему скорость и вызывать ai::followMouseXY на каждый кадр игры.

register('o', BallSprite::new)
.onInit(b -> b.setColor(BallColor.GREEN))
.onInit(b -> b.setSpeed(12))
.onLoop(ai::followMouseXY);

Непроницаемые для шарика стены

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

register('o', BallSprite::new)
.onInit(b -> b.setColor(BallColor.GREEN))
.onInit(b -> b.setSpeed(12))
.onLoop(ai::followMouseXY)
.onCollision(ai::stopXY);

Спрайт GemSprite

Если мы хотим изменить вид спрайта GemSprite, есть возможность поменять его цвет и картинку:

register('x', GemSprite::new)
.onInit(g -> g.setColor(GemColor.BLUE))
.onInit(g -> g.setIcon(GemIcon.FIRE));
Доступные цвета
 Название цвета
 
GREEN
 
 WHITE 
 ORANGE 
 BLUE 
 VIOLET 
 NONE (невидимый)

Доступные картинки (иконки)

 Название иконки
 
 QUESTION 
 HEART 
 SKULL 
 FIRE 
 ONE_BALL 
 SNAIL_CIRCLE 
 LIGHTNING_SQUARE 
 EXPAND 
 SNAIL_SQUARE 
 LIGHTNING_CIRCLE 
 SHRINK 
 THREE_BALLS 
 NONE Без иконки

Загрузка нового уровня

Теперь, когда у нас первый уровень лабиринта готов и в нем есть шарик и спрайт, означающий выход, создадим еще один лабиринт - level-2.txt.

Для этого на панели Project надо развернуть список файлов как показано на картинке:

Затем кликнуть правой кнопкой по строчке src и выбрать New -> File:

Должно появится окошко, куда нужно ввести название файла - level-2.txt и нажать OK:

В результате должно получится следующее:

Создадим второй уровень игры - другой лабиринт. Например, такой:

###############################
#o # # # #
# # # # #
# #### ####### # ### ## #
# # # # #
# # # # #
# ########## ####### # ####
# # # # # #
# # # # # #
####### # # # # # # ####
# # # # # # # #
# # # # # # # #
# # ########## ####### ####
# # # # #
# # # # #
# ####### ########## #### #
# # # # # # #
# # # # # # #
####### # # # # # #######
# # # # # #
# # # # # #
# # ####### # ####### # #
# # # # # # #
# # # # # # #
# ####### ####### ##########
# #
# #
#### # ####### #############
# # # #
# # # x#
###############################

Нарисуем этот лабиринт в созданном файле level-2.txt

Осталось сделать так, чтобы этот уровень загрузился, когда шарик врезается в драгоценный камень.

Сделать это очень просто, в коде отвечающим за GemSprite напишем следующее:

register('x', GemSprite::new)
.onInit(g -> g.setColor(GemColor.BLUE))
.onInit(g -> g.setIcon(GemIcon.FIRE))
.onCollision(g -> load("/level-2.txt"));

В последней строчке этого кода - самое главное - если чтото врежется в драгоценный камень - произойдет загрузка второго уровня (load("/level-2.txt"))

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

  1. Нарисовать еще один уровень. Сделать так, чтобы из второго уровня попадали в третий.
    Подсказка: Для этого надо будет зарегистрировать еще один GemSprite под другой буквой и во втором уровне рисовать его вместо 'x'. В событии onCollision этого, нового, спрайта загружать третий уровень.
  2. Сделать возможным переход из второго уровня не только в третий, но и обратно в первый. И так же из третьего - возможность вернуться во второй.

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");
}

9 октября 2016 г

Отправлено 9 окт. 2016 г., 13:04 пользователем Dimitrijs Fedotovs   [ обновлено 10 окт. 2016 г., 08:53 ]

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

  • Вспомнили как создавать уровень игры из стен, блоков, огня и шарика
  • Начали разбираться о том, что такое событие, какие события бывают и как на них реагировать.
    • onInit - событие, срабатывающие в самом начале, перед тем, как отобразить первый кадр игры.
    • onLoop - событие, срабатывающее на каждый кадр игры
    • onCollision - событие, срабатывающее если спрай сталкивается с другим спрайтом.

Примеры, которые использовали на занятии

Шарик, который улетает за экран:

       // зарегистрировать символ 'o' для создания шарика (BallSprite)
register('o', BallSprite::new)                   
           // при инициализации "включить" огненный хвост
    .onInit(b -> b.setFlame(true))
           // при инициализации указать скорость движения 10 клеток в секунду
    .onInit(b -> b.setSpeed(10))                 
           // на каждый кадр сдвигать шарик в указанном направлении с указанной скоростью
    .onLoop(ai::followDirection);

Мяч, который отскакивает от других спрайтов

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

Мяч отскакивает от других спрайтов и исчезает, если врезается в спрайт огня

Код аналогичный предыдущему примеру, только с дополнительной строчкой в конце, указывающей, что надо шарику исчезнуть, если врезался в огонь:

           // при столкновении со спрайтом огня - удалить шарик из игры
    .onCollision(ai::halt, TrapSprite.class);

Мяч, следующий за курсором мышки

    // зарегистрировать символ 'o' для создания шарика (BallSprite)
register('o', BallSprite::new)                   
        // при инициализации указать скорость движения 10 клеток в секунду
    .onInit(b -> b.setSpeed(10))                 
        // на каждый кадр сдвигать шарик по координатам X и Y
        // в направлении курсора мышки, с указанной скоростью

    .onLoop(ai::followMouseXY)                   
        // на каждый кадр поворачивать шарик "лицом" по направлению к курсору мышки
    .onLoop(ai::turnToMouse)                     
        // при столкновении с другим (любым) спрайтом - остановиться
    .onCollision(ai::stopXY);

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

Для родителей

Для детей

  • Повторить все что делали на занятии, но по мере возможности самостоятельно
  • Можно "подсмотреть" чем занималась другая группа 2 октября 2016 г. Там чуть-чуть больше информации.

25 сентября 2016 г

Отправлено 6 окт. 2016 г., 10:18 пользователем Dimitrijs Fedotovs   [ обновлено 10 окт. 2016 г., 08:58 ]

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

  • что такое алгоритм
  • элементы игр (спрайты, уровни, коллизии)
  • ознакомление с IDE, и редактирование уровня игры

Создание спрайта на экране

register('#', WallSprite::new);     // стена

register('o', BallSprite::new);     // шарик

register('-', BlockSprite::new);    // блок

register('w', TrapSprite::new);     // лава

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

  1. Представь, что ты дома, делаешь домашние задания. Вдруг захотелось чего то перекусить. (Яблоко, конфету и т.д. и т.п.). Нарисовать алгоритм действий.
    Постараться учесть все возможные условия. Например: "Сходить на кухню, посмотреть, есть ли яблоки. Если нет, сходить в магазин - купить. А есть ли деньги? Если нет попросить у родителей" и т.д.
    Нарисовать в виде блок-схемы. Пример, блок-схемы распечатанный выдан каждому ребенку. Если забыли - скачать здесь Sorting.pdf
  2. Придумать свою простую игру. Постараться уложиться в не более 3-5 персонажей. На бумаге в клеточку схематично нарисовать один или несколько уровней этой игры. Пример здесь: level.pdf
    На разных уровнях использовать по максимуму одни и те же персонажи/спрайты.
  3. Нарисовать блок-схему поведения персонажей. Например: algorithm_monster.pdf

1-7 of 7