Основная механика: вращение автоматически сгенерированных слоев с помощью Utils.interval
Другие игры и/или игровые механики из этой серии
На данный момент это последняя запись в этой серии. Буду рад прочитать ваши предложения в комментариях.
- Выбор персонажа в штаб-квартире рейда [четверг, 23 июня]
- Бесконечный бегун [четверг, 30 июня]
- Guitar Hero [четверг, 7 июля]
- Карточный матч [четверг, 14 июля]
- Змея [четверг, 21 июля]
- Ловец падающего мяча [четверг, 28 июля]
- Аркадный джойстик [четверг, 4 августа]
- Раздвижные блоки [четверг, 11 августа]
- Вертикальный платформер [четверг, 18 августа]
- Понг [четверг, 25 августа]
- Буря [четверг, 1 сентября]
Ссылка на прототип Framer
Элементы игры
- Шкала здоровья
- Игровые кольца
- Объект игрока
- Пуля игрока
- Враг
- Управление игроком
- Игровые циклы
Шкала здоровья
Состоит из двух слоев, один является родителем другого. Счетчик здоровья ребенка будет масштабироваться горизонтально, когда игрок получает удар.
# Health gauge damageMeter = new Layer width: Screen.width height: 50 health = new Layer parent: damageMeter width: Screen.width height: 50 backgroundColor: "green" originX: 0
Игровые кольца
- playerRing управляет вращением объекта игрока
- bulletRing управляет вращением игрока (это отдельно от playerRing, поэтому после выстрела пуля может сохранять свою собственную траекторию и не будет вращаться при вращении объекта игрока)
- вражеское кольцо управляет вращением вражеского объекта. Ему присваивается случайное значение в каждом игровом цикле.
# Three game rings playerRing = new Layer width: 600 height: 600 x: Align.center y: Align.center borderRadius: "50%" backgroundColor: "transparent" bulletRing = new Layer width: 600 height: 600 x: Align.center y: Align.center borderRadius: "50%" backgroundColor: "transparent" enemyRing = new Layer width: 600 height: 600 x: Align.center y: Align.center borderRadius: "50%" backgroundColor: "transparent" rotation: Utils.randomNumber(0, 360)
Объект игрока
Простой слой с одним дополнительным состоянием, указывающим на то, что он был поражен вражеским объектом.
# Player object plane = new Layer parent: playerRing width: 100 height: 100 x: Align.center y: Align.top(-50) borderRadius: 10 backgroundColor: "white" plane.states.add damaged: backgroundColor: "red"
Управление игроком
SliderComponent дает нам хорошо сопоставленный элемент управления для нашего объекта игрока. Поскольку я решил запустить объект игрока в верхней части playerRing, я установил ползунок в середину и сопоставил вращение playerRing, чтобы игрок мог перемещать ручку влево или вправо от центра.
# Primary control control = new SliderComponent x: Align.center y: Align.bottom(-100) width: Screen.width - 200 control.knobSize = 100 control.value = 0.5 control.on "change:value", -> playerRing.rotation = Utils.modulate(control.value, [0,1], [-180,180])
Игровой цикл: стрельба пулями
Каждую секунду:
- Кольцо пули настроено так, чтобы соответствовать кольцу игрока.
- Новая пуля создается с двумя анимациями: одна для перемещения к центру, а другая для создания эффекта взрыва. Инициализируется первая анимация, и по ее окончании сработает вторая анимация. После окончания второй анимации слой пули уничтожается в качестве очистки.
# Game loop: shoot bullets Utils.interval 1, -> bulletRing.rotation = playerRing.rotation bullet = new Layer parent: bulletRing width: 25 height: 25 x: Align.center y: Align.top(50) backgroundColor: "yellow" borderRadius: "50%" shoot = new Animation layer: bullet properties: y: Align.center opacity: .2 time: 1 curve: "linear" explode = new Animation layer: bullet properties: scale: 2 opacity: 0 time: 0.5 shoot.start() shoot.onAnimationEnd -> explode.start() explode.onAnimationEnd -> bullet.destroy()
Игровой цикл: возродить врага
Запуск с интервалом в 4 секунды:
- кольцо врага случайно вращается
- Создается новый враг, и ему назначается анимация, которая перемещает его от центра наружу к объекту игрока.
- Когда вражеский слой движется к объекту игрока, игра наблюдает за ним, чтобы обнаружить столкновение либо между пулей игрока, либо между объектом игрока.
- Если он сталкивается с пулей, он уничтожается, а интервал уменьшается (чтобы игра шла быстрее, тем самым увеличивая сложность)
- Если он сталкивается с объектом игрока, кажется, что игрок получает урон, индикатор здоровья уменьшается, а пуля уничтожается.
# Game loop: respawn enemy object time = 4 Utils.interval 4, -> enemyRing.rotation = Utils.randomNumber(-180,180) enemy = new Layer parent: enemyRing backgroundColor: "red" width: 25 height: 25 borderRadius: "50%" opacity: 0 x: Align.center y: Align.center move = new Animation layer: enemy properties: y: Align.top opacity: 1 time: time curve: "linear" move.start() move.onAnimationEnd -> enemy.destroy() enemy.on "change:y", -> for bullet in bulletRing.children if (enemy.midX > bullet.x && enemy.midX < bullet.maxX) && (enemy.midY > bullet.y && enemy.midY < bullet.maxY) && (Utils.round(enemyRing.rotation, 0, 10) == Utils.round(bulletRing.rotation, 0, 10)) if time > 1 time -= 0.25 else if time < 1 time = 1 bullet.destroy() enemy.destroy() if (enemy.midX > plane.x && enemy.midX < plane.maxX) && (enemy.midY > plane.y && enemy.midY < plane.maxY) && (Utils.round(enemyRing.rotation, 0, 40) == Utils.round(playerRing.rotation, 0, 40)) if health.scaleX > 0.1 health.scaleX -= 0.1 else if Utils.round(health.scaleX, 1) == 0.1 print "You died" plane.states.switchInstant "damaged" plane.states.switch "default" enemy.destroy()
Механика Framer/CoffeeScript выделена здесь
- Слушатели событий
- Состояния слоя
- Поток управления
- Петли
- Глобальные переменные